
HTTP-Proxy-Bridge für Sicherheitstests von Remote-MCP-Servern, die es Standard-HTTP-Tools ermöglicht, JSON-RPC-Nachrichten zu senden und Sitzungen zu verwalten.
Dieses Projekt implementiert einen HTTP-Server, der als Brücke zwischen HTTP/1.1-Anfragen und einem entfernten MCP-Server fungiert und dabei die Python-Bibliothek mcp verwendet (GitHub).
Der Hauptzweck dieser Initiative ist es, HTTP-Sicherheitstools einsetzen zu können, um entfernte MCP-Server über die Remote-Transportmechanismen (HTTP+SSE oder Streamable HTTP) zu testen.
Es wurde festgestellt, dass beim Senden von JSON-RPC-V2-Nachrichten mit derselben ID unter Verwendung paralleler Threads Antworten zusammengeführt werden können. Bitte beachten Sie dies, wenn Sie das Tool in Ihrer Bewertung verwenden. Bis wir dieses Problem behoben haben, stellen Sie sicher, dass Sie mit einem einzelnen Thread testen.
Klonen Sie zunächst das Repository und installieren Sie die erforderlichen Abhängigkeiten:
git clone <repository-url>
cd http-mcp-bridge
pip install -r requirements.txt
Um den HTTP-Server auszuführen, führen Sie den folgenden Befehl aus:
python3 main.py --remote-url="http://127.0.0.1:8787/mcp"
Der HTTP-Server lauscht auf der Standard-Schnittstelle und dem Standard-Port (http://127.0.0.1:8000), und die MCP-Verbindung wird zu der angegebenen Remote-URL aufgebaut. Unter der angegebenen URL sollte ein entfernter MCP-Server erreichbar sein, der einen unterstützten Transportmechanismus implementiert. Der HTTP-Server hat früher den korrekten Transportmechanismus, Streamable HTTP oder HTTP+SSE, automatisch erkannt, aber das verursachte Probleme in einigen Produktionsumgebungen, daher ist diese Funktion jetzt deaktiviert. Standardmäßig wurde der Streamable-HTTP-Transportmechanismus verwendet. Wir werden ein Flag erstellen, um die Verwendung von HTTP+SSE zu erzwingen, aber in der Zwischenzeit können Sie einfach den Code bearbeiten und diesen Transportmechanismus aktivieren.
Sie können dann HTTP-Anfragen an den Server senden, der sie an die SSE-/Streamable-HTTP-Clients weiterleitet.
Der im Python-SDK implementierte Mechanismus richtet einen Lese- und einen Schreibkanal ein, um über den entsprechenden Transportmechanismus mit dem Endpunkt zu kommunizieren. Diese HTTP-zu-MCP-Bridge leitet HTTP-Anfragen an den Schreibkanal weiter und wartet im Lesekanal auf die Antwort (falls zutreffend). Sobald diese eingegangen ist, wird sie als Antwort auf die HTTP-Anfrage zurückgegeben.
HTTP-Anfragen unterstützen den Parameter timeout, der die maximale Anzahl von Sekunden begrenzt, die die Bridge im Lesekanal auf die Antwort wartet, bevor sie eine Fehlermeldung zurückgibt. Wenn timeout null ist, wartet die HTTP-zu-MCP-Bridge überhaupt nicht.
Da die HTTP-zu-MCP-Bridge mehrere Sitzungen mit dem MCP-Server unterstützt, besteht der erste Schritt darin, eine Sitzungs-ID zu erhalten, die in weiteren Anfragen verwendet wird.
Anfrage:
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
Antwort:
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"}
Diese Sitzungs-ID unterscheidet sich von der Sitzungs-ID, die zwischen dem MCP-Client und dem Server aufgebaut wird, und ist unabhängig davon. Letztere wird von der Bibliothek mcp im Hintergrund verwaltet.
Es gibt eine Ping-Methode, die aufgerufen werden kann, um zu überprüfen, ob der MCP-Dienst erreichbar ist und der gewählte Transportmechanismus korrekt ist.
Anfrage:
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}
Antwort:
[{"jsonrpc":"2.0","id":2,"result":{}}]
Der erste Schritt einer MCP-Kommunikation ist der Initialisierungs-Handshake, bei dem beide Seiten ihre verfügbaren Fähigkeiten austauschen.
Anfrage:
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}
Antwort:
[{"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"Demo","version":"1.0.0"}}}]
Der Handshake muss mit dieser Nachricht abgeschlossen werden, die keine Antwort hat, daher können wir zu diesem Zeitpunkt timeout=0 verwenden. Wir erhalten eine Timeout-Fehlermeldung, aber das ist zu erwarten.
Anfrage:
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"}
Antwort:
{"message":"Timeout waiting for messages"}
Sobald der Handshake abgeschlossen ist, können wir die verfügbaren Methoden aufrufen, wie z. B. tools/list (Auflistung der Tools).
Anfrage:
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}
Antwort:
[{"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#"}}]}}]
Schließlich können wir Tools aufrufen oder andere Fähigkeiten nutzen.
Anfrage:
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}
Antwort:
[{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"3"}]}}]
Beiträge sind willkommen! Bitte eröffnen Sie ein Issue oder reichen Sie einen Pull-Request für Verbesserungen oder Fehlerbehebungen ein.
Dieses Projekt ist unter der MIT-Lizenz lizenziert. Weitere Details finden Sie in der Datei LICENSE.