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. The client can also run admin operations, such as creating agents, running tests, and adding sources. You do not need to add an organization ID to each call.
Server URL
Use the streamable HTTP endpoint:
The MCP Server settings page shows the exact URL. You can also copy a ready-made configuration for each client from that page.
Connect to part of the server
The default URL gives the client every tool. Two other forms narrow that:
| URL | Mounts |
|---|---|
/api/mcp | Every toolset, plus the catalog tools |
/api/mcp/x/<toolsets> | Only the listed toolsets, plus the catalog tools |
/api/mcp/readonly | Only the tools that read data |
Toolset names are agents, analytics, apikeys, catalog, contacts, conversations, inbox, members, organizations, and sources. Separate several with commas, as in /api/mcp/x/inbox,agents. A client that can send a custom header can select the same list with X-MCP-Toolsets on /api/mcp. The path form ignores that header, so the path wins when you use both.
Use a narrow connection to keep a client's tool list short and focused. AgentStack applies the selection on the server, so an unselected tool is never offered. /api/mcp/readonly is a real restriction, not a hint: the client cannot write, even with a write scope on its token.
Authentication
AgentStack uses OAuth through Better Auth. The first time a client connects, AgentStack opens a browser window for sign-in. You approve the scopes: read-only or write. The client then stores a refresh token. Tokens are scoped to your user account. The organization that is active at the time of authorization is the organization that the tools operate on.
Scopes
The MCP endpoint requires at least one MCP scope on the access token:
| Scope | Grants |
|---|---|
mcp:read | Read agents, sources, and conversations |
mcp:write | Create, update, and delete agents, sources, and conversations |
mcp:send | Send customer-facing messages, such as replying to a ticket |
mcp:admin | View the member roster, pending invitations, and API key inventory |
mcp:billing | View credit balance, subscription, and usage history |
Clients can also request the standard openid, profile, email, and offline_access scopes. The server publishes every supported scope in its discovery documents (/.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource). A spec-compliant client requests them automatically, so you do not need to configure anything. A client that requests no scopes at all is granted read and write access. You still approve this access on the consent screen. See MCP scopes for the full reference.
The scopes that you approve stay fixed for the life of that token. To change the scopes, remove the client and reauthorize it.
Install
The settings page shows the right snippet for your client. Use this quick reference:
Cursor
Add this to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
Claude Code
Claude Desktop
Claude Desktop supports stdio only. Route the connection through mcp-remote. Add this to claude_desktop_config.json:
Codex
Add this to ~/.codex/config.toml:
Gemini CLI
Add this to ~/.gemini/settings.json:
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. If your client supports only stdio, use the mcp-remote relay instead.
What you get
- Read agents, sources, conversations, contacts, teams, and analytics.
- Create and update agents, run agent tests, add URL or text sources, and restore soft-deleted records.
- Work Help Desk tickets: list, inspect, assign, note, close, and reply.
- Read the member roster, pending invitations, and API key inventory, and revoke a key.
- Reach any other REST API v1 operation through the catalog tools, including operations with no dedicated tool of their own.
- Approve read-only or write access during browser sign-in.
Each tool declares whether it only reads data or also writes data. This lets a client ask for confirmation before a destructive call, on only the right tools. The following tools are flagged as destructive: delete_agent, delete_source, update_agent, update_source_metadata, revoke_api_key, improve_answer (it replaces the QnA pair written for the same message), test_agent (it spends credits), switch_organization (it changes the organization for every later call), and execute_delete_action (it runs a destructive operation from the catalog). Reads, creates, and restores are not destructive.
Organization scoping
Tools operate on one active organization. You do not pass an organization ID with each call. get_current_organization reports the active organization. list_organizations marks it in the list. switch_organization changes it. The active organization is stored per user, and it does not depend on which organization you have open in the dashboard.
The active organization applies to every call automatically. For this reason, every response echoes the organization that it acted on:
switch_organization echoes the organization that was active when you called it. The new scope applies starting with the next call.
Finding deleted records
delete_agent and delete_source perform soft deletes. You have 30 days to restore a soft-deleted record. To find a record to restore, pass a status filter to the list tools:
status | Returns |
|---|---|
active (default) | Live records only |
deleted | Soft-deleted records only, each with a restoreBefore deadline |
all | Both |
Take the id from a status: "deleted" listing and pass it to restore_agent or restore_source. After restoreBefore passes, the record is gone, and restore fails with OUT_OF_GRACE_PERIOD. Sources that belong to a soft-deleted agent are not listable. If you need to restore such a source, restore the agent first.
Reading back what you wrote
get_agent takes an include array for larger fields: system_prompt, tools, sources, channels, and widget_config. widget_config returns every field that update_agent can write: the widget, lead-capture, floating-message, suggested-message, session-resume, and geo-restriction settings. You can read this field before you patch a value, or check it after you write a value.
Indexing is asynchronous
create_source with type: "url" returns as soon as the crawl is queued. The response has status: "indexing" and a nextAction hint. The tool does not wait for the crawl to finish. On a large site, the crawl can take longer than the request timeout. Poll get_source with the returned sourceId until its status reads ready.
Errors
A failure returns a JSON error object with a code, a message, and usually a suggestion:
The server rejects a malformed id or a malformed pagination cursor as INVALID_INPUT. It does not silently return the first page instead. An unexpected server-side failure returns INTERNAL_ERROR with a reference id. Quote this id to support. The server never forwards the underlying database error to the client.
Troubleshooting
- Client says "not authenticated": Go to the MCP Server page and check that your client is listed under Authorized Clients. If you run the install command again, the OAuth flow starts again.
- A stdio client cannot connect to streamable HTTP: Use the
mcp-remoteform shown above. It runs locally and sends requests to the AgentStack endpoint. - Wrong organization: Call
switch_organization. Theorganizationfield echoed on every response tells you which organization a call used. The MCP scope is stored per user. It does not follow the active organization in the dashboard. - Sign-in succeeds, but every call is rejected: The client holds a token that was issued without an MCP scope. Remove the connector and add it again. This issues a new token, and the consent screen reappears, listing the scopes that you grant.
- Tool descriptions look out of date: The client caches the tool list from when it connected. Remove the connector and add it again to refresh the list.