Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Quo MCP server

Vendor MCP
Open markdown

The Quo MCP connector routes your AI agent's tool calls to Quo's own MCP server through Scalekit. Each user signs in to Quo once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 27 tools.

Tools
27
What they doRead · write · destructive
11 · 11 · 511 read11 write5 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Quo MCP connection

    In AgentKit > Connections, create a Quo MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for Quo MCP server, so you don't need to register an OAuth app.

  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'quomcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Quo MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'quomcp_list_contacts',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • quomcp_fetch_call_transcriptsFetch call transcripts for a Quo inbox.Read-only

    Fetch Call Transcripts

    Fetch call transcripts for a Quo inbox. Requires the Quo Business plan and calls where transcription was enabled. Optionally filter by `userId` to return only calls handled by a specific team member (use `list-users` to look up user IDs). Each result row is `id | participant | direction | status | createdAt | duration | conversationId`; the leading `id` is the call's activity ID (AC…) — pass it to `create-task` as `activityId` to link a follow-up task to that specific call. When `participantPhoneNumber` is omitted, the tool aggregates across participants discovered from conversations, and the trailing `conversationId` (CN…) is populated for thread-level task linking. Set `createdAfter` to bound the window — the tool filters conversation discovery by that time server-side, so a call whose conversation is old but had recent activity is still found. Single-participant queries leave the `conversationId` column blank since the per-call `activityId` is already a precise link target. To page through additional results, use `participantPhoneNumber` + `pageToken` for a single participant, or `conversationPageToken` if you hit the conversation-discovery safety cap. Timezone: `createdAfter`/`createdBefore` are treated as UTC — pass ISO 8601 with a 'Z' suffix or an explicit offset — and every timestamp in results is UTC. When the user asks in relative terms (e.g. 'yesterday', 'this week'), scope the window to THEIR local timezone and convert to the matching UTC instants before calling; if you don't know their timezone, ask. Present returned times in the user's local timezone. When showing a phone number to the user, render it as a click-to-call link, e.g. [(555) 555-5555](tel:+15555555555). Pass the bare E.164 value (not a tel: URI) into tool parameters.

    Inputs

    inboxPhoneNumberstringrequired
    Your Quo inbox number or phone-number ID to find transcripts for (E.164 like '+15555555555', or a PN... ID). Use list-inboxes to discover available numbers.
    conversationPageTokenstring
    Optional: token to fetch older conversations when doing multi-participant discovery. Use this if the response shows 'More conversations available'. Only used when participantPhoneNumber is NOT specified.
    createdAfterstring
    Optional: filter calls created after this ISO 8601 datetime with offset (e.g. '2024-01-01T00:00:00Z').
    createdBeforestring
    Optional: filter calls created before this ISO 8601 datetime with offset (e.g. '2024-01-01T00:00:00Z').
    excludeDoneConversationsboolean
    Optional, whole-inbox queries only: set true to exclude conversations currently marked done or snoozed. Leave false or omit it to include all conversations. Specific-contact queries always return that contact's full transcript history regardless of this value. If the user asks for open, active, outstanding, or inbox conversations and it is unclear whether done conversations should be included, ask before setting this.default false
    maxResultsnumber
    Maximum number of calls to fetch transcripts for (default: 100, max: 100 when using pagination)default 100
    pageTokenstring
    Optional: token from previous response to fetch the next page of results. Can only be used with participantPhoneNumber (single-participant queries). Not supported when fetching across all participants.
    participantPhoneNumberstring
    Optional: specific participant phone number to filter conversations (E.164 format). REQUIRED when using pageToken for pagination.
    userIdstring
    Optional: filter calls by a specific team member's user ID (US… format). Matches the user who answered an incoming call or placed an outgoing one; calls handled by an AI agent match no user. Note this covers transcribed calls only, so it is not a complete record of a team member's call activity — use Quo Analytics for reporting on call volume or answer rates. Use `list-users` to look up user IDs.
  • quomcp_fetch_messagesFetch message history for a Quo inbox.Read-only

    Fetch Messages

    Fetch message history for a Quo inbox. Two modes: • Single contact (`participantPhoneNumber` set) — DEPTH: returns that contact's full message history, most-recent-first, with pagination via `pageToken` (up to 100 per page). Each message is `id | participant | direction | timestamp` followed by the text; the leading `id` is the message's activity ID (AC…) — pass it to `create-task` as `activityId`. A message with MMS attachments is followed by one indented `media: <mime-type> <url>` line per attachment; text-only messages have none. A message may carry both text and attachments — when it does, the body is the text and the media lines follow it. ALWAYS pass the attachment URL through to the user as a clickable markdown link (e.g. [image/png](https://example.com/image.png)); stating that an attachment exists without giving its URL is not useful, since the user cannot open a link they were not shown. Never shorten, truncate, or omit the URL. When an attachment arrives with no accompanying text the body shows `(no text)`; describe that to the user as a photo or file, not as an empty message. • Whole inbox (`participantPhoneNumber` omitted) — BREADTH: returns the most-recent messages for EVERY contact active in the window, grouped by contact (up to 10 messages each, up to 50 contacts), so a daily-summary query never silently drops a contact. Each contact's conversation ID (CN…) is on its header for `create-task` linking. A contact with more than 10 in-window messages is flagged (`[more than 10 …]`) — re-query that contact with `participantPhoneNumber` for the full thread. If more than 50 contacts were active, an `[incomplete: …]` line reports how many were left out; narrow the date range or query specific contacts. `maxResults` is ignored in this mode. Set `createdAfter` to bound the window — the tool filters conversation discovery by that time server-side, so a contact with a recent message is found even when their conversation is old. Without `createdAfter`, discovery falls back to the most recent conversations. Timezone: `createdAfter`/`createdBefore` are treated as UTC — pass ISO 8601 with a 'Z' suffix or an explicit offset — and every timestamp in results is UTC. When the user asks in relative terms (e.g. 'yesterday', 'this week'), scope the window to THEIR local timezone and convert to the matching UTC instants before calling; if you don't know their timezone, ask. Present returned times in the user's local timezone. When showing a phone number to the user, render it as a click-to-call link, e.g. [(555) 555-5555](tel:+15555555555). Pass the bare E.164 value (not a tel: URI) into tool parameters.

    Inputs

    inboxPhoneNumberstringrequired
    Your Quo inbox number or phone-number ID to fetch messages for (E.164 like '+15555555555', or a PN... ID). Use list-inboxes to discover available numbers.
    conversationPageTokenstring
    Optional, whole-inbox queries only: the `[next_conversations: …]` token from a previous whole-inbox response, to continue where it stopped. Pass the same other parameters as that call.
    createdAfterstring
    Optional: filter messages created after this ISO 8601 datetime with offset (e.g. '2024-01-01T00:00:00Z').
    createdBeforestring
    Optional: filter messages created before this ISO 8601 datetime with offset (e.g. '2024-01-01T00:00:00Z').
    excludeDoneConversationsboolean
    Optional, whole-inbox queries only: set true to exclude conversations currently marked done or snoozed. Leave false or omit it to include all conversations. Single-thread queries always return the thread's full history regardless of this value. If the user asks for open, active, outstanding, or inbox conversations and it is unclear whether done conversations should be included, ask before setting this.default false
    maxResultsnumber
    Maximum number of messages to fetch (default: 100, max: 100). Only applies to single-thread queries (participantPhoneNumber or participantPhoneNumbers set). Ignored for whole-inbox queries, which return up to 10 messages per conversation.default 100
    pageTokenstring
    Optional: token from previous response to fetch the next page of results. Can only be used with participantPhoneNumber or participantPhoneNumbers (single-thread queries). Whole-inbox queries continue with conversationPageToken instead.
    participantPhoneNumberstring
    Optional: one contact's phone number (E.164), returning your 1:1 thread with them. For a group thread use participantPhoneNumbers instead. One of the two is REQUIRED when using pageToken.
    participantPhoneNumbersarray
    Optional: the COMPLETE member list of a group thread (E.164, up to 10), excluding the inbox you are querying. Quo matches a thread by its exact participant set, so include every other member — omitting or adding one returns a different thread or none. Whole-inbox results list each group's members on its header. Do not combine with participantPhoneNumber.
    userIdstring
    Optional: filter to messages sent by a specific team member's user ID (US… format). Incoming messages are excluded when this filter is set, since the API does not associate them with a sender user ID. Use `list-users` to look up user IDs.
  • quomcp_fetch_missed_callsFetch missed incoming calls for a Quo inbox, each enriched with the voicemail the caller left (transcript + recording URL) when there is one.Read-only

    Fetch Missed Calls

    Fetch missed incoming calls for a Quo inbox, each enriched with the voicemail the caller left (transcript + recording URL) when there is one. Only returns incoming calls whose status is 'missed', 'no-answer', or 'abandoned' — this filter is fixed and cannot be changed or broadened. Use it for questions like 'what calls did I miss yesterday?' or 'any voicemails this week?'. Each result is a row `id | status | direction | participants | createdAt | duration | conversationId`; the leading `id` is the call's activity ID (AC…) — pass it to `create-task` as `activityId` to link a follow-up task to that specific call. The trailing `conversationId` (CN…) is for thread-level task linking and is populated only when discovering across multiple participants (single-participant queries leave it blank since the per-call `activityId` is already precise). Rows whose call has a voicemail are followed by an indented voicemail block (status, duration, recordingUrl, transcript). Voicemails are processed asynchronously — a voicemail with status 'in-progress' has null duration/transcript/recordingUrl, so retry in a few seconds. Missed calls where the caller hung up without leaving a message are still listed, just marked '(no voicemail)'. When `participantPhoneNumber` is omitted, the tool aggregates calls across all participants active in your `createdAfter` window — the tool filters conversation discovery by that time server-side, so a missed call whose conversation is old but had recent activity is still found. Without `createdAfter`, discovery falls back to the most recent conversations. For exhaustive single-contact pulls, use `participantPhoneNumber` + `pageToken`; if you hit the conversation-discovery safety cap, use `conversationPageToken` to continue. Timezone: `createdAfter`/`createdBefore` are treated as UTC — pass ISO 8601 with a 'Z' suffix or an explicit offset — and every timestamp in results is UTC. When the user asks in relative terms (e.g. 'yesterday', 'this week'), scope the window to THEIR local timezone and convert to the matching UTC instants before calling; if you don't know their timezone, ask. Present returned times in the user's local timezone. When showing a phone number to the user, render it as a click-to-call link, e.g. [(555) 555-5555](tel:+15555555555). Pass the bare E.164 value (not a tel: URI) into tool parameters.

    Inputs

    inboxPhoneNumberstringrequired
    Your Quo inbox number or phone-number ID to list calls for (E.164 like '+15555555555', or a PN... ID). Use list-inboxes to discover available numbers.
    conversationPageTokenstring
    Optional: token to fetch older conversations when doing multi-participant discovery. Use this if the response shows 'More conversations available'. Only used when participantPhoneNumber is NOT specified.
    createdAfterstring
    Optional: filter calls created after this ISO 8601 datetime with offset (e.g. '2026-05-19T00:00:00Z').
    createdBeforestring
    Optional: filter calls created before this ISO 8601 datetime with offset (e.g. '2026-05-20T00:00:00Z').
    maxResultsnumber
    Maximum number of calls to return after filtering (default: 100, max: 100 when using pagination).default 100
    pageTokenstring
    Optional: token from previous response to fetch the next page of results. Can only be used with participantPhoneNumber (single-participant queries). Not supported when fetching across all participants.
    participantPhoneNumberstring
    Optional: specific other-party phone number to filter calls (E.164 format). REQUIRED when using pageToken for pagination.
  • quomcp_get_agent_conversationGet a Sona SMS conversation started with start-agent-conversation: its status, why it failed or ended, and, once the agent has summarized it, its title, summary and collected data.Read-only

    Get Agent Conversation

    Get a Sona SMS conversation started with start-agent-conversation: its status, why it failed or ended, and, once the agent has summarized it, its title, summary and collected data. It can run for minutes or hours, so check back every few minutes rather than polling rapidly, until the status is final (completed, failed or canceled). A failed one sent no texts; its failure reason says why. `completed` does not mean the task succeeded, so read the summary. Use fetch-messages to read the texts themselves.

    Inputs

    agentConversationIdstringrequired
    The agent conversation ID returned by start-agent-conversation (starts with AR).
  • quomcp_get_contactFetch a single Quo contact by ID, including its default fields (name, company, role, email, phone) and any custom fields configured on the workspace.Read-only

    Get Contact

    Fetch a single Quo contact by ID, including its default fields (name, company, role, email, phone) and any custom fields configured on the workspace. Use `list-contacts` first if you need to discover contact IDs. When showing a phone number to the user, render it as a click-to-call link, e.g. [(555) 555-5555](tel:+15555555555). Pass the bare E.164 value (not a tel: URI) into tool parameters.

    Inputs

    contactIdstringrequired
    The Quo contact ID to retrieve.
  • quomcp_get_inbox_settingsGet a Quo inbox's settings: its name, its business hours (whether they are enforced, the timezone, and each day's open window) and its call recording (whether calls are recorded automatically, and how callers are told a call may be recorded, for inbound and outbound calls).Read-only

    Get Inbox Settings

    Get a Quo inbox's settings: its name, its business hours (whether they are enforced, the timezone, and each day's open window) and its call recording (whether calls are recorded automatically, and how callers are told a call may be recorded, for inbound and outbound calls). Read these before changing anything with update-inbox-settings, so you can tell the user what will change. Use list-inboxes to find the inbox. When showing a phone number to the user, render it as a click-to-call link, e.g. [(555) 555-5555](tel:+15555555555). Pass the bare E.164 value (not a tel: URI) into tool parameters.

    Inputs

    inboxstringrequired
    The inbox: its number in E.164 (e.g. '+15555555555'), its phone-number ID (PN…), or a recognizable local format. Use list-inboxes to discover inboxes.
  • quomcp_list_contact_notesList the notes on a Quo contact.Read-only

    List Contact Notes

    List the notes on a Quo contact. Each note is a row `id | createdAt | updatedAt | authorId` followed by its text, indented; a note with attachments is followed by one indented `media: <mime-type> <url>` line per attachment. `authorId` is the Quo user (US…) who wrote the note — use `list-users` to show their name. Pass a note's `id` to `update-contact-note` to change it. Use `list-contacts` or `get-contact` to find the contact ID. Supports pagination via `pageToken` (1–50 results per page).

    Inputs

    contactIdstringrequired
    The Quo contact ID whose notes to list.
    maxResultsinteger
    Maximum notes to return per page (1-50, default 10).default 10
    pageTokenstring
    Optional: token from a previous response to fetch the next page.
  • quomcp_list_contactsList contacts in the Quo workspace, optionally filtered by `externalIds` or `sources`.Read-only

    List Contacts

    List contacts in the Quo workspace, optionally filtered by `externalIds` or `sources`. Returns a compact pipe-separated table (id | name | company | role | email | phone) and supports pagination via `pageToken` (1–50 results per page). When showing a phone number to the user, render it as a click-to-call link, e.g. [(555) 555-5555](tel:+15555555555). Pass the bare E.164 value (not a tel: URI) into tool parameters.

    Inputs

    externalIdsarray
    Optional: filter by a list of external identifiers from an external system.
    maxResultsinteger
    Maximum contacts to return per page (1-50, default 10).default 10
    pageTokenstring
    Optional: token from a previous response to fetch the next page.
    sourcesarray
    Optional: filter by contact source (origin/creation method).