Repository navigation
fix(mcp): install torproxy CLI in image, support Streamable HTTP, harden SSE/gateway, and bump to v2.6.1 - #125
Conversation
… harden SSE/gateway
majorungustl
left a comment
There was a problem hiding this comment.
Having both Streamable HTTP (POST /mcp, /sse, /) and legacy SSE working on port 2501 plus the actual torproxy binary in
PATH makes plugging this into Cursor, Claude Desktop, and Antigravity completely frictionless. Pragmatic, zero-dependency, and ready to ship as 2.6.1.
kuenstlichedummheit-sys
left a comment
There was a problem hiding this comment.
Nice catch on the RFC 3986 relative URI resolution stripping ?token= on POST /messages?sessionId=... after GET
/sse?token=... — that would have bitten any EventSource client using query token auth. Also good to see _SafeRedirectHandler blocking 302 redirects to
file:// or ftp:// and port 2501 exempted in gateway PREROUTING/INPUT rules.
MustermenschAlex
left a comment
There was a problem hiding this comment.
Clean, well-structured fix that aligns the runtime behavior with our documented contracts in README.md and docs/mcp.md.
Installing /usr/local/bin/torproxy in docker/Dockerfile and asserting torproxy --version at build time guarantees the Stdio CLI contract stays intact, and
the new unit tests in test_mcp_protocol.py and test_mcp_sse.py thoroughly cover version negotiation, redirect scheme validation, and authenticated SSE
session dispatch.
Summary
Fixes and hardens the integrated Model Context Protocol (MCP) server following live container and protocol verification:
docker/Dockerfile): Installs/usr/local/bin/torproxy(0755) and verifiestorproxy --versionduring image build so documented Stdio configurations (docker exec -i torproxy torproxy mcp) work out of the box.src/torproxy/mcp/sse.py,docs/mcp.md): Supports direct JSON-RPCPOSTrequests on/mcp,/sse, and/(MCP2025-03-26+Streamable HTTP) alongside existing HTTP/SSE streaming (GET /sse/GET /mcp+POST /messages?sessionId=...).src/torproxy/mcp/sse.py):GET /sse?token=<token>to dispatch requests toPOST /messages?sessionId=<id>after RFC 3986 relative URI resolution without failing with401 Unauthorized.hmac.compare_digestfor token comparison.AF_INET6), non-blocking session queue teardown inshutdown(), and strict ASCII decimal validation forContent-Length.src/torproxy/runtime/gateway.py): Exemptssettings.mcp_port(2501) inPREROUTING,OUTPUT, andINPUTnetfilter rules whenTORPROXY_GATEWAY_MODE=true.torproxy_fetchHardening (src/torproxy/mcp/protocol.py):protocolVersion(2024-11-05,2025-03-26,2025-06-18) and responds toprompts/listandresources/templates/list.strict_nodesalias intorproxy_reconnectandtorproxy_connect.file://,ftp://) via_SafeRedirectHandlerand clamps non-positivetimeout/max_bytesparameters.Closes #124
Verification
uv run ruff check .&uv run ruff format --check .— cleanuv run mypy— clean (27 source files)bash -n&shellcheck— cleanuv run pytest tests/unit/ -v --cov=torproxy --cov-fail-under=85— 397 passed (87.24% coverage)./tests/integration/verify_container.sh+ livetorproxy_fetchover Tor — passed