MCP server
Adeli runs a Model Context Protocol server, so an AI agent can use the API as typed tools instead of hand-written HTTP requests. The tools are the REST API: each one calls the same endpoint with the same validation, profile scoping, errors, and side effects. Nothing is available over MCP that is not available over REST.
Endpoint and authentication
POST https://app.tryadeli.com/mcp
Authorization: Bearer rk_live_...- Transport — Streamable HTTP. The server is stateless and answers each request with JSON; there is no session to keep and no event stream to hold open.
- Key — the same
rk_live_API key you use for REST, created under API keys. See Authentication. - Scope — every tool acts on the one profile the key is bound to.
profileIdis optional on every tool and defaults to that profile.
A missing or revoked key fails the connection with 401 unauthorized and a
WWW-Authenticate: Bearer header, before any tool runs.
The key lives in your client's config
MCP clients store the header in a local config file. Read the key from an environment variable where your client supports it, give each machine or agent its own key, and never commit the file. If one leaks, delete that key under API keys — revocation is immediate.
Connect your client
claude mcp add --transport http adeli https://app.tryadeli.com/mcp \
--header "Authorization: Bearer $ADELI_API_KEY"Claude Code expands $ADELI_API_KEY when you run the command and stores the
result in its config. Clients that can only launch local processes reach the
server through mcp-remote, which
bridges stdio to HTTP.
Check the connection
List the tools with a single request. You should get back the tools described in MCP tools.
curl https://app.tryadeli.com/mcp \
-H "Authorization: Bearer $ADELI_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'To call tools interactively, run npx @modelcontextprotocol/inspector, choose
Streamable HTTP, and add the Authorization header.
How tools behave
- Results are REST bodies. A tool returns exactly the JSON the matching
endpoint returns, as
structuredContentand as text. - Partial is not an error. Reads that span providers can succeed for some
accounts and fail for others. That result carries
status: "partial"and anerrorslist, as described in Core concepts, and is not marked as a tool error. - Errors keep the envelope. Any
4xxor5xxbecomes a tool error whose content is the usual{ "error": { "code", "message", "details" } }body. See Errors for every code. - Tools say what they change. Read-only tools are annotated
readOnlyHint.disconnect_accountandads_set_statusare annotateddestructiveHint, so clients that ask before acting will ask. - Large reads are truncated in text only. Past about 100 KB, the text copy
is cut short and
structuredContentstill holds the whole body. Filter byplatformoraccountIdto keep responses small.
What MCP does not do
- No OAuth sign-in. The server takes an API key, so clients that can only
connect through an OAuth flow, such as claude.ai custom connectors, cannot
add it directly yet. Use
mcp-remotefrom a desktop client instead. - No multipart uploads.
create_posttakes the JSON body ofPOST /api/v1/posts. For TikTok and YouTube video, pass a public HTTPSvideo.urlrather than base64. Send large files through REST. - No key or profile management. Create keys and profiles in the dashboard. A key cannot create a profile, and deleting a profile is not a tool.
- WhatsApp sends templates only.
send_messagesends one of the business's approved WhatsApp templates; free-form WhatsApp replies stay in the dashboard inbox. Connecting a WhatsApp number is done on the dashboard's Accounts page.
For agents
If you are an AI agent reading this page, the essentials are:
- Call
list_accountsfirst. Every account-level tool takes anaccountIdfrom it, and every ads tool takes anadAccountIdfromads_list_accounts. - Leave
profileIdout. It defaults to the only profile your key can reach. - Ask the user before calling
create_post,send_message,disconnect_account,ads_create_campaign,ads_create_account,ads_update_account, orads_delete_campaign. These act on a real customer's real accounts, and an ad account, once created, cannot be deleted. - Never call
ads_set_statuswithACTIVEunless the user has confirmed the budget and dates in this conversation. It starts spending money. - Publishing to TikTok and YouTube, and Facebook Reels and videos, is
asynchronous: poll the matching status tool with the returned
publishId. Ask the user for a YouTube video's visibility and whether it is made for kids; never choose either for them. - For anything not covered here, read the
adeli://docs/llms.txtresource. It is this entire documentation site as plain text.