Skip to content

fix(mcp): install torproxy CLI in image, support Streamable HTTP, harden SSE/gateway, and bump to v2.6.1 - #125

Merged
hapheus merged 2 commits into
mainfrom
fix/mcp-server-hardening
Nov 10, 2026
Merged

hapheus merged 2 commits into
mainfrom
fix/mcp-server-hardening

Conversation

@hapheus

@hapheus hapheus commented Nov 10, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes and hardens the integrated Model Context Protocol (MCP) server following live container and protocol verification:

  • Docker Image CLI Entrypoint (docker/Dockerfile): Installs /usr/local/bin/torproxy (0755) and verifies torproxy --version during image build so documented Stdio configurations (docker exec -i torproxy torproxy mcp) work out of the box.
  • Streamable HTTP & Dual-Transport Support (src/torproxy/mcp/sse.py, docs/mcp.md): Supports direct JSON-RPC POST requests on /mcp, /sse, and / (MCP 2025-03-26+ Streamable HTTP) alongside existing HTTP/SSE streaming (GET /sse / GET /mcp + POST /messages?sessionId=...).
  • SSE Session Auth & Transport Hardening (src/torproxy/mcp/sse.py):
    • Allows active sessions established via authenticated GET /sse?token=<token> to dispatch requests to POST /messages?sessionId=<id> after RFC 3986 relative URI resolution without failing with 401 Unauthorized.
    • Uses constant-time hmac.compare_digest for token comparison.
    • Adds IPv6 listener support (AF_INET6), non-blocking session queue teardown in shutdown(), and strict ASCII decimal validation for Content-Length.
  • Transparent Gateway Mode Exemption (src/torproxy/runtime/gateway.py): Exempts settings.mcp_port (2501) in PREROUTING, OUTPUT, and INPUT netfilter rules when TORPROXY_GATEWAY_MODE=true.
  • Protocol & torproxy_fetch Hardening (src/torproxy/mcp/protocol.py):
    • Negotiates protocolVersion (2024-11-05, 2025-03-26, 2025-06-18) and responds to prompts/list and resources/templates/list.
    • Accepts strict_nodes alias in torproxy_reconnect and torproxy_connect.
    • Blocks HTTP redirects to non-HTTP(S) schemes (e.g., file://, ftp://) via _SafeRedirectHandler and clamps non-positive timeout/max_bytes parameters.

Closes #124

Verification

  • uv run ruff check . & uv run ruff format --check . — clean
  • uv run mypy — clean (27 source files)
  • bash -n & shellcheck — clean
  • uv run pytest tests/unit/ -v --cov=torproxy --cov-fail-under=85 — 397 passed (87.24% coverage)
  • Local Docker build + ./tests/integration/verify_container.sh + live torproxy_fetch over Tor — passed

@hapheus hapheus changed the title fix(mcp): install torproxy CLI in image, support Streamable HTTP, and harden SSE/gateway fix(mcp): install torproxy CLI in image, support Streamable HTTP, harden SSE/gateway, and bump to v2.6.1 Nov 10, 2026

@majorungustl majorungustl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 kuenstlichedummheit-sys left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 MustermenschAlex left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@hapheus
hapheus merged commit 18d8e85 into main Nov 10, 2026
12 checks passed
@hapheus
hapheus deleted the fix/mcp-server-hardening branch November 10, 2026 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(mcp): install torproxy CLI entrypoint in image, support Streamable HTTP, and harden SSE/gateway

4 participants