> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qubesync.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP server

> Point Claude Code, Codex, Cursor, Gemini CLI, VS Code or any MCP client at QuBe Sync. Your agent can look up every QuickBooks operation, build the exact API request, write and validate workflows, and never needs your API key.

QuBe Sync runs a public [Model Context Protocol](https://modelcontextprotocol.io) server at:

```
https://qubesync.com/mcp
```

Connect an AI coding agent to it and the agent knows QuickBooks Desktop the way QuBe Sync does: every
operation and field, the errors each one can raise, the webhook your app will receive, and how to write a
workflow. It works for anything from "how do I find inactive vendors?" to building your whole integration.

```mermaid theme={null}
flowchart LR
  agent["Your coding agent"] -- "which operation?" --> mcp["MCP server<br/>no key needed"]
  mcp -- "request, webhook,<br/>error codes" --> agent
  agent -- "sends it with your<br/>sandbox key" --> api["QuBe Sync API"]
```

## Connect your agent

The server speaks Streamable HTTP and needs no authentication.

> [tab] Claude Code
>
> ```bash theme={null}
> claude mcp add --transport http qubesync https://qubesync.com/mcp
> ```

> [tab] Codex
>
> ```bash theme={null}
> codex mcp add qubesync --url https://qubesync.com/mcp
> ```
>
> Or add it to `~/.codex/config.toml`:
>
> ```toml theme={null}
> [mcp_servers.qubesync]
> url = "https://qubesync.com/mcp"
> ```

> [tab] Cursor
>
> Add it to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` for every project:
>
> ```json theme={null}
> {
>   "mcpServers": {
>     "qubesync": { "url": "https://qubesync.com/mcp" }
>   }
> }
> ```

> [tab] Gemini CLI
>
> ```bash theme={null}
> gemini mcp add --transport http qubesync https://qubesync.com/mcp
> ```
>
> That adds it to the project's `.gemini/settings.json`. Add `--scope user` for every project.

> [tab] VS Code
>
> For GitHub Copilot's agent mode, add it to `.vscode/mcp.json` in your project:
>
> ```json theme={null}
> {
>   "servers": {
>     "qubesync": { "type": "http", "url": "https://qubesync.com/mcp" }
>   }
> }
> ```

> [tab] Windsurf
>
> Add it to `~/.codeium/windsurf/mcp_config.json`:
>
> ```json theme={null}
> {
>   "mcpServers": {
>     "qubesync": { "serverUrl": "https://qubesync.com/mcp" }
>   }
> }
> ```

> [tab] Other clients
>
> Add a remote (HTTP) MCP server with the URL `https://qubesync.com/mcp`. Most clients take a config like:
>
> ```json theme={null}
> {
>   "mcpServers": {
>     "qubesync": { "type": "http", "url": "https://qubesync.com/mcp" }
>   }
> }
> ```

## What it can do

The server **never touches a QuickBooks connection** and never needs an API key. Its tools check parameters,
build requests and validate charts, and your agent sends what they build with your key. So there is nothing
for the server to leak.

> [card] 261 operation tools
>
> One per QuickBooks operation: `find_customers`, `create_invoice`, `update_vendor`, `record_payment`,
> `execute_txn_void`... Each checks the arguments against QuickBooks' schema and returns the API request
> that runs it.

> [card] 4 workflow tools
>
> `get_workflow_authoring_guide`, `validate_workflow_chart`, `list_workflow_templates` and
> `get_workflow_template`: everything an agent needs to write a [workflow](https://docs.qubesync.com/workflow-authoring.md) and check
> it. Runs start only on realtime and simulated connections.

Three more are hand-written. `match_records` builds a [match](https://docs.qubesync.com/matching.md): the request that finds the record a
name means in a customer's company file, `POST /api/v2/connections/{connection_id}/matches`, checked the way
the API checks it, with the answer's schema and what each tier means. Like the operation tools it never
touches a connection, so the agent sends the request with your key. And `report_confusion` lets an agent tell
us when a tool, guide or API response confused it, without sending any keys or customer data. We read those
reports to improve the tools. Last, `get_integration_checklist` returns the
[integration checklist](https://docs.qubesync.com/integration-checklist.md): every rule an integration has to get right, or one area's
with `area`, each with what to check in the code, so an agent writing or reviewing your webhook handler has
them to hand.

## What an operation tool returns

Calling `create_customer` with a name and email returns the request to send, ready to use:

```json structuredContent theme={null}
{
  "method": "POST",
  "url": "https://qubesync.com/api/v2/connections/{connection_id}/customers",
  "body": { "name": "Northwind Builders", "email": "ap@northwind.example" },
  "headers": { "Idempotency-Key": "0b7e4f2c-9a1d-4c63-8e5b-2f7d1a9c3e40" },
  "webhook": { "type": "object", "properties": { "state": { ... }, "response_json": { ... } } }
}
```

**method, url, query or body** `string, string, object`

The API call, with `query` for a `GET` or `body`. Swap in a real `connection_id`, add your
`webhook_url`, and send it with your API key.

**headers** `object`

Send them too. Each call of a tool gives a fresh `Idempotency-Key`, so if the `201` never arrives, the
same request sent again, key and all, answers with the request already queued instead of queueing a
second one. See [Retrying a call safely](https://docs.qubesync.com/making-requests.md#retrying-a-call-safely).

**webhook** `object`

The JSON Schema of the [webhook](https://docs.qubesync.com/webhooks.md) the answer will arrive in, including this operation's own
`data` and every QuickBooks status code it can fail with, each with what it means and what to do.

The text content repeats the same as a ready-to-run `curl` command, plus a short guide to handling each
webhook `state` and the rest of the operation's notes from Intuit's qbXML reference. The tool's
description carries only their opening paragraph, since a client loads every tool's description at once.

So an agent writing your webhook handler gets the data shape and the error cases from the same call that
built the request. Pass `"include_qbxml": true` to also see the qbXML QuBe Sync will send QuickBooks. That's
for curiosity and debugging only: your app always sends JSON.

`validate_workflow_chart` runs the same checks as `POST /api/v2/workflows/validate`, except the ones that need
your app: the server never has your API key, so it can't see your workflows. Pass the chart as `chart`, a JSON
object or a string holding one, and the keys of the workflows your app already has as `known_workflows`. A
`workflow` state that calls a key not in that list is a warning rather than an error, and the key is listed in
`workflows_to_create`: create those in your app before you push this chart, because saving it there checks
that each one exists and takes the `input` you pass. The result is
`{valid, errors, warnings, workflows_to_create}`, and each error or warning has a `path` into the chart and a
`message`. Errors block saving; warnings are likely mistakes worth a look.

## Pair it with the CLI

The MCP server tells your agent what to send. The [qube CLI](https://docs.qubesync.com/cli.md) lets it send it safely: log in yourself
with the default **sandbox** scope, and your agent can create a simulated connection, run the requests it
built, inject faults, and push the workflows it wrote, without ever seeing a secret or a production app.

## Calling it directly

It's plain JSON-RPC over `POST`, so `curl` works for scripting or debugging. (A `GET` answers `405`.)

List tools

<pre>`POST`</pre>

List tools:

```http theme={null}
POST /mcp

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}
```

```bash theme={null}
curl -X POST \
  "https://qubesync.com/mcp" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'
```

Build a request

<pre>`POST`</pre>

Build a request:

```http theme={null}
POST /mcp

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "find_customers",
    "arguments": {"active_status": "ActiveOnly", "max_returned": 25}
  }
}
```

```bash theme={null}
curl -X POST \
  "https://qubesync.com/mcp" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "find_customers",
      "arguments": {"active_status": "ActiveOnly", "max_returned": 25}
    }
  }'
```

`tools/list` returns 100 tools per page. The first page starts with the workflow tools,
`report_confusion`, `match_records` and `get_integration_checklist`, then the operations in alphabetical order. Pass `nextCursor` back as
`params.cursor` for the rest.

> [!NOTE]
>
> The server is public, so don't send it real customer data. Use it to explore and build requests, then send
> them yourself with your API key.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.