ac-co.ai docs

SDK

@repo/sdk — a thin client for accounting-mcp, the MCP-based sibling surface to the REST Public API.

@repo/sdk (package name @repo/sdk) is a small TypeScript client for accounting-mcp — a separate, MCP-protocol surface that exposes the same underlying product domain (invoices, quotes, counterparties, expenses, transactions, reports, Self Assessment, CRM, and more) as self-describing tools, rather than as REST/OpenAPI routes.

A different surface from api.ac-co.ai

Everything else on this site (Authentication, Scopes, the API Reference) documents api.ac-co.ai, the REST gateway over a curated slice of the platform contract. @repo/sdk talks to accounting-mcp instead — a Model Context Protocol server built for LLM hosts (Claude, ChatGPT, MCP Inspector) and this repo's own ac-co CLI. Both surfaces authenticate with the same ac_… API keys, but they are different products with different endpoint sets — don't assume an endpoint documented here also exists as an MCP tool, or vice versa.

What it does

The SDK is a wrapper around the official @modelcontextprotocol/sdk StreamableHTTPClientTransport, plus a raw fetch call to a companion /uploads route (MCP tool calls can't carry binary file bodies). It exposes:

connect(options?: { url?: string; apiKey?: string }): Promise<{
  serverUrl: URL;
  listTools(): Promise<AccoTool[]>;
  call(name: string, args?: Record<string, unknown>): Promise<AccoCallResult>;
  upload(bytes: Uint8Array, opts: { name: string; contentType: string }): Promise<UploadResult>;
  close(): Promise<void>;
}>
  • listTools() — the full set of available tools (every product API accounting-mcp exposes), each with a JSON Schema describing its arguments. This is what powers the ac-co CLI's auto-generated subcommands.
  • call(name, args) — invoke any tool by name with a JSON argument object.
  • upload(bytes, { name, contentType }) — POST a file to be ingested and auto-classified (invoices, bank statements, contracts, …).

Install and authenticate

bun add @repo/sdk   # workspace package — inside this monorepo only

Auth is an ac_… API key (the same kind used against the REST Public API), passed as a bearer token on the underlying HTTP transport:

import { connect } from "@repo/sdk";

const client = await connect({ apiKey: process.env.AC_CO_API_KEY });

If you omit apiKey, it falls back to the AC_CO_API_KEY environment variable. If you omit url, it falls back to AC_CO_API_URL, then ACCOUNTING_MCP_URL, then ACCOUNTING_MCP_PUBLIC_BASE_URL, then a local development default — set AC_CO_API_URL to accounting-mcp's real endpoint (e.g. https://accounting-mcp.ac-co.ai/mcp) for anything other than local dev.

Example: list and call tools

import { connect } from "@repo/sdk";

const client = await connect({ apiKey: process.env.AC_CO_API_KEY });

const tools = await client.listTools();
console.log(tools.map((t) => t.name));

const result = await client.call("search_invoices", { status: "unpaid" });
console.log(result.structuredContent ?? result.content);

await client.close();

Example: upload a document

import { readFile } from "node:fs/promises";
import { connect } from "@repo/sdk";

const client = await connect({ apiKey: process.env.AC_CO_API_KEY });
const bytes = await readFile("./invoice.pdf");
const result = await client.upload(new Uint8Array(bytes), {
  name: "invoice.pdf",
  contentType: "application/pdf",
});
console.log(result.documentId);

See also

The CLI is built directly on this SDK — every tool listTools() returns becomes a CLI subcommand automatically, with zero CLI-side code changes needed when a new tool ships.

On this page