Connect your AI assistant to Chirply once, and from then on you run your whole workspace by conversation. “Reply to everyone who messaged us overnight, book the Hendersons for Thursday, and send the Ortega invoice” — the agent does it with the same operations, the same permissions and the same validation as the buttons in the app, because they are the same catalog.
Chirply speaks the Model Context Protocol at https://app.chirply.io/api/mcp, authenticated with the same Authorization: Bearer chp_live_… key as the REST API. Every operation in the catalog is exposed as an MCP tool — the dot in an action name becomes an underscore, so contacts.create is the tool contacts_create. Everything is scoped to the key presenting it: a read-only key reaches read operations only, never offered something it would be refused for.
Because the catalog is 2,509 operations deep, tools/list hands an assistant five tools rather than all of them. Those five are how it reaches the rest:
| Tool | What it does |
|---|---|
search_capabilities | Find operations in plain words — “text a customer”, “refund an invoice”. Returns names, titles and descriptions, flagging the ones that need care. |
describe_capability | One operation in full: what it does, what it costs in the real world, and the JSON Schema for its arguments — plus how to call it over MCP and REST. |
run_capability | Run it. Identical validation, permissions and effects to clicking the button in the app. |
list_domains | Every feature area with its operation count, for an agent that would rather browse than search. |
whoami | Which account this credential acts for, what it may do, and how many operations it can reach. |
A name missing from that list is never a name you can’t call: search it, describe it, run it. Operations are also callable directly by name at any time, so an integration that already knows what it wants can skip the search.
It is also an authenticated bridge to the accounts the workspace has already connected — Facebook & Instagram, Twilio, Stripe, Mailgun, Klaviyo, Cloudflare and more. An agent calls providers_connected to see what exists, then providers_read or providers_request to act, and the credential is attached on the way out — your agent never handles those provider keys, and revoking the one Chirply key cuts all of it off at once.
The built-in MCP server is included with the Scale and Founder plans.
Create an API key in the app under Developers → Create key (it is shown once), then paste one of these. Give the agent a read-only key first if you want to watch it work before letting it write.
claude mcp add --transport http chirply https://app.chirply.io/api/mcp \
--header "Authorization: Bearer chp_live_your_key"Claude Desktop launches local MCP servers from its config file, so the hosted endpoint connects through the mcp-remote bridge:
// claude_desktop_config.json
// (Settings → Developer → Edit Config)
{
"mcpServers": {
"chirply": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://app.chirply.io/api/mcp",
"--header", "Authorization: Bearer chp_live_your_key"
]
}
}
}Cursor speaks HTTP MCP natively, so it takes the URL directly — the same url-style block works in any client with a native HTTP transport:
// .cursor/mcp.json (per project) or ~/.cursor/mcp.json (everywhere)
{
"mcpServers": {
"chirply": {
"url": "https://app.chirply.io/api/mcp",
"headers": { "Authorization": "Bearer chp_live_your_key" }
}
}
}Restart the client and ask it what it can see. tools/list comes back with five tools — search_capabilities, describe_capability, run_capability, list_domains and whoami — and those five reach every operation your key may run.
That is the whole workflow: the agent searches in plain words, reads the chosen action’s JSON Schema, and runs it. A short tool list is what makes this practical — the full catalog is 2509 operations, far more than an assistant can hold in view at once, and a name it hasn’t seen listed is still one search away. Clients that prefer the complete list can ask for it: add ?tools=full to the server URL and tools/list pages through every operation, 50 at a time, following nextCursor. Calling an operation by name works on either profile, so an integration that already names its tools keeps working unchanged.
The transport is JSON-RPC 2.0 over HTTP POST: send one message (or a batch array) per request and the response comes back in the body as plain JSON. There is no SSE stream and no session to maintain — every request is independent and carries the Authorization header — which makes the server easy to drive from anything that can make an HTTPS request.
initialize. 2025-06-18, 2025-03-26 and 2024-11-05 are supported; the server echoes yours when it recognises it and otherwise answers with the newest. Server info chirply 2.1.0.initialize, ping, tools/list and the four read meta-tools — bills the read budget; running an operation bills the write budget. A batch bills the most expensive tier it contains. See rate limits.initialize, notifications/initialized, notifications/cancelled, ping, tools/list, tools/call. Anything else is JSON-RPC -32601.id) get no reply — the response is HTTP 204. A batch of only notifications is also 204.content array with one text part: a human-readable summary first, then the JSON payload — useful to a model even when it doesn’t parse the data. A tool that fails returns a successful RPC with isError: true, per MCP convention.readOnlyHint (safe to run without asking) and destructiveHint (derived from the operation’s own risk classification), so your client’s approval UX can agree with ours about what deserves a look first.-32001 bad or missing credential (HTTP 401), -32003 plan doesn’t include the MCP server (HTTP 402), -32005 rate limited (HTTP 429, with RateLimit headers on every response so a long-running agent can pace itself).# 1 — handshake
curl -X POST https://app.chirply.io/api/mcp \
-H "Authorization: Bearer chp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-06-18","capabilities":{},
"clientInfo":{"name":"my-agent","version":"1.0"}}}'
# → {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18",
# "capabilities":{"tools":{"listChanged":false}},
# "serverInfo":{"name":"chirply","version":"2.1.0"},"instructions":"…"}}
# 2 — acknowledge (a notification: no id, so no body comes back — HTTP 204)
curl -X POST https://app.chirply.io/api/mcp -H "Authorization: Bearer chp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
# 3 — what can I do here? (five tools: search, describe, run, domains, whoami)
curl -X POST https://app.chirply.io/api/mcp -H "Authorization: Bearer chp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 4 — find the action you want, in plain words
curl -X POST https://app.chirply.io/api/mcp -H "Authorization: Bearer chp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{"name":"search_capabilities",
"arguments":{"query":"add a new contact"}}}'
# 5 — read its arguments, then run it
curl -X POST https://app.chirply.io/api/mcp -H "Authorization: Bearer chp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call",
"params":{"name":"describe_capability",
"arguments":{"name":"contacts.create"}}}'
curl -X POST https://app.chirply.io/api/mcp -H "Authorization: Bearer chp_live_your_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":5,"method":"tools/call",
"params":{"name":"run_capability",
"arguments":{"name":"contacts.create",
"arguments":{"first_name":"Ada","phone":"+15551234567"}}}}'
# → {"jsonrpc":"2.0","id":5,"result":{"content":[{"type":"text","text":"…"}],
# "isError":false}}
# Calling a capability by name directly still works, listed or not:
# "params":{"name":"contacts_create","arguments":{…}}Over MCP the answer is search_capabilities: ask in plain words (“send a text”, “refund an invoice”), get back the matching operations with their descriptions, then describe_capability for the arguments. list_domains gives the same agent a map of the feature areas when it would rather browse than search. Outside a tool call, the REST catalog offers the identical data with filters, which is handy while you are building:
# Search the catalog without loading all of it:
curl "https://app.chirply.io/api/v1/actions?q=invoice" \
-H "Authorization: Bearer chp_live_your_key"
# Or browse one area at a time:
curl "https://app.chirply.io/api/v1/actions?domain=contacts&scope=write" \
-H "Authorization: Bearer chp_live_your_key"Calling a tool name that doesn’t exist returns a pointer back to search_capabilities rather than a dead end — and if the platform genuinely can’t do something, the agent can file the feature request itself with support_request_feature, from right inside the session.
Operations that send real messages, spend money or delete data are classified confirm and surface to MCP clients as destructiveHint: true. For an MCP caller the deliberately-issued API key is the authorization — the server runs the call — and the hint is there so your client can put a human in the loop where you want one. The in-app assistant uses the same classification and always asks first.
An agent usually can’t host a webhook endpoint, so the platform keeps a pull stream: webhooks_read_events returns everything that happened since the agent last looked, oldest first with a cursor. Subscribe once (see the webhook guide), then the agent starts each session by asking what’s new.
Once connected, working your workspace reads like delegating to a colleague who never loses the thread:
You: Morning — anything waiting on us?
Agent: Three new conversations overnight (conversations_list). Two are booking questions; one is Maria Ortega confirming the quote. Want me to answer the booking questions from the calendar’s availability?
You: Yes, and offer them Thursday.
Agent: Replied to both (messages_send) and booked the Hendersons for Thursday at 10 (booking_book_appointment). For Maria — the quote was $2,400. Shall I send the invoice?
You: Send it.
Agent: Invoice sent (invoices_send) and the deal moved to “Invoiced” (deals_update). I’ll let you know when the payment lands — invoice_paid is in the event stream.
Every one of those steps is an operation from the catalog, run under your key’s permissions, visible in your audit trail — and everything the agent did, you could have done by clicking. That’s the contract: one catalog, whether the hands on it are yours or your agent’s.