#101

Require auth on MCP HTTP server + bind localhost by default (issue #90)

OpenDiogo-Damascenowants to merge intofrom

Summary

Fixes #90. The MCP HTTP server (transport sse) bound to 0.0.0.0:8080 with no authentication, exposing run_task/update_config/get_conversation_history to any network client — which could drive LocalRuntime shell execution on the operator's host.

Changes

  • mcp_transport_streamable_http.py: create_streamable_http_app(router, token=None). When a token is set, all /mcp routes (POST/GET/DELETE) require Authorization: Bearer <token>, returning 401 otherwise.
  • interface/main.py:
    • New --mcp-token flag; threaded into both server start paths.
    • Default --host changed from 0.0.0.0 → 127.0.0.1 (localhost only).
    • Warns when binding to 0.0.0.0 without a token.
  • Legacy behaviour preserved when no token is given, but now defaults to localhost so it isn't accidentally network-exposed.

Verification

  • pytest tests/security/test_mcp_auth.py → 8 passed (auth helper + integration: unauthenticated POST rejected 401, authenticated POST allowed, GET requires auth, no-token stays open).
  • pytest tests/security/ → 145 passed.
  • ruff: clean on all changed files.

Test plan for reviewers

  1. pentestagent mcp_server --type sse → binds 127.0.0.1:8080.
  2. With --mcp-token SECRET: curl -X POST localhost:8080/mcp -d '...' → 401; with -H "Authorization: Bearer SECRET" → proceeds.
  3. --host 0.0.0.0 without --mcp-token → prints a warning.