Browse docs

MCP server

What is MCP?

The Model Context Protocol is an open standard that lets AI clients (Claude Desktop, ChatGPT, Cursor, VS Code, and others) call tools running on a remote server. There There ships an MCP server, so once you connect your AI client, the assistant can read your tickets, work on private drafts, triage tickets, reply to customers, and edit your knowledge base directly, without leaving the AI client.

Connections are scoped to one user but may grant access to one or more workspaces. The user picks the workspaces on the consent screen. Every tool call runs as that user and obeys the same channel access rules as the dashboard.

Server URL

https://there-there.app/mcp

The endpoint speaks JSON-RPC 2.0 over HTTP and accepts POST requests only. There is also a discovery URL at https://there-there.app/.well-known/oauth-protected-resource that AI clients read automatically to find the OAuth flow.

How to connect

Most clients walk you through OAuth: you click Connect, There There opens a consent screen where you pick the workspace and the abilities to grant, you click Allow, and the client is connected. You never need to copy a token by hand.

Claude Code (CLI)

Run this in your terminal:

claude mcp add there-there --transport http https://there-there.app/mcp --scope user

The --scope user flag makes There There available in all of your projects. Leave it off if you only want the connection in the current project.

The first time the assistant uses a tool, your browser opens the There There consent screen. After you click Allow you are returned to Claude and the connection is live.

Claude Desktop, ChatGPT, Cursor, VS Code

Each of these clients exposes a "custom MCP connector" or equivalent setting. The exact menu path differs by version, but the only value any of them needs is the server URL:

https://there-there.app/mcp

When the client first calls a tool, it opens your browser, you choose the workspace and abilities on the There There consent screen, and the connection is live.

For clients that take JSON configuration (some Cursor versions, for example) the entry looks like:

{
    "mcpServers": {
        "there-there": {
            "url": "https://there-there.app/mcp"
        }
    }
}

Other clients

Any MCP client that supports HTTP transport with OAuth 2.1 (PKCE with the S256 challenge method, plus Dynamic Client Registration as defined in RFC 7591) will work. Point it at the server URL and it will discover everything else through /.well-known/oauth-protected-resource.

The consent screen

When an AI client first connects, There There shows a screen where you choose:

  1. Which workspaces the connection should be able to act in. Tick one or more. You only see workspaces you belong to.
  2. Which abilities to grant. Each ability is a checkbox; the connection cannot use any tool whose ability you did not check.

The same abilities apply across every workspace you ticked. Pick the smallest set you need.

You can revoke the connection at any time from Settings, Connected apps.

Acting in multiple workspaces

If you ticked more than one workspace, every tool call carries a workspace_ulid argument that picks which workspace it acts on. The AI sees the list of granted workspaces (with their names and ids) in the server instructions, so when you say "tickets in Spatie" the assistant picks the right id automatically.

If you only ticked one workspace, workspace_ulid is optional. The connection defaults to that workspace and the AI does not need to think about it.

You never need to look up a workspace ID for an OAuth connection. You only need one when you connect with an API token.

Abilities

Abilities are what the AI client is allowed to do. There There has five:

Ability What it allows
mcp:read List and read tickets, your private ticket drafts, contacts, channels, and the knowledge base.
mcp:tickets:manage Triage tickets: change status, assign, tag, set custom fields, add internal notes.
mcp:tickets:drafts Create and edit private ticket drafts without sending messages.
mcp:tickets:reply Send replies and forwards, and create outbound tickets. Sent messages are customer-visible.
mcp:knowledge:write Create, update, and delete brain articles.

Pick the smallest set you need. Grant mcp:tickets:drafts without mcp:tickets:reply to let an AI prepare replies without sending them.

The reply ability is flagged on the consent screen because it permits sending messages that customers see. Saving a draft does not send it.

Tools

The tools available to a connection are filtered by the abilities you granted. A connection without mcp:tickets:reply will not even see reply-to-ticket-tool in its tools list.

Read tools (mcp:read)

Tool Description
list-tickets-tool List tickets in the workspace. Filter by status, channel, tag, contact, assignee, custom field, and a free-text search over the subject.
get-ticket-tool Fetch a single ticket along with its message thread and its custom fields.
get-ticket-draft-tool Read your private reply, note, or forward draft for a ticket. Returns the HTML body, recipients, and attachment names and ULIDs.
search-tickets-tool Semantic search across tickets and messages by meaning, not just subject text. Use it for topic queries like "tickets about export bugs".
lookup-contacts-tool Find contacts by email or name. Returns up to 10 matches with recent ticket counts.
search-knowledge-tool Search the brain articles and documentation.
list-channels-tool List the channels the user can access.

Triage tools (mcp:tickets:manage)

Tool Description
change-ticket-status-tool Set a ticket to open, waiting, closed, or spam.
assign-ticket-tool Assign a ticket to a user or a team, or unassign one of those.
add-note-to-ticket-tool Post an internal note. Notes are visible to teammates only, never to the customer.
add-tag-to-ticket-tool Add an existing workspace tag to a ticket.
remove-tag-from-ticket-tool Remove a tag from a ticket.
set-ticket-custom-field-tool Set a custom field on a ticket. Call get-ticket-tool first for the field and option ids that apply to it.

