MCP & API

Connect Claude, ChatGPT, Cursor, or any MCP client to your issues: file bugs from chat, triage from your editor, script your board.

The endpoint

Every Exponential instance exposes a streamable-HTTP MCP server at:

text
https://app.exponential.at/api/mcp

Self-hosting? It's the same path on your instance: https://your-instance/api/mcp. There is no separate /sse variant; modern clients speak streamable HTTP directly.

Authentication

OAuth for interactive clients

Point a client at the endpoint with no credentials and it registers itself (dynamic client registration) and sends you to your browser to approve. The consent screen is a scope picker: grant the client everything, specific teams, or specific boards. The token it receives is confined to exactly that grant. A client with no grant gets nothing. Re-running consent updates the grant, so you can widen or narrow access later.

API keys for headless use

Scripts and CI use a personal API key instead. Generate one under Settings → Security in the web app and send it as a bearer token:

text
Authorization: Bearer expu_...

API keys act as you, with your full membership. Guard them accordingly.

Client setup

Claude (Desktop & claude.ai)

Settings → Connectors → Add custom connector, paste the endpoint URL, and hit Connect. Your browser opens for OAuth and the scope picker. Works the same in the Claude desktop app and on claude.ai.

Connectors dial from Anthropic's cloudClaude's connectors connect server-side, so a self-hosted instance must be reachable from the internet. A LAN-only instance won't work here. Connectors are OAuth-only; to use an API key instead, bridge through mcp-remote (see "Other clients" below).

ChatGPT

On chatgpt.com, enable Settings → Apps & Connectors → Advanced settings → Developer mode (Plus/Pro/Business; the menu naming varies while the feature is in beta). Then Create connector, paste the MCP URL, and choose OAuth as the authentication. Write-capable tools ask for confirmation per call.

Claude Code

shell
claude mcp add --transport http --scope user exponential https://app.exponential.at/api/mcp

Then run /mcp in a session to sign in via OAuth. For headless use, attach an API key instead:

shell
claude mcp add --transport http --scope user exponential https://app.exponential.at/api/mcp \
  --header "Authorization: Bearer expu_..."

A configured header disables the OAuth fallback. In .mcp.json form, the server entry needs "type": "http".

Codex CLI

shell
codex mcp add exponential --url https://app.exponential.at/api/mcp
codex mcp login exponential

Or configure it in config.toml, with an API key via an environment variable:

toml
[mcp_servers.exponential]
url = "https://app.exponential.at/api/mcp"
bearer_token_env_var = "EXPONENTIAL_API_KEY"

Cursor

