Reading as an AI? Append .md to this URL for markdown — /llms.txt
Kronos AI

Kronos MCP

Plug Kronos AI into Claude Desktop, ChatGPT, n8n, or any MCP-compatible client. Send messages, look up conversations, and fetch your WhatsApp templates directly from inside the client's chat or workflow — no glue code, no custom integrations.

Endpoint: https://mcp.kronos.com.mx/v1Transport: streamable-httpVersion: v1 (beta)

What is MCP?

The Model Context Protocol (MCP) is an open standard for connecting AI clients to tool servers. A client speaks MCP, a server exposes tools, and the client's underlying model decides when to call them. It is what lets Claude Desktop's chat send a real message, or an n8n workflow call into your CRM without you writing the glue yourself.

Kronos MCP is the server side of that protocol for the Kronos inbox. Once you plug it into a client like Claude Desktop, ChatGPT, or n8n, the model can ask Kronos to send a WhatsApp message, look up a sent message, list your conversations, or pick a template — using the exact same account credentials that power the Kronos dashboard. No glue code, no scopes you can't see.

Setup in Claude Desktop

  1. Open Claude Desktop Settings Developer Edit Config. This opens claude_desktop_config.json.
  2. Add Kronos under mcpServers (snippet below). Replace kronos_sk_live_xxx with a real key created from Settings → API Keys.
  3. Restart Claude Desktop. The Kronos tools appear in the chat composer under the tools menu.

Config snippet

{
  "mcpServers": {
    "kronos": {
      "url": "https://mcp.kronos.com.mx/v1",
      "headers": { "Authorization": "Bearer kronos_sk_live_xxx" }
    }
  }
}

Other clients

Any client that speaks MCP's streamable-HTTP transport can use Kronos with the same URL + Bearer header. ChatGPT (with custom connectors) and n8n are common examples — point them at https://mcp.kronos.com.mx/v1 and include the same Authorization: Bearer … header.

Discovery manifest

For tooling that auto-discovers servers, the discovery manifest lives at:

curl https://mcp.kronos.com.mx/.well-known/mcp.json

Authentication

Kronos MCP uses the same API keys as the REST API. Create one from Settings → API Keys. The plaintext key is shown ONCE at creation — store it in your password manager or secrets store immediately. Server-side only: never embed it in a browser bundle or commit it to a repo.

Header format

Authorization: Bearer kronos_sk_live_<random>

Available scopes

Each key carries one or more scopes. Tools the key doesn't have a scope for never appear in tools/list and calling them returns the same generic -32001 as any other auth failure — we never reveal which scope is missing.

account:readOpt-in

Read account setup, aggregate metrics, agents, and connected inbox metadata.

messages:send

Send messages, including templates.

messages:read

Look up a message by id.

conversations:read

List conversations and metadata.

templates:read

List approved WhatsApp templates.

calls:initiateOpt-in · costs money

Place outbound voice calls with one of your AI agents.

calls:read

List the voice numbers connected to your account.

integrations:connectOpt-in

Start safe integration connection flows.

agents:writeOpt-in

Create draft agents and update configuration.

agents:assignOpt-in

Assign agents to inboxes or conversations.

Scopes & tools matrix

ToolScope requiredPurpose
get_account_overviewaccount:readRead safe account setup, aggregate metrics, agents, and inbox metadata.
start_integration_connectionintegrations:connectReturn a safe URL to start an integration login flow.
create_draft_agentagents:writeCreate an inactive draft AI agent.
update_agent_configurationagents:writeUpdate safe editable fields on an account-owned agent.
reassign_agentagents:assignAssign an agent to an inbox or specific conversations.
send_messagemessages:sendSend a text / template / media message.
send_templatemessages:sendConvenience wrapper for an approved WhatsApp template.
get_messagemessages:readLook up an outbound message by id.
list_conversationsconversations:readPaginate conversation metadata (no message bodies).
list_templatestemplates:readList approved WhatsApp templates for a WABA.
initiate_callcalls:initiatePlace an outbound voice call with one of your AI agents.
list_voice_numberscalls:readList the voice numbers connected to your account.
search_docsdocs:readSemantic search over the public Kronos docs (RAG). Auto-included on every key.

Issue keys with the minimum scopes the client needs. A key with only conversations:read cannot send messages or read message bodies — the inbox stays read-only and metadata-only.

Tool reference

Every tool is invoked through the JSON-RPC tools/call method. The wire envelope:

{
  "jsonrpc": "2.0",
  "id":      1,
  "method":  "tools/call",
  "params":  { "name": "<tool>", "arguments": { /* per-tool */ } }
}

On success, the response carries result.content[0].text as a JSON-encoded string — parse it client-side. Errors carry the standard JSON-RPC error.code / error.message shape (see Errors).

