Skip to content

Repository files navigation

MCP Proxy

English | 简体中文

MCP Proxy turns OpenAPI/Swagger endpoints into runnable MCP tools. It loads upstream API specs, generates MCP tool schemas, starts one MCP server per configured endpoint, and provides a dashboard for managing endpoints, tool visibility, request examples, response examples, health status, and metrics.

Dashboard

MCP Proxy dashboard

Demo

Import an OpenAPI document, enable a generated tool, and call it through MCP:

OpenAPI to MCP tool call demo

Features

  • Generate MCP tools from OpenAPI 3 and Swagger 2 specifications.
  • Run endpoints in HTTP, SSE, or STDIO mode.
  • Manage upstream endpoints from the embedded dashboard.
  • Enable or disable individual Swagger paths without editing upstream specs.
  • Show copyable tool-call request examples and response examples.
  • Validate required path/query/header/form/body parameters before calling upstream.
  • Forward upstream auth with none, basic, bearer, or api_key.
  • Optional dashboard admin key for write operations.
  • Optional app-client JWT auth for MCP server access.
  • Prometheus metrics for upstream request latency and status classes.
  • MySQL-backed storage for endpoints, cached swagger specs, and path toggles.

Requirements

  • Go 1.24.1 or newer

Quick Start

  1. From the repository root, initialize a fresh database with the bundled SQL file. Run this once; skip it when reusing an initialized database:

    mysql -u root -p -e "source docs/endpoints.sql"

    This creates the mcp_proxy database, the required tables, and the test-params endpoint used by the local demo.

  2. Update config.yaml with your MySQL connection:

    db:
      driver: "mysql"
      host: "127.0.0.1"
      port: 3306
      user: "root"
      password: ""
      database: "mcp_proxy"
      params: "parseTime=true&charset=utf8mb4&collation=utf8mb4_unicode_ci"
  3. Start the bundled mock upstream in a separate terminal:

    go run ./test_tools/mock_upstream

    The mock API listens on http://127.0.0.1:18900, and its OpenAPI document is available at http://127.0.0.1:18900/openapi.json.

  4. Start the proxy:

    go run ./cmd --config config.yaml
  5. Open the dashboard:

    http://localhost:18081/mcp/
    
  6. Select test-params in the Dashboard. It was created by the SQL script in step 1. If you skipped database initialization and the endpoint does not exist, click New and enter the following values:

    {
      "name": "test-params",
      "enabled": true,
      "version": "1.0.0",
      "mode": "http",
      "host": "0.0.0.0",
      "port": 18993,
      "timeout": "30s",
      "base_url": "http://127.0.0.1:18900",
      "gateway_url": "http://127.0.0.1:18900",
      "doc_path": "/openapi.json",
      "auth_type": "none",
      "auth_config": {},
      "headers": {}
    }
  7. Open test-params in the Dashboard and enable /ping or any other paths you want to expose. New upstream paths are disabled by default.

  8. Connect an MCP client to:

    http://127.0.0.1:18993/mcp/
    

    The generated tools now call the local mock upstream and return the request details it received, so the full OpenAPI-to-MCP request flow can be tested without an external API.

Runtime Layout

The process exposes two kinds of HTTP servers:

  • Dashboard server: defaults to 0.0.0.0:18081
  • Endpoint MCP servers: one server per enabled endpoint row in the database

The dashboard server provides:

  • /mcp/: embedded dashboard UI
  • /mcp/servers: aggregated running MCP server and tool information
  • /mcp/api/endpoints: endpoint management API
  • /mcp/api/tools: per-path enable/disable API
  • /mcp/api/docs: Swagger UI for the dashboard API
  • /mcp/api/openapi.yaml: dashboard OpenAPI document
  • /metrics: Prometheus metrics

Endpoint MCP servers expose generated MCP tools on their configured port using the selected transport mode.

Configuration

config.yaml contains process-wide settings:

server:
  name: "MCP Proxy"
  version: "1.0.0"

logging:
  level: "info"
  format: "json"
  color: true
  disable_stacktrace: false
  output_path: "logs/mcp-proxy.log"
  append_to_file: true
  disable_console: false

app_auth:
  enabled: false
  jwt_secret: "test-secret-key-for-development-use-32bytes-minimum"
  token_expiry: "24h"

dashboard:
  admin_key: ""

Dashboard Admin Key

When dashboard.admin_key is empty, dashboard write operations are allowed. When it is non-empty, non-GET requests under /mcp/api/* must include:

X-Admin-Key: <admin_key>

The dashboard UI will prompt for the key when write access is required.

Upstream Authentication

Each endpoint can configure how requests are authenticated when forwarded to the upstream API:

  • none: no auth headers are added
  • basic: uses auth_config.username and auth_config.password
  • bearer: sends Authorization: Bearer <token>
  • api_key: sends auth_config.key in header auth_config.header

Example:

{
  "auth_type": "bearer",
  "auth_config": {
    "token": "upstream-token"
  }
}

App Client Authentication

When app_auth.enabled is true, MCP server access can be guarded by app-client JWTs. App clients are managed through /mcp/api/app-clients, and tokens are issued by /auth/token.

The dashboard API documentation at /mcp/api/docs includes the app-client schemas and auth endpoints.

Tool Generation Behavior

For each enabled Swagger/OpenAPI path, MCP Proxy creates tools from supported HTTP methods:

  • GET
  • POST
  • PUT
  • DELETE
  • PATCH

Generated tool names use the pattern:

<method>_<path>

For example, GET /v1/items/{id} becomes:

get_v1_items_id

Request arguments follow these rules:

  • Path, query, and header parameters stay at the top level.
  • JSON request bodies must be wrapped under the top-level body key.
  • Multipart form fields stay flat.
  • Required parameters are validated before the proxy calls upstream.

Example JSON-body call arguments:

{
  "id": "item-1",
  "trace_id": "abc",
  "body": {
    "name": "demo"
  }
}

Metrics

Prometheus metrics are exposed at:

GET /metrics

Custom upstream metrics include:

  • mcp_proxy_upstream_requests_total
  • mcp_proxy_upstream_request_duration_seconds

Labels are intentionally bounded:

  • endpoint
  • method
  • path
  • status_class

The default Go runtime and process collectors are also enabled.

Development

Run tests:

go test ./...

Run with a specific config file:

go run ./cmd --config config.yaml

Print version information:

go run ./cmd --version

Notes

  • Swagger specs are cached in MySQL after the first successful fetch.
  • Dashboard reload clears the cached swagger document and restarts the endpoint.
  • New remote paths are inserted into swagger_paths disabled by default.
  • Deleted remote paths are removed from swagger_paths during sync.
  • Spring Actuator paths are skipped and are not exposed as tools.

About

Turn OpenAPI/Swagger services into managed MCP tools with a dashboard, authentication, path controls, and metrics.

Topics

Resources

Stars

79 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages