OdyDocs

MCP tool reference

All 20 Ody MCP tools: what each does, its arguments, required scope, annotations and test-mode behaviour.

Every tool requires one scope. tools/list only returns the tools the key can call. Results come back as JSON text in content[0].text, and the same data is also in structuredContent.result.

Annotation key: R read-only · W writes to the workspace · $ spends money or reaches the outside world (openWorldHint) · D destructive · I idempotent (safe to repeat).

#At a glance

ToolScopeHintsTest key
workspace_summaryconversations:readRSame
list_contactscontacts:readRSame
create_contactcontacts:writeWSame (real write)
update_contactcontacts:writeW · ISame (real write)
delete_contactcontacts:writeW · D · ISame (real delete)
list_conversationsconversations:readRSame
get_conversationconversations:readRSame
set_conversation_statusconversations:writeW · ISame (real write)
search_messagesconversations:readRSame
wait_for_messageconversations:readRSame
send_messagemessages:sendW · $Simulated
list_numbersnumbers:readRSame
search_numbersnumbers:manageR · $Same (live inventory)
buy_numbernumbers:manageW · $Simulated
get_messaging_statusnumbers:manageRSame
submit_10dlc_registrationnumbers:manageW · $ · IMock filing
place_callcalls:placeW · $Simulated
get_agentagent:manageRSame
configure_agentagent:manageW · $ · ISaves; publish simulated
connect_agent_to_numberagent:manageW · $ · IReal routing change
Test keys still write data

A test key simulates anything that sends, spends or dials. Contact, conversation-status and routing changes are real writes to the workspace. Use a dedicated test workspace if you don't want them in your live data.

#Orientation

#workspace_summary

A snapshot of the workspace: contact count, open and done conversation counts, unread total, active numbers, and message and call volume over the last 7 days. Good as an assistant's first call.

Arguments: none.

#Contacts

#list_contacts

Lists or searches contacts.

  • q string — Full-text search over names, company, phones and emails.

#create_contact

Creates a contact. Provide at least one of firstName, lastName, company, phone, email.

  • firstName, lastName, company string
  • phone string — E.164.
  • email string

#update_contact

Updates a contact. Only the fields you provide change. phone and email replace the contact's phone and email lists.

  • contactId uuid required
  • firstName, lastName, company, phone, email string

#delete_contact

Permanently deletes a contact. Its conversations remain. This can't be undone.

  • contactId uuid required

#Conversations

#list_conversations

Lists recent conversations, most recent activity first.

  • status "open" | "done"

#get_conversation

The full thread: messages, calls, voicemails, transcripts and AI summaries.

  • conversationId uuid required

#set_conversation_status

Marks a conversation open or done.

  • conversationId uuid required
  • status "open" | "done" required

#search_messages

Case-insensitive search over message bodies, voicemail transcripts and call notes, newest first. Each match includes its conversationId.

  • q string required
  • limit integer

#wait_for_message

Long-polls for a new inbound message in a conversation, for up to 25 seconds. It returns { activities, lastActivityId } as soon as something arrives, or { activities: [], timedOut: true, lastActivityId }. Call it again with afterActivityId: lastActivityId to keep waiting without missing anything.

  • conversationId uuid required
  • afterActivityId uuid — Only return activities newer than this. Defaults to the newest activity at call time.
  • timeoutSeconds integer — 1–25, default 20.

#Texting

#send_message

Sends an SMS. Provide body, plus either conversationId or to (E.164). With to, the conversation is created from the workspace's number. Live texting needs 10DLC.

  • body string required
  • conversationId uuid
  • to string — E.164.

#Numbers and 10DLC

#list_numbers

The workspace's phone numbers, with routing (voiceMode).

#search_numbers

Searches carrier inventory, with Ody's monthly price per result: local numbers are $5/mo (the first is included in the plan), toll-free $10/mo (calling only).

  • type "local" | "toll_free" — Default local.
  • country string — ISO 3166 alpha-2, default US.
  • startsWith string — Area-code prefix (local only).
  • contains string, locality string, state string
  • limit integer

#buy_number

Buys a number. Spends real money: it's billed to the workspace's plan like an in-app purchase. The same plan, identity and App Store gates as the REST endpoint apply.

  • phoneNumber string required — E.164, from search_numbers.
  • type "local" | "toll_free" — A hint; Ody works out the real type from the number.

#get_messaging_status

10DLC status: step, canText and any failure reasons. See Messaging (10DLC).

#submit_10dlc_registration

Files the brand and campaign. Submitting is a purchase. On a free trial it ends the trial and charges the plan plus the $20 per-number setup fee right away, so the assistant must tell the user and pass acknowledge_trial_end: true. Fields match POST /messaging/registration.

  • business object required
  • campaign object
  • acknowledge_trial_end boolean — Required on a trial, after the user has been told.

#Calls and agent

#place_call

The published AI agent calls to and holds the conversation. Billed in AI credits like an inbound AI call. See Place an AI call.

  • to string required — E.164.
  • from string — One of the workspace's numbers.

#get_agent

The agent's configuration (name, greeting, tone, voice, jobs, hours, publish status) plus this cycle's credit usage.

#configure_agent

Creates or updates the agent. Only the fields you provide change. Pass publish: true to push the configuration live in the same call.

  • name, greeting, tone, voice, language string
  • timezone string — IANA, for example America/Chicago.
  • inHoursAction, offHoursAction "agent" | "voicemail" | "app" | "forward"
  • enabled boolean
  • jobs array of {name, instructions}
  • publish boolean

#connect_agent_to_number

Routes a number's inbound calls to the agent. The agent must exist; publish it for live answering.

  • phoneNumber string required — One of the workspace's numbers.

#Errors

A tool that fails returns a normal result with isError: true and a readable message, so the model can explain or recover:

JSON
{
  "content": [{ "type": "text", "text": "Unauthorized: this API key does not have the 'messages:send' scope required by send_message. Ask the workspace admin for a key with that scope." }],
  "isError": true
}

Protocol-level problems (unknown tool, missing name) come back as JSON-RPC errors instead. See Protocol details.

Last updated Wed Oct 14 2026 00:00:00 GMT+0000 (Coordinated Universal Time)Something wrong on this page? Tell us