feat: add admin panel
This commit is contained in:
+35
-4
@@ -12,6 +12,7 @@ from beaver_gateway.agents.base import ExposedMcp
|
||||
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.admin import AdminFrontend
|
||||
from beaver_gateway.frontends.anthropic import AnthropicMessagesFrontend
|
||||
from beaver_gateway.frontends.mcp_server import McpServerFrontend
|
||||
from beaver_gateway.mcp.types import McpServer
|
||||
@@ -28,6 +29,7 @@ def current_time() -> str:
|
||||
|
||||
return datetime.now().astimezone().isoformat()
|
||||
|
||||
|
||||
gateway = Gateway(
|
||||
agents=[
|
||||
# Phase 2.2 — ClaudeCodeBackendAdapter routes this agent's
|
||||
@@ -98,7 +100,7 @@ gateway = Gateway(
|
||||
# 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]),
|
||||
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
|
||||
@@ -124,12 +126,41 @@ gateway = Gateway(
|
||||
# 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`).
|
||||
#
|
||||
# Behind a reverse proxy (Caddy / nginx / Cloudflare) pass
|
||||
# `public_base_url=` so the admin dashboard advertises the
|
||||
# outside URL instead of `host:port`. Caddy strips its own
|
||||
# prefix and the frontend's internal paths (`/v1/messages`,
|
||||
# `/v1/models`) get appended:
|
||||
# Caddy: handle_path /ai/* { reverse_proxy localhost:8000 }
|
||||
# Config: AnthropicMessagesFrontend(
|
||||
# port=8000,
|
||||
# public_base_url="https://domain.com/ai")
|
||||
# Result: https://domain.com/ai/v1/messages
|
||||
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
|
||||
# gateway with bearer auth + audit log. Each namespace lives
|
||||
# at `/<name>/` on this port (the port itself disambiguates
|
||||
# MCP traffic — no extra `/mcp` segment in the route); a flat
|
||||
# bundle is published at `/all/`. Discovery page (HTML,
|
||||
# auth-gated) at `/` with copy-pastable Cursor / Claude
|
||||
# Desktop snippets. Auth re-uses `BOOTSTRAP_TOKENS`.
|
||||
#
|
||||
# Same `public_base_url=` knob as above. Caddy strips its
|
||||
# prefix; the frontend's `/<name>/` segment gets appended:
|
||||
# Caddy: handle_path /mcp/* { reverse_proxy localhost:8001 }
|
||||
# Config: McpServerFrontend(
|
||||
# port=8001,
|
||||
# public_base_url="https://domain.com/mcp")
|
||||
# Result: https://domain.com/mcp/<name>/ (and /mcp/all/)
|
||||
McpServerFrontend(host="0.0.0.0", port=8001),
|
||||
# Phase 4.3 — browser admin UI. Creds come from
|
||||
# `ADMIN_USER`/`ADMIN_PASS`; the session cookie is signed with
|
||||
# `SESSION_SECRET`. Use it to mint tokens (Argon2-hashed in
|
||||
# the DB), revoke them, and watch the audit log. Scope is
|
||||
# enforced on the bearer frontends: tokens minted with scope
|
||||
# `messages` only work on `/v1/messages`; `mcp` only on
|
||||
# `/mcp/<name>`; `*` works everywhere.
|
||||
AdminFrontend(host="0.0.0.0", port=8002),
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user