# Build and Package

This guide is for developers who want to build the MCP server from source and create packages.

## Prerequisites

- **Node.js 24.6.0+** installed
- **npm** or **yarn** package manager
- **TypeScript** knowledge (for development)

## Project Structure

```
mcp/
├── src/
│   ├── index.ts              # MCP bootstrap entrypoint
│   ├── config.ts             # Environment parsing and runtime limits
│   ├── client/
│   │   ├── index.ts          # BanyanDB HTTP client
│   │   └── types.ts          # Client type definitions
│   ├── query/
│   │   ├── context.ts        # Schema/resource discovery helpers
│   │   ├── llm-prompt.ts     # BydbQL prompt generation
│   │   ├── types.ts          # Query type definitions
│   │   └── validation.ts     # Query and hint validation
│   ├── server/
│   │   ├── http.ts           # HTTP transport, auth, and rate limiting
│   │   └── mcp.ts            # MCP prompt/tool registration and handlers
│   └── utils/
│       ├── http.ts           # HTTP utilities
│       └── logger.ts         # Logging utilities
├── tools/
│   └── checkversion.js        # Version checking utility
├── dist/                     # Compiled JavaScript (generated)
├── banyandb-data/            # BanyanDB data directory (runtime)
├── Dockerfile                # Multi-stage Docker build file
├── docker-compose.yml        # Docker Compose configuration
├── eslint.config.mjs         # ESLint configuration
├── tsconfig.json             # TypeScript configuration
├── package.json              # Node.js dependencies and scripts
├── package-lock.json         # Dependency lock file
├── example-config.json       # Example MCP configuration
├── LICENSE                   # License file
├── LICENSE.tpl               # License template
├── Makefile                  # Build automation
```

## Building from Source

### 1. Install Dependencies

```bash
cd mcp
npm install
```

### 2. Build

```bash
npm run build
```

This compiles TypeScript to JavaScript in the `dist/` directory.

### 2b. Build the BydbQL validator binary

The `validate_bydbql` tool runs the prebuilt Go validator at `tools/bin/bydbql-parse`.
Build it (requires the Go toolchain) so the tool does not depend on `go run` at
runtime:

```bash
npm run build:validator
```

To produce both the TypeScript output and the validator binary in one step:

```bash
npm run build:all
```

The runtime is organized into small modules:

- `src/index.ts` wires together configuration, transport selection, and startup.
- `src/server/mcp.ts` owns MCP prompt/tool registration and handlers.
- `src/server/http.ts` owns HTTP transport, request limits, auth, and rate limiting.
- `src/query/validation.ts` centralizes validation for BydbQL and entity hints.

### 3. Verify Build

```bash
BANYANDB_ADDRESS=localhost:17900 node dist/index.js
```

The server starts in `stdio` mode by default. Use `TRANSPORT=http` if you want to verify the HTTP transport:

```bash
TRANSPORT=http BANYANDB_ADDRESS=localhost:17900 node dist/index.js
```

## Development Mode

For development, you can use `tsx` to run TypeScript directly without compilation:

```bash
npm run dev
```

This runs `src/index.ts` directly using `tsx`, which is faster for iterative development.

## Development Workflow

### 1. Make Changes

Edit the relevant files in `src/`:

- transport/bootstrap changes: `src/index.ts`, `src/server/http.ts`
- tool behavior and prompt wiring: `src/server/mcp.ts`
- query validation: `src/query/validation.ts`
- BanyanDB API access: `src/client/index.ts`

### 2. Format and Lint

Before testing, format your code and check for linting issues:

```bash
npm run format
npm run lint
```

### 3. Test Changes

Use development mode for quick testing:

```bash
npm run dev
```

Or build and test:

```bash
npm run build
node dist/index.js
```

### 3. Test with Inspector

Use MCP Inspector to test your changes:

```bash
# Terminal 1: start the MCP server
npm run build
BANYANDB_ADDRESS=localhost:17900 node dist/index.js

# Terminal 2: run Inspector and point it at the local server command or HTTP URL
npx @modelcontextprotocol/inspector
```

## Debugging

### VS Code Debug Configuration

Create `.vscode/launch.json` in the `mcp` directory:

```json
{
  "version": "0.1.0",
  "configurations": [
    {
      "name": "Debug with MCP Inspector",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "npx",
      "runtimeArgs": [
        "@modelcontextprotocol/inspector",
        "--cli"
      ],
      "env": {
        "BANYANDB_ADDRESS": "localhost:17900"
      },
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "skipFiles": ["<node_internals>/**"],
      "sourceMaps": true,
      "outputCapture": "std"
    }
  ]
}
```

### Debugging Steps

1. Set breakpoints in TypeScript files
2. Select "Debug with MCP Inspector" from the debug dropdown
3. Press F5 to start debugging
4. Inspector UI opens at http://localhost:6274
5. Test queries through the Inspector UI - breakpoints will trigger

## Packaging

### Create Distribution Package