get_account_overviewscope: account:read

Read the current account's onboarding state, aggregate counts, agents, and connected inbox metadata. This is the safe discovery tool for AI-native clients and does not return message bodies, prompts, access tokens, API keys, or platform account ids.

Arguments

{}

Success payload shape

// JSON.parsed from result.content[0].text
{
  account: {
    user_id: string,
    display_name: string | null,
    company_name: string | null,
    onboarding_state: "onboarding" | "dashboard",
    onboarding_completed_at: string | null
  },
  counts: {
    agents_total: number,
    agents_active: number,
    integrations_total: number,
    connected_channels: string[],
    conversations_total: number,
    messages_7d: number,
    contacts_total: number,
    open_followups: number,
    pending_kron_cards: number,
    voice_calls_inbound_30d: number,
    voice_calls_outbound_30d: number
  },
  onboarding: { exists: boolean, is_first_onboarding: boolean, use_cases: string[] },
  agents: Array<{ id: string, name: string, is_active: boolean, model_id: string | null }>,
  integrations: Array<{ id: string, platform: string, account_name: string | null }>
}

Account action toolsscopes: integrations:connect · agents:write · agents:assign

These tools expose the same Tool Kernel actions used by Kron and the REST API. They always run against the authenticated account. User-mode API keys must not pass user_id; admin MCP calls require user_id at the dispatcher layer.

start_integration_connection

Scope: integrations:connect

{
  provider: "instagram" | "facebook" | "messenger" | "whatsapp" | "gmail" | "shopify" | "telegram" | "mcp",
  return_to?: string
}

create_draft_agent

Scope: agents:write

{
  name: string,
  description?: string,
  prompt?: string
}

update_agent_configuration

Scope: agents:write

{
  agent_id: string,
  name?: string,
  description?: string,
  prompt?: string,
  is_active?: boolean,
  memory_level?: "disabled" | "simple" | "advanced" | "pro",
  followup_mode?: "disabled" | "classic" | "agentic" | "guided",
  temperature?: number
}

reassign_agent

Scope: agents:assign

{
  target_type: "inbox",
  inbox_id: string,
  agent_id: string
}
// or
{
  target_type: "conversations",
  conversation_ids: string[],
  agent_id: string
}

send_messagescope: messages:send

Send a text, template, or media message via Meta Cloud API for any of your connected channels.

Arguments

{
  channel:         "whatsapp" | "instagram" | "messenger" | "telegram",
  integration_id?: string,        // UUID — required if you have >1 inbox on this channel
  recipient:       string | { chat_id: string },
                                  // Meta channels: plain string (wa_id | PSID)
                                  // Telegram: { chat_id: string } (int64 as decimal)
  message: {
    type: "text";
    text: string                  // max 4096 chars
  } | {
    type: "template";             // WhatsApp only
    template: {
      name:     string,
      language: string,           // e.g. "en_US"
      components?: Array<{ type, parameters?: object[] }>
    }
  } | {
    type: "media";
    media: {
      url:       string,
      mediaType: "image" | "video" | "audio" | "document",
      caption?:  string           // max 1024 chars
    }
  },
  tag?:             "CONFIRMED_EVENT_UPDATE" | "POST_PURCHASE_UPDATE"
                  | "ACCOUNT_UPDATE" | "HUMAN_AGENT",   // IG / Messenger >24h
  idempotency_key?: string        // 8..128 chars
}

Success result

{
  "content": [{
    "type": "text",
    "text": "{\"id\":\"wamid.HBgN...\",\"channel\":\"whatsapp\",\"status\":\"sent\",\"created_at\":\"2026-05-12T07:42:27.852Z\"}"
  }]
}

Idempotent replays carry an extra idempotent_replay: true inside the JSON payload of content[0].text.

Example — curl

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      1,
    "method":  "tools/call",
    "params": {
      "name": "send_message",
      "arguments": {
        "channel":   "whatsapp",
        "recipient": "5215555555555",
        "message":   { "type": "text", "text": "Hi from MCP!" }
      }
    }
  }'

send_templatescope: messages:send

Convenience wrapper for an approved WhatsApp template. Internally constructs a send_message call with message.type="template". WhatsApp only — Messenger / Instagram do not support templates.

Arguments

{
  channel?:        "whatsapp",      // implicit
  integration_id?: string,
  recipient:       string,
  template_name:   string,
  language:        string,          // e.g. "en_US"
  components?:     Array<{ type, parameters?: object[] }>,
  tag?:            "CONFIRMED_EVENT_UPDATE" | "POST_PURCHASE_UPDATE"
                 | "ACCOUNT_UPDATE" | "HUMAN_AGENT",
  idempotency_key?: string          // 8..128 chars
}

