Skip to content

Reference

MCP

Every Tinbox deployment exposes a Model Context Protocol endpoint at /mcp. Connect the Claude app, Claude Code, or any MCP agent and it gets the exact same tools the in-app assistant runs — search mail, summarize threads, draft and send, and manage audiences and campaigns.

84 tools over MCP

Connect a client

Point your MCP client at the deployment's /mcp URL. The Claude app one-click-connects via OAuth; CLI agents use a static tbx_… bearer token.

json
{
  "mcpServers": {
    "tinbox": {
      "url": "https://acme.com/mcp"
    }
  }
}
Guide: Connect an MCP client

search_docs

The endpoint also exposes a search_docs tool: a full-text search over these docs (guides + the tool, CLI, and SDK reference) so an agent can look up how a capability works before calling it.

Tools exposed over MCP

Each links to its full schema and example payload. See the capability matrix for how these correspond to the CLI and SDK.

Email

search_emails

Full-text search the user's mail by subject, sender, or body. Call this to find relevant emails BEFORE answering — never answer from memory about specific mail. Returns matching messages with threadId, inboxId, subject, sender, and a body preview.

list_threads

List recent conversation threads (most recent first). Use to browse an inbox or get an overview. Returns thread summaries with id, subject, participants, and message count.

get_thread

Fetch one thread with its full message history (sender, recipients, subject, body) and attachments. Call this to read a conversation before summarizing or drafting a reply.

create_draft

Create a reply DRAFT (never sends on its own — a human reviews and sends, or use send_email if enabled). Provide the inboxId and, for a reply, the threadId. Returns the new draft's id and version.

update_draft

Edit an existing draft (compare-and-swap on baseVersion to avoid clobbering concurrent edits). Pass the draft id, the baseVersion you last saw, and the fields to change.

summarize_thread

Summarize an email thread: who's involved, what they want, the state, and what needs a response. Use when the user asks for a summary or 'what's this about'. Reads the thread, then summarizes.

send_email

SEND an email now (this actually dispatches mail — it is not a draft). Requires a human approval step in chat. Use only when the user explicitly asks to send. Prefer create_draft when unsure.

get_delivery_status

Check the delivery status of a specific sent email by its id. Returns the current status, delivery events timeline, and any errors. Use to verify if an email was delivered, bounced, or is still pending.

send_campaign

Send an approved campaign immediately to all recipients. This is irreversible — the emails will be sent. Requires the campaign to be in approved status.

send_test_campaign

Send a one-off test of a campaign draft to a single verified address (e.g. yourself) before the real send. Goes only to that address; it does NOT touch the recipient list or ledger. The natural last check before approve_campaign.

draft_outreach_body

Draft (or re-draft) one prospect's personalized cold body from the campaign's first sequence-step instruction (or an override) + the prospect's qualification signal. Moves the prospect sourced → drafted; nothing sends. Needs a model wired.

draft_all_pending

Draft a personalized cold body for EVERY sourced (not-yet-drafted) prospect in a campaign, in one bounded pass. Moves each sourced → drafted; nothing sends. Returns a tally. Needs a model wired.

get_send_readiness

Check whether this deployment can send a given campaign type right now, and if not, exactly what's missing. Returns an ordered checklist per lane (broadcast, outreach, journey) with fix hints and deep-links. Use before creating or launching a campaign to know what to set up first. Pass phase 'send' to treat an empty audience as a hard blocker (would send to 0 people); 'create' is permissive.

check_sending_domain

Check a domain's live DNS / verification state — re-runs the DNS check now and returns which records are verified (MX/SPF/DKIM/DMARC) and which are still missing, plus whether receiving and sending are valid. Read-only (it changes no config; it just checks). Use to answer 'is my domain verified yet?' during onboarding, or to point the operator at the exact records still to add in Settings → Domains. Give the domain (e.g. yourdomain.com).

set_thread_directive

Attach follow-up logic to a thread: when a reply arrives (or after a delay), the platform drafts/sends/asks/notifies per your instructions. Use it when the user wants a standing reply plan on a conversation ('if they reply, draft an answer in my voice'; 'remind me if no reply in 3 days'). `trigger`: 'reply' fires on the next inbound; 'no_reply_after'/'after' are timers (set `after` like '3d'/'7d'). `action.mode`: 'draft' (default — lands in Review), 'send' (auto-sends, if the deployment permits; otherwise downgraded to a draft), 'ask' (parks a check-in question), 'notify' (notification only). Cancel with cancel_thread_directive.

