Skip to main content
“Show me every lead we could not reach this week and queue them for Monday.” An assistant connected over MCP (Model Context Protocol, the open standard for giving AI assistants tools) can do that: it reads the same API you do and calls the same endpoints, with the scopes you gave it and nothing more. TFUAI has two separate MCP interfaces. They solve different jobs. The documentation search MCP does not turn OpenAPI operations into callable action tools. Use the API action MCP when an agent needs live TFUAI data.

Connect

Give your coding agent this link and ask it to connect TFUAI: Connect TFUAI It can read these setup instructions before signing in. The agent should start its client’s browser authorisation, wait for you to sign in and approve, verify the connection, then continue your task. You do not need to share a password or API key in the conversation. Clients that require their own authentication button or a restart still control that step. The endpoint accepts either credential. Pick by how the client runs:
  • OAuth suits coding agents and hosted assistants such as Claude, Cursor, ChatGPT, and Gemini. The user signs in and approves the scopes in a browser, so no secret is ever pasted into a chat. Most clients only need the server URL.
  • API keys suit scripts, backend jobs, and self-hosted clients where no person is present to approve a browser prompt.

OAuth

Point the client at https://api.teamfollowup.ai/api/mcp and let it run discovery and start its native browser sign-in. An unauthenticated request returns 401 with the pointer that starts the flow:
From there the client reads the metadata, registers itself, and opens the consent screen. The client keeps the PKCE verifier, callback and credentials; the model should not build an authorisation URL or copy tokens into the chat. Both discovery documents link to the public setup instructions. The endpoints exist if you need them directly: What to expect during the flow:
  • PKCE is required, S256 only. A request without a code challenge is refused.
  • The consent screen lists the exact scopes the client asked for. Anything the user does not grant is not issued.
  • Access tokens last 8 hours. Refresh tokens last 30 days and rotate on every use, so a refresh token is only ever valid once.
  • Reusing a spent refresh token or authorization code revokes that whole token family. This is the standard response to a stolen token, and it means the client must store the newest refresh token it received.
Revoke a connection at any time from the dashboard, or by calling /revoke.

API keys

Send the key as a bearer token:
Create a narrowly scoped key from the API Keys page in the dashboard. Do not put a key in a prompt, repository, browser bundle, screenshot, or support message. Tool results can contain contact details, call records, billing data, and other tenant information. Connect the MCP only to clients approved to receive that data, request only the modules needed for the task, and avoid broad exports when a narrower read answers the question. You can verify the connection with an MCP initialize request:
The negotiated protocol version in the response can be newer than the version in this example.

Tool visibility

tools/list returns only tools that meet all three conditions:
  1. The operation is published in the API reference.
  2. The credential carries the operation’s required scope.
  3. Your role can use the operation. Agents, campaign setup, phone numbers, voices, billing, TFU Live, Native Contacts and Native Calendar tools are for agency admins (agency_admin). A role without agency admin rights, such as a sales rep (rep), sees the call, contact, analytics and Power Dialer tools.
This applies the same way to an API key’s scopes and to the scopes a user granted an OAuth client. A module write scope also covers its matching read scope. Public read operations can appear for any valid credential. Filtering is not only cosmetic. A tool the credential lacks the scope for, or that your role cannot use, is hidden from tools/list and refused if called by name. For broad credentials, narrow the advertised catalogue with a comma-separated module filter. Module names are lowercase tag slugs:
This reduces the number and size of tool definitions sent to the agent. An unknown module returns HTTP 400 with the valid module names. The product module names match the documentation and reference: for example agents, campaigns, power-dialer and master-campaigns. Existing filters such as skills-and-tools, split-testing and campaign-workflows remain compatible with their previous operations. Module filtering does not grant scopes or replace credential and role checks.

Search mode for clients that limit tools

