Skip to content

Connect an agent over MCP

Fanout serves MCP at /mcp for external agents. Its tools query telemetry and manage the authenticated user’s dashboards. The browser client and built-in agent use the same typed query results.

Build and refine dashboards covers schema discovery, panel previews, targeted edits and saved-version restore through chat or MCP.

You need a running instance with an HTTPS address first: install Fanout, finish first boot, then serve it over TLS, directly or behind a proxy. That HTTPS origin is the URL your MCP client connects to.

Terminal window
export FANOUT_PUBLIC_URL=https://fanout.example.com

Fanout derives the MCP resource URI from this canonical, externally reachable origin that clients are issued tokens against. It must be HTTPS, and it must stay stable across restarts: tokens carry the derived resource as their audience, so changing it invalidates every one already issued.

FANOUT_PUBLIC_URL is the only public-origin setting; see server settings.

Set FANOUT_MCP_ENABLED=false to turn the endpoint off entirely; it defaults to true.

Fanout implements the standard remote-MCP OAuth flow, so a compliant client needs only the URL:

  1. Discovers the endpoints from /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server.
  2. Registers itself at /oauth/register through dynamic client registration, so nothing is pre-provisioned by hand.
  3. Obtains a token from /oauth/token, bound to the resource URI above.

You authorize it in the browser as yourself, which ties the agent to your account without delegating your first-party account role.

Add Fanout as a remote MCP server:

Terminal window
claude mcp add --transport http fanout https://fanout.example.com/mcp

Use your instance’s public URL, then authorize the connection in your browser.

Open Settings → Connected agents, find the agent, and choose Disconnect. Confirm to revoke its access immediately. Your other agents and browser session stay connected. To reconnect, authorize that agent again in your browser.

Administrators can still revoke all of a user’s access, including browser sessions and OAuth tokens.

Fanout serves modern and legacy MCP clients concurrently over Streamable HTTP on /mcp. Modern 2026-07-28 requests carry per-request metadata and MCP-Protocol-Version: 2026-07-28, with no session or initialize handshake. Legacy clients use initialize to negotiate 2025-11-25 or 2025-06-18 and receive an Mcp-Session-Id bound to the authenticated user. Legacy sessions expire after 10 idle minutes, with at most eight live sessions per user/OAuth client pair. An expired session or a server restart requires re-initialization. Versions 2025-03-26 and 2024-11-05 are not served. The browser’s /api/mcp route uses only the modern protocol.

On /mcp and /api/mcp, an Origin header must exactly match the RFC 6454 serialization of FANOUT_PUBLIC_URL. Malformed or untrusted origins receive 403 before authentication. Without a public URL, only same-authority loopback origins are accepted. Requests without Origin pass this check.

tools/call requests are limited to 20 per second per user/OAuth client pair, with a burst of 100. Excess calls receive 429 with Retry-After. The in-process agent is exempt. Modern client disconnects cancel in-flight tool calls, including DuckDB queries.

ScopeGrants
telemetry:readRequired for every remote MCP request.
dashboard:managelist_dashboards, get_dashboard, create_dashboard, replace_dashboard, edit_dashboard, list_dashboard_versions, and restore_dashboard_version

Dashboard tools additionally require dashboard:manage. An insufficient_scope challenge lists every scope required by the request, including scopes already granted.

Restore requires an explicit user request and appends the selected historical spec as a new saved version with a save receipt. Dashboard deletion uses the HTTP API; there is no MCP delete tool.

It acts on your behalf, but its delegated authority comes from the scopes you approve rather than your account role. Fanout also checks that your current account capabilities still permit those scopes. Two consequences:

  • Dashboard tools are owner-scoped. An agent can manage your dashboards and cannot touch anyone else’s.
  • agent:run is not involved here. That capability gates Fanout’s own built-in agent; an external MCP client is a separate path.

There is no tool that writes telemetry, edits configuration, manages users or changes alert rules.

If TLS terminates at a reverse proxy, FANOUT_PUBLIC_URL must be the externally visible HTTPS origin rather than the internal address Fanout is listening on. Terminate TLS covers the rest of that setup.

/.well-known/oauth-protected-resource is unauthenticated, so a plain fetch tells you whether discovery is answering and what resource it advertises:

Terminal window
curl -s https://fanout.example.com/.well-known/oauth-protected-resource

If the resource in that document is not the URL your client is calling, fix FANOUT_PUBLIC_URL before debugging anything else.