Repository avatar
AI Tools
v1.0.0
active

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 401 challenge, 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 send Authorization: Bearer aybox_.... The examples here read it from AYINBOX_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).

ToolsetWhat it coversTools
inboxRead and sort replies, draft answers, offer meeting timeslist_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
campaignsCampaigns, their steps, campaign brains and auto-replylist_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
contactsContacts, segments (saved audiences) and the do-not-contact listsearch_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
crmPipelines, deals, tasks and noteslist_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
formsHosted forms and their submissionslist_forms, get_form, create_form, update_form, delete_form, list_form_submissions, get_form_stats, get_campaign_forms, mint_form_link
analyticsSending results, mailbox health, the Advisor, placement testsget_dashboard_analytics, list_mailboxes, list_recommendations, get_advisor_summary, list_placement_tests, get_placement_test, list_placement_batches, get_placement_batch
mailboxesSettings of connected sender mailboxesget_mailbox, update_mailbox, set_mailbox_warmup, set_mailbox_send_hold, set_mailbox_tracking_domain, get_warmup_ban_status, submit_warmup_appeal, disconnect_mailbox
workspacePlan, limits, AI credits, labelsget_workspace_limits, get_org_settings, get_subscription, get_subscription_limits, get_credit_balance, get_credit_usage, list_credit_transactions, list_labels
developerAPI keys and webhookslist_api_keys, create_api_key, update_api_key, revoke_api_key, list_webhooks, list_webhook_deliveries, delete_webhook, verify_webhook
automationAutomationslist_automations, get_automation, create_automation_draft, update_automation, set_automation_enabled, delete_automation
leadsPaid lead finding within a budget, address checksfind_leads, get_lead_job, list_lead_jobs, verify_email
researchWeb search and the workspace's playbookssearch_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. Add WRITE_CONTACTS and WRITE_CAMPAIGNS for an agent that builds lists and campaigns.
  • Starting a campaign with set_campaign_status takes START_CAMPAIGNS or SEND_CAMPAIGNS. A client connected with OAuth holds START_CAMPAIGNS only when its person ticked Start and resume campaigns on the consent screen. No key preset includes START_CAMPAIGNS; add it on purpose.
  • What a person must grant. A client connected with OAuth is never granted SEND_CAMPAIGNS, API-key management or WRITE_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 gave SEND_CAMPAIGNS on purpose.
  • Spending. find_leads (needs INTEGRATIONS and BULK_CONTACTS and a max_cost_usd budget) and generate_reply_draft spend 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 is load_skill, which returns the workspace's own playbook.

Troubleshooting

You seeMeaningDo
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 inLet the client sign in (for example /mcp in Claude Code), or check the key
A client that worked stops with 401OAuth access tokens last one hour and refresh themselves with a rotating refresh token; a revoked app or a failed refresh ends thatSign in again from the client. Disconnected apps are under connected apps in the dashboard
HTTP 405 with Allow: POST on GET, HEAD or DELETEThe server keeps no session and opens no event streamSend every message as a POST. A client that insists on an SSE stream cannot connect
HTTP 400 with JSON-RPC -32600MCP-Protocol-Version names a version the server does not implementStart again with initialize
isError text naming a scopeThe credential lacks that scope; nothing ranFor OAuth, reconnect and grant it at consent where a client may hold it; for a key, the workspace owner widens it
-32000 mailbox limitThe key is limited to some mailboxes and tools act across the workspaceUse a key without mailbox limits
-32601No such tool on this surfaceUse a name from tools/list

Quote the request_id from an error body when you report a problem to team@ayinbox.com.

Docs

What's in this repository

PathWhat it is
server.jsonThe server's entry in the official MCP Registry
clients/One folder per client with a ready-to-copy config and a README
mcp.jsonA generic mcpServers entry for clients that take that shape
.claude-plugin/, .mcp.jsonClaude Code plugin and marketplace manifests, and the plugin's MCP connection (OAuth)
gemini-extension.jsonGemini CLI extension manifest
skills/ayinbox/SKILL.mdThe agent skill the plugin and the extension load
PUBLISH.mdHow 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.

Remote