Skip to main content
Glama
dyy-fq
by dyy-fq

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

Related MCP server: OpenAPI REST MCP Server

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)

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

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dyy-fq/mcp-proxy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server