Example — curl

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      2,
    "method":  "tools/call",
    "params": {
      "name": "send_template",
      "arguments": {
        "recipient":     "5215555555555",
        "template_name": "appointment_reminder",
        "language":      "en_US",
        "components": [{
          "type": "body",
          "parameters": [
            { "type": "text", "text": "Maria" },
            { "type": "text", "text": "Tuesday at 10:00 AM" }
          ]
        }]
      }
    }
  }'

get_messagescope: messages:read

Look up an outbound message by its platform_message_id — the same id returned from send_message and from Meta's delivery webhooks.

Arguments

{ id: string }

Not-found behavior

A missing id (or a message that doesn't belong to your account) is returned as a result.isError = true tool result — NOT a JSON-RPC error code. This lets MCP clients display the "not found" text directly to the model without branching on protocol-level error handling.

Example

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      3,
    "method":  "tools/call",
    "params":  { "name": "get_message", "arguments": { "id": "wamid.HBgN..." } }
  }'

list_conversationsscope: conversations:read

List conversation metadata across your inboxes, most-recent first. Returns the conversation id, channel, contact name / handle, and timestamps. Message bodies are NOT included — reading bodies requires the separate messages:read scope and a future per-conversation tool.

Arguments

{
  integration_id?: string,        // UUID — filter to a single inbox
  limit?:          number,        // 1..100, default 25
  cursor?:         string         // opaque, from prior response next_cursor
}

Success payload shape

// JSON.parsed from result.content[0].text
{
  items: Array<{
    id:               string,
    integration_id:   string,
    channel:          "whatsapp" | "instagram" | "messenger" | "telegram",
    contact_name:     string | null,
    contact_handle:   string,            // wa_id | PSID | telegram chat_id
    last_message_at:  string | null,     // ISO timestamp
    created_at:       string
  }>,
  next_cursor: string | null              // null when no more pages
}

Example

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      4,
    "method":  "tools/call",
    "params":  { "name": "list_conversations", "arguments": { "limit": 25 } }
  }'

list_templatesscope: templates:read

List WhatsApp message templates for a WABA. Resolves the WhatsApp integration the same way send_message does — single-inbox auto-picks, multi-inbox requires an explicit integration_id.

Arguments

{
  integration_id?: string,        // UUID — required if you have multiple WA inboxes
  status?:         "APPROVED" | "PENDING" | "REJECTED" | "PAUSED"
}

Example — only approved templates

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      5,
    "method":  "tools/call",
    "params":  { "name": "list_templates", "arguments": { "status": "APPROVED" } }
  }'

search_docsscope: docs:read

Semantic search over the public Kronos documentation. Backed by a gemini-embedding-001 vector index (768d, cosine). Returns the top-K matching chunks with their doc slug, section heading, full chunk content, and similarity score in [0, 1] (higher = closer).

The docs:read scope is auto-included on every newly emitted API key — no rotation needed. The same surface is reachable without a Bearer at POST https://api.kronos.com.mx/v1/docs/search (rate-limited 60 req/min/IP).

Arguments

{
  query:    string,         // 1..500 chars, trimmed server-side
  limit?:   number,         // 1..20, default 5
  doc_slug?: string         // restrict to one doc; ^[a-z][a-z0-9-]*$
}

Response shape

{
  items: Array<{
    doc_slug:     string,
    doc_title:    string,
    doc_category: "getting-started" | "products" | "integrations"
                | "billing" | "security" | "developer",
    section:      string | null,    // H2/H3 heading, null for preamble
    content:      string,           // chunk text as embedded
    score:        number            // 1 - cosine_distance, ~[0, 1]
  }>
}

Example — natural-language query

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      6,
    "method":  "tools/call",
    "params":  {
      "name": "search_docs",
      "arguments": {
        "query": "how do I connect a WhatsApp business inbox",
        "limit": 3
      }
    }
  }'

Example — public REST mirror (no Bearer)

curl -X POST https://api.kronos.com.mx/v1/docs/search \
  -H "Content-Type: application/json" \
  -d '{ "query": "send a template message", "limit": 5 }'

initiate_call

Scope: calls:initiate Opt-in · costs money

Place an outbound voice call. The recipient picks up and hears your AI agent — the model initiates the dial; the agent has the conversation. Mirrors the REST endpoint POST /v1/calls/initiate exactly.

Arguments

{
  to:              string,           // international format, "+" optional
  agent_id:        string,           // UUID; agent must have Voice channel enabled
  context?:        string,           // optional briefing for the agent (background,
                                     // not instructions). Max 2000 chars.
  integration_id?: string,           // UUID; required only if you have >1 voice number
  tag?:            string,           // optional free-form correlation id, max 100
  idempotency_key?: string           // 8..128 chars
}

