AgentStack Docs

MCP Server

Connect MCP-compatible clients to your AgentStack organization to read agents, sources, and conversations and run admin operations from your editor.

AgentStack exposes a Model Context Protocol server scoped to your active organization. Once connected, your MCP client (Cursor, Claude Code, Claude Desktop, Codex, Gemini CLI, and others) can read agents, sources, and conversations and perform admin operations like creating agents, running tests, and adding sources — without you threading an organization ID through every call.

Server URL

Use the streamable HTTP endpoint:

https://www.agentstack.build/api/mcp

The exact URL is shown on the MCP Server settings page, where you can also copy ready-made configs for each client.

Authentication

OAuth via Better Auth. The first time a client connects, AgentStack opens a browser sign-in. You approve the scopes (read-only or write), and the client stores a refresh token. Tokens are scoped to your user account; the active organization at the time of authorization determines which org the tools operate against.

Scopes

The MCP endpoint requires at least one MCP scope on the access token:

ScopeGrants
mcp:readRead agents, sources, and conversations
mcp:writeCreate, update, and delete agents, sources, and conversations

Alongside these, clients may request the standard openid, profile, email, and offline_access scopes. All six are published in the server's discovery documents (/.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource), so a spec-compliant client requests them automatically — there is nothing to configure. A client that requests no scopes at all is granted read and write access, which you still explicitly approve on the consent screen.

Whichever scopes you approve are fixed for the life of that token. To change them, remove the client and reauthorize it.

Install

The settings page renders the right snippet for your client. Quick reference:

Cursor

Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "agentstack": {
      "url": "https://www.agentstack.build/api/mcp"
    }
  }
}

Claude Code

claude mcp add --transport http agentstack https://www.agentstack.build/api/mcp -s user

Claude Desktop

stdio-only, so route through mcp-remote. Add to claude_desktop_config.json:

{
  "mcpServers": {
    "agentstack": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://www.agentstack.build/api/mcp"]
    }
  }
}

Codex

Add to ~/.codex/config.toml:

[mcp_servers.agentstack]
command = "npx"
args = ["-y", "mcp-remote", "https://www.agentstack.build/api/mcp"]

Gemini CLI

Add to ~/.gemini/settings.json:

{
  "mcpServers": {
    "agentstack": {
      "httpUrl": "https://www.agentstack.build/api/mcp"
    }
  }
}

Other clients

VS Code, Windsurf, OpenCode, Zed, Warp, v0, Kiro, Roo Code and most other MCP-compatible clients accept the standard mcpServers block. Use the direct URL form first; fall back to the mcp-remote relay if your client only supports stdio.

What you get

  • Read agents, sources, and conversations.
  • Create and update agents, run agent tests, add URL or text sources, and restore soft-deleted records.
  • Approve read-only or write access during browser sign-in.

Each tool declares whether it only reads or also writes, so clients that ask for confirmation before destructive calls do so on the right ones. delete_agent, delete_source, update_agent, update_source_metadata, test_agent (it spends credits) and switch_organization (it retargets every later call) are flagged as destructive. Reads, creates, and restores are not.

Organization scoping

Tools operate on one active organization rather than taking an organization id per call. get_current_organization reports which one that is, list_organizations flags it, and switch_organization changes it — persisted per user, independent of which org you have open in the dashboard.

Because that scope is ambient, every response echoes the organization it acted on:

{
  "organization": { "id": "org_...", "slug": "acme" },
  "items": [ ... ]
}

switch_organization echoes the organization that was active when you called it; the new scope applies from the next call onward.

Finding deleted records

delete_agent and delete_source are soft deletes with a 30-day restore window. To find something you need to restore, pass a status filter to the list tools:

statusReturns
active (default)Live records only
deletedSoft-deleted records only, each with a restoreBefore deadline
allBoth

Feed the id from a status: "deleted" listing to restore_agent or restore_source. After restoreBefore passes, the record is gone and restore fails with OUT_OF_GRACE_PERIOD. Note that sources belonging to a soft-deleted agent are not listable at all — restore the agent first.

Reading back what you wrote

get_agent takes an include array for heavier fields: system_prompt, tools, sources, channels, and widget_config. widget_config returns every field update_agent can write — the widget, lead-capture, floating-message, suggested-message, session-resume, and geo-restriction settings — so a value can be verified after writing it, or read before patching.

Indexing is asynchronous

create_source with type: "url" returns as soon as the crawl is queued, with status: "indexing" and a nextAction hint. It does not wait for the crawl, which on a large site would outlast the request timeout. Poll get_source with the returned sourceId until its status reads ready.

Errors

Failures come back as a JSON error object with a code, a message, and usually a suggestion:

{
  "organization": { "id": "org_...", "slug": "acme" },
  "error": {
    "code": "INVALID_INPUT",
    "message": "One of the supplied values is not in the format that field accepts.",
    "suggestion": "Check that every id argument is a uuid copied from a list or get response."
  }
}

A malformed id or a malformed pagination cursor is rejected as INVALID_INPUT rather than silently returning the first page. Unexpected server-side failures return INTERNAL_ERROR with a reference id to quote to support; the underlying database error is never forwarded to the client.

Troubleshooting

  • Client says "not authenticated": revisit the MCP Server page and confirm your client is listed under Authorized Clients. Re-running the install command re-triggers the OAuth flow.
  • stdio client can't connect to streamable HTTP: use the mcp-remote form shown above. It runs locally and proxies to the AgentStack endpoint.
  • Wrong organization: call switch_organization — the organization echoed on every response tells you which org a call actually used. The MCP scope is stored per user and does not follow the dashboard's active org.
  • Sign-in succeeds but every call is rejected: the client holds a token issued without an MCP scope. Remove the connector and add it again so a new token is issued — the consent screen will reappear, listing the scopes being granted.
  • Tool descriptions look out of date: clients cache the tool list from when they connected. Remove and re-add the connector to refresh it.

On this page