Some clients take only a limited number of tools, or slow down with a long list. Cursor warns at 40 tools. Add mode=search to the server URL:
tools/list then returns four tools instead of every tool: Every tool you can call without search mode is still reachable, and list_tools shows all of them, with the same scopes, role checks and argument validation. Reads and writes run through separate tools, so your client can approve reads automatically and still ask before every write. mode=search works together with modules. Clients such as Claude Code that already search large tool lists themselves do not need it.

Reads and writes

The MCP advertises every operation the API reference publishes, reads and writes alike, except the three that charge a card. If you can reach it over REST, a credential with the matching scope can reach it as a tool. A credential with agents:write can create, update and delete agents; one with campaign_workflows:write can edit workflows. Write tools carry standard MCP annotations so your client knows when to ask before running one: Every write tool, create, update or delete, is annotated destructiveHint: true, so a client that honours the hint asks before each one. Reads are annotated readOnlyHint: true.
Most operations do not accept an Idempotency-Key. If a tool call times out, a retry can repeat the write. Prefer reading current state back before retrying a create.

Operations whose effect leaves the platform

One scope is withheld from tools/list: billing:charge. Every operation under it charges a card, your agency’s or a client’s, so none of them is a tool and no OAuth client can be granted the scope. Charge a card with an API key, from a program you control. The three are Buy a plan, Charge a sub-account and Enable rebilling with a charge. Nothing else is withheld. Every other published operation is advertised as a tool, filtered only by the credential’s scopes. So scope the credential deliberately, because these tools are reachable and their effect does not stay inside the platform:
destructiveHint makes a client ask; it does not stop anything. Every write carries it, so it cannot tell you which ones reach outside the platform. This table can. A client set to approve writes automatically will place calls, run the dialler and buy numbers without asking.
What the surface leans on instead is the credential itself: scopes are granted per credential, so a key holds only what it was issued, and route-level authorisation, tenant checks and role checks are unchanged. Issue a key with the narrowest scope set that does the job, and prefer OAuth for hosted assistants so a person approves the scopes.

Tool arguments

Tool schemas preserve the original OpenAPI parameter locations:
Only groups used by an operation appear in that tool’s schema, and each schema lists the groups it actually requires. A group the schema does not require can be left out entirely rather than sent as an empty object. For example, deleting an agent skill takes only path, because the optional expectedVersion in its body is the sole thing a body would carry. A contact call-history read can accept:
The server validates arguments before the API request. It controls the request URL and authentication header, so an agent cannot supply an arbitrary URL or forward arbitrary headers.

Large tools

A few tools take a body nested several objects deep, such as patch_agent_builder_agents_by_id, update_agent_campaign and search_call_transcripts. To keep every tool small enough for clients to read in full, the tool list shows them with shorter field descriptions, and where that is not enough, some of their deepest objects by name only: the object’s description lists its keys in place of the full field definitions. Search mode returns their full schemas. Every field is still accepted. The server checks each argument against the full schema before the request, so a misspelt key or a wrong type is refused with the path that failed. Read the current record first when you need a nested shape, and see the API reference for every field.

Results

  • Every operation published today answers with JSON, which returns as both MCP text content and structured content.
  • Public API errors return tool results with isError: true and the original safe error body. The HTTP status is on the result as _meta["tfuai/httpStatus"].
  • Network failures and timeouts fail as tool errors.
  • A result over 100 KB is not returned. A read fails and says how to narrow it. A write reports that it succeeded, so it is not repeated.
  • A call’s recording links return as full links, such as https://api.teamfollowup.ai/api/call-history/call_123/recording: recordingUrl, and for a transferred call transferRecordingUrl and fullRecordingUrl. Each plays when opened in a browser signed in to Team Follow Up AI.
CSV exports and logo reads are not part of the published surface, so no tool returns text or image content. If a module publishing either is added later, the adapter already carries them through as MCP text and image content. Every tool call goes through the same public REST route as a direct API call. Credential validation, scopes, tenant access, role checks, rate limits, and public response projections still apply.

Common connection errors

Use the Authentication page for scopes and key management. Search saved call text with search_call_transcripts, passing the structured query inside body. In search mode use call_read_tool. See Transcript search and Search call transcripts.