该项目实现了一个HTTP服务器,充当HTTP/1.1请求与远程MCP服务器之间的桥接,使用mcp Python库(GitHub)。
此项目的主要目的是能够使用HTTP安全工具,通过远程传输机制(HTTP+SSE或Streamable HTTP)测试远程MCP服务器。
据观察,在使用并发线程发送具有相同id的JSON-RPC-V2消息时,响应可能会被合并。在评估中使用此工具时请牢记这一点。在我们修复此问题期间,请确保使用单线程进行测试。
首先克隆仓库并安装所需依赖:
git clone <repository-url>
cd http-mcp-bridge
pip install -r requirements.txt
要运行HTTP服务器,请执行以下命令:
python3 main.py --remote-url="http://127.0.0.1:8787/mcp"
HTTP服务器将监听默认接口和端口(http://127.0.0.1:8000),MCP连接将建立到所提供的远程URL。该URL处应存在一个实现了受支持的传输机制的远程MCP服务器。HTTP服务器原本会自动检测正确的传输机制(Streamable HTTP或HTTP+SSE),但这在某些生产环境中引发了问题,因此该功能现已禁用。它默认使用Streamable HTTP传输机制。我们将创建一个标志来强制使用HTTP+SSE,但在此期间,您可以直接编辑代码并启用该传输机制。
然后,您可以向该服务器发送HTTP请求,服务器会将请求中继给SSE/Streamable HTTP客户端。
Python SDK中实现的机制会建立读取通道和写入通道,通过相应的传输机制与端点通信。此HTTP到MCP桥接服务将HTTP请求转发到写入通道,并在读取通道中等待响应(如适用)。收到响应后,该响应将作为HTTP请求的响应返回。
HTTP请求支持timeout参数,该参数限制桥接服务在返回错误消息之前在读取通道中等待响应的最大秒数。如果timeout为零,则HTTP到MCP桥接服务完全不等待。
由于HTTP到MCP桥接服务支持与MCP服务器的多个会话,第一步是获取会话ID,该ID将用于后续请求。
请求:
GET /mcp/messages HTTP/1.1
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
User-Agent: python-httpx/0.28.1
Content-Type: application/json
Cache-Control: no-store
Content-Length: 0
响应:
HTTP/1.1 400 Bad Request
date: Fri, 02 May 2025 15:40:32 GMT
server: uvicorn
content-length: 87
content-type: application/json
{"detail":"Invalid session id. Try /mcp/messages/7fc2cce5-3b0b-4d63-9df6-e703c1df091c"}
该会话ID与MCP客户端和服务器之间建立的会话ID不同且相互独立。后者由mcp库在底层处理。
有一个Ping方法,可调用它来验证MCP服务是否存在以及所选的传输机制是否正确。
请求:
POST /mcp/messages/7fc2cce5-3b0b-4d63-9df6-e703c1df091c HTTP/1.1
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
User-Agent: python-httpx/0.28.1
Content-Type: application/json
Cache-Control: no-store
Authorization: Bearer [REDACTED]
Content-Length: 40
{"method":"ping","jsonrpc":"2.0","id":2}
响应:
[{"jsonrpc":"2.0","id":2,"result":{}}]
MCP通信的第一步是初始化握手,双方在此交换各自可用的能力。
请求:
POST /mcp/messages/7fc2cce5-3b0b-4d63-9df6-e703c1df091c HTTP/1.1
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
User-Agent: python-httpx/0.28.1
Content-Type: application/json
Cache-Control: no-store
Authorization: Bearer [REDACTED]
Content-Length: 213
{"method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {"sampling": {}, "roots": {"listChanged": true}}, "clientInfo": {"name": "mcp", "version": "0.1.0"}}, "jsonrpc": "2.0", "id": 0}
响应:
[{"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"Demo","version":"1.0.0"}}}]
握手需要使用此消息关闭,该消息没有响应,因此此时可以使用timeout=0。我们会收到一条超时错误消息,但这是预期行为。
请求:
POST /mcp/messages/7fc2cce5-3b0b-4d63-9df6-e703c1df091c?timeout=0 HTTP/1.1
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
User-Agent: python-httpx/0.28.1
Content-Type: application/json
Cache-Control: no-store
Authorization: Bearer [REDACTED]
Content-Length: 54
{"method":"notifications/initialized","jsonrpc":"2.0"}
响应:
{"message":"Timeout waiting for messages"}
握手完成后,我们可以调用可用的方法,例如tools/list(列出工具)。
请求:
POST /mcp/messages/7fc2cce5-3b0b-4d63-9df6-e703c1df091c HTTP/1.1
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
User-Agent: python-httpx/0.28.1
Content-Type: application/json
Cache-Control: no-store
Content-Length: 46
{"method":"tools/list","jsonrpc":"2.0","id":1}
响应:
[{"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"add","inputSchema":{"type":"object","properties":{"a":{"type":"number"},"b":{"type":"number"}},"required":["a","b"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}}]}}]
最后,我们可以调用工具或使用其他能力。
请求:
POST /mcp/messages/7fc2cce5-3b0b-4d63-9df6-e703c1df091c HTTP/1.1
Host: 127.0.0.1:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
User-Agent: python-httpx/0.28.1
Content-Type: application/json
Cache-Control: no-store
Content-Length: 100
{"method":"tools/call","params":{"name":"add","arguments":{"a":1, "b":2 }},"jsonrpc":"2.0","id":2}
响应:
[{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"3"}]}}]
欢迎贡献!如有任何改进或错误修复,请提交issue或拉取请求。
本项目基于MIT许可证进行许可。有关更多详细信息,请参阅LICENSE文件。