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.
Import an OpenAPI document, enable a generated tool, and call it through MCP:
- 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, orapi_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.
- Go 1.24.1 or newer
-
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_proxydatabase, the required tables, and thetest-paramsendpoint used by the local demo. -
Update
config.yamlwith 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"
-
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 athttp://127.0.0.1:18900/openapi.json. -
Start the proxy:
go run ./cmd --config config.yaml
-
Open the dashboard:
http://localhost:18081/mcp/ -
Select
test-paramsin 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": {} } -
Open
test-paramsin the Dashboard and enable/pingor any other paths you want to expose. New upstream paths are disabled by default. -
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.
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.
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: ""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.
Each endpoint can configure how requests are authenticated when forwarded to the upstream API:
none: no auth headers are addedbasic: usesauth_config.usernameandauth_config.passwordbearer: sendsAuthorization: Bearer <token>api_key: sendsauth_config.keyin headerauth_config.header
Example:
{
"auth_type": "bearer",
"auth_config": {
"token": "upstream-token"
}
}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.
For each enabled Swagger/OpenAPI path, MCP Proxy creates tools from supported HTTP methods:
GETPOSTPUTDELETEPATCH
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
bodykey. - 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"
}
}Prometheus metrics are exposed at:
GET /metrics
Custom upstream metrics include:
mcp_proxy_upstream_requests_totalmcp_proxy_upstream_request_duration_seconds
Labels are intentionally bounded:
endpointmethodpathstatus_class
The default Go runtime and process collectors are also enabled.
Run tests:
go test ./...Run with a specific config file:
go run ./cmd --config config.yamlPrint version information:
go run ./cmd --version- 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_pathsdisabled by default. - Deleted remote paths are removed from
swagger_pathsduring sync. - Spring Actuator paths are skipped and are not exposed as tools.

