feat: implement mcp frontend

This commit is contained in:
h
2026-05-20 09:59:47 +02:00
parent 99a30f256d
commit 7970d4be9b
7 changed files with 902 additions and 24 deletions
+30 -2
View File
@@ -13,6 +13,7 @@ from beaver_gateway.agents.claude import ClaudeAgent
from beaver_gateway.agents.raycast import RaycastAgent, RemoteTool, UserPreferences
from beaver_gateway.core.registry import Gateway
from beaver_gateway.frontends.anthropic import AnthropicMessagesFrontend
from beaver_gateway.frontends.mcp_server import McpServerFrontend
from beaver_gateway.mcp.types import McpServer
@@ -94,14 +95,41 @@ gateway = Gateway(
# Phase 2.1 — bundle of plain Python callables exposed as one
# FastMCP namespace. The internal aggregator mounts it under
# ``/mcp/time`` on ``127.0.0.1:INTERNAL_MCP_PORT``; Phase 2.2's
# ClaudeCode adapter will forward that URL into
# ``BackendOptions.mcp_servers``.
# ClaudeCode adapter forwards that URL into
# ``BackendOptions.mcp_servers``. Phase 3's ``McpServerFrontend``
# reverse-proxies the same internal URL out to external clients.
McpServer.python_tool(name="time", tools=[current_time]),
# Phase 3 — illustrates the ``lenient`` flag. Real-world stdio MCPs
# sometimes print "Processing..." or other chatter to stdout before
# their actual JSON-RPC frames; the default mcp client forwards
# those parse failures downstream as warnings (visible in
# Cursor/Cline). With ``lenient=True`` we silently drop non-JSON
# lines, so downstream UIs see clean JSON-RPC only. The command
# below is just a placeholder — replace with whatever stdio MCP
# you actually want gateway to ingest (e.g. an obsidian-mcp).
#
# Commented out by default: example users won't have the binary
# installed and an unreachable command makes ``docker compose up``
# surface a confusing "command not found" line at first request.
# Uncomment after pointing ``command`` at a real stdio MCP.
#
# McpServer.stdio(
# name="obsidian",
# command=["uvx", "mcp-obsidian"],
# env={"OBSIDIAN_API_KEY": "..."},
# lenient=True,
# ),
],
frontends=[
# Phase 1.4 — expose the agents as `model=<name>` on an
# Anthropic-compatible Messages endpoint. Auth comes from
# `BOOTSTRAP_TOKENS` in the env (`name1:value1,name2:value2`).
AnthropicMessagesFrontend(host="0.0.0.0", port=8000),
# Phase 3 — re-exposes every declared `McpServer` outside the
# gateway with bearer auth + audit log. Per-namespace endpoints
# at `/mcp/<name>/`; flat bundle at `/mcp/all/`. Discovery page
# (HTML, auth-gated) at `/` with copy-pastable Cursor / Claude
# Desktop snippets. Auth re-uses `BOOTSTRAP_TOKENS`.
McpServerFrontend(host="0.0.0.0", port=8001),
],
)