feat(mcp): mount /mcp endpoint with bearer-token auth

Wires FastMCP's streamable-HTTP ASGI sub-app into the Quart app via
asgi_app replacement. Requests under /mcp are stripped, auth-checked
against api_keys, and forwarded to FastMCP with fable_user_id set on
the ASGI scope. All other paths pass through to the original Quart
dispatch unchanged.

Tests cover the three auth paths (no header, invalid token, valid
token) plus a regression check that non-/mcp paths bypass the MCP
dispatch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 19:15:42 -04:00
parent caa504913f
commit 94f7a6de37
3 changed files with 130 additions and 2 deletions
+2
View File
@@ -34,6 +34,7 @@ from fabledassistant.routes.search import search_bp
from fabledassistant.routes.voice import voice_bp
from fabledassistant.routes.profile import profile_bp
from fabledassistant.routes.knowledge import knowledge_bp
from fabledassistant.mcp import mount_mcp
STATIC_DIR = Path(__file__).parent / "static"
logger = logging.getLogger(__name__)
@@ -441,4 +442,5 @@ def create_app() -> Quart:
return jsonify({"error": "Internal server error"}), 500
return "Internal Server Error", 500
mount_mcp(app)
return app