feat(mcp): add MCP gateway — 14 tools over SSE, all agent calls forced local

Architecture:
- agent_service/mcp/tools.py: 14 Tool definitions with JSON schemas
    dispatch, finance_query, accounting_query, crm_query, sales_query,
    project_query, elearning_query, expenses_query, employees_query,
    get_health, list_agents, trigger_sweep, get_pending_approvals, approve_directive
- agent_service/mcp/server.py: mcp.Server with list_tools + call_tool handlers
- agent_service/routers/mcp_router.py: Starlette routes at /mcp/sse + /mcp/messages
- main.py: mounts MCP routes alongside existing FastAPI routers (graceful fallback if mcp not installed)

Privacy guarantee (enforced in server.py, not by convention):
- _force_local_context() sets llm_router._privacy_mode = 'local' before EVERY agent call
- _restore_mode() restores original mode after the tool returns
- HIPAA agents (finance, accounting, expenses, employees) were already Ollama-only;
  MCP adds a second enforcement layer for all 8 agents
- MCP client (e.g. Claude Code CLI) receives only tool results — no LLM completions cross the boundary

Usage (Claude Code CLI):
  claude mcp add --transport sse http://192.168.2.47:8001/mcp/sse
  or copy claude_mcp_config.json to ~/.claude/mcp_servers.json

requirements.txt: added mcp==1.3.0
tests/test_mcp_server.py: 13 tests covering tool count, schemas, HIPAA labelling, privacy override

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ActiveBlue Build
2026-04-15 16:45:49 -04:00
parent fb4bf56816
commit 66b114cdcf
8 changed files with 751 additions and 0 deletions

View File

@@ -232,6 +232,18 @@ def create_app() -> FastAPI:
app.include_router(registry.router)
app.include_router(sweep.router)
app.include_router(health.router)
# MCP gateway — mount SSE transport routes
# All agent calls through MCP are forced to local (Ollama) mode.
try:
from .routers.mcp_router import mcp_routes
from starlette.routing import Route
for route in mcp_routes:
app.router.routes.append(route)
logger.info('MCP gateway mounted at /mcp/sse and /mcp/messages')
except ImportError as exc:
logger.warning('MCP package not installed — gateway disabled: %s', exc)
return app