mcp-proxy
Bridges LLM clients with existing RESTful microservices by converting MCP tool calls into REST requests, enabling any REST API to be used as an MCP tool without modifying the microservices.
README
MCP Proxy Service
An enterprise-grade MCP (Model Context Protocol) proxy that bridges LLM clients with existing RESTful microservices. Configure any REST API as an MCP tool — no changes to your microservices required.
Table of Contents
- Features
- Prerequisites
- Quick Start
- Environment Setup
- Configuration
- CLI Usage
- Transport Modes
- Monitoring
- Security
- Testing
- Project Structure
- Troubleshooting
- Scripts Reference
- Technology Stack
- Related Documentation
- Contributing
- License
Features
- Protocol Translation — Automatically converts MCP tool calls into REST API requests
- Dynamic Tool Registration — Define REST endpoints as MCP tools via YAML configuration
- OpenAPI Import — Generate tool definitions from OpenAPI/Swagger specifications
- Transport Agnostic — Supports stdio (for Claude Desktop, CLI) and HTTP (Streamable HTTP with SSE)
- Circuit Breaker — Fault tolerance with automatic service recovery (opossum)
- Rate Limiting — Fixed window, sliding window, and token bucket strategies
- Access Control — Role-based permissions at service and tool level
- Authentication — API key, bearer token, basic auth, and OAuth2 client credentials
- Request Validation — Type checking, pattern matching, format validation (email, URL, UUID)
- Request Cancellation — Abort in-flight requests with signal propagation to upstream services
- Response Transformation — JSON, text, and XML response format conversion
- Monitoring — Prometheus metrics, health checks, readiness probes
- Retry with Jittered Backoff — Prevents thundering herd on failure recovery
- Graceful Shutdown — Clean connection draining on SIGINT/SIGTERM
Prerequisites
- Node.js >= 18.0.0
- npm >= 8.0.0
- Docker (optional, for containerized deployment)
- Redis (optional, for distributed rate limiting across multiple instances)
Quick Start
# Install dependencies
npm install
# Copy environment file
cp .env.example .env
# Build
npm run build
# Start with stdio transport (default, for Claude Desktop)
npm run start:stdio
# Start with HTTP transport
npm run start:http
Environment Setup
Development
# .env
NODE_ENV=development
LOG_LEVEL=debug
# Server
MCP_SERVER_PORT=3000
HEALTH_CHECK_PORT=8080
# Redis (optional — in-memory rate limiting used if not configured)
REDIS_HOST=localhost
REDIS_PORT=6379
# Monitoring
METRICS_ENABLED=true
Run in development mode with hot reload:
npm run dev
Production
# .env
NODE_ENV=production
LOG_LEVEL=info
# Server
MCP_SERVER_PORT=3000
HEALTH_CHECK_PORT=8080
# Redis (required for distributed rate limiting)
REDIS_HOST=redis.internal
REDIS_PORT=6379
REDIS_PASSWORD=your-secure-password
# MCP server authentication (protect the /mcp endpoint)
MCP_SERVER_AUTH_ENABLED=true
MCP_SERVER_AUTH_TYPE=bearer
MCP_SERVER_AUTH_TOKEN_ENV=MCP_AUTH_TOKEN
MCP_AUTH_TOKEN=your-secret-token-here
# Service authentication tokens
USER_SERVICE_TOKEN=your_user_service_token
PAYMENT_API_KEY=your_payment_api_key
ANALYTICS_CLIENT_SECRET=your_oauth_client_secret
# OAuth2 (if using oauth2 auth strategy)
OAUTH2_CLIENT_ID=your_client_id
OAUTH2_CLIENT_SECRET=your_client_secret
OAUTH2_TOKEN_URL=https://auth.example.com/oauth/token
# Monitoring
METRICS_ENABLED=true
PROMETHEUS_PORT=9090
Deploy with Docker:
docker build -t mcp-proxy .
docker run -p 3000:3000 -p 8080:8080 \
-v ./config:/app/config:ro \
--env-file .env \
mcp-proxy
Or with Docker Compose (includes Redis):
docker-compose up
Configuration
Service configuration is defined in YAML. The proxy reads config/services.yaml by default.
Specifying a Custom Config File
Use the --config (or -c) flag to load a different configuration file:
# Stdio with custom config
node dist/server/unified-server.js --transport stdio --config ./config/my-services.yaml
# HTTP with custom config
node dist/server/unified-server.js --transport http --port 3000 --config /absolute/path/to/services.yaml
Important: The config path is resolved relative to the working directory of the process, not relative to the project root. When the proxy is spawned by an external tool (Claude Desktop, LangChain, etc.), the working directory may differ from the project root. Use an absolute path to avoid
CONFIGURATION_ERRORfailures.
Minimal Example (No Auth)
version: "1.0"
settings:
log_level: "info"
metrics_enabled: true
health_check_port: 8080
services:
- name: "jsonplaceholder"
description: "JSONPlaceholder - Free fake REST API"
base_url: "https://jsonplaceholder.typicode.com"
tools:
- name: "get_post"
description: "Get a blog post by ID"
method: "GET"
path: "/posts/{id}"
parameters:
- name: "id"
type: "number"
required: true
description: "Post ID (1-100)"
in: "path"
- name: "list_posts"
description: "List all blog posts"
method: "GET"
path: "/posts"
- name: "get_user"
description: "Get user by ID"
method: "GET"
path: "/users/{id}"
parameters:
- name: "id"
type: "number"
required: true
description: "User ID (1-10)"
in: "path"
Full Enterprise Example
version: "1.0"
settings:
log_level: "info"
metrics_enabled: true
health_check_port: 8080
mcp_server_port: 3000
services:
- name: "user_service"
description: "User management service"
base_url: "https://api.example.com/v1/users"
auth:
type: "bearer"
config:
token_env: "USER_SERVICE_TOKEN"
circuit_breaker:
enabled: true
timeout: 3000
error_threshold: 50
reset_timeout: 30000
volume_threshold: 10
rate_limit:
enabled: true
max_requests: 100
window: 60000
strategy: "sliding_window"
access_control:
enabled: true
allowed_roles: ["admin", "user"]
required_permissions: ["read:users"]
retry:
enabled: true
max_attempts: 3
backoff_ms: 1000
timeout: 5000
tools:
- name: "create_user"
description: "Create a new user account"
method: "POST"
path: "/"
access_control:
enabled: true
required_permissions: ["write:users"]
parameters:
- name: "username"
type: "string"
required: true
description: "Username for the new account"
in: "body"
validation:
min_length: 3
max_length: 50
pattern: "^[a-zA-Z0-9_]+$"
- name: "email"
type: "string"
required: true
description: "Email address"
in: "body"
validation:
format: "email"
request_body:
content_type: "application/json"
template: |
{
"username": "{{username}}",
"email": "{{email}}",
"created_at": "{{$timestamp}}"
}
response:
success_codes: [201]
error_codes: [400, 409]
transform: "json"
- name: "payment_service"
description: "Payment processing service"
base_url: "https://api.payments.example.com/v2"
auth:
type: "api_key"
config:
key_env: "PAYMENT_API_KEY"
header_name: "X-Payment-API-Key"
circuit_breaker:
enabled: true
timeout: 5000
error_threshold: 30
reset_timeout: 60000
volume_threshold: 5
rate_limit:
enabled: true
max_requests: 50
window: 60000
strategy: "token_bucket"
tools:
- name: "create_payment"
description: "Process a payment transaction"
method: "POST"
path: "/payments"
parameters:
- name: "amount"
type: "number"
required: true
description: "Payment amount in cents"
in: "body"
validation:
minimum: 1
- name: "currency"
type: "string"
required: true
description: "Currency code"
in: "body"
validation:
enum: ["USD", "EUR", "GBP"]
- name: "analytics_service"
description: "Analytics and reporting service"
base_url: "https://analytics.example.com/api"
auth:
type: "oauth2"
config:
client_id: "analytics_client"
client_secret_env: "ANALYTICS_CLIENT_SECRET"
token_url: "https://auth.example.com/oauth/token"
scope: "analytics:read analytics:write"
tools:
- name: "get_report"
description: "Generate analytics report"
method: "GET"
path: "/reports/{report_id}"
parameters:
- name: "report_id"
type: "string"
required: true
description: "Report identifier"
in: "path"
- name: "format"
type: "string"
required: false
description: "Report format"
in: "query"
validation:
enum: ["json", "csv", "pdf"]
Authentication Types
| Type | Config | Description |
|---|---|---|
bearer |
token_env |
Bearer token from environment variable |
api_key |
key_env, header_name |
API key injected as a header |
basic |
username_env, password_env |
HTTP Basic authentication |
oauth2 |
client_id, client_secret_env, token_url, scope |
OAuth2 client credentials flow |
MCP Server Inbound Authentication
Protect the /mcp endpoint for HTTP transport with environment variables:
# Bearer token
MCP_SERVER_AUTH_ENABLED=true
MCP_SERVER_AUTH_TYPE=bearer
MCP_AUTH_TOKEN=your-secret-token-here
# API key
MCP_SERVER_AUTH_ENABLED=true
MCP_SERVER_AUTH_TYPE=api_key
MCP_API_KEY=your-api-key-here
# JWT (HMAC-SHA256)
MCP_SERVER_AUTH_ENABLED=true
MCP_SERVER_AUTH_TYPE=jwt
JWT_SECRET=your-jwt-secret-here
Request Body Templates
Templates support variable substitution with JSON injection prevention:
request_body:
content_type: "application/json"
template: |
{
"name": "{{name}}",
"id": "{{$uuid}}",
"timestamp": "{{$timestamp}}",
"date": "{{$date}}"
}
Special variables: {{$timestamp}} (ISO 8601), {{$date}} (YYYY-MM-DD), {{$uuid}} (v4 UUID).
Parameter Validation
parameters:
- name: "email"
type: "string"
required: true
in: "body"
validation:
format: "email" # email, url, uuid, date
pattern: "^[a-z]+$" # regex pattern
min_length: 5
max_length: 100
enum: ["a", "b", "c"] # allowed values
- name: "count"
type: "number"
required: false
in: "query"
validation:
minimum: 1
maximum: 1000
Response Transformation
Control how upstream REST responses are converted to MCP tool results:
response:
success_codes: [200, 201]
error_codes: [400, 404, 500]
transform: "json" # json | text | xml
| Transform | Behavior |
|---|---|
json (default) |
Parses response as JSON object. If already an object, passes through. If string, attempts JSON.parse. |
text |
Wraps response in { "text": "..." }. Useful for plain-text APIs. |
xml |
Wraps raw XML in { "xml": "..." }. Returns the XML string as-is for client-side parsing. |
Request Cancellation
The proxy supports MCP request cancellation. When a client cancels a pending tool call:
- The MCP engine receives the cancellation notification
- The associated
AbortSignalis triggered - The in-flight HTTP request to the upstream service is aborted
- Any pending retry sleep is interrupted immediately
- The client receives a cancellation acknowledgment
This prevents wasted upstream resources on abandoned requests.
CLI Usage
The CLI manages configuration and server lifecycle.
Generate Config from OpenAPI
# Generate from an OpenAPI spec
npm run cli -- generate \
-i ./specs/petstore.yaml \
-n pet_service \
-u https://api.petstore.example.com \
-o ./config/pet-service.yaml
# With auth and filtering
npm run cli -- generate \
-i ./specs/api.yaml \
-n my_service \
-u https://api.example.com \
--auth-type bearer \
--auth-token-env MY_SERVICE_TOKEN \
--include-tags "users,orders" \
--exclude-operations "deleteAll,purge" \
-o ./config/my-service.yaml
Options:
| Flag | Description |
|---|---|
-i, --openapi <path> |
Path to OpenAPI/Swagger spec (required) |
-n, --service-name <name> |
Service name (required) |
-u, --base-url <url> |
Base URL (required) |
-o, --output <path> |
Output path (default: ./config/generated-service.yaml) |
--auth-type <type> |
Auth type: api_key, bearer, basic, oauth2 |
--auth-token-env <var> |
Env var name for auth token |
--include-operations <ops> |
Comma-separated operation IDs to include |
--exclude-operations <ops> |
Comma-separated operation IDs to exclude |
--include-tags <tags> |
Comma-separated tags to include |
--exclude-tags <tags> |
Comma-separated tags to exclude |
--circuit-breaker |
Enable circuit breaker (default: true) |
--rate-limit |
Enable rate limiting (default: true) |
Validate Configuration
# Validate a config file
npm run cli -- validate -c ./config/services.yaml
# Strict mode
npm run cli -- validate -c ./config/services.yaml --strict
Start Server via CLI
npm run cli -- serve -c ./config/services.yaml -p 3000
Transport Modes
Stdio (Default)
Used with Claude Desktop, LangChain, and other MCP clients that communicate over stdin/stdout.
# Using default config (config/services.yaml)
npm run start:stdio
# Using a custom config file
node dist/server/unified-server.js --transport stdio --config ./config/my-services.yaml
Add to Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"my-proxy": {
"command": "node",
"args": [
"/path/to/mcp-proxy/dist/server/unified-server.js",
"--transport", "stdio",
"--config", "/path/to/mcp-proxy/config/services.yaml"
],
"env": {
"NODE_ENV": "production"
}
}
}
}
Use with LangChain (langchain-mcp-adapters):
from langchain_mcp_adapters.client import MultiServerMCPClient
server_configs = {
"my_proxy": {
"command": "node",
"args": [
"/path/to/mcp-proxy/dist/server/unified-server.js",
"--transport", "stdio",
"--config", "/path/to/mcp-proxy/config/services.yaml"
],
"transport": "stdio",
}
}
async with MultiServerMCPClient(server_configs) as client:
tools = await client.get_tools()
Note: Always use absolute paths for both the server script and the
--configfile when the proxy is launched by an external tool. These tools may set a different working directory, causing relative paths to fail withCONFIGURATION_ERROR.
HTTP (Streamable HTTP + SSE)
For web-based clients and multi-client deployments.
# Using default config
npm run start:http
# With custom port, host, and config
node dist/server/unified-server.js --transport http --host 127.0.0.1 --port 8000 --config ./config/my-services.yaml
The HTTP transport supports:
- Session management with cryptographic session IDs
- Optional inbound authentication (bearer, API key, JWT, basic)
- CORS configuration
- TLS support
Graceful Shutdown
The server handles SIGINT and SIGTERM for clean shutdown:
- Stops accepting new connections
- Waits for in-flight requests to complete
- Closes transport connections
- Cleans up the MCP engine (flushes metrics, closes circuit breakers)
- Exits with code 0
Uncaught exceptions and unhandled rejections also trigger graceful shutdown with exit code 1.
Monitoring
The monitoring server runs on a separate port (default: 8080) and exposes:
| Endpoint | Description |
|---|---|
GET /health |
Detailed health status of all services (ping + circuit breaker state) |
GET /ready |
Readiness probe — returns 200 when all services are reachable |
GET /live |
Liveness probe — always returns 200 if the process is running |
GET /metrics |
Prometheus-format metrics |
GET /metrics/json |
Metrics in JSON format |
GET /status |
Human-readable status summary |
Metrics Collected
mcp_requests_total— Total MCP requests by tool and statusmcp_request_duration_seconds— Request duration histogrammcp_request_errors_total— Error count by tool and error typemcp_tool_executions_total— Tool execution countmcp_tool_execution_duration_seconds— Tool execution duration
Health Check Response
{
"status": "healthy",
"services": {
"user_service": {
"status": "up",
"responseTime": 45,
"circuitBreaker": "closed"
}
},
"timestamp": "2025-01-15T10:30:00.000Z"
}
Kubernetes Integration
# Deployment probe configuration
livenessProbe:
httpGet:
path: /live
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Security
Credential Management
All secrets are managed through environment variables — never stored in configuration files. The .env file is gitignored. Use a secrets manager (Vault, AWS Secrets Manager, etc.) in production.
JSON Template Injection Prevention
Request body templates use JSON.stringify().slice(1,-1) to escape user-supplied values before substitution. This prevents injection of additional JSON keys or malformed payloads:
Input: hello", "admin": true, "x": "y
Result: {"message": "hello\", \"admin\": true, \"x\": \"y"}
^--- injection neutralized, treated as literal string
Timing-Safe Token Comparison
Authentication token comparison uses crypto.timingSafeEqual with buffer padding to prevent timing attacks. Both buffers are padded to equal length before comparison, eliminating length-based timing leaks.
Cryptographic Session IDs
HTTP transport sessions use crypto.randomUUID() (CSPRNG-backed) instead of predictable Math.random(). This prevents session prediction attacks.
Input Validation
- Configuration: Zod schemas validate all config at load time (types, ranges, required fields)
- Runtime: Per-tool parameter validation checks types, patterns, formats, and ranges before any upstream call is made
Rate Limiting
Protects upstream services from abuse. Supports per-service and per-user keying with Redis for distributed enforcement across multiple proxy instances.
Testing
# Unit tests
npm test
# Unit tests with coverage
npm run test:coverage
# Watch mode
npm run test:watch
# E2E tests (stdio transport + cancellation)
npm run test:e2e
# E2E: HTTP transport
npm run test:http
# E2E: HTTP with authentication
npm run test:http:auth
# All tests (unit + e2e)
npm run test:all
# Type checking only
npm run typecheck
Test Coverage
| Area | Tests |
|---|---|
| Config schema validation | Zod schema correctness |
| Template injection | JSON escape and injection neutralization |
| Health checker | Ping, circuit breaker state, multi-service |
| REST client | Ping, timeout, error handling |
| Access control | Role/permission checks, deny/allow |
| Request validator | Type, pattern, format, range validation |
| Timing-safe comparison | Correctness across lengths, no early-return |
| E2E stdio | Full tool call roundtrip over stdin/stdout |
| E2E HTTP | HTTP transport with session management |
| E2E cancellation | Request abort propagation |
Project Structure
mcp-proxy/
├── src/
│ ├── core/
│ │ └── mcp-engine.ts # Transport-agnostic MCP protocol engine
│ ├── transport/
│ │ ├── index.ts # Transport exports
│ │ ├── types.ts # ITransport interface, configs, states
│ │ ├── factory.ts # Transport factory (createTransport)
│ │ ├── stdio-transport.ts # Stdio transport implementation
│ │ └── http-transport.ts # HTTP transport (Streamable HTTP + SSE)
│ ├── server/
│ │ ├── unified-server.ts # Main entry: CLI arg parsing + bootstrap
│ │ └── tool-registry.ts # Dynamic tool registration
│ ├── config/
│ │ ├── loader.ts # YAML/JSON configuration loader
│ │ ├── schema.ts # Zod validation schemas
│ │ └── openapi-parser.ts # OpenAPI/Swagger → tool config parser
│ ├── rest/
│ │ ├── client.ts # Axios HTTP client with circuit breaker + retry
│ │ └── transformer.ts # Response transformation (JSON, text, XML)
│ ├── auth/
│ │ ├── manager.ts # Auth strategy manager
│ │ ├── types.ts # Auth types
│ │ └── strategies/
│ │ ├── api-key.ts
│ │ ├── bearer.ts
│ │ ├── basic.ts
│ │ └── oauth2.ts
│ ├── middleware/
│ │ ├── rate-limiter.ts # Rate limiting (fixed/sliding/token bucket)
│ │ ├── access-control.ts # RBAC implementation
│ │ └── validator.ts # Request parameter validation
│ ├── monitoring/
│ │ ├── metrics.ts # Prometheus-style metrics collector
│ │ ├── health.ts # Health checker (ping + circuit breaker)
│ │ └── http-server.ts # Monitoring HTTP server (/health, /metrics)
│ ├── types/
│ │ └── config.ts # ProxyConfig, ServiceConfig, ToolConfig types
│ ├── utils/
│ │ ├── errors.ts # Custom error classes
│ │ └── logger.ts # Winston structured logging
│ └── cli/
│ ├── index.ts # CLI entry point (commander)
│ └── commands/
│ ├── generate.ts # Generate config from OpenAPI
│ ├── validate.ts # Validate configuration
│ └── serve.ts # Start server
├── config/
│ ├── services.yaml # Active service configuration
│ ├── example-services.yaml # Full-featured example
│ └── openapi/
│ └── example-user-api.yaml # Example OpenAPI spec
├── tests/
│ ├── unit/ # Unit tests (Jest)
│ └── e2e/ # End-to-end tests
├── Dockerfile # Multi-stage production build
├── docker-compose.yaml # Docker Compose (proxy + Redis)
├── package.json
├── tsconfig.json
└── jest.config.js
Troubleshooting
Circuit breaker stays open
Symptom: All requests to a service fail immediately with "service temporarily unavailable".
Cause: The error rate exceeded error_threshold percentage within volume_threshold requests.
Fix:
- Check the upstream service is healthy:
curl <service_base_url>/health - Review logs for the root cause:
LOG_LEVEL=debug npm run start:http - The circuit will auto-close after
reset_timeoutms if a test request succeeds - To force reset, restart the proxy
Rate limit exceeded
Symptom: Requests return rate limit errors before reaching the upstream service.
Cause: More than max_requests were made within window ms.
Fix:
- Increase
max_requestsorwindowin config - If using
per_userkeying, check if a single user is dominating - For distributed deployments, ensure Redis is connected — without Redis, each instance tracks limits independently
Redis connection failures
Symptom: Startup warning about Redis connection, or rate limiting behaves inconsistently.
Cause: Redis is unreachable or credentials are wrong.
Fix:
- Verify Redis is running:
redis-cli ping - Check
REDIS_HOST,REDIS_PORT,REDIS_PASSWORDin.env - The proxy falls back to in-memory rate limiting if Redis is unavailable — this is safe for single-instance deployments
Config validation errors
Symptom: Server fails to start with a Zod validation error.
Fix:
- Run
npm run cli -- validate -c ./config/services.yamlfor detailed error output - Common issues: missing
base_url, invalidmethod(must be uppercase GET/POST/PUT/DELETE/PATCH),typemust be one of string/number/boolean/object/array
Authentication failures to upstream services
Symptom: Upstream returns 401/403 even though auth is configured.
Fix:
- Verify the env var specified in
token_env/key_envis set:echo $USER_SERVICE_TOKEN - For OAuth2, check that
token_urlis reachable and client credentials are valid - Enable debug logging to see the outgoing auth headers (tokens are redacted):
LOG_LEVEL=debug
Stdio transport not connecting
Symptom: Claude Desktop shows the MCP server as disconnected.
Fix:
- Ensure the project is built:
npm run build - Verify the path in
claude_desktop_config.jsonpoints todist/server/unified-server.js - Test manually:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | node dist/server/unified-server.js - Check that no other output (console.log, debug prints) pollutes stdout — the stdio transport requires clean JSON-RPC over stdin/stdout
Request timeout
Symptom: Tool calls fail with "Request timeout" after the configured timeout period.
Fix:
- Increase
timeoutat the service level or per-tool level - If circuit breaker is enabled, ensure
circuit_breaker.timeoutis >= servicetimeout - Check network connectivity to the upstream service
Scripts Reference
| Script | Description |
|---|---|
npm run build |
Compile TypeScript to dist/ |
npm run dev |
Development mode with hot reload |
npm run start |
Start server (legacy entry point) |
npm run start:unified |
Start unified server (auto-detect transport) |
npm run start:stdio |
Start with stdio transport |
npm run start:http |
Start with HTTP transport on port 3000 |
npm run test |
Run unit tests |
npm run test:all |
Run unit + e2e tests |
npm run test:e2e |
Run E2E tests (stdio + cancellation) |
npm run test:http |
Run HTTP transport E2E |
npm run test:http:auth |
Run HTTP auth E2E |
npm run test:coverage |
Unit tests with coverage report |
npm run cli -- <cmd> |
Run CLI commands (generate, validate, serve) |
npm run typecheck |
TypeScript type checking |
npm run lint |
ESLint |
npm run lint:fix |
ESLint with auto-fix |
npm run format |
Prettier formatting |
Technology Stack
| Component | Technology |
|---|---|
| Runtime | Node.js >= 18 |
| Language | TypeScript 5.x |
| MCP SDK | @modelcontextprotocol/sdk |
| HTTP Client | Axios |
| Circuit Breaker | Opossum |
| Rate Limiting | rate-limiter-flexible + optional Redis (ioredis) |
| Validation | Zod |
| Logging | Winston (structured JSON) |
| Metrics | prom-client (Prometheus) |
| HTTP Server | Express |
| OpenAPI Parsing | @apidevtools/swagger-parser |
| CLI | Commander |
| Testing | Jest + ts-jest (ESM) |
| Containerization | Docker (multi-stage, node:20-alpine) |
Related Documentation
- Architecture Overview — System design, request flow diagrams, component details
- Testing Guide — End-to-end testing walkthrough
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run the full test suite:
npm run test:all - Run type checking:
npm run typecheck - Run linting:
npm run lint - Commit with a descriptive message
- Open a Pull Request
Please ensure all tests pass and type checking succeeds before submitting.
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.