#101
Require auth on MCP HTTP server + bind localhost by default (issue #90)
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/mcproutes (POST/GET/DELETE) requireAuthorization: Bearer <token>, returning401otherwise.interface/main.py:- New
--mcp-tokenflag; threaded into both server start paths. - Default
--hostchanged from0.0.0.0→127.0.0.1(localhost only). - Warns when binding to
0.0.0.0without a token.
- New
- 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
pentestagent mcp_server --type sse→ binds127.0.0.1:8080.- With
--mcp-token SECRET:curl -X POST localhost:8080/mcp -d '...'→ 401; with-H "Authorization: Bearer SECRET"→ proceeds. --host 0.0.0.0without--mcp-token→ prints a warning.