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:
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 (operator scope), the result includes a completion_url — a short-lived (10 minute), single-use link to an authenticated Panels page with a secure form. The one-shot capability rides in the URL fragment, which browsers never send to servers, so it stays out of access logs. How this looks per client:
  • Panels chat — an inline credential card renders automatically; type the value there. No URL needed.
  • Web/desktop MCP hosts (Claude, ChatGPT, …) — the tool result carries a clickable resource_link; open it, sign in if prompted, and submit the value on the handoff page.
  • Terminal hosts (Claude Code, …) — the completion_url is printed in the tool result. Open it in any browser. If you prefer to stay in the terminal, complete it with a no-echo prompt (capability is the value after #capability= in the URL):
Whichever path you use, the same authorization applies: an authenticated session for the same user who requested the handoff, with tenant owner/admin role (plus operator scope for OAuth sessions). The link’s UI affordances never change the security checks. Agents can poll core_get_secret_handoff_status (metadata only — never the capability or value) to learn when the handoff completes, then bind the stored key in node DSL.