list_thread_directives

List the follow-up directives on a thread — the reply logic attached to it (trigger, mode, status, how many times it's fired, when it expires). Read-only; use it to check what will happen when a reply lands before setting or canceling one.

cancel_thread_directive

Cancel a thread follow-up directive by id (from list_thread_directives) so it never fires again. The undo for set_thread_directive. Idempotent — canceling an already-canceled or already-fired directive is a safe no-op.

Other

create_disposable_mailbox

Mint a throwaway email address and a pollToken to read its mail with poll_disposable_mailbox. Ideal for grabbing a one-time code (OTP) without touching a real inbox. By default the ADDRESS is kept (a catch-all keeps routing its mail) and the TOKEN never expires — pass expiresIn (e.g. '2h', '30m', '7d') to expire the token, and expireAddress:true to also tear the address down at that time.

poll_disposable_mailbox

Read the mail that has arrived at a disposable mailbox, newest first (returns ALL messages — a fresh box holds under 10). Pass the pollToken from create_disposable_mailbox. Use format='simplifiedMD' or 'otpOnly' to get a one-time code fast: any code the OTP skill detected is surfaced first.

drop_disposable_mailbox

Stop NEW mail from arriving at a disposable address (e.g. once a newsletter or signup starts spamming it) while KEEPING the mail already received and the poll token. You can still poll what's there; future mail to the address is rejected. Use burn_disposable_mailbox instead to also delete everything.

burn_disposable_mailbox

Immediately destroy a disposable mailbox and EVERYTHING in it — the address, the stored mail, and the token (don't wait for expiry). Pass the pollToken. Use drop_disposable_mailbox instead if you only want to stop NEW mail but keep what's there.

company_brief

Trace and summarize the whole relationship with a company (everyone you've emailed at a domain). Use when the user asks 'what's going on with <company>' or 'summarize our relationship with X'. Searches mail from that domain, groups by person, and summarizes.

list_templates

List all email templates available for campaigns. Returns each template's name, preview, and last update time.

get_template

Get a specific email template's full content (HTML with merge tags). Use to review or copy template content.

create_template

Create a new email template. Provide HTML content with optional merge tags like {{contact.name}}, {{contact.email}}, {{urls.unsub}}.

update_template

Update an existing email template's name or HTML content.

preview_template

Render a template's merge-tag HTML with sample data to see what a recipient would receive. Pass a saved template `id`, or raw `html` to preview an unsaved draft.

list_personalized_review

Read the per-recipient review queue for a personalized warm campaign — each subscriber's drafted (or approved) body. Use to review the rewritten bodies before approving them to send.

approve_personalized

Bulk-approve (or revert) per-recipient warm bodies by their review-row ids. Approving marks them ready to send on the next campaign send — gated on the newsletter:send capability. This is the content lock for personalized sends.

source_prospects

Source + qualify prospects into a cold campaign WITHOUT sending. Resolve a candidate set from explicit org domains and/or a Contacts search (plus the campaign's stored sourcing config), run the GTM qualifier over each, and persist the qualified rows (idempotent per recipient). Writes sourced rows only — no email goes out.

list_review_queue

Read the ranked review queue for a cold campaign — every prospect (optionally one stage), hottest-first by qualification score, with whether each has a drafted body. Use to review what's ready before approving prospects to send.

approve_prospects

Approve specific prospects (drafted → approved) so they become eligible to send on the next scheduled tick. Capability-gated (outreach:send) AND routed through the HARD cold-domain gate server-side: a prospect can never be approved on a warm/unverified domain. This begins real, irreversible cold sends.

deny_prospects

Reject specific prospects out of the review queue (→ denied). Denying never sends, so it's reversible (re-source or re-draft to bring rows back). Capability-gated (outreach:send) like approve.

launch_outreach

Launch a cold campaign (review → approved) — the content lock that makes its approved prospects dispatchable. Capability-gated (outreach:send) AND routed through the HARD cold-domain gate: a campaign whose from/reply-to isn't on a VERIFIED cold subdomain is rejected. Actual sends fire on the scheduled tick (throttled + ramped). Irreversible: begins real outreach.

pause_outreach

Hold a cold campaign mid-sequence (→ paused). Resumable — no prospects are lost; sending stops until resumed. Reversible.

outreach_replies_digest

A reply-intent triage summary for a cold campaign: how many prospects replied (of how many sent), with a pointer to the Inbox where the actual reply conversations live (the one place an AI summary of intent earns its keep). Use to triage 'who replied to my outreach?'.

list_journeys

List email automation journeys (triggered multi-step sequences like welcome series or drips), newest first, with each journey's status, step count, and per-status run counts. Use to discover journeys before inspecting, editing, activating, or enrolling contacts.

get_journey

Get one journey with its ordered steps (email/delay/condition/tag) and trigger. Use before editing, activating, or enrolling contacts.

create_journey

Create a new email automation journey (draft) for an audience. A journey is a triggered, multi-step sequence (e.g. a 3-email welcome series). It starts in 'draft' with no steps — add steps with add_journey_step, then activate_journey to turn it on. Optionally set a trigger (e.g. { type: "api_event" } for contacts enrolled via enroll_in_journey, or { type: "signup" }).

add_journey_step

Append a step to a journey (or insert it at `order`). Step types and their `config`: - email: { subject: string, bodyMd?: string } — the email to send. ALWAYS write the body (`bodyMd`, markdown), not just a subject, so the draft is complete and reviewable. - delay: { amount: number, unit: 'minutes'|'hours'|'days' } (wait before the next step) - condition: { conditions: { match: 'all'|'any', rules: [...] }, onPass?: 'continue'|'skip'|'exit', onFail?: 'continue'|'skip'|'exit' } — branch on subscriber attributes or prior-email engagement (rule op 'opened_prev'/'clicked_prev' needs the previous email to be a tracked email step with a delay after it). onPass/onFail route the run: 'continue' = fall through, 'skip' = jump the next step, 'exit' = end the run. Defaults: onPass 'continue', onFail 'exit' (a plain gate). - tag: { tag: string } (apply a tag to the contact) Build the sequence by adding steps in order; the journey must have ≥1 step before it can be activated. If the requested logic can't be expressed (only 4 trigger types; conditions test the immediately-preceding email + segment attributes; branching is continue/skip/exit only, no arbitrary goto), say so in the create_journey `rationale` rather than silently building the wrong graph.

activate_journey

Activate a journey (draft|paused → active). Once active, triggers enroll contacts and the scheduler sends the journey's email steps. The journey must have at least one step. This starts REAL sends — treat like sending a campaign.

pause_journey

Pause an active journey (active → paused). Existing runs freeze and no new contacts enroll until it's activated again. The off-switch for activate_journey.

enroll_in_journey

Enroll a contact into an api_event journey by contact id or email — the manual trigger. The journey must be active. Ledger-safe: it only enrolls (the send happens on the next scheduler tick). A non-reentrant duplicate is a no-op (enrolled:false).

dispatch_notification

Dispatch a notification to a subscriber across their active channels matching the topic. payload should include a title and body. Returns per-channel delivery results.

list_forwarding_rules

List inbound forwarding rules — which inbound addresses forward a copy to which external destinations.

add_forwarding_rule

Forward a copy of inbound mail to an external address. matchAddress restricts to one inbound address; omit it to forward ALL inbound mail.

search_images

Find stock images (or generate an AI placeholder) for a campaign or newsletter body. mode='search' queries the okslop stock library by keyword; mode='generate' returns a deterministic AI-generated placeholder for a prompt (use when nothing fits or you need a hero image). Returns image URLs you can drop into markdown as ![alt](url). Read-only — picking an image is your job; nothing is inserted or sent.

get_setup_state

Check how set up this deployment is and what's left to configure. Returns the ordered onboarding checklist — every milestone (add a sending domain, verify DNS, confirm inbound routing, create an inbox, receive/send the first email, enable the assistant, invite the team) with its state (done | pending | blocked), a fix hint, and a deep link to the exact settings pane. Use this to answer 'what's left to set up?' and to walk the operator through remaining steps ONE at a time. For 'can I send a campaign right now?' use get_send_readiness instead. Read-only; never fabricate DNS or dashboard steps — take them from this tool's hints.

create_inbox

Create ONE new inbox at a mailbox address (e.g. support@yourdomain.com). ORG-ADMIN ONLY and requires a human approval step in chat — the approval card shows the exact address and type before it's created. Use for the onboarding 'set up your first mailbox' step or when the operator asks to add a shared/personal inbox. Provide localPart (the bit before @); domain defaults to the deployment's sending domain. type 'shared' is a team inbox (support@, sales@), 'personal' is one person's. To create a SET of role addresses at once, tell the operator to use Settings → Inboxes presets (this tool creates one at a time).

get_handbook

Read the team handbook — the operator's standing policies (plain-language lines like 'Never email competitor domains'). Returns every active entry with its id, text, topic, source, and creation time; pass `topic` to filter to one section. Use it to check what standing behavior applies before acting, or when the user asks what's in the handbook. Read-only.

update_handbook

Record, edit, or archive a standing policy in the team handbook. Use this when the user states a standing preference or corrects your behavior ('from now on…', 'always…', 'never…'): propose the exact one-line wording, get their confirmation, THEN call this with op:'add'. Never record anything silently. If the new preference contradicts an existing line (check get_handbook), use op:'edit' on that line's entryId instead of adding a duplicate. op:'archive' retires a line that no longer applies. Reversible: nothing is ever hard-deleted — an add is undone by archive, an edit by another edit. `entryId` accepts the full id or the short [hbk_*] handle.

Audiences

search_contacts

Find people the user corresponds with — by name or email prefix. Use to resolve a recipient before drafting/sending, or to look someone up. Returns matching contacts (recent correspondents first).

upsert_contact

Register a person in the contacts registry (add-or-update by email). Use to save someone you found or were asked to track. Provide `sourceUrl` + `confidence` when the contact came from web research. Auto-commits (reversible via undo).

tag_contact

Apply one or more labels to a contact (by contactId or email). Labels are created if new. Idempotent — re-tagging is a no-op. Auto-commits.

untag_contact

Remove one or more labels (by name or label id) from a contact (by contactId or email). No-op for a label the contact doesn't carry. Auto-commits.

set_contact_lifecycle

Set a contact's lifecycle stage: `prospect` (unverified), `active` (engaged), or `invalid` (bad/bounced). Identify by contactId or email. Auto-commits.

add_contacts

Add many contacts in ONE batch (e.g. results of a research task). FLOW: find companies/people via web_search, THEN call add_contacts with each row's `sourceUrl` + `confidence` (the research provenance) and any `labels`. Returns a batch summary you can later filter the directory by. Auto-commits.

delete_contact

Delete a contact (by contactId or email). This is a REVERSIBLE quarantine — the contact drops out of the registry but can be restored from Trash for 30 days before it's permanently purged. Safe to run without asking.

list_audiences

List all mailing list audiences (subscriber lists). Returns each audience's name, subscriber count, and settings. Use before adding subscribers or creating campaigns to find the right audience id.

get_audience

Get detailed info about a specific audience (mailing list), including subscriber stats by status (subscribed, unsubscribed, pending, cleaned).

create_audience

Create a new mailing list (audience). The agent can list audiences and add subscribers, but needs this to create the list to add them to. Set the sender identity (fromName/fromEmail) and reply-to.

update_audience

Update a mailing list's settings (name, sender identity, reply-to, double opt-in). Partial — only the fields you pass change.

list_subscribers

List subscribers (members) in an audience, optionally filtered by status or tag. Returns email, name, status, and subscription date.

add_subscriber

Add or update a subscriber in an audience. If the email already exists, updates their info. Use to subscribe new contacts or update existing ones.

remove_subscriber

Unsubscribe a member from an audience (sets status to unsubscribed). The contact record is preserved for compliance. Use when someone wants to stop receiving emails.

list_campaigns

List all email campaigns (newsletters). Returns each campaign's title, status, audience, and send progress.

get_campaign

Get detailed info about a specific campaign, including content, status, audience, and send progress/analytics.

create_campaign

Create a COMPLETE email campaign (newsletter) draft in one call: audience (and optional segment), subject, body, sender identity (from/reply-to), a PROPOSED send time, and a short rationale for your choices. The draft lands in the campaign builder for human review — it never sends or schedules itself. Use list_audiences / list_segments first to resolve ids by name, and get_send_readiness('broadcast') before creating.

update_campaign

Update a campaign's settings or content. Only works for campaigns in draft or in_review status. Use to edit subject, content, audience/segment, sender details (from/reply-to/preview text), or move/clear the proposed send time (null clears it).

approve_campaign

Approve a campaign for sending (moves from in_review → approved). Requires newsletter:send capability. After approval, the campaign can be scheduled or sent immediately.

schedule_campaign

Schedule an approved campaign to send at a specific time. The campaign must be in 'approved' status. Provide a Unix timestamp (milliseconds) for when to send.

get_campaign_report

Get a sent campaign's performance: open/click/unsubscribe analytics plus recipient-ledger progress (sent/pending/failed/suppressed) and the resolved recipient count. Use to answer 'how did my last newsletter do?'. Distinct from get_campaign (which only returns status/content).

preview_segment

Count and sample the subscribers in an audience that match a set of conditions, WITHOUT saving a segment. Lets you reason about reach before composing a campaign (e.g. 'how many active subscribers tagged VIP?'). `conditions` is { match: 'all'|'any', rules: [{ field, op, value }] }.

list_segments

List an audience's SAVED segments (rule-based and static) with live member counts. Use to resolve a segment by name (e.g. 'active customers') before targeting a campaign at it via segmentId. For an ad-hoc, unsaved condition check use preview_segment instead.

personalize_campaign

Draft PER-RECIPIENT warm bodies for a campaign from a list of subscribers + their first-party usage stats — the LLM rewrites the body for each. Flips the campaign to per-recipient mode and lands each body in the shared Review queue (drafted). Nothing sends. Needs a model wired.

list_outreach_campaigns

List all cold outreach campaigns (the 1:1-at-bulk Campaign surface), newest first, each with its sourced/to-review/sent/replied rollup. Use to find a campaign id before sourcing, reviewing, or launching.

get_outreach_campaign

Get one cold outreach campaign's settings (name, brief, sender identity, cold sending domain, daily cap) plus its per-stage rollup (sourced/drafted/approved/denied/sent/replied). Use to inspect a campaign before acting on it.

create_outreach_campaign

Create a new cold outreach campaign DRAFT. Provide a name and a brief (the ICP / goal prompt that drives sourcing + drafting). Bind the COLD sending domain (`sendingDomainId` + `fromEmail`/`replyTo` on it) — a domain that doesn't exist, or a deployment with no cold BYO-SMTP transport, is REFUSED here with a fix-link (run get_send_readiness('outreach') first to see what's missing). Optionally set `sourcingConfig` to source via a tenant agentic skill (kind:'agentic_skill' + skillId). Starts in draft; nothing sends — source prospects, draft bodies, and review before launch.

list_subscriber_channels

List the notification channels (email/push/webhook) registered for a subscriber (contact). Use to see where a subscriber can be reached before dispatching.

add_subscriber_channel

Register a delivery channel for a subscriber. type=email|push|webhook. For webhook, endpoint must be an http(s) URL; a signing secret is returned. Optional topics restrict which notification topics this channel receives (e.g. ['order.*']).

import_contacts

Bulk-import contacts from user-supplied rows INTO an audience (mailing list). ORG-ADMIN ONLY and requires a human approval step in chat — the approval card shows how many rows and which audience before it runs. Provide `csv`: a header row with an `email` column (optional `name` + any merge-field columns), then one row per contact. Re-importing the same email updates rather than duplicates. Use when the operator pastes or supplies a list of people to add to a list. `status` sets the initial membership state for new members (default the audience's — usually subscribed/pending). This is the ONLY way to bulk-add people via the assistant; single contacts go through add_subscriber/upsert_contact.

create_segment

Save a multi-condition SEGMENT of an audience (a reusable rule-based slice, e.g. 'members tagged vip who opened the last campaign'). Requires a human approval step in chat — the approval card shows the segment name and how many members currently match (a live preview of the conditions). For a 'saved' segment, provide `conditions` (a match mode + rules); a 'static' segment has none (members are added manually later). To just PREVIEW reach without saving, use preview_segment instead. `newsletter:send` permission is required.