Panels exposes one MCP (Model Context Protocol) connection that lets external AI tools — Claude Code, Claude Desktop, Cursor, Codex, Windsurf, or any MCP-compatible client — manage your account and work in one explicitly selected workspace. The MCP is the only supported control surface — the legacy panels CLI has been removed.

What is MCP?

MCP is an open protocol for connecting AI assistants to external tools. Panels implements a remote MCP server (Streamable HTTP with OAuth) so any compatible client can query your data, create nodes, build dashboards, and administer your workspace — signing in with your Panels account rather than a long-lived key. The server speaks the current 2026-07-28 protocol revision (stateless server/discover negotiation) and remains fully compatible with earlier clients back to 2024-11-05 — version selection is automatic, so no client configuration is needed. Because every catalog is composed per authenticated connection, responses are never cacheable by shared intermediaries (cacheScope: "private" plus Cache-Control: no-store).

Connect a client (production)

Configure one server named panels at the canonical endpoint:
For Claude Code:
For Codex:

Codex reports OAuth but Panels tools are missing

codex mcp list reports whether Codex has a stored credential; it does not prove that the current process loaded a usable Panels tool catalog. Exit and start Codex once. If the tools are still missing, run codex mcp login panels, approve the same workspaces and permissions, and restart Codex after authorization. Do not broaden the approved workspaces or scopes to repair a stale credential. Codex has tracked a similar post-OAuth tool-catalog symptom in openai/codex#32590. For Cursor, add this as the single panels entry in .cursor/mcp.json:
Cursor Agent users can then start the OAuth flow explicitly:
On first use the client bootstraps OAuth automatically (dynamic client registration + authorization-code flow) and opens a browser consent screen where you sign in, approve account access, and explicitly select one or more workspaces when they exist. You can also find this under Settings → Connect AI in the app, which lists the same endpoint and per-client setup snippets.

Migrating from the retired Panels CLI

The old panels CLI, its panels mcp serve command, and its shared static OAuth client are no longer supported. Add the hosted /mcp URL to your MCP client and complete OAuth there; each client manages its own tokens. Panels does not delete ~/.panels/credentials.json or any other local config during this migration. Hosted MCP clients do not read that file. Keep or archive it while any private test harness still depends on it, and remove it manually only after you have confirmed nothing local uses it. Revoking an old “Panels CLI” grant in Settings → Connect AI invalidates its server-side tokens but does not delete the local file. The repository’s cmd/v15 / bin/panels executable is a deployment and maintenance utility, not the retired product CLI; operators should keep using it for database migrations and documented maintenance commands.

Authorization and workspace context

The one /mcp connection can expose account tools and workspace tools. An OAuth grant contains an explicit set of authorized workspaces and has no implicit default when that set contains more than one workspace:
  • No workspace yet: approve account access, call account_create_workspace, then run your client’s authenticate/login step again against the same panels connection to add the new workspace to the authorized set.
  • One or more workspaces: select every workspace the client may access on the consent screen. Each workspace tool call identifies its target with workspace_id; compatible clients expose the authorized IDs in that argument’s schema.
  • Changing the authorized set: reconnect or log in again to add or remove workspace access. Switching among workspaces already in the set only requires a different workspace_id, not reauthentication. Account and workspace permissions remain enforced independently even though the tool catalog comes from one endpoint.

Connect to a local stack (panels-local)

The local edge serves the identical /mcp surface, so you can develop and test against your own stack instead of production. With a dev-c stack running, use its frontend hostname (for example, the ui-testing environment):
Replace v15-ui-testing with the active stack name. The client discovers the local authorization server from /.well-known/oauth-protected-resource, registers against the local Hydra, and runs the same consent flow — sign in with your local dev identity. Everything that works against production works against local, including account tools, workspace scope-documents, secrets tools, and privileged commands.

Legacy account endpoint compatibility

