
ayinbox
com.ayinbox/ayinbox
Cold email from your agent: contact lists, campaigns, campaign brains, reply drafts and a CRM.
Documentation
AY Inbox MCP server
AY Inbox is a hosted cold email platform: it sends cold email at a paced daily volume, brings every reply into one inbox (Unibox), drafts answers from a campaign brain, and can offer a meeting time from Cal.com or Calendly. Its MCP server lets an AI agent build contact lists, draft campaigns and their brains, read replies and draft answers, and track deals, with the same credential as the REST API.
- Server URL:
https://api.ayinbox.com/v1/mcp(streamable HTTP; one JSON-RPC message per POST, no session, no event stream) - Protocol versions:
2025-11-25,2025-06-18,2025-03-26 - Sign in with OAuth 2.1: add the URL with no key. The client finds the sign-in on its own (a
401challenge, protected-resource metadata, dynamic client registration, PKCE), you sign in at app.ayinbox.com and approve the scopes. No key to copy. - Or use an API key: create one in the dashboard under Settings > API keys (it starts with
aybox_and is shown once) and sendAuthorization: Bearer aybox_.... The examples here read it fromAYINBOX_API_KEY. - Official MCP Registry:
com.ayinbox/ayinbox - Access: Access to the hosted service is invite only for now: ask at team@ayinbox.com.
- Agent guide: ayinbox.com/skill.md
AY Inbox is a hosted service. This repository holds the registry manifest, connect steps and ready-to-copy client configs for its MCP server. The service itself is not open source.
Connect
Every client below has a folder in clients/ with the config file and a short README. Where a client can read an environment variable in its config, the API-key form uses AYINBOX_API_KEY. Where it cannot, the file has aybox_... to replace with your key, and the key then sits in that file in plain text: keep it out of version control.
Claude (web and desktop)
Customize > Connectors > Add > Add custom connector, name it AY Inbox, paste https://api.ayinbox.com/v1/mcp, choose Continue, keep the detected options, choose Add, then Connect and sign in. On Team and Enterprise plans an owner adds it under Organization settings > Connectors > Add > Custom > Web and members connect it from Customize > Connectors.
Custom connectors use OAuth. For an API key in Claude Desktop, bridge it with mcp-remote (third party, needs Node.js) in claude_desktop_config.json: clients/claude-desktop/.
{
"mcpServers": {
"ayinbox": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.ayinbox.com/v1/mcp", "--header", "Authorization:${AYINBOX_AUTH}"],
"env": { "AYINBOX_AUTH": "Bearer aybox_..." }
}
}
}
Claude Code
claude mcp add --transport http --scope user ayinbox https://api.ayinbox.com/v1/mcp
claude mcp login ayinbox
API key:
claude mcp add --transport http --scope user ayinbox https://api.ayinbox.com/v1/mcp \
--header "Authorization: Bearer $AYINBOX_API_KEY"
Or install this repository as a plugin, which connects with OAuth and adds the agent skill:
/plugin marketplace add ayinbox/ayinbox-mcp
/plugin install ayinbox@ayinbox
A project .mcp.json with ${AYINBOX_API_KEY} is in clients/claude-code/.
ChatGPT
Where your plan offers developer mode: chatgpt.com/plugins > + > Add custom MCP server, paste https://api.ayinbox.com/v1/mcp, choose OAuth, then Create as a plugin and sign in. ChatGPT documents no header or API-key option for custom servers.
Codex CLI
codex mcp add ayinbox --url https://api.ayinbox.com/v1/mcp
codex mcp login ayinbox
API key (Codex reads the variable when it connects):
codex mcp add ayinbox --url https://api.ayinbox.com/v1/mcp --bearer-token-env-var AYINBOX_API_KEY
# ~/.codex/config.toml
[mcp_servers.ayinbox]
url = "https://api.ayinbox.com/v1/mcp"
bearer_token_env_var = "AYINBOX_API_KEY"
Cursor
~/.cursor/mcp.json or .cursor/mcp.json. With only the URL, Cursor signs in with OAuth:
{
"mcpServers": {
"ayinbox": { "url": "https://api.ayinbox.com/v1/mcp" }
}
}
API key:
{
"mcpServers": {
"ayinbox": {
"url": "https://api.ayinbox.com/v1/mcp",
"headers": { "Authorization": "Bearer ${env:AYINBOX_API_KEY}" }
}
}
}
VS Code (GitHub Copilot agent mode)
.vscode/mcp.json, or MCP: Open User Configuration. VS Code registers itself and opens the browser to sign in:
{
"servers": {
"ayinbox": { "type": "http", "url": "https://api.ayinbox.com/v1/mcp" }
}
}
API key (VS Code asks for it once and stores it as a secret):
{
"inputs": [
{ "type": "promptString", "id": "ayinbox-api-key", "description": "AY Inbox API key", "password": true }
],
"servers": {
"ayinbox": {
"type": "http",
"url": "https://api.ayinbox.com/v1/mcp",
"headers": { "Authorization": "Bearer ${input:ayinbox-api-key}" }
}
}
}
GitHub Copilot CLI
Add the server to ~/.copilot/mcp-config.json (see clients/copilot-cli/), then run /mcp auth ayinbox in copilot to sign in. API key:
copilot mcp add --transport http --header "Authorization: Bearer $AYINBOX_API_KEY" ayinbox https://api.ayinbox.com/v1/mcp
Gemini CLI
gemini mcp add --transport http --scope user ayinbox https://api.ayinbox.com/v1/mcp
Sign in with /mcp auth ayinbox. API key (your shell expands the variable when you run it):
gemini mcp add --transport http --scope user --header "Authorization: Bearer $AYINBOX_API_KEY" ayinbox https://api.ayinbox.com/v1/mcp
Or install this repository as an extension, which connects with OAuth and loads the agent skill: gemini extensions install https://github.com/ayinbox/ayinbox-mcp.
Windsurf
~/.codeium/windsurf/mcp_config.json. Without headers, Cascade signs in with OAuth:
{
"mcpServers": {
"ayinbox": {
"serverUrl": "https://api.ayinbox.com/v1/mcp",
"headers": { "Authorization": "Bearer ${env:AYINBOX_API_KEY}" }
}
}
}
Zed
settings.json, or Settings > AI > MCP Servers > Add Server > Add Remote Server. With no header, Zed runs the MCP OAuth sign-in:
{
"context_servers": {
"ayinbox": { "url": "https://api.ayinbox.com/v1/mcp" }
}
}
API key: add "headers": { "Authorization": "Bearer aybox_..." } with your key pasted in. Zed documents no variable expansion in headers.
JetBrains Junie
~/.junie/mcp/mcp.json (or Tools > Junie > MCP Settings > Add) with {"mcpServers": {"ayinbox": {"url": "https://api.ayinbox.com/v1/mcp"}}}, then open the server's menu, choose Authorize and sign in. API key: add "headers": { "Authorization": "Bearer aybox_..." } with your key pasted in. See clients/junie/.
Cline
OAuth: MCP Servers > Remote Servers, name ayinbox, URL https://api.ayinbox.com/v1/mcp, transport Streamable HTTP, Add Server, then sign in. API key:
cline mcp add ayinbox https://api.ayinbox.com/v1/mcp --transport http --header "Authorization: Bearer $AYINBOX_API_KEY" --yes
Roo Code
API key only (Roo Code does not document MCP OAuth), in .roo/mcp.json or the global mcp_settings.json:
{
"mcpServers": {
"ayinbox": {
"type": "streamable-http",
"url": "https://api.ayinbox.com/v1/mcp",
"headers": { "Authorization": "Bearer aybox_..." }
}
}
}
Kilo Code
~/.config/kilo/kilo.jsonc or kilo.jsonc in a project. Kilo starts the OAuth flow when it connects:
{
"mcp": {
"ayinbox": { "type": "remote", "url": "https://api.ayinbox.com/v1/mcp", "enabled": true }
}
}
API key: add "headers": { "Authorization": "Bearer {env:AYINBOX_API_KEY}" } and "oauth": false.
Continue
API key only (Continue does not document MCP OAuth). .continue/mcpServers/ayinbox.yaml:
name: AY Inbox
version: 1.0.0
schema: v1
mcpServers:
- name: AY Inbox
type: streamable-http
url: https://api.ayinbox.com/v1/mcp
apiKey: ${{ secrets.AYINBOX_API_KEY }}
Goose
~/.config/goose/config.yaml, or goose configure > Add Extension > Remote Extension (Streamable HTTP). With no headers Goose runs the OAuth sign-in itself:
extensions:
ayinbox:
type: streamable_http
name: ayinbox
enabled: true
uri: https://api.ayinbox.com/v1/mcp
timeout: 300
API key: add the header and list the variable in env_keys, which Goose requires before it substitutes it:
headers:
Authorization: "Bearer ${AYINBOX_API_KEY}"
env_keys:
- AYINBOX_API_KEY
OpenCode
opencode.json, then opencode mcp auth ayinbox:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ayinbox": { "type": "remote", "url": "https://api.ayinbox.com/v1/mcp", "enabled": true }
}
}
API key: add "oauth": false and "headers": { "Authorization": "Bearer {env:AYINBOX_API_KEY}" }.
Crush
In crushrc (./.crushrc, ./crushrc or ~/.config/crush/crushrc):
# OAuth
mcp add ayinbox --type http --url "https://api.ayinbox.com/v1/mcp" --oauth true
# or an API key
mcp add ayinbox --type http --url "https://api.ayinbox.com/v1/mcp" \
--header Authorization "Bearer $AYINBOX_API_KEY"
Amp
amp mcp add ayinbox https://api.ayinbox.com/v1/mcp
Amp opens the browser to sign in. API key, in ~/.config/amp/settings.json:
{
"amp.mcpServers": {
"ayinbox": {
"url": "https://api.ayinbox.com/v1/mcp",
"headers": { "Authorization": "Bearer ${AYINBOX_API_KEY}" }
}
}
}
Hermes Agent
~/.hermes/config.yaml, then hermes mcp login ayinbox:
mcp_servers:
ayinbox:
url: https://api.ayinbox.com/v1/mcp
auth: oauth
API key: replace auth: oauth with a headers: map holding Authorization: "Bearer aybox_..." and your key pasted in. See clients/hermes/.
OpenAI Agents SDK and Responses API
import os
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
async with MCPServerStreamableHttp(
name="ayinbox",
params={
"url": "https://api.ayinbox.com/v1/mcp?toolsets=inbox",
"headers": {"Authorization": f"Bearer {os.environ['AYINBOX_API_KEY']}"},
},
) as ayinbox:
agent = Agent(name="Inbox assistant", mcp_servers=[ayinbox])
result = await Runner.run(agent, "Summarize my unread replies from today.")
For the Responses API, the remote MCP tool entry is in clients/openai-agents/responses-mcp-tool.json.
Claude Agent SDK
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Summarize my unread AY Inbox replies from today.",
options: {
mcpServers: {
ayinbox: {
type: "http",
url: "https://api.ayinbox.com/v1/mcp",
headers: { Authorization: `Bearer ${process.env.AYINBOX_API_KEY}` },
},
},
allowedTools: ["mcp__ayinbox__*"],
},
})) {
if (message.type === "result" && message.subtype === "success") console.log(message.result);
}
The SDK runs no interactive sign-in, so use an API key. Python is in clients/claude-agent-sdk/agent.py.
Any other client
Point a client that supports remote MCP over streamable HTTP at https://api.ayinbox.com/v1/mcp. If it supports MCP OAuth, it signs in on its own; otherwise send Authorization: Bearer <key>. A plain request works too:
curl -s https://api.ayinbox.com/v1/mcp \
-H "Authorization: Bearer $AYINBOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Check it worked: ask your agent to call get_workspace_limits. It is a free read that shows the plan's limits next to what the workspace uses.
Tools
The server lists only the tools your credential may call. With every scope, that is 174 tools in twelve toolsets. Add ?toolsets= to the URL to narrow the list for a small model, for example https://api.ayinbox.com/v1/mcp?toolsets=inbox,campaigns (some OAuth clients tie the token to the exact URL and then get the whole list).
| Toolset | What it covers | Tools |
|---|---|---|
inbox | Read and sort replies, draft answers, offer meeting times | list_threads, get_thread, draft_reply, generate_reply_draft, get_inbox_overview, get_unread_count, list_agent_drafts, discard_agent_draft, mark_thread_seen, set_thread_labels, move_thread_folder, snooze_thread, unsnooze_thread, list_scheduled_sends, cancel_scheduled_send, get_booking_settings, update_booking_settings, enable_booking_auto, get_booking_summary, list_booking_types, create_booking_type, update_booking_type, delete_booking_type, list_booking_event_types, get_availability, list_meeting_offers, get_meeting_offer, offer_meeting_times, stop_meeting_offer, resume_meeting_offer, reject_meeting_pick |
campaigns | Campaigns, their steps, campaign brains and auto-reply | list_campaigns, get_campaign, get_campaign_stats, list_campaign_leads, create_campaign_draft, update_campaign, delete_campaign, set_campaign_status, set_lead_hold, list_campaign_senders, set_campaign_senders, verify_campaign_tracking_domain, get_campaign_logs, list_campaign_steps, add_campaign_step, update_campaign_step, delete_campaign_step, list_brains, get_brain, preview_brain, get_brain_material, get_brain_internal, list_brain_pages, get_brain_page, write_brain_page, create_brain, update_brain, delete_brain, add_brain_material, update_brain_material, remove_brain_material, refresh_brain_material, set_campaign_brain, set_default_brain, get_auto_reply_settings, enable_auto_reply, pause_auto_reply, get_campaign_auto_reply, update_campaign_auto_reply, enable_campaign_auto_reply, list_auto_reply_runs, get_auto_reply_run, cancel_auto_reply_run |
contacts | Contacts, segments (saved audiences) and the do-not-contact list | search_contacts, get_contact, add_contact, update_contact_fields, delete_contact, add_tag, remove_tag, bulk_edit_contacts, get_contact_timeline, get_contact_sent_emails, list_segments, get_segment, list_segment_fields, preview_segment, create_segment, update_segment, delete_segment, set_segment_members, list_campaign_segments, set_campaign_segments, add_segment_to_campaign, list_suppressions, add_suppressions |
crm | Pipelines, deals, tasks and notes | list_pipelines, create_pipeline, update_pipeline, delete_pipeline, create_pipeline_stage, update_pipeline_stage, delete_pipeline_stage, list_deals, get_deal, list_deals_by_contact, create_deal, update_deal, move_deal_stage, delete_deal, list_tasks, list_task_types, create_task, update_task, complete_task, delete_task, list_contact_notes, add_contact_note, update_contact_note, delete_contact_note |
forms | Hosted forms and their submissions | list_forms, get_form, create_form, update_form, delete_form, list_form_submissions, get_form_stats, get_campaign_forms, mint_form_link |
analytics | Sending results, mailbox health, the Advisor, placement tests | get_dashboard_analytics, list_mailboxes, list_recommendations, get_advisor_summary, list_placement_tests, get_placement_test, list_placement_batches, get_placement_batch |
mailboxes | Settings of connected sender mailboxes | get_mailbox, update_mailbox, set_mailbox_warmup, set_mailbox_send_hold, set_mailbox_tracking_domain, get_warmup_ban_status, submit_warmup_appeal, disconnect_mailbox |
workspace | Plan, limits, AI credits, labels | get_workspace_limits, get_org_settings, get_subscription, get_subscription_limits, get_credit_balance, get_credit_usage, list_credit_transactions, list_labels |
developer | API keys and webhooks | list_api_keys, create_api_key, update_api_key, revoke_api_key, list_webhooks, list_webhook_deliveries, delete_webhook, verify_webhook |
automation | Automations | list_automations, get_automation, create_automation_draft, update_automation, set_automation_enabled, delete_automation |
leads | Paid lead finding within a budget, address checks | find_leads, get_lead_job, list_lead_jobs, verify_email |
research | Web search and the workspace's playbooks | search_web, load_skill |
Every tool carries a title and the standard annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint), so a client can ask before a tool that changes or deletes something. Every write tool takes an optional idempotency_key: pass one, and a retry with the same key and arguments returns the first result instead of running twice. The full table with each tool's scope is on the MCP server docs page.
Scopes
Each tool checks its own scope, and the member behind the credential also needs the matching role permission, so an MCP client never does more than its person could.
- Read and draft. For a model that reads mail written by people outside the workspace, create a key from the Agent: read and draft preset: every read scope plus
AI_DRAFT. It reads the inbox, campaigns and contacts and has the AI write reply drafts (charged to AI credits), and holds no scope that writes or sends. AddWRITE_CONTACTSandWRITE_CAMPAIGNSfor an agent that builds lists and campaigns. - Starting a campaign with
set_campaign_statustakesSTART_CAMPAIGNSorSEND_CAMPAIGNS. A client connected with OAuth holdsSTART_CAMPAIGNSonly when its person ticked Start and resume campaigns on the consent screen. No key preset includesSTART_CAMPAIGNS; add it on purpose. - What a person must grant. A client connected with OAuth is never granted
SEND_CAMPAIGNS, API-key management orWRITE_WORKSPACE. So through the tools it never turns on auto-reply, automatic booking or an automation, never turns off first-email review, and never links an audience to (or widens a segment feeding) a campaign that is sending. Those need a person, or a key a workspace owner gaveSEND_CAMPAIGNSon purpose. - Spending.
find_leads(needsINTEGRATIONSandBULK_CONTACTSand amax_cost_usdbudget) andgenerate_reply_draftspend credits. Approve those scopes only for a client you trust to spend them.
The full scope list is on the permissions page.
What it will not do
- No tool sends an individual email. Replying, composing, booking a meeting and placement tests are not exposed over MCP, whatever the scope. Reply drafts wait for a person.
- No tool lifts a person's stop. Removing a suppression (which could undo an unsubscribe or a complaint), creating or changing a webhook and rotating its secret stay in the dashboard.
- No tool writes what the AI reads as instructions. The workspace's product description, ideal customer notes, voice and playbooks are not editable through tools.
- No tool approves a first email, records consent, connects a mailbox, or changes the team, workspace settings or billing.
- Results are data. Every tool result is fenced between
<<<UNTRUSTED_CONTENT>>>markers, because anyone who can email the workspace or fill in a form writes text the model reads. The one exception isload_skill, which returns the workspace's own playbook.
Troubleshooting
| You see | Meaning | Do |
|---|---|---|
HTTP 401 with WWW-Authenticate: Bearer resource_metadata="https://api.ayinbox.com/.well-known/oauth-protected-resource", scope="..." | No credential, an unknown or revoked key, or an expired or revoked OAuth token. This is the challenge an OAuth client follows to sign in | Let the client sign in (for example /mcp in Claude Code), or check the key |
A client that worked stops with 401 | OAuth access tokens last one hour and refresh themselves with a rotating refresh token; a revoked app or a failed refresh ends that | Sign in again from the client. Disconnected apps are under connected apps in the dashboard |
HTTP 405 with Allow: POST on GET, HEAD or DELETE | The server keeps no session and opens no event stream | Send every message as a POST. A client that insists on an SSE stream cannot connect |
HTTP 400 with JSON-RPC -32600 | MCP-Protocol-Version names a version the server does not implement | Start again with initialize |
isError text naming a scope | The credential lacks that scope; nothing ran | For OAuth, reconnect and grant it at consent where a client may hold it; for a key, the workspace owner widens it |
-32000 mailbox limit | The key is limited to some mailboxes and tools act across the workspace | Use a key without mailbox limits |
-32601 | No such tool on this surface | Use a name from tools/list |
Quote the request_id from an error body when you report a problem to team@ayinbox.com.
Docs
- MCP server: every tool and its scope, toolsets, retries, errors
- Agent quickstart
- For agents
- OAuth 2.1
- Authentication
- Permissions
- Agent tools over REST
- OpenAI-compatible agents
- Agent guide (skill.md)
What's in this repository
| Path | What it is |
|---|---|
server.json | The server's entry in the official MCP Registry |
clients/ | One folder per client with a ready-to-copy config and a README |
mcp.json | A generic mcpServers entry for clients that take that shape |
.claude-plugin/, .mcp.json | Claude Code plugin and marketplace manifests, and the plugin's MCP connection (OAuth) |
gemini-extension.json | Gemini CLI extension manifest |
skills/ayinbox/SKILL.md | The agent skill the plugin and the extension load |
PUBLISH.md | How server.json is published to the registry |
License
The files in this repository are MIT licensed. Access to the AY Inbox service is separate: ask at team@ayinbox.com.
No installation packages available.