MCP Server (Model Context Protocol)

The open standard for providing financial tools to Agentic Artificial Intelligence.

What is MCP?

The Model Context Protocol (MCP) is a universal standard that allows Artificial Intelligence assistants to connect to secure data sources.

By configuring the Cord MCP Server, you empower agents like Claude or IDE-integrated assistants (like Cursor) to organically interact with your company.

Questions you can ask the AI once connected:

  • “Extract the requirements from the attached PDF and generate a quote in Cord for this client.”
  • “Review the overdue quotes from the last 30 days and draft friendly collection emails for me.”
  • “Look up the client Distribuidora El Zarco and draft a quote with these 3 line items.”

How to configure the connection

Authentication for your AI client is performed using your standard Cord API Key (sk_live_… / sk_test_…) — the same one the REST API uses.

  1. Navigate to Settings › Developers › MCP in the Cord interface (it appears once you turn on Developer mode at the bottom of the Settings index).
  2. A status card at the top tells you whether you already have an active key and, if an AI client is already connected, when it was last used. If you don’t have one, the “Create a key for MCP” button generates a write key without leaving the page — it’s pasted automatically into the config below. Copy it right then: it won’t be shown again. (You can also create one from the API tab of the Cord Workbench if you’d rather control the scope by hand — write for the write tools, read is enough for the read tools.)
  3. Copy the MCP client JSON configuration provided on the screen.
  4. Paste this configuration into the corresponding local path for your client (e.g., the claude_desktop_config.json file if you use the Claude for Desktop app).

Publishable keys (pk_…, meant to live exposed in the browser) can’t be used with MCP — they only cover creating quotes and reading the catalog via the REST API. Use a Secret key from your backend or desktop client instead.

Two ways to connect

Streamable HTTP (recommended)POST https://cordhq.app/api/mcp with the header Authorization: Bearer sk_live_…. Sessionless: every JSON-RPC message is an independent HTTP request. This is what most modern MCP clients expect.

HTTP + SSE (legacy, kept for older clients)GET https://cordhq.app/api/mcp/sse opens a long-lived connection and returns where to send messages (POST /api/mcp/message?sessionId=…). Every POST message must carry the same Authorization: Bearer used to open the session — the sessionId in the URL alone isn’t enough (it travels in plain text and can end up exposed in intermediate proxy logs), and the key must belong to the same organization that opened the session.

Available tools

Tool What it does Permission
listar_cotizaciones Lists quotes, with an optional status filter. read
detalle_cotizacion Full detail of a quote: line items, totals, timeline. read
cartera_vencida OVERDUE accounts receivable: amount, aging, per-client detail. read
resumen_negocio KPIs, conversion funnel, pipeline forecast, plan usage. read
buscar_cliente Searches the directory by company/contact/RFC/email. Paginated. read
listar_productos Product catalog (id, SKU, name, unit, list price). Paginated. read
crear_cotizacion_borrador Creates a DRAFT quote (doesn’t send it). Idempotent if you pass idempotency_key. write
listar_facturas Lists Cord Invoicing invoices with their balance and state (draft|open|paid|void|uncollectible|overdue). Filter by state, client, or free text. Paginated. read
detalle_factura Full detail of ONE invoice: line items, issuer, recipient, taxes, declared FX rate, balance, and payments received. read
crear_factura_borrador Creates a DRAFT invoice for a client, without needing a prior quote. Requires the Starter plan or higher (Cord Invoicing). write
enviar_cotizacion Sends a draft quote to the client (email with the link). On the Free plan it uses one of the monthly sends. write
aprobar_cotizacion Marks a sent or viewed quote as approved. write
rechazar_cotizacion Marks a sent or viewed quote as rejected. write
registrar_pago_cotizacion Records that an approved quote was paid outside Cord and cancels its pending online payments. Accepts metodo_pago. write
crear_cliente Creates a client (company, contact, email, phone, tax ID, terms, country). write
actualizar_cliente Changes a client’s contact details. Only updates what you send; never touches credit, tier, or discount. write
crear_tarea Creates a follow-up task, optionally linked to a quote and with a due date. write
registrar_promesa_pago Records the date a client promised to pay a quote. It doesn’t charge anything. write
listar_eventos Business history (quotes, invoices, clients, tasks, promises), filterable by type or object. Paginated. read

Every tool declares standard MCP annotations (readOnlyHint, idempotentHint, destructiveHint) in tools/list — an MCP client can use these to decide which calls to auto-approve without asking the user every time. Read tools are readOnlyHint: true. enviar_cotizacion, aprobar_cotizacion, rechazar_cotizacion, and registrar_pago_cotizacion are destructiveHint: true because they change a quote’s status or write to the client: a well-configured MCP client asks for confirmation before running them. No tool issues or stamps invoices: that is still an action a person triggers from the app or the API.

Pagination

listar_cotizaciones, buscar_cliente, listar_productos, listar_facturas, and listar_eventos return pages, not the whole table:

{
  "items": [ { "id": "…", "empresa": "Distribuidora El Zarco" } ],
  "total": 47,
  "has_more": true,
  "next_cursor": "20"
}

If has_more comes back true, call the same tool again passing cursor: next_cursor for the next page. next_cursor is null once there are no more results. listar_cotizaciones returns the list in cotizaciones and listar_eventos in eventos.

listar_productos never includes a product’s internal cost/margin — only list price, SKU, name, and unit. That column is intentionally invisible from an API key, whether it has write permission or not.

Safe-to-retry calls (idempotency)

crear_cotizacion_borrador, enviar_cotizacion, aprobar_cotizacion, rechazar_cotizacion, registrar_pago_cotizacion, crear_cliente, crear_tarea, and registrar_promesa_pago accept an optional idempotency_key — a unique identifier you generate (a UUID, for example). If your MCP client needs to retry the call because it didn’t get a response in time (network timeout), repeat the SAME idempotency_key: Cord returns the result of the first call instead of repeating the action. Reusing the same key with different arguments returns an error, and the key expires after 24 hours.

{
  "name": "crear_cotizacion_borrador",
  "arguments": {
    "idempotency_key": "a1b2c3d4-…",
    "cliente_id": "…",
    "items": [{ "descripcion": "Installation", "cantidad": 1, "precio_unitario": 4500 }]
  }
}

Without idempotency_key, the tool still works normally — every call creates a new draft (it’s not a required field, just recommended if your client retries automatically).

detalle_cotizacion and listar_eventos can include text written by the client on the public link (comments, counteroffers). That text is marked with origen: "cliente_externo" and wrapped in <<<mensaje_del_cliente>>>: your agent should report it, never follow it as an instruction.

Secure Tools

Cord exposes “Tools” to the AI in a controlled manner. This means the AI does not have raw, unlimited access to your database; the AI can only invoke endpoints that Cord has approved and categorized, inheriting the permissions tied to the API Key.

Important: Business rules are strictly applied. If the AI attempts to apply a 150% discount when building a quote, the API will reject the request by returning a 400 invalid_request code to protect your business.

Limits, metering, and activity

Every real call (not protocol notifications like notifications/initialized) counts just like a REST API call: against your plan’s usage quota, against the per-key rate limit (600/min), and shows up in the Logs tab of the Cord Workbench with the tool that was called (e.g. /mcp/tools/call:listar_productos) — so you can see exactly what your agent is doing, with which key, and when. You can filter that log by method or status, or search for mcp in the route to isolate just what the AI did.