Draft tool (mcp:tickets:drafts)

Tool Description
save-ticket-draft-tool Create or edit your private reply, note, or forward draft. Saving never sends a message.

Reply tools (mcp:tickets:reply)

Tool Description
reply-to-ticket-tool Send a reply to the customer through the ticket's channel.
forward-ticket-tool Forward a specific message of a ticket to one or more recipients.
create-ticket-tool Start a new outbound ticket: pick a channel, supply the recipient email, subject, and body.

To edit a draft, call get-ticket-draft-tool with the ticket reference and mode (reply, note, or forward), then pass the revised full body to save-ticket-draft-tool. For predictable spacing, put each paragraph in its own adjacent <p> block, for example <p>First paragraph.</p><p>Second paragraph.</p>. Do not add empty <p> or <p><br></p> blocks between paragraphs. The save tool inserts one visible spacer. Newline characters between tags do not affect spacing. An inline <br> within a paragraph is fine. The save tool preserves existing recipients and attachments unless you explicitly replace a recipient list. It cannot upload or remove attachments. The body is limited to 100,000 characters, so embedded image data is generally too large for this tool.

Knowledge tools (mcp:knowledge:write)

Tool Description
create-brain-article-tool Create a new article in a brain. New articles default to draft (private) so they do not surface in the widget until you publish them.
update-brain-article-tool Update an existing article's title, body, or visibility.
delete-brain-article-tool Delete a brain article.

Channel access

If your team uses restricted channels (channels not all members can see), AI tool calls obey those rules. The connection can only see and act on tickets in channels you yourself have access to. Tickets in channels you cannot access return "not found" rather than a permission error, so the AI cannot probe for their existence.

Audit trail

Every tool call is logged in the workspace with the tool name, the user, the connection, the duration, and whether it succeeded. You can review activity for a connection by clicking it in Settings, Connected apps.

Sensitive fields are redacted in the audit log. The body of a draft, reply, forward, or note, the subject and body of a new outbound ticket, and the title and body of a created or updated brain article are all replaced with [REDACTED] in the log entry. Recipient lists on drafts, replies, forwards, and outbound tickets are also redacted. The actual draft, message, or article keeps the original content; only the audit row is masked.

Managing connections

Settings, Connected apps lists every active AI connection for the current workspace. From there you can:

  • See which abilities each connection holds.
  • Open a connection to view its recent tool calls and any errors.
  • Revoke a connection. Revoking immediately invalidates the connection's tokens; the AI client has to reconnect to use any tool again.

Each user manages their own connections. Other people in the workspace cannot see or revoke yours.

API tokens (advanced)

If you prefer to use a personal access token instead of OAuth, you can create one in Settings, API Tokens. The token's permission level decides which abilities it gets over MCP:

Token permission MCP abilities
Read & write All five: mcp:read, mcp:tickets:manage, mcp:tickets:drafts, mcp:tickets:reply, mcp:knowledge:write
Read-only mcp:read

The token also needs access to the workspace you want to act in. Send the token in the Authorization header. If the token can access more than one workspace, tool calls pick a workspace with the workspace_ulid argument, just like an OAuth connection. To pin the connection to one workspace instead, send its workspace ID in X-Workspace-Id. You can copy the ID from Settings, API Tokens, which lists every workspace you belong to, or from Settings, Workspace, General. See Finding your workspace ID.

POST /mcp
Authorization: Bearer <token>
X-Workspace-Id: <workspace-id>
Content-Type: application/json

OAuth is recommended for AI clients because the consent flow is friendlier and the connection is per-client. Use API tokens for scripts and CI.

Limits

  • Each connection is rate-limited per minute. If you hit the limit, the response is HTTP 429 and the AI client should retry after a short pause.
  • Reply and forward bodies are capped at 100,000 characters. Note bodies are capped at 50,000. Brain article bodies are capped at 200,000. These caps prevent runaway prompts from exceeding database column limits.
  • Subjects on outbound tickets are capped at 998 characters (the RFC 5322 line limit).

Troubleshooting

The AI client says it cannot connect. Check that you can reach https://there-there.app/mcp from the same machine. Some corporate networks block POST to unknown hosts.

The consent screen says I do not belong to any workspace. You need to be a member of at least one workspace before you can connect an AI client.

A tool returns "not found" for a ticket I know exists. The connection probably does not have access to that ticket's channel. Open the ticket in the dashboard to confirm. If you cannot see it there either, ask a workspace owner to grant access.

The AI keeps asking for permission. Your connection may be revoked or expired. Open Settings, Connected apps and check whether the connection is still listed. If not, reconnect from the AI client.

My replies are not reaching customers. Verify the channel is configured to send mail (Settings, Channels, the channel's Send section). When you create a new outbound ticket through create-ticket-tool, the tool refuses up front if the channel is not ready to send.