
이 프로젝트는 mcp 파이썬 라이브러리(GitHub)를 사용하여 HTTP/1.1 요청과 원격 MCP 서버 간의 브리지 역할을 하는 HTTP 서버를 구현합니다.
이 이니셔티브의 주요 목적은 원격 전송 메커니즘(HTTP+SSE 또는 Streamable HTTP)을 사용하는 원격 MCP 서버를 테스트하기 위해 HTTP 보안 도구를 사용할 수 있게 하는 것입니다.
동일한 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)에서 수신 대기하며, 제공된 원격 URL로 MCP 연결이 설정됩니다. 해당 URL에는 지원되는 전송 메커니즘을 구현한 원격 MCP 서버가 존재해야 합니다. HTTP 서버는 원래 Streamable HTTP 또는 HTTP+SSE 중 올바른 전송 메커니즘을 자동으로 감지했지만, 일부 프로덕션 환경에서 문제를 일으켜 현재는 비활성화되어 있습니다. 기본적으로 Streamable HTTP 전송 메커니즘을 사용했습니다. HTTP+SSE 사용을 강제하는 플래그를 만들 예정이지만, 그동안 코드를 직접 편집하여 해당 전송 메커니즘을 활성화할 수 있습니다.
그런 다음 서버에 HTTP 요청을 보낼 수 있으며, 서버는 이를 SSE/Streamable HTTP 클라이언트로 중계합니다.
python SDK에 구현된 메커니즘은 해당 전송 메커니즘을 사용하여 엔드포인트와 통신하기 위해 읽기 채널과 쓰기 채널을 설정합니다. 이 HTTP to MCP Bridge는 HTTP 요청을 쓰기 채널로 전달하고, 읽기 채널에서 (해당하는 경우) 응답을 기다립니다. 응답을 수신하면 해당 응답이 HTTP 요청의 응답으로 전달됩니다.
HTTP 요청은 timeout 매개변수를 지원하며, 이는 브리지가 오류 메시지를 반환하기 전에 읽기 채널에서 응답을 기다리는 최대 시간(초)을 제한합니다. timeout이 0이면 HTTP to MCP Bridge는 전혀 기다리지 않습니다.
HTTP to MCP Bridge는 MCP 서버와의 여러 세션을 지원하므로, 첫 번째 단계는 이후 요청에 사용될 세션 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 라이브러리가 처리합니다.
MCP 서비스가 존재하고 선택한 전송 메커니즘이 올바른지 확인하기 위해 호출할 수 있는 ping 메서드가 있습니다.
요청:
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"}]}}]
기여는 언제나 환영합니다! 개선 사항이나 버그 수정이 있으면 이슈를 열거나 풀 리퀘스트를 제출해 주세요.
이 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.