Verix API MCP Server Starter
Overview
This template provides a production-ready Model Context Protocol (MCP) server built with TypeScript and Express, purpose-built for integrating the Verix API into AI assistant workflows. It ships with HTTP Streamable transport, API key authentication, and a reusable Verix API client so you can move from zero to a fully functional MCP server in under twenty minutes.
The template is engineered for enterprise environments. Every layer — from input validation (Zod) to structured logging (Pino with correlation IDs) to retry logic and rate limiting — is implemented with production concerns in mind. Docker multi-stage builds keep images lean, and a GitHub Actions CI/CD pipeline runs lint, type-check, tests, and Docker build on every pull request.
This template is ideal for platform engineers, backend developers, and AI integration teams who need a trustworthy starting point that they can extend with their own Verix API operations without rethinking the infrastructure. Whether you are deploying to Railway, Fly.io, or your own Kubernetes cluster, the deployment path is straightforward and fully documented.
What You'll Learn
- How to register and expose MCP tools over HTTP Streamable transport using the official MCP TypeScript SDK
- How to implement API key authentication middleware that integrates cleanly with the MCP request lifecycle
- How to build a reusable, typed HTTP client for an external API with automatic retry logic using exponential backoff
- How to set up Pino for structured JSON logging with per-request correlation IDs propagated through async context
- How to use Zod to validate MCP tool input parameters and return descriptive errors to the LLM caller
- How to implement a
/healthendpoint that checks external API reachability and returns structured JSON status - How to write supertest-based integration tests that cover auth rejection, health checks, and tool execution
- How to configure a multi-stage Dockerfile that produces a minimal production image
- How to wire up a GitHub Actions pipeline with lint, type-check, test, and Docker build jobs
- How to apply Express rate limiting to protect the server under high concurrency
- How to manage all configuration through validated environment variables with sensible defaults
- How to structure a TypeScript MCP server project for long-term maintainability
Architecture
Claude Desktop / Cursor / Windsurf
│
▼ HTTP POST (MCP JSON-RPC)
┌───────────────────┐
│ Express Server │ :3000
│ Rate Limiter │
│ Auth Middleware │ ← validates X-API-Key header
│ Correlation ID │ ← attaches request ID to logs
└────────┬──────────┘
│
▼
┌───────────────────┐
│ MCP SDK Layer │ tool registration & dispatch
│ (StreamableHTTP) │
└────────┬──────────┘
│
▼
┌───────────────────┐
│ Tool Handlers │ Zod-validated inputs
│ verix_search │
│ verix_get_record │
│ verix_analyze │
└────────┬──────────┘
│
▼
┌───────────────────┐
│ Verix API Client │ retry + timeout + auth
│ (node-fetch) │
└────────┬──────────┘
│
▼
Verix REST API
Project Structure
verix-mcp-server/
├── src/
│ ├── __tests__/
│ │ ├── server.test.ts
│ │ └── setup.ts
│ ├── auth.ts
│ ├── config.ts
│ ├── health.ts
│ ├── logger.ts
│ ├── server.ts
│ └── verix-client.ts
├── .env.example
├── .gitignore
├── babel.config.js
├── jest.config.js
├── package-lock.json
├── package.json
└── tsconfig.json
Prerequisites
- Node.js 20 or later
- npm 10 or later
- A Verix API key (sign up at https://verix.example.com)
- Docker (optional, for containerised deployment)
- An MCP-compatible client: Claude Desktop, Claude Code, Cursor, Windsurf, or Continue
Quick Start
# 1. Clone the project
git clone https://github.com/your-org/verix-mcp-server.git
cd verix-mcp-server
# 2. Install dependencies
npm install
# 3. Configure environment variables
cp .env.example .env
# Generate a secure value for MCP_API_KEY:
# openssl rand -hex 32
# Then fill in MCP_API_KEY and VERIX_API_KEY in .env
# 4. Start in development mode (hot reload)
npm run dev
# 5. Check the health endpoint (no API key required)
curl http://localhost:3000/health
# 6. Check the MCP endpoint (API key and Accept header required)
curl -s -X POST http://localhost:3000/mcp \
-H "X-API-Key: <your-MCP_API_KEY>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# 7. Run tests
npm test
# 8. Build and run in production
npm run build
npm start
Features
- HTTP Streamable MCP transport — compatible with all modern MCP clients
- API key authentication —
X-API-Keyheader validation on every request - Reusable Verix API client — typed methods, retry with exponential backoff, configurable timeout
- Zod input validation — every tool parameter is validated before execution
- Pino structured logging — JSON output, configurable log level, per-request correlation IDs
- Health endpoint —
/healthchecks Verix API reachability and returns structured JSON - Rate limiting — configurable requests-per-minute via environment variable
- Multi-stage Dockerfile — builder stage compiles TypeScript; production stage runs compiled JS on minimal Node image
- docker-compose.yml — one-command local development environment
- Jest + supertest tests — integration tests covering auth, health, and tool execution
- GitHub Actions CI/CD — lint, type-check, test, and Docker build on every PR
- Three realistic Verix tools —
verix_search,verix_get_record,verix_analyze
Works With
- Claude Desktop — add the server URL and API key to
claude_desktop_config.json - Claude Code — configure via
--mcp-serverflag or settings - Cursor — add under Settings → MCP Servers
- Windsurf — configure in the MCP server settings panel
- Continue — add as a custom MCP provider in
config.json
Claude Desktop Config Example
{
"mcpServers": {
"verix": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:3000/mcp"],
"env": {
"MCP_API_KEY": "your-mcp-api-key"
}
}
}
}
Configuration
| Variable | Description | Required | Default |
|---|---|---|---|
PORT | HTTP port the server listens on | Optional | 3000 |
NODE_ENV | Runtime environment (development / production) | Optional | development |
MCP_API_KEY | API key clients must send in X-API-Key header | Required | — |
VERIX_API_KEY | Your Verix API secret key | Required | — |
VERIX_BASE_URL | Base URL for the Verix REST API | Optional | https://api.verix.example.com/v1 |
VERIX_TIMEOUT_MS | Request timeout for Verix API calls (ms) | Optional | 10000 |
VERIX_MAX_RETRIES | Max retry attempts for failed Verix requests | Optional | 3 |
LOG_LEVEL | Pino log level (trace debug info warn error) | Optional | info |
RATE_LIMIT_RPM | Max requests per minute per IP | Optional | 60 |
RATE_LIMIT_WINDOW_MS | Rate limit window in milliseconds | Optional | 60000 |
Deployment
Docker (local)
# Build and start with docker-compose
docker-compose up --build
# Or build the image manually
docker build -t verix-mcp-server .
docker run -p 3000:3000 --env-file .env verix-mcp-server
Railway
npm install -g @railway/cli
railway login
railway init
railway up
# Set environment variables in the Railway dashboard
Fly.io
npm install -g flyctl
fly auth login
fly launch --name verix-mcp-server
fly secrets set MCP_API_KEY=your-key VERIX_API_KEY=your-key
fly deploy
Production Checklist
-
MCP_API_KEYis a cryptographically random string (≥ 32 characters) -
VERIX_API_KEYis stored in a secrets manager, not in source code -
NODE_ENV=productionis set in the deployment environment -
LOG_LEVEL=infoorwarnin production (avoiddebug/trace) - Rate limiting values reviewed and tuned for your expected traffic
- Health endpoint is connected to your load balancer's health check
- Docker image is built from the production multi-stage target
- All CI checks (lint, type-check, tests) pass on the main branch
- HTTPS/TLS termination is handled upstream (reverse proxy or platform)
- Container restart policy is set to
unless-stoppedor equivalent - Resource limits (CPU, memory) are configured for the container
- Log aggregation (Datadog, Grafana Loki, CloudWatch) is connected
- Alerts are configured for health check failures
- Dependency versions are pinned and Dependabot / Renovate is enabled
- A
CODEOWNERSfile designates reviewers for this repository
Testing
Run the test suite
npm test # run all tests once
npm run test:watch # watch mode during development
npm run test:coverage # generate coverage report
Manual testing with curl
# Health check
curl http://localhost:3000/health
# MCP initialize (replace YOUR_MCP_API_KEY)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_MCP_API_KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}'
# List tools
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_MCP_API_KEY" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
# Call verix_search tool
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_MCP_API_KEY" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"verix_search","arguments":{"query":"enterprise contracts","limit":5}}}'
Testing with Claude Desktop
- Start the server:
npm run dev - Add the MCP server config to
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) - Restart Claude Desktop
- Open a new conversation and ask: "Search Verix for recent enterprise contracts"
- Claude will invoke the
verix_searchtool and display the results