Verify the MCP pipe; echoes a message and returns the resolved org and actor type.
Tools your agent can call.
Munin exposes 108 tools at /mcp. Audiences gate which tokens see which tools — admin keys see everything, delegated end-user tokens see only self-service tools.
Admin tools 103
Available to admin API keys and admin sessions. Includes everything that writes or that reads across the org.
List CMS collections (content types) defined for your org.
Input schema
Read one collection by id or slug, including its field definitions.
Input schema
Define a new collection. Fields is an array of { name, type, required?, options? } — see field types: text, rich_text, markdown, number, integer, boolean, date, datetime, select, multi_select, asset, reference, array, json.
Input schema
Patch a collection. Field migration is lossy: dropped or renamed fields stay in entries' `data` jsonb but stop being read by the projection layer.
Input schema
Delete a collection. Cascades to all entries, versions, and references.
Input schema
List entries. Filters: collection (id or slug), status, locale. Drafts and scheduled entries are returned to admins; the public delivery API only ever returns published.
Input schema
Read one entry. Data is projected through the collection's current field schema.
Input schema
Create a new entry in a collection. `data` is keyed by field name; required fields must be present. Pass `status: "published"` to publish on creation; default is draft.
Input schema
Update an entry. Pass `ifVersion` (the current version you read) for optimistic concurrency. Updating `data` re-validates against the collection schema, regenerates search_text + embedding, and rewrites references.
Input schema
Flip an entry to status="published". Stamps publishedAt and fires cms.entry.published.
Input schema
Revert an entry to status="draft". Clears publishedAt; fires cms.entry.unpublished.
Input schema
Schedule an entry to flip to published at a future ISO 8601 datetime. The schedule worker drains due rows every minute.
Input schema
Delete an entry. Cascades to its versions and references.
Input schema
List all prior versions of an entry, newest first.
Input schema
Roll an entry back to an earlier version. Creates a new current version with that historical data.
Input schema
List media-library assets in your org.
Input schema
Mint a presigned upload URL for a new asset. The asset row is created in `uploaded:false` state; PUT the file body to `uploadUrl`, then call cms_complete_asset_upload to mark it live.
Input schema
Mark a previously-requested asset upload as complete.
Input schema
Delete an asset and remove the underlying file from storage.
Input schema
List configured locales for your org. The default locale is used when an entry omits one.
Input schema
Add a locale. Code is ISO 639-1 (e.g. "en") or BCP-47 ("en-US"). The first locale is the default unless overridden.
Input schema
Set which locale is treated as the org's default for new entries.
Input schema
List entries that link to the given entry. Useful before deleting — see "what would break".
Input schema
Hybrid full-text + semantic search across CMS entries. Returns drafts and published; the public delivery API runs the same engine but hard-filters to published-only.
Input schema
List conversations for your org, newest activity first. Filter by status (open / snoozed / closed / spam), assignee, or topic.
Input schema
Read one conversation including every public + internal message.
Input schema
Append a message to a conversation. Pass `internal: true` to leave a staff-only note (drafts, side comments) — end-user agents never see internal messages.
Input schema
Assign a conversation to a user (pass user id) or unassign (pass null). Useful for routing escalated conversations.
Input schema
Change a conversation's status. `snoozeUntil` (ISO 8601) is required when status is "snoozed".
Input schema
Flag a conversation as needing human attention. Use this when you have reached the limit of what you can resolve autonomously — billing decisions, refunds outside policy, sensitive complaints, anything where a human teammate should step in. Appends an internal system note (visible only to staff) recording your stated `reason`, sets the conversation's "needs human attention" flag (which pins it to the top of the dashboard's Conversations page), and emits `conversation.handover_requested`. Also pass `suggestedReply` — your best guess at what a human teammate could send to resolve the issue. The team sees this as a starting draft they can edit, approve, or rewrite. Idempotent — calling again on an already-flagged conversation is a no-op. The flag clears automatically once a human teammate replies or closes the conversation.
Input schema
Substring search over message bodies. Returns the matching messages newest first; use conv_get_conversation to load surrounding context.
Input schema
List conversation channels configured for your org. Currently shipping adapters: email and chat (widget). The `voice` and `sms` channel types are reserved for upcoming adapters.
Input schema
Add a new conversation channel. Currently shipping adapters: `email` and `chat` (widget). Channel-specific configuration goes in `config`. The `voice` and `sms` channel types are reserved and not yet wired to an adapter.
Input schema
List conversation topics (Billing, Support, Refunds, …) for your org.
Input schema
Add a new conversation topic. Slug must be lowercase letters, digits, hyphens.
Input schema
Tag a conversation with one of the org's existing topics, or pass `topicId: null` to clear the topic. Use `conv_list_topics` first to see what topics exist; topics must be pre-created via `conv_create_topic`.
Input schema
Replace an inbound message's body with a signature-stripped version. Used by the strip-email-signature curator skill — runs after the regex quote-stripper to clean up the trailing sign-off / contact block. The original body is kept in `metadata.preStripBody` for audit; the removed signature (if provided) is stored in `metadata.signatureText`. Refuses if the new body is empty, more than 50% shorter than the original, or if the message isn't an end-user inbound in the caller's org.
Input schema
Create or update an email channel's transport configuration. Pass plaintext SMTP / IMAP passwords; the server encrypts them before storage and returns them redacted. Set `outbound.provider: 'mailer'` to send via Munin's configured Resend mailer instead of a custom SMTP host.
Input schema
Test an email channel's stored credentials. Attempts an SMTP connect (and an IMAP connect if inbound is configured) without sending or fetching anything. Returns `{ smtp: "ok" | error, imap: "ok" | error | "not configured" }`.
Input schema
Send a real test email through this channel's configured outbound transport (SMTP or Mailer). The message is addressed `to` the recipient you pass in. Useful for confirming credentials and deliverability end-to-end.
Input schema
Create or update a MessageBird SMS channel. Pass `channelId` to update; omit to create. The plaintext `accessKey` and `signingKey` are encrypted before storage and returned redacted. On update, omit either secret to keep the existing one.
Input schema
Verify a MessageBird channel's stored Access Key by fetching the account balance. Returns `{ ok: true, balance }` on success.
Input schema
Send a real SMS through this channel's MessageBird account. Useful for end-to-end deliverability checks.
Input schema
Create or update a Twilio SMS channel. Pass `channelId` to update an existing channel; omit to create one. The plaintext `authToken` is encrypted before storage and is returned redacted. On update, omit `authToken` to keep the existing one. Either `fromNumber` (E.164) or `messagingServiceSid` is required.
Input schema
Verify a Twilio SMS channel's stored Account SID + Auth Token by fetching the account record from Twilio. Returns `{ ok: true, friendlyName, status }` on success.
Input schema
Send a real SMS through this channel's Twilio account. The recipient must be a number Twilio is permitted to reach (verified caller ID on trial accounts). Useful for end-to-end deliverability checks.
Input schema
Create or update a Vapi voice channel. Pass `channelId` to update; omit to create. The plaintext `apiKey` and `webhookSecret` are encrypted before storage and returned redacted. The assistant + phone number must already exist in Vapi — paste their IDs here.
Input schema
Verify a Vapi channel's stored API key and assistant by fetching the assistant from Vapi. Returns `{ ok: true, assistant }` on success.
Input schema
Initiate an outbound voice call through this channel. The Vapi assistant will run the conversation. Returns the Vapi call id and status.
Input schema
Place an outbound voice call to the contact attached to a conversation. Resolves the phone number from the conversation's contact and picks the org's active Vapi voice channel automatically. For arbitrary destinations, use `conv_voice_call_initiate` instead.
Input schema
Create a chat-widget channel and mint a widget API key (`mn_widget_*`) bound to it. Returns the plaintext key once; store it server-side and pass it as `Authorization: Bearer` when calling POST /api/v1/widget/messages from the external agent.
Input schema
Update a chat-widget channel's originAllowlist / webhookOnEscalation. Pass null to clear webhookOnEscalation. The widget API key is unchanged.
Input schema
Revoke any active widget keys bound to this channel and mint a fresh `mn_widget_*` key. Returns the new plaintext key once. Existing inflight requests using the old key keep working until revocation lands.
Input schema
Generate a fresh per-channel HMAC secret used to verify browser-side `data-user-hash` values against `data-external-id`. The previous secret is replaced atomically; any previously-issued user hashes stop verifying immediately and the operator must re-render their pages with newly-computed hashes. Returns the new plaintext once.
Input schema
List contacts in your org, newest-updated first. Filter by company or tag.
Input schema
Read one contact, including AI fields, tags, custom fields, and compliance flags.
Input schema
Find an existing contact by email and/or phone before creating a new one. Returns null if no match.
Input schema
Create a new contact. Search with crm_find_contact first to avoid duplicates.
Input schema
Update fields on a contact. Setting `doNotContact: true` also stamps `unsubscribedAt`; setting it false clears it. Pass `mode: 'fill-null'` from automated/curator contexts to refuse overwriting existing non-null values (only null/empty fields are filled). Default `mode: 'overwrite'` applies the patch as-is and is appropriate for human-driven edits.
Input schema
Bulk-create contacts with dedupe + compliance checks: rows whose email or phone already match a do_not_contact contact are skipped, as are rows that would duplicate an existing contact.
Input schema
Substring search across name, email, phone, and title. Returns contacts ordered newest-updated first.
Input schema
List companies in your org.
Input schema
Create a new company.
Input schema
List sales pipelines for your org with their stages in position order.
Input schema
Create a new sales pipeline with at least one stage. Stages are inserted in array order; mark a stage `winLoss: "won"` or `"lost"` to record terminal outcomes.
Input schema
List deals, optionally filtered by pipeline or stage.
Input schema
Create a new deal in a pipeline. If `stageId` is omitted, the deal lands in the pipeline's first stage by position.
Input schema
Move a deal to a new stage. If the destination stage is a won/lost terminal, `closedAt` is stamped automatically.
Input schema
Record an activity (note / call / email / meeting / task) against a contact, company, or deal. If `contactId` is set, the contact's `lastContactedAt` is also bumped.
Input schema
List CRM activities filtered by contact, deal, or company.
Input schema
Set the AI-generated summary and/or next-action for a contact, company, or deal. These live in dedicated columns so agents do not pollute the human-edited description.
Input schema
File a structured proposal that two contacts are the same person. Pass `confidence` ("high" | "medium"), `evidence` (the matched signals — same email, same phone, similar name, etc.), `recommendedKeeperId` (which row to keep), and optionally `recommendedPatch` (fields to copy onto the keeper from the duplicate). Idempotent on the (contactA, contactB) pair while a pending proposal exists — calling again upserts the existing pending row. The CRM clean-contact-data curator runs this on a periodic cadence; see `skill://crm/clean-contact-data`.
Input schema
List CRM merge proposals, defaulting to `status: "pending"` (the operator review queue). Returns each proposal with both contacts embedded as summaries — no extra `crm_get_contact` calls needed. Pass `status: "dismissed"` once per curator pass to skip pairs the operator has already rejected.
Input schema
Atomically apply a pending merge proposal: copies `recommendedPatch` fields onto the keeper, archives the duplicate (adds `dedup-archived-YYYY-MM` tag, sets `customFields.mergedInto = <keeperId>`, sets `doNotContact: true`), and marks the proposal `applied`. Activities and deals stay on whichever contactId they were originally logged under — that's a documented v1 limitation. Throws if the proposal is not in `pending` status.
Input schema
Mark a pending merge proposal as dismissed (the operator decided these are not the same person). The next CRM hygiene curator pass queries dismissed proposals and skips refiling the same pair. Optional `reason` is stored for audit. Throws if the proposal is not in `pending` status.
Input schema
List saved contact segments. A segment is a named CRM filter — used as the audience for outreach campaigns and other targeting workflows. Returns each segment with its filter definition.
Input schema
Read one segment, including its filter definition.
Input schema
Create a saved contact segment. `filter` supports tagsAny (any-of match), tagsAll (all-of match), companyId, searchQuery (substring over name/email/title), and contactedSince (ISO-8601 — narrows to contacts NOT contacted since that timestamp). Combine fields and they AND together.
Input schema
Patch a segment: rename, edit description, or replace the filter.
Input schema
Delete a segment. Outreach campaigns referencing it will fail until reassigned.
Input schema
Resolve a segment to its current contacts. ALWAYS excludes suppressed contacts (do_not_contact OR unsubscribed) AND contacts without a recorded lawful basis (consent_lawful_basis IS NULL). Use this — not crm_list_contacts — to materialize an outreach audience: the suppression and consent floors are non-overridable here.
Input schema
Record the lawful basis and source for contacting this person. Required before they can appear in any outreach segment. `lawfulBasis` is one of `consent`, `legitimate_interest`, or `contract`. `source` is a short label (e.g. "imported-2026-q2", "web-form-trial-signup", "event-attendee-summit-2025"). Logs a CRM activity for audit.
Input schema
List knowledge-base spaces in your org.
Input schema
Create a new knowledge-base space. Slug must be unique within your org and only contain lowercase letters, digits and hyphens.
Input schema
List knowledge-base documents in your org, newest-updated first. Optionally filter by space or tag.
Input schema
Read one knowledge-base document, including its full body, tags, and current version. End-user agents see only documents whose `audiences` includes `'self_service'`.
Input schema
Read a knowledge-base document by its space slug and document slug — used when a stable identifier (e.g. 'agent-runtime/system-prompt') is needed instead of the document UUID. Returns null when the document does not exist.
Input schema
Search the knowledge base by natural-language query. Combines full-text search and vector similarity for the best of both. End-user agents see only documents whose `audiences` includes `'self_service'`.
Input schema
Create a knowledge-base document inside a space. Body should be markdown. Set `audiences: ['admin', 'self_service']` to expose it to end-user agents; defaults to `['admin']` (admin-only).
Input schema
Update a knowledge-base document. Pass `ifVersion` (the current version you read) for optimistic concurrency; the call fails if it has changed.
Input schema
Delete a knowledge-base document. Pass `ifVersion` for optimistic concurrency. Cascades to chunks and versions.
Input schema
List all prior versions of a knowledge-base document, newest first.
Input schema
File a draft FAQ-style document into the `kb-curation-inbox` KB space (admin audience only). Used after a curation pass over resolved-handover conversations. The space is created on first use. See `skill://kb/review-content` for the procedure. The candidate is NOT visible to end-user agents until it's promoted with `kb_publish_curation_candidate`.
Input schema
Promote a reviewed curation candidate into a target KB space. Copies the doc to the target space (default audiences `['admin', 'self_service']` so the self-service agent can find it), drops the `curation`/`candidate` tags, and removes the candidate from the inbox. The target space must already exist.
Input schema
Roll a document back to an earlier version. Creates a new current version with that historical content.
Input schema
List outbound-campaign definitions for this org. Each row carries the brief, the targeted CRM segment, the email channel used to send, cadence rules, CTA URL, and the enabled flag. The draft-initial curator only drafts proposals for `enabled = true` campaigns.
Input schema
Read a single campaign by id, including brief and cadence rules.
Input schema
Create an outbound-campaign definition. Operators write `brief` as a one-paragraph human description of intent (the curator personalises per contact from this). `segmentId` chooses the audience; the curator calls `crm_list_contacts_in_segment` (which always enforces suppression+consent floor) to materialize it. `channelId` must reference an email channel. New campaigns default `enabled: false` so the curator does not start drafting until you flip it on.
Input schema
Patch fields on a campaign — rename, swap segment, adjust cadence, toggle enabled.
Input schema
List drafted outreach proposals (initials in PR2; replies in PR3). Defaults to all statuses. The draft-initial curator queries `status: "pending", kind: "initial"` filtered by `(campaignId, contactId)` to dedupe before drafting a new candidate. The operator review surface queries `status: "pending"`.
Input schema
File one drafted initial outreach email per (campaign, contact) for human approval. Idempotent: re-proposing the same (campaign, contact, kind=initial) while a pending row exists throws — call `outreach_list_proposals` first to dedupe. Suppression and consent are re-checked at approve-time too; this tool refuses up-front if the contact is already suppressed.
Input schema
File a drafted reply to an inbound message on an outreach-originated conversation, for human approval. The conversation must have an `outreachCampaignId` set (it's an outreach conversation) and a CRM contact resolvable by email. Idempotent: re-proposing while a pending reply exists for the same conversation throws — the operator should approve or dismiss the existing one first. Reply approvals send via `conv_send_message` on the existing conversation; no unsubscribe footer is appended (replies thread inside the existing email chain that already carries the unsubscribe link).
Input schema
Self-service tools 8
Visible to delegated end-user tokens. Scoped to one principal and read-only or contributor at most.
Verify the MCP pipe; echoes a message and returns the resolved org and actor type.
Input schema
Flag the current conversation as needing human attention. Use this when you can't answer the end-user's question on your own — pricing exceptions, account-specific issues you can't verify, anything sensitive. Pass the exact `conversationId` you were given in the system context. Sets a "needs human attention" flag on the conversation (pinning it to the top of the team's dashboard) and posts an internal note recording your `reason`. Also pass `suggestedReply` — your best guess at what a human teammate could send to resolve the issue. The team sees this as a starting draft they can edit, approve, or rewrite. After calling this, do not keep generating replies on your own — let the user know a teammate will follow up, then stop. The flag clears once a teammate replies. The end-user does not see the system note or the suggested reply — only the team does.
Input schema
Place an outbound phone call to the contact in this conversation. Use this only when the user has asked to be called — e.g. "can you call me?". The call goes to the phone number already on file for this conversation's contact; you cannot specify an arbitrary number. The org must have an active Vapi voice channel configured. After requesting the call, tell the user briefly that a call is on the way and stop replying — the rest of the conversation happens on the phone.
Input schema
Read the CRM contact linked to the calling end-user. RLS restricts visibility to that single row.
Input schema
Update the calling end-user's own contact record. Only basic personal fields (name, phone, address) are editable from this surface — tags, ownership, custom fields, and AI fields are admin-only.
Input schema
Record an activity attributed to the calling end-user agent (e.g. a voice agent logging "spoke with customer for 4m, follow-up needed"). Auto-scoped to the end-user's own CRM contact when one exists.
Input schema
Read one knowledge-base document, including its full body, tags, and current version. End-user agents see only documents whose `audiences` includes `'self_service'`.
Input schema
Search the knowledge base by natural-language query. Combines full-text search and vector similarity for the best of both. End-user agents see only documents whose `audiences` includes `'self_service'`.