Foan hosts a Model Context Protocol server. Give Claude Code, Codex, Cursor, claude.ai, ChatGPT or any MCP client one URL, log in when the browser opens, and your agent can build voice agents, buy numbers, load contacts, run campaigns and top up your wallet. You never need to open a dashboard.
https://api.foan.ai/mcpGET /mcp/health, no auth, reports 37 toolsThree steps. The only time you see a browser is the login window, and it closes itself once you approve.
Paste https://api.foan.ai/mcp into your host. For Claude Code that is one command, shown below.
A browser window opens. Sign in to Foan, or create an account right there, pick your organisation if you have several, and approve. No key to copy anywhere.
Create an agent, buy a number, add contacts, start a campaign. Anything that spends money or is hard to undo shows you a preview first and waits for a yes.
Every host below runs the standard MCP authorization flow: OAuth 2.1 with PKCE and dynamic client registration. It opens a browser window where you log in to Foan and approve. Behind the scenes the host receives a Foan API key created for it and named after it, which you can see and revoke under API keys at any time.
One command, then run /mcp inside Claude Code, pick foan and choose Authenticate. The browser opens. --scope user makes the server available in every project; without it the server is only active in the directory you ran the command in, which is easy to mistake for not installed.
claude mcp add --transport http --scope user foan https://api.foan.ai/mcp
Codex detects the login flow on first use and opens the browser. codex mcp login foan forces it. The equivalent ~/.codex/config.toml entry is below the command.
codex mcp add foan --url https://api.foan.ai/mcp
[mcp_servers.foan] url = "https://api.foan.ai/mcp"
Install in Cursor with one click. If the browser does not open on its own, click Needs login next to the server in Cursor's MCP settings. Or add this to .cursor/mcp.json yourself.
{
"mcpServers": {
"foan": { "url": "https://api.foan.ai/mcp" }
}
}Settings, then Connectors, then Add custom connector. Paste the URL, leave the OAuth client id and secret fields empty (the connector registers itself), click Connect and log in.
https://api.foan.ai/mcp
Settings, then Connectors, then Create (developer mode). Paste the URL, set authentication to OAuth, connect and log in.
https://api.foan.ai/mcp
Any client that implements the MCP Authorization spec (2025-06-18) works with just the URL. A request without a token gets HTTP 401 with a WWW-Authenticate header pointing at the protected resource metadata, which is how the host discovers the login flow. To see it for yourself:
curl -si https://api.foan.ai/mcp -X POST -H 'Content-Type: application/json' -d '{}' | grep -i www-authenticate
curl -s https://api.foan.ai/.well-known/oauth-protected-resource/mcp
curl -s https://api.foan.ai/.well-known/oauth-authorization-serverFor scripts, CI and anything without a browser, an API key still works. Create one under API keys in your Foan account and send it as a bearer header. Set FOAN_API_KEY in your shell before running these.
# Claude Code
claude mcp add --transport http --scope user foan https://api.foan.ai/mcp \
--header "Authorization: Bearer $FOAN_API_KEY"
# Codex CLI
codex mcp add foan --url https://api.foan.ai/mcp --bearer-token-env-var FOAN_API_KEY
# Raw JSON-RPC from anything that can POST
curl -s https://api.foan.ai/mcp \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Cursor takes the same key in .cursor/mcp.json: add "headers": { "Authorization": "Bearer YOUR_FOAN_API_KEY" } next to the URL. OpenClaw and Hermes take a generic HTTP MCP block with the same header; both are written from their docs and not yet verified end to end.
A foan command on npm. foan login opens the browser once, and foan mcp add claude registers the server with Claude Code for you. Same login, same tools, no config files to edit.
npm install -g foan-ai foan login foan mcp add claude
Everything a customer can do in Foan is here: agents, campaigns and their contacts, calls and sessions, numbers, the knowledge base, and the wallet. Every tool carries MCP annotations so your host knows what is safe to run on its own. Read-only tools never change anything. Tools marked confirm return a dry-run preview first and only act when called again with confirm: true.
agents:read, changes need agents:writeagents_list | List the agents in an organisation | Read-only |
agents_get | Full configuration of one agent | Read-only |
agents_create | Create a Gemini voice agent. identity and task are required, and greeting is required for voice agents | Writes |
agents_update | Edit fields and get a before and after diff back | Writes |
agents_delete | Delete an agent | Destructive Confirm |
agents_duplicate | Clone an agent | Writes |
agents_list_voices | List the available text to speech voices | Read-only |
campaigns:read, create and add contacts need campaigns:write, start, pause and complete need campaigns:controlcampaigns_list | List campaigns | Read-only |
campaigns_get | Configuration and current state of a campaign | Read-only |
campaigns_create | Create an outbound campaign. Calls run 09:00 to 17:00 by default | Writes |
campaigns_contacts_list | Contacts of a campaign with their call status and an exact total | Read-only |
campaigns_contacts_add | Append up to 500 contacts (phone, optional name and variables). Duplicates are skipped and nothing is removed | Writes |
campaigns_start | Start a campaign | Destructive Confirm |
campaigns_pause | Pause a campaign | Writes |
campaigns_complete | Mark a campaign complete | Destructive Confirm |
campaigns_stats | Campaign performance statistics | Read-only |
calls:read, placing a call needs calls:createcalls_list | Recent call sessions | Read-only |
calls_get | One call session | Read-only |
calls_get_transcript | Transcript by room name | Read-only |
calls_search | Search across transcripts | Read-only |
calls_place | Place an outbound call over the Plivo websocket bridge | Destructive Confirm |
sessions_get | Voice session by id | Read-only |
sessions_by_agent | Sessions for an agent, with offset pagination | Read-only |
sessions_conversation | Conversation transcript for a session | Read-only |
numbers:read, purchase, assign and unassign need numbers:writenumbers_list | Telephony numbers connected to the organisation | Read-only |
numbers_search | Search Plivo inventory by country, type, pattern, region or city | Read-only |
numbers_purchase | Buy a Plivo number after reviewing the preview | Destructive Confirm |
numbers_assign | Route a number's inbound calls to an agent | Destructive Confirm |
numbers_unassign | Detach a number from its agent | Destructive Confirm |
knowledge:read, add and delete need knowledge:writeknowledge_list | Knowledge documents of the organisation | Read-only |
knowledge_get | One knowledge document with its ingestion status | Read-only |
knowledge_add | Add a document from text and/or a base64 file, up to 4 MB | Writes |
knowledge_delete | Delete a document and its chunks | Destructive Confirm |
wallet:read and billing:read, organisations need org:read, top-up needs wallet:write and an owner or admin loginaccount_balance | Wallet balance, billing status and plan | Read-only |
account_org | Organisations visible to the connection | Read-only |
account_topup | Quote a wallet top-up. With confirm, create the order and return a checkout link you open to pay | Destructive Confirm |
foan_help | The bundled usage guide. No scope needed | Read-only |
Two prompts ship with the server: create_voice_agent walks through building an agent, and launch_campaign reviews a campaign and starts it only after explicit approval.
Deleting an agent or a document, starting or completing a campaign, placing a call, buying, assigning or unassigning a number and topping up the wallet all use the same gate. The AI host has to show you what is about to happen and ask before it goes through. Errors from Foan's API come back as tool results, never as transport failures, so the host can show them to you in plain text.
confirmThe tool returns a dry-run preview of the target and what would change. No action is taken.
Check the agent, campaign, number, document, call or top-up amount in the preview.
confirm: trueOnly now does the action run. The same rule applies to every tool marked confirm.
When the browser window opens you approve what the host may do. By default it gets every customer permission below; a host may ask for a narrower set. To change what a host can do, disconnect it and connect again, and you will be asked afresh. A tool that needs a permission the connection does not hold returns Foan API 403: Insufficient scope as its result. For API keys used in automation, the same scopes are chosen when the key is created.
| Scope | Unlocks |
|---|---|
agents:read | List and inspect agents, list voices |
agents:write | Create, update, duplicate and delete agents |
campaigns:read | List and inspect campaigns, contacts and campaign statistics |
campaigns:write | Create campaigns and add contacts |
campaigns:control | Start, pause and complete campaigns |
calls:read | Call history, transcripts, search and voice sessions |
calls:create | Place an outbound call |
numbers:read | List connected numbers and search inventory |
numbers:write | Purchase, assign and unassign numbers |
knowledge:read | List and inspect knowledge documents |
knowledge:write | Add and delete knowledge documents |
wallet:read, billing:read | Wallet balance, billing status and plan |
wallet:write | Top up the wallet. The logged-in user must also be an owner or admin of the organisation |
org:read | Organisations visible to the connection |
Tools that take org_id use it when given. Otherwise the server uses the organisation you picked at login, or the one the API key belongs to. If a connection can see several organisations, pass org_id explicitly.
The token your host stores is a Foan API key created for it and named after it. Foan API keys do not expire; a refresh rotates the key and revokes the old one. You can revoke any host's key under API keys in your account, and it stops working immediately.
List tools return 20 records by default and cap limit at 100. Use page where supported, offset for sessions_by_agent, and fields to trim each item to the keys you need. Results are cut at roughly 30 KB with a note to narrow the request.
Calls always go over the Plivo websocket bridge. SIP is not exposed. Connecting an existing Plivo account is not done through MCP, so your Plivo auth token never passes through an AI host.
Only Gemini voice agents can be created through agents_create. agents_update exposes language_accent, the field Gemini agents act on.
Every tool result is scrubbed before it leaves the server. Credential-shaped values such as tokens, passwords and API keys, including ones inside URLs, are replaced with [redacted]. The MCP endpoint also has its own rate limit per connection, separate from the REST API.
Add the URL to your host, log in when the browser opens, and ask your assistant to create your first agent.