Success result

{
  "content": [{
    "type": "text",
    "text": "{\"call_id\":\"7d63af24-...\",\"twilio_call_sid\":\"CA159e...\",\"from\":\"+15187329372\",\"to\":\"+5215555555555\",\"status\":\"initiated\",\"agent_id\":\"547ce9ba-...\"}"
  }]
}

Idempotent replays carry an extra idempotent_replay: true inside the JSON payload of content[0].text. Failed dials are NOT cached — retrying with the same key after a failure re-attempts.

Example — curl

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      1,
    "method":  "tools/call",
    "params": {
      "name": "initiate_call",
      "arguments": {
        "to":       "+5215555555555",
        "agent_id": "547ce9ba-55b5-4992-baaa-bdfb232310aa",
        "context":  "Lead asked about onboarding hours. Speak Spanish."
      }
    }
  }'

Error semantics: validation issues, missing / wrong agent, no voice number, multi voice numbers without integration_id, or quota exhausted → -32602 invalid_params with a human-readable message. The REST surface uses distinct HTTP codes for each (see REST errors); MCP collapses them to invalid_params since JSON-RPC has no dedicated quota code. Carrier-side dial refusals → -32003 upstream_failed with the reason code embedded in the message text.

list_voice_numbers

Scope: calls:read

List the voice numbers connected to your account. Useful for picking the right integration_id for initiate_call when you have multiple. Mirrors the REST endpoint GET /v1/voice/numbers.

Arguments

None. The schema is { } strict — extra keys are rejected.

Success result

{
  "content": [{
    "type": "text",
    "text": "{\"numbers\":[{\"integration_id\":\"...\",\"phone_number\":\"+15187329372\",\"inbox_name\":\"Support\",\"iso_country\":\"US\",\"default_agent_id\":\"...\"}]}"
  }]
}

Example — curl

curl -X POST https://mcp.kronos.com.mx/v1 \
  -H "Authorization: Bearer $KRONOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id":      2,
    "method":  "tools/call",
    "params":  { "name": "list_voice_numbers", "arguments": {} }
  }'

Errors

Protocol-level failures (auth, validation, missing methods) are returned INSIDE the JSON-RPC envelope with HTTP 200 per the JSON-RPC 2.0 spec. Transport-level failures (body too large, method not allowed on the endpoint) use real HTTP codes.

{
  "jsonrpc": "2.0",
  "id":     1,
  "error":  { "code": -32602, "message": "..." }
}

JSON-RPC error codes

CodeMeaningWhen
-32700Parse errorBody is not valid JSON.
-32600Invalid requestEnvelope is shaped wrong, or notification (missing id) — notifications are not supported.
-32601Method not foundUnknown JSON-RPC method (not the same as unknown tool name — that returns -32001).
-32602Invalid paramsArguments failed validation (wrong shape, missing required field, value out of range).
-32603Internal errorUnexpected Kronos-side error.
-32001UnauthorizedMissing / invalid / expired / revoked key, OR your key lacks the required scope, OR the tool name doesn't exist. The envelope is byte-identical across all auth failure modes — we never reveal which one happened.
-32002Idempotency conflictSame idempotency_key reused with a different request body.
-32003Upstream failedMeta rejected the call (rate limit, ban, template rejection). Distinct code so clients can retry differently than on Kronos-internal errors.
-32004Rate limitedYour key exceeded its per-minute budget. Back off and retry.

Transport-level (HTTP)

StatusWhen
405GET on /v1. The endpoint accepts POST (and OPTIONS for CORS preflight) only.
413Body exceeds 32 KB.

Rate limits

Each API key is capped at 60 requests / minute. Crossing the cap returns -32004 with a short backoff. The bucket is per-key — separate keys (e.g. one per environment) get separate budgets.

Meta's own per-channel limits still apply on top (WhatsApp Business tiers, Messenger rate caps). If you need higher bursts (e.g. backfilling a campaign), reach out via in-app support so we can whitelist your account.

Versioning

MCP protocol
2025-03-26

Returned by initialize as protocolVersion.

Server version
1.0.0

Returned by initialize as serverInfo.version.

Breaking changes to tool schemas or error envelopes will bump the server version's major component and ship a parallel v2 endpoint — your existing integration continues working at https://mcp.kronos.com.mx/v1 until you migrate.

For AI agents and LLMs: every docs page has a clean markdown twin — append .md to its URL. Curated index: /llms.txt. Open semantic search, no auth: POST https://api.kronos.com.mx/v1/docs/search.
MCP — Kronos AI | Kronos AI