Add the server to ~/.cursor/mcp.json (or a project's .cursor/mcp.json):

json
{
  "mcpServers": {
    "exponential": {
      "url": "https://app.exponential.at/api/mcp"
    }
  }
}

Click Connect next to the server in Cursor's MCP list to run the OAuth flow. For API keys, add a headers object with the Authorization header instead.

OpenClaw

Install the Exponential plugin from ClawHub (the MCP server plus a skill) and give the gateway an API key, or add the server by hand and sign in with OAuth:

shell
openclaw plugins install clawhub:@exponential/openclaw-plugin
export EXPONENTIAL_API_KEY=expu_...

# or, with OAuth
openclaw mcp add exponential --url https://app.exponential.at/api/mcp --transport streamable-http --auth oauth
openclaw mcp login exponential

Turn on OpenClaw's MCP Apps bridge (openclaw config set mcp.apps.enabled true --strict-json) and the issue list and a run's report render as Exponential's own views in the dashboard; the issue list also opens straight from the app catalog.

Interactive views (MCP Apps)

Clients that render MCP Apps show five tools as Exponential views instead of JSON: exponential_issues_show (the issue list, grouped by status; a row opens the issue), exponential_sessions_list (your runs), exponential_sessions_get (a coding run's report), exponential_notifications_list (your inbox) and exponential_devices_list (your machines and their agent logins). Self-hosted instances serve the same views; nothing to configure on the server.

Other clients

Most MCP clients accept the generic mcpServers JSON shown above. VS Code (Copilot) uses a top-level servers key with "type": "http" per server. Clients that only speak stdio can bridge:

shell
npx mcp-remote https://app.exponential.at/api/mcp

Tool reference

What a connected client can do, grouped by area. Every call is confined to the OAuth grant's scope (or the API key's membership). Every list tool paginates (50 by default, 200 at most, 1000 for issues_list), and issue parameters take an identifier ("EXP-42") wherever they take a UUID.

Some tools only exist in contextexponential_sessions_end, exponential_sessions_ask_parent, exponential_sessions_results and exponential_sessions_show only inside an agent run the launcher started; and exponential_report_bug only on the cloud. Ask the server's own tools/list for the exact set your client sees.

Teams

  • exponential_teams_list: List the teams you belong to.
  • exponential_teams_get: Get a single team by id.
  • exponential_teams_create: Create a new team you own.
  • exponential_teams_update: Rename a team or change its icon (owner only).

Boards

  • exponential_boards_list: List boards in one team or across all your teams.
  • exponential_boards_get: Get a single board.
  • exponential_boards_create: Create a board (optionally repo-backed).
  • exponential_boards_update: Update name, color, icon, or the board's default branch.
  • exponential_boards_delete: Move a board to the 48-hour trash (owner only).
  • exponential_boards_set_repository: Point a board at a different registered repository.

Issues

  • exponential_issues_list: List issues, open work only unless includeClosed (or a status filter) says otherwise: boards, statusId / statusCategory, priority, assignee, labels (any, all, or unlabeled), source (user or widget), comment activity, created/updated ranges, title search, each with an exclude twin, plus sort (a "-" prefix descends). Up to 1000 per page.
  • exponential_issues_get: Get one issue with labels, relations and recent comments, by UUID or identifier ("EXP-42").
  • exponential_issues_show: The issue list as an interactive view in clients that render MCP Apps (OpenClaw, Claude, ChatGPT): status groups, priorities and PR numbers; a row opens the issue. Other clients get the same rows as exponential_issues_list.
  • exponential_issues_create: Create an issue. Pass statusId for a custom status.
  • exponential_issues_update: Update an issue's fields. Pass only what changes.
  • exponential_issues_delete: Permanently delete an issue and everything attached to it.
  • exponential_issues_update_status: Set status during a coding run (PR events move it to the team's configured statuses).
  • exponential_pr_open: Open + link the pull request server-side: issueId for one, issueIds + head for a batch, or repositoryId + head for a chore PR that links nothing. A follow-up run builds on its parent run's branch with base; such a tree merges root first, and the root's merge retargets its children.
  • exponential_pr_merge: Squash-merge through the GitHub App (no gh, no token): issueId, issueIds, or repositoryId + prNumber. endSessions overrides the team's end-sessions-on-merge setting for this call.
  • exponential_pr_retarget: Repoint an open PR's base branch, the fix for a PR whose base branch is gone.
  • exponential_issues_pr_files: List the linked PR's changed files with patches and add/delete counts.

Relations

  • exponential_issue_relations_add: Link two issues: blocks, parent, duplicate or related, stored one way (issueId blocks / is the parent of / duplicates relatedIssueId; related is symmetric). Pass inverse for blocked by, sub-issue of or duplicated by.
  • exponential_issue_relations_remove: Unlink two issues, named in the direction the link is stored; exponential_issues_get lists them.

Statuses

  • exponential_statuses_list: List a team's issue statuses with id, name, category and color — the ids you pass as statusId.
  • exponential_statuses_create: Create a custom status in a category (never duplicate; started allows at most four).
  • exponential_statuses_update: Rename or recolor a custom status. Builtins are locked.
  • exponential_statuses_delete: Delete a custom status; issues still on it need a reassignToId replacement.

Labels & issue labels

  • exponential_labels_list: List a team's labels.
  • exponential_labels_get: Get a label by id.
  • exponential_labels_create: Create a label.
  • exponential_labels_update: Rename or recolor a label.
  • exponential_labels_delete: Delete a label.
  • exponential_issue_labels_add: Attach a label to an issue.
  • exponential_issue_labels_remove: Detach a label from an issue.

Comments

  • exponential_comments_list: List an issue's comments, oldest first, each with its parentId when it is a reply.
  • exponential_comments_create: Post a comment as the connected user; it shows as "via MCP". Pass parentId to reply under a comment (threads are one level deep), or audience: "reporter" on a widget-filed issue whose reporter left an email to send it to them as well (top-level only); the result says whether that mail went out.
  • exponential_comments_update: Edit your own comment.
  • exponential_comments_delete: Delete a comment.

Subscriptions & notifications

  • exponential_issues_subscribe: Subscribe to an issue's notifications.
  • exponential_issues_unsubscribe: Unsubscribe (and suppress auto-resubscribe).
  • exponential_notifications_list: List your notifications, newest first.
  • exponential_notifications_mark_read: Mark one notification read, or all of them.
  • exponential_notifications_send: Send a notification (inbox row + push) to members of a team, or to yourself; recipients are member user ids or emails. A member who turned off messages from teammates' agents is reported as declined; your own user always receives.

Members & invites

  • exponential_members_list: List a team's members (useful to resolve an assigneeId).
  • exponential_invites_create: Create an invite link (owner only).
  • exponential_invites_list: List pending invites.
  • exponential_invites_revoke: Revoke a pending invite (owner only).

Repositories & branch diff

  • exponential_repositories_list: List a team's registered repositories and the boards they back.
  • exponential_repositories_add: Register a GitHub repository ("owner/name") with a team.
  • exponential_repositories_branch_diff: Diff an issue's branch against the repo's default branch.

Actions

  • exponential_actions_list: List a team's actions, the reusable AI prompts members run on their own desktop, each with its triggers.
  • exponential_actions_create: Create an action with markdown instructions and an optional repository (owner only).
  • exponential_actions_update: Update an action (owner only). The triggers field replaces the whole array: send every trigger you keep with its id, a new one without an id.
  • exponential_actions_delete: Delete an action (owner only).

Coding sessions & devices

  • exponential_devices_list: List your machines (desktop app or CLI daemon) plus servers shared with the team, with their online state and the agents each can run.
  • exponential_devices_account_login: Sign an agent account in on one of your own machines. The machine runs the agent's own login; only the sign-in link and the code you type travel, the credential never leaves it.
  • exponential_sessions_start: Start a run on an ONLINE device: an issue, a batch of issues, an action, or a resume. Offline devices are refused — starts are live, never queued.
  • exponential_sessions_list: List coding sessions newest first, with status, subject, branch, device, any usage wall, and who ended an ended run.
  • exponential_sessions_get: Get one session; poll it after a start to follow running → in review → ended, with any question the run parked for you. waitForIdle holds the call until the run's turn ends (120s at most).
  • exponential_sessions_messages: Read what a session you own or host said: its transcript (your messages, its replies, tool calls and questions), its newest messages with a cursor for what comes next.
  • exponential_sessions_message: Send text into a live session you own or host — it arrives as user input to that agent.
  • exponential_sessions_results: Publish a screenshot of this run's work: it hands back a short-lived upload link and a curl line, filed under a topic with one label per picture, and shows up on the run's Results face everywhere.
  • exponential_sessions_show: Show a screenshot while the run works: it appears in the run's transcript at the call, on every client, and is filed under the Results face (topic Progress by default). A local file gets a curl line; small images upload inline as base64.
  • exponential_sessions_kill: Abort a live session you own or host. Never your own run.
  • exponential_sessions_end: End this run with a close-out summary for whoever started it (not stored on the run). Unattended (trigger- or agent-started) runs call it last; a person-started run only when asked.
  • exponential_sessions_ask_parent: Inside a run: ask whoever started it, or the person who owns it, a question and end your turn; its answer arrives as a user message. A starter that is not a run reads the parked question with sessions_get and answers with sessions_message.

Bug reports

  • exponential_report_bug: File a bug about Exponential itself with its developers. Never for the caller's own project. Cloud only.

Attachments

  • exponential_attachments_get: Fetch any attachment: metadata plus a short-lived signed download URL (images also come back inline).
  • exponential_attachments_upload: Upload an image and get its embeddable markdown form back.
  • exponential_attachments_delete: Delete an attachment; embeds in descriptions and comments are rewritten in the same transaction.

Recipes

File a bug with labels, from chat

"File a bug on the app board: it drops drag events on narrow viewports. Priority high, label it bug." The client chains exponential_boards_list → exponential_issues_create → exponential_labels_list → exponential_issue_labels_add, and answers with the new identifier.

Check a PR's files from chat

"What does EXP-42's PR actually change?" The client calls exponential_issues_pr_files, which returns the changed files with patches, so the model can summarize the diff, flag a risky change, or compare it against the issue's acceptance criteria.

One combined PR for several issues

An agent that fixed several issues on one pushed branch opens a single PR for all of them: exponential_pr_open with issueIds (the batch) and head (the pushed branch). Every listed issue links to the PR and moves to In Review; merging completes them all. This is exactly what a batch coding run does.

A pull request with no issue behind it

Some work never gets filed: a dependency bump, a typo sweep. Pass repositoryId + head to exponential_pr_open (and repositoryId + prNumber to exponential_pr_merge) and you get an ordinary pull request with nothing linked, moved, or notified.

Start a run on one of your machines, from chat

"Have my build box take EXP-42." The client calls exponential_devices_list to find an online machine that runs the agent you want, then exponential_sessions_start, and follows the run with exponential_sessions_get. Steer it mid-run with exponential_sessions_message and read its replies with exponential_sessions_messages. Details in CLI & daemon.

Your own MCP servers

Everything above is Exponential as an MCP server. This is the other direction: the MCP servers your coding runs connect to besides Exponential — your error tracker, your docs, your internal API.

They are a team registry under Settings → MCP servers. Every member sees the list; owners add and edit. A row is non-secret configuration only: a name, the transport (a remote URL or a local command), the auth kind, and the names of the headers or environment variables a machine has to supply.

Credentials stay on the machineThe server keeps names and readiness, never values. A secret is typed on the machine that will use it — in the desktop app's own MCP servers pane, or with exponential mcp set-secret <server> <NAME> on a daemon — and never travels through a command line.

Each row carries a readiness chip per machine, so you can see at a glance which of your machines can actually reach the server. For an OAuth server, the chip on one of your own machines offers Sign in: that machine builds the authorize URL, you consent in the browser you are already in, and the machine finishes the sign-in itself. On a headless box, exponential mcp login <server> does the same locally, or --paste prints a URL you open anywhere and paste the redirect back.

Pick the servers a run gets in the Agent page composer and on the session page. Runs are strict about it: an agent started by Exponential connects to the servers Exponential wired in and nothing else, whatever the CLI has configured globally.