The build process creates a `dist/` directory with compiled JavaScript files. To create a distributable package:

```bash
# Build
npm run build

# Create package (includes dist/ and package.json)
tar -czf banyandb-mcp.tar.gz dist/ package.json
```

### Docker Image

The project includes a production-ready Dockerfile that uses a multi-stage build for optimal image size and security.

#### Build Docker Image

To build a Docker image:

```bash
cd mcp

# Build the image
docker build -t apache/skywalking-banyandb-mcp:latest .
```

Or using the Makefile:

```bash
# From the project root
make -C mcp docker

# Or from the mcp directory
cd mcp
make docker
```

#### Dockerfile Features

The Dockerfile includes:
- **Multi-stage build**: Separate build and production stages for smaller final image
- **Security**: Runs as non-root user (`appuser`) for better security
- **Optimization**: Only production dependencies in final image
- **Runtime validation**: Supports HTTP safety controls such as `MCP_HOST`, `MCP_AUTH_TOKEN`, request size limits, and rate limiting

#### Build Arguments

The Dockerfile supports standard Docker build arguments. You can customize the build:

```bash
docker build \
  --build-arg NODE_ENV=production \
  -t apache/skywalking-banyandb-mcp:latest .
```

#### Testing the Docker Image

After building, test the image:

```bash
# Run the container
docker run --rm \
  -e BANYANDB_ADDRESS=localhost:17900 \
  apache/skywalking-banyandb-mcp:latest
```

To test HTTP mode in Docker:

```bash
docker run --rm \
  -p 3000:3000 \
  -e TRANSPORT=http \
  -e MCP_HOST=0.0.0.0 \
  -e MCP_AUTH_TOKEN=replace-with-a-strong-random-token \
  -e BANYANDB_ADDRESS=host.docker.internal:17900 \
  apache/skywalking-banyandb-mcp:latest
```

#### Publishing Docker Image

To publish the image to a registry:

```bash
# Tag the image
docker tag apache/skywalking-banyandb-mcp:latest \
  ghcr.io/apache/skywalking-banyandb-mcp:v1.0.0

# Push to registry
docker push ghcr.io/apache/skywalking-banyandb-mcp:v1.0.0
```

### Integration with Main Makefile

The MCP server is already integrated into the main project Makefile. The `mcp/Makefile` includes:

- **Build targets**: `build`, `all`, `docker`
- **Clean targets**: `clean-build`
- **Install targets**: `install`
- **License targets**: `license-check`, `license-fix`, `license-dep`
- **Version checking**: `check-version`

#### Common Makefile Commands

```bash
# Build the project (includes format check, lint, and TypeScript compilation)
make -C mcp build

# Build Docker image
make -C mcp docker

# Install dependencies
make -C mcp install

# Clean build artifacts
make -C mcp clean-build

# Check license headers
make -C mcp license-check

# Fix license headers
make -C mcp license-fix
```

The Makefile automatically handles:
- Code formatting checks (`format:check`)
- Code linting (`lint`)
- Dependency installation
- TypeScript compilation
- Docker image building (with proper tagging)
- Version management

## Testing

### Integration Tests

Test with real BanyanDB instance:

1. Start BanyanDB:
   ```bash
   docker-compose up -d
   ```

2. Run MCP Inspector:
   ```bash
   npm run build
   BANYANDB_ADDRESS=localhost:17900 node dist/index.js
   ```

   In another terminal:

   ```bash
   npx @modelcontextprotocol/inspector
   ```

3. Test various queries through the Inspector UI

## Code Quality

### Linting

The project includes ESLint for code quality checks. Run linting:

```bash
npm run lint
```

This will check all TypeScript files in the `src/` directory for code quality issues.

### Formatting

The project uses Prettier for code formatting. Format your code:

```bash
npm run format
```

Check formatting without making changes (useful for CI):

```bash
npm run format:check
```

Both linting and formatting are integrated into the build process via the Makefile.

## Release Process

1. **Update version** in `package.json`
2. **Format code**: `npm run format`
3. **Lint code**: `npm run lint`
4. **Build** the project: `npm run build` (or `make build` which includes lint/format checks)
5. **Test** with Inspector
6. **Create package** or Docker image
7. **Tag** the release in git
8. **Publish** Docker image (if applicable)

## Troubleshooting

**Build fails:**
- Check Node.js version: `node --version` (should be 20+)
- Clear node_modules and reinstall: `rm -rf node_modules && npm install`
- Check TypeScript version compatibility

**Type errors:**
- Run `npm run build` to see all TypeScript errors
- Check `tsconfig.json` configuration

**Runtime errors:**
- Verify all dependencies are installed: `npm install`
- Check environment variables are set correctly
- Verify BanyanDB is accessible

## Resources

- [TypeScript Documentation](https://www.typescriptlang.org/docs/)
- [MCP SDK Documentation](https://github.com/modelcontextprotocol/typescript-sdk)
- [Node.js Documentation](https://nodejs.org/docs/)