Existing clients registered against https://app.panels-analytics.com/account/mcp continue to work during the measured migration window. That resource does not redirect authenticated MCP requests: its tokens are audience-bound, so migrating means adding /mcp and completing a new authorization rather than reusing the old token. Responses from the legacy endpoint carry RFC 9745 Deprecation and migration Link headers. Panels separately counts accepted and rejected legacy requests with edge_mcp_legacy_account_requests_total{authorization}. The endpoint becomes a retirement candidate only after this query remains zero for a complete 30-day window following the guidance rollout:
Rejected probes are monitored but do not prove an active client dependency. Set and announce a Sunset date only after the accepted-traffic gate is satisfied. Rollback does not invalidate unified-resource tokens. If client interoperability requires it, restore the previous account-client instructions and reconnect those clients to /account/mcp; existing /mcp registrations and grants can stay in place while the guidance is corrected.

Scopes & elevated access

Most tools work with the default read / write grant. Privileged, credential-issuing operations — regenerating a webhook token, rotating an email hook, issuing service-principal or OAuth-client credentials, creating share links, managing secrets, and reading PII/admin scope-documents (identities, groups, service-principals) — require the elevated operator scope. operator is never granted silently: when a client requests it, the consent screen shows it as a distinct, default-off permission with a warning, and you must explicitly approve it for that session. A session that hasn’t been elevated is rejected with insufficient_scope if it attempts a privileged command. This keeps autonomous agent sessions narrow by default while letting a human operator opt into elevated access deliberately.

Available operations

  • Read graph structure, node schemas, and query results
  • Create and modify nodes; build dashboard layouts
  • Read and edit tenant scope-documents (projects, members, settings, OAuth clients, identities, groups, service-principals)
  • Manage data connections and secrets
  • Run privileged operations (with operator scope): webhook-token regeneration, credential issuance, share links
Use core_list_scopes and get_schema from any connected client to discover the full, current tool surface.

Render and inspect an app view

Use render_view to inspect the exact AppDSL view users see. Pass the project and view IDs returned by the project/view discovery tools. Add element_id to crop a chart, metric, table, or container while retaining its complete layout, theme, and data context.
The tool returns an inline image/png block plus structured provenance. Omit width and height to use 1440 × 900; each dimension must be an integer from 1 through 8000. Use full_page to expand the complete composed scene, or omit element_id to capture the whole view. Branch captures can be pinned with branch_id and effective_cursor.
render_view mounts the production React renderers and queries the same committed artifacts as the live app. It does not start a viewport-specific data run or accept caller HTML, URLs, cookies, or JavaScript.

Next: build something

Your first pipeline with the MCP

Once you’re connected, build and run a three-node pipeline end-to-end — source, transform, aggregate — without touching the UI.

Storing secrets from any MCP client

Secret values never travel through MCP arguments or model context. When an agent calls core_request_secret_handoff with operator scope, a compatible MCP host receives a short-lived Panels URL through standard URL elicitation. The URL contains only a non-secret handoff ID and conveys no authority. How this looks per client:
  • Panels chat — an inline credential card renders automatically; type the value there.
  • Web/desktop MCP hosts (Claude, ChatGPT, …) — the host presents the URL elicitation; open it, sign in if prompted, and submit the value on the handoff page.
  • Terminal hosts — a URL-elicitation-capable client presents the link for you to open. A client without URL elicitation (most terminal agents today) is not refused: the request is created and the result says completion: "in_app". Open Panels in your browser — the pending request appears there for an owner or admin, with any connection fields the agent proposed already filled in. Either way the link is deliberately absent from ordinary tool results and model-visible history.
Panels accepts the value only from the authenticated browser form. Your signed-in subject and active team must match the subject and team that requested the handoff. Panels also checks the browser origin before accepting completion or cancellation. If you opened a handoff while another team is active, the page offers your owner/admin teams as an explicit switch-and-retry choice. The handoff ID does not reveal its team and cannot switch teams by itself.
Do not treat the handoff URL as a bearer link. Copying it to another account or team does not grant access, and direct API completion is not supported.
You can abandon a pending request from the Panels form without submitting a value. Declining MCP URL elicitation does not perform a server-side cancellation; the request expires after 10 minutes — or after an hour when it is waiting for you in the Panels app because the client could not show a link — unless you cancel it in Panels. Agents can poll core_get_secret_handoff_status for metadata-only status, then bind a completed key in node DSL. For services that support OAuth, prefer a managed provider connection over a durable API key. MCP can list stable connection IDs and status through core_list_provider_connections, but it cannot receive or refresh provider credentials.