Access Point
STDIOLightweight protocol conversion gateway bridging HTTP services with MCP clients seamlessly
Lightweight protocol conversion gateway bridging HTTP services with MCP clients seamlessly
MCP Access Point is a lightweight protocol conversion gateway tool designed to establish a communication bridge between traditional HTTP services and MCP (Model Context Protocol) clients. It enables MCP clients to interact directly with existing HTTP services without requiring any server-side interface modifications.

This project is built on Pingora - an ultra-high performance gateway proxy library capable of supporting massive-scale request proxy services. Pingora has been used to build services that handle core traffic for the Cloudflare platform, consistently serving over 40 million requests per second across the internet for years. It has become the technical cornerstone supporting a significant proportion of traffic on the Cloudflare platform.
This mode allows clients like Cursor Desktop to communicate with remote HTTP servers through SSE, even when the servers themselves don't support the SSE protocol.
127.0.0.1:8090api.example.comMCP Access Point, both services can be converted to MCP services without any code modifications.Service 1 and Service 2 via the MCP protocol. The MCP Access Point automatically distinguishes MCP requests and forwards them to the appropriate backend services.graph LR A["Cursor Desktop"] <--> |SSE| B["MCP Access Point"] A2["Other Desktop"] <--> |Streamable Http| B["MCP Access Point"] B <--> |http 127.0.0.1:8090| C1["Existing API Server"] B <--> |https//api.example.com| C2["Existing API Server"] style A2 fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px style B fill:#e6e6af,stroke:#333,color:black,stroke-width:2px style C1 fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px style C2 fill:#e6ffd6,stroke:#333,color:black,stroke-width:2px
Currently supports SSE and Streamable HTTP protocols:
✅ Streamable HTTP (stateless) 2025-03-26
ip:port/mcpip:port/api/{service_id}/mcp✅ SSE 2024-11-05
ip:port/sseip:port/api/{service_id}/sseuse IP:PORT/sse for SSE
use IP:PORT/mcp for Streamable HTTP
# Install from source git clone https://github.com/sxhxliang/mcp-access-point.git cd mcp-access-point cargo run -- -c config.yaml # Use inspector for debugging (start service first) npx @modelcontextprotocol/inspector node build/index.js # Access http://127.0.0.1:6274/ # Select "SSE" and enter 0.0.0.0:8080/sse, then click connect # or select "Streamable HTTP" and enter 0.0.0.0:8080/mcp
The MCP Access Gateway supports multi-tenancy, where each tenant can configure multiple MCP services accessible via:
/api/{mcp-service-id}/sse (for SSE)/api/{mcp-service-id}/mcp (for Streamable HTTP)Example configuration:
# config.yaml example (supports multiple services) mcps: - id: service-1 # Access via /api/service-1/sse or /api/service-1/mcp ... # Service configuration - id: service-2 # Access via /api/service-2/sse or /api/service-2/mcp ... # Service configuration - id: service-3 # Access via /api/service-3/sse or /api/service-3/mcp ... # Service configuration
To access all services simultaneously, use:
0.0.0.0:8080/mcp (Streamable HTTP)0.0.0.0:8080/sse (SSE)-c config.yaml
-c (or --config) specifies the configuration file path (config.yaml).The configuration file supports multi-tenancy, allowing independent configuration of upstream services and routing rules for each MCP service. Key configuration items include:
mcps - MCP service list
id: Unique service identifier used to generate access pathsupstream_id: Associated upstream service IDpath: OpenAPI specification file path. Supports local files (e.g., config/openapi.json) and remote HTTP/HTTPS URLs (e.g., https://petstore.swagger.io/v2/swagger.json). Both JSON and YAML formats are supported.routes: Custom routing configuration (optional)upstream: Upstream service specific configuration (optional)upstreams - Upstream service configuration
id: Upstream service IDnodes: Backend node addresses and weightstype: Load balancing algorithm (roundrobin/random/ip_hash)scheme: Upstream protocol (http/https)pass_host: HTTP Host header handlingupstream_host: Override Host header valueComplete configuration example:
# config.yaml example (supports multiple services) mcps: - id: service-1 # Unique identifier, accessible via /api/service-1/sse or /api/service-1/mcp upstream_id: 1 path: config/openapi_for_demo_patch1.json # Local OpenAPI spec path - id: service-2 # Unique identifier upstream_id: 2 path: https://petstore.swagger.io/v2/swagger.json # Remote OpenAPI spec - id: service-3 upstream_id: 3 routes: # Custom routing - id: 1 operation_id: get_weather uri: /points/{latitude},{longitude} method: GET meta: name: Get Weather description: Retrieve weather information by coordinates inputSchema: # Optional input validation type: object required: - latitude - longitude properties: latitude: type: number minimum: -90 maximum: 90 longitude: type: number minimum: -180 maximum: 180 upstreams: # Required upstream configuration - id: 1 headers: # Headers to send to upstream service X-API-Key: "12345-abcdef" # API key Authorization: "Bearer token123" # Bearer token User-Agent: "MyApp/1.0" # User agent Accept: "application/json" # Accept header nodes: # Backend nodes (IP or domain) "127.0.0.1:8090": 1 # Format: address:weight - id: 2 nodes: "127.0.0.1:8091": 1 - id: 3 nodes: "api.weather.gov": 1 type: roundrobin # Load balancing algorithm scheme: https # Protocol pass_host: rewrite # Host header handling upstream_host: api.weather.gov # Override Host
To run the MCP Access Gateway with config file:
cargo run -- -c config.yaml
# Note: Replace /path/to/your/config.yaml with actual path docker run -d --name mcp-access-point --rm \ -p 8080:8080 \ -e port=8080 \ -v /path/to/your/config.yaml:/app/config/config.yaml \ ghcr.io/sxhxliang/mcp-access-point:main
# Clone repository git clone https://github.com/sxhxliang/mcp-access-point.git cd mcp-access-point # Build image docker build -t liangshihua/mcp-access-point:latest .
# Using environment variables (service running on host) # Note: Replace /path/to/your/config.yaml with actual path docker run -d --name mcp-access-point --rm \ -p 8080:8080 \ -e port=8080 \ -v /path/to/your/config.yaml:/app/config/config.yaml \ liangshihua/mcp-access-point:latest
port: MCP Access Point listening port (default: 8080)Example Scenario:
When MCP-based AI clients need to interface with legacy HTTP microservices, the MCP Access Gateway acts as a middleware layer enabling seamless protocol conversion.
Many thanks to @limcheekin for writing an article with a practical example: https://limcheekin.medium.com/building-your-first-no-code-mcp-server-the-fabric-integration-story-90da58cdbe1f
The MCP Access Point now supports dynamic configuration management through a RESTful Admin API, allowing you to update configurations without restarting the service.
Add the following to your config.yaml to enable the Admin API:
access_point: admin: address: "127.0.0.1:8081" # Admin API listening address api_key: "your-api-key" # Optional API key for authentication
GET /admin/resources - Get resource summary and statisticsGET /admin/resources/{type} - List all resources of a specific typeGET /admin/resources/{type}/{id} - Get a specific resourcePOST /admin/resources/{type}/{id} - Create a new resourcePUT /admin/resources/{type}/{id} - Update an existing resourceDELETE /admin/resources/{type}/{id} - Delete a resourcePOST /admin/validate/{type}/{id} - Validate resource configurationPOST /admin/batch - Execute batch operationsPOST /admin/reload/{type} - Reload a specific resource typePOST /admin/reload/config - Reload full configuration from file (defaults to config.yaml). Optional JSON body: { "config_path": "path/to/config.yaml" }upstreams - Backend server configurationsservices - Service definitionsroutes - Routing rulesglobal_rules - Global plugin rulesmcp_services - MCP service configurationsssls - SSL certificate configurationscurl -X POST http://localhost:8081/admin/resources/upstreams/my-upstream \ -H "Content-Type: application/json" \ -d '{ "id": "my-upstream", "type": "RoundRobin", "nodes": ["127.0.0.1:8001", "127.0.0.1:8002"], "timeout": { "connect": 5, "read": 10, "send": 10 } }'
curl -X POST http://localhost:8081/admin/resources/services/my-service \ -H "Content-Type: application/json" \ -d '{ "id": "my-service", "upstream_id": "my-upstream", "hosts": ["api.example.com"] }'
curl -X POST http://localhost:8081/admin/batch \ -H "Content-Type: application/json" \ -d '{ "dry_run": false, "operations": [ { "operation_type": "create", "resource_type": "upstreams", "resource_id": "batch-upstream", "data": { "id": "batch-upstream", "type": "Random", "nodes": ["192.168.1.10:8080"] } }, { "operation_type": "create", "resource_type": "services", "resource_id": "batch-service", "data": { "id": "batch-service", "upstream_id": "batch-upstream" } } ] }'
curl http://localhost:8081/admin/resources
GET /admin serves a built-in dashboard (static/admin_dashboard.html).
mcp_services, 2) ssls, 3) global_rules, 4) routes, 5) upstreams, 6) services.count and a formatted last_updated derived from the API response.# Uses default config.yaml curl -X POST http://localhost:8081/admin/reload/config \ -H "Content-Type: application/json" \ -H "x-api-key: your-api-key" # Or specify a different config path curl -X POST http://localhost:8081/admin/reload/config \ -H "Content-Type: application/json" \ -H "x-api-key: your-api-key" \ -d '{"config_path": "./config.yaml"}'
Use the provided test script to verify Admin API functionality:
# Make the test script executable chmod +x test-admin-api.sh # Run comprehensive API tests ./test-admin-api.sh
For detailed Admin API documentation, see RUNTIME_CONFIG_API.md.