mcp-proxy

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.

Category
Visit Server

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

  • 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_ERROR failures.

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:

  1. The MCP engine receives the cancellation notification
  2. The associated AbortSignal is triggered
  3. The in-flight HTTP request to the upstream service is aborted
  4. Any pending retry sleep is interrupted immediately
  5. 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 --config file when the proxy is launched by an external tool. These tools may set a different working directory, causing relative paths to fail with CONFIGURATION_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:

  1. Stops accepting new connections
  2. Waits for in-flight requests to complete
  3. Closes transport connections
  4. Cleans up the MCP engine (flushes metrics, closes circuit breakers)
  5. 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 status
  • mcp_request_duration_seconds — Request duration histogram
  • mcp_request_errors_total — Error count by tool and error type
  • mcp_tool_executions_total — Tool execution count
  • mcp_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:

  1. Check the upstream service is healthy: curl <service_base_url>/health
  2. Review logs for the root cause: LOG_LEVEL=debug npm run start:http
  3. The circuit will auto-close after reset_timeout ms if a test request succeeds
  4. 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:

  1. Increase max_requests or window in config
  2. If using per_user keying, check if a single user is dominating
  3. 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:

  1. Verify Redis is running: redis-cli ping
  2. Check REDIS_HOST, REDIS_PORT, REDIS_PASSWORD in .env
  3. 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:

  1. Run npm run cli -- validate -c ./config/services.yaml for detailed error output
  2. Common issues: missing base_url, invalid method (must be uppercase GET/POST/PUT/DELETE/PATCH), type must be one of string/number/boolean/object/array

Authentication failures to upstream services

Symptom: Upstream returns 401/403 even though auth is configured.

Fix:

  1. Verify the env var specified in token_env / key_env is set: echo $USER_SERVICE_TOKEN
  2. For OAuth2, check that token_url is reachable and client credentials are valid
  3. 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:

  1. Ensure the project is built: npm run build
  2. Verify the path in claude_desktop_config.json points to dist/server/unified-server.js
  3. 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
  4. 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:

  1. Increase timeout at the service level or per-tool level
  2. If circuit breaker is enabled, ensure circuit_breaker.timeout is >= service timeout
  3. 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

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes and add tests
  4. Run the full test suite: npm run test:all
  5. Run type checking: npm run typecheck
  6. Run linting: npm run lint
  7. Commit with a descriptive message
  8. Open a Pull Request

Please ensure all tests pass and type checking succeeds before submitting.

License

MIT

Recommended Servers

playwright-mcp

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

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.

Official
Featured