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

# Connecting an AI client

> Put Zeno inside Claude, ChatGPT, Claude Code, Codex, Cursor, or VS Code — one install link and a browser approval.

The hosted firm workspace speaks MCP over HTTPS. Any client that supports
remote MCP servers connects with one URL and a browser approval. There is
nothing to install and no API key to copy; the endpoint uses OAuth 2.1 with
dynamic client registration, so the client registers itself and sends you to a
consent screen.

|               |                                               |
| ------------- | --------------------------------------------- |
| **Endpoint**  | `https://api.zenofirm.com/mcp`                |
| **Transport** | Streamable HTTP                               |
| **Auth**      | OAuth 2.1 + PKCE, dynamic client registration |
| **Scope**     | Your firm — every company connected to it     |

<Tip>
  The console builds every link and command on this page for you, already
  carrying your own endpoint. A new workspace lands on **Get started**; after
  that it is **This firm → AI clients**. Nothing here has to be typed by hand.
</Tip>

## Before you connect

1. You need a Zeno account. [Start one](https://app.zenofirm.com/signup?plan=firms)
   if you haven't — 30 days free, no card.
2. Sign in at [app.zenofirm.com](https://app.zenofirm.com) in the browser you
   normally use. The approval screen recognizes that session and approves as
   you, with nothing to retype.
3. Connect at least one QuickBooks Online company, from **Get started** or the
   **Clients** page. The MCP token is scoped to your firm, so a client sees
   exactly the companies the firm has connected — connecting an AI client
   never grants Intuit access by itself.

Connecting the AI and connecting the books are independent, and either order
works. A client connected before any company simply sees an empty roster until
one arrives.

## Claude

One connector on your Claude account, used from claude.ai, Claude Desktop, and
mobile.

**[Add Zeno to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector\&connectorName=Zeno\&connectorUrl=https%3A%2F%2Fapi.zenofirm.com%2Fmcp)**

<Steps>
  <Step title="Confirm the name and URL">
    The link opens **Add custom connector** with `Zeno` and
    `https://api.zenofirm.com/mcp` already in it. Check them, then **Continue**.

    By hand instead: **Customize → Connectors → Add**, and type the same two
    values.
  </Step>

  <Step title="Leave the detected settings alone">
    Claude has probed the endpoint and marked **Always required** under
    **Authentication** and **No client ID — register one automatically** under
    **OAuth client**. Both are right for Zeno. Add no **Additional request
    headers**. Choose **Add**.
  </Step>

  <Step title="Connect">
    The connector's own page opens, saying **You are not connected to Zeno yet.**
    Press **Connect** and approve on the Zeno screen.

    Adding is not connecting. Until you press it, the connector exposes no tools
    and never reaches **AI clients** here.
  </Step>
</Steps>

New chats can then use the Zeno tools; Claude asks before each write the first
time.

<Note>
  On a Claude Team or Enterprise plan, an owner can
  [add it for the organization](https://claude.ai/admin-settings/connectors?modal=add-custom-connector\&connectorName=Zeno\&connectorUrl=https%3A%2F%2Fapi.zenofirm.com%2Fmcp).
  Each member still presses **Connect** and approves as themselves, and each
  approval is a separate grant this firm can revoke.
</Note>

## ChatGPT

ChatGPT reaches custom MCP servers through **developer mode**, on its paid
plans. There is no install link: the values go into its **New Plugin** dialog,
which OpenAI files under **Plugins** — older walkthroughs call it
**Connectors**.

What the dialog asks for:

| Field           | Value                                                                                           |
| --------------- | ----------------------------------------------------------------------------------------------- |
| **Icon**        | [zenofirm-logo-256.png](https://zenofirm.com/brand/zenofirm-logo-256.png) — 256 × 256 PNG, 6 KB |
| **Name**        | `Zeno`                                                                                          |
| **Description** | `Bookkeeping in QuickBooks Online: read the books, plan the work, post what a person approved.` |
| **Server URL**  | `https://api.zenofirm.com/mcp`                                                                  |

Save the icon before you start — right-click if your browser opens it in a tab.

<Steps>
  <Step title="Turn on developer mode, first">
    **Settings → Plugins → Developer mode**, and switch **Developer mode** on.
    Leave **Enforce CSP in developer mode** as you found it.

    Until developer mode is on there is no **+** for a custom server — **Plugins**
    shows only OpenAI's directory. The **ELEVATED RISK** badge is OpenAI's standing
    warning for any MCP server it has not reviewed; see
    [what approval means](#what-approval-means).

    On Business and Enterprise workspaces an admin allows custom MCP connectors for
    the workspace before the toggle appears.
  </Step>

  <Step title="Open the New Plugin dialog">
    **Settings → Plugins → Browse plugins**, then the **+** beside the search box.
  </Step>

  <Step title="Fill it in">
    * **Icon** — the PNG you saved. PNG only, 256 × 256 or larger, 10 KB or less.
      It marks each tool call as Zeno's. Optional.
    * **Name** — `Zeno`.
    * **Description** — ChatGPT reads it when deciding whether to reach for these
      tools, so name the books: `Bookkeeping in QuickBooks Online for Northline
      Freight and 3 other clients` beats `accounting`.
    * **Connection** — **Server URL**, not **Tunnel**. Paste the endpoint including
      the `/mcp` path.
    * **Authentication** — **OAuth**. Leave **Advanced OAuth settings** closed;
      Zeno registers ChatGPT itself, so there is no client ID or secret to supply.
  </Step>

  <Step title="Create and approve">
    Tick **I understand and want to continue**, choose **Create**, and approve on
    the Zeno screen. The plugin then appears under **Installed**.
  </Step>

  <Step title="Enable it in the chat">
    Switch Zeno on from the **+** menu in the composer of each new chat. Installed
    is not enabled, and the two failure modes look identical.
  </Step>
</Steps>

<Tip>
  Ask ChatGPT to list your companies. It should call `qb_list_companies` and name
  them, with the Zeno mark on the call.
</Tip>

## Claude Code

```bash theme={null}
claude mcp add --transport http zenofirm https://api.zenofirm.com/mcp --scope user
```

Then, inside a session, run `/mcp` and choose **Authenticate** next to
`zenofirm` to complete the browser approval. `--scope user` makes the server
available in every project; drop it to add Zeno to the current directory
only.

## Codex

Add the server to `~/.codex/config.toml` (on Windows,
`%USERPROFILE%\.codex\config.toml`):

```toml theme={null}
[mcp_servers.zenofirm]
url = "https://api.zenofirm.com/mcp"
```

Then complete the browser approval:

```bash theme={null}
codex mcp login zenofirm
```

<Note>
  Remote MCP servers need a recent Codex. If Codex reports it cannot use a
  `url` server, upgrade it, or on slightly older versions set
  `experimental_use_rmcp_client = true` at the top of `config.toml`.
</Note>

## Cursor

**[Add Zeno to Cursor](https://cursor.com/en/install-mcp?name=zenofirm\&config=eyJ1cmwiOiJodHRwczovL2FwaS56ZW5vZmlybS5jb20vbWNwIn0%3D)**

Cursor opens with the server prefilled; install it, then use its **Login**
action next to `zenofirm` to complete the browser approval.

By hand, add the server to `~/.cursor/mcp.json`:

```json theme={null}
{
  "mcpServers": {
    "zenofirm": { "url": "https://api.zenofirm.com/mcp" }
  }
}
```

## VS Code

**[Add Zeno to VS Code](https://insiders.vscode.dev/redirect/mcp/install?name=zenofirm\&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fapi.zenofirm.com%2Fmcp%22%7D)**

VS Code asks you to confirm the server before adding it, and signs in through
the browser the first time Copilot's agent mode uses it.

By hand, add the server to `.vscode/mcp.json` in the workspace, or to your user
`mcp.json`:

```json theme={null}
{
  "servers": {
    "zenofirm": { "type": "http", "url": "https://api.zenofirm.com/mcp" }
  }
}
```

## Any other MCP client

Everything above is one server described in each client's own dialect.
Anything that speaks remote MCP connects on four facts:

* **URL** — `https://api.zenofirm.com/mcp`
* **Transport** — streamable HTTP
* **Auth** — OAuth 2.1 with PKCE and dynamic client registration, so there is
  no client ID or secret to configure
* **Discovery** — the client reads
  `https://api.zenofirm.com/.well-known/oauth-authorization-server` itself

## What approval means

The consent screen authorizes the client **for your firm**, not for one
company. If you are signed in to the console in that browser, approval is
recorded as you. Otherwise the screen asks for your firm's connect code,
which the console shows under **This firm → AI clients** — whoever can type
it can authorize a client for the firm, so treat the code like a password.

An install link only ever prefills a dialog. It carries no credential, grants
nothing by itself, and cannot skip either the client's own confirmation or
Zeno's approval screen — which is why a forwarded link is harmless until
somebody approves it as themselves.

Once a client has approved, it is listed under **AI clients** with the date it
connected. That list is the honest answer to "is this set up?": a client
appears on it only when Zeno has actually issued it a token.

Access is bearer-token based with refresh rotation. Approving a client does
not weaken the operating model: reads answer directly, and every write still
travels [plan, review, apply, reverse](/docs/cloud/governed-work) — the client
proposes, a person approves in review, and only approved entries reach the
ledger. [The tool surface](/docs/cloud/tools) lists what the client can reach.

## Disconnecting a client

**This firm → AI clients** lists every client holding access, with the date it
connected and a **Disconnect** beside each one. Disconnecting revokes that
client's tokens immediately — the next tool call it makes is refused, and it
cannot renew, so there is no fourteen-day tail while an access token ages out.

Two things worth knowing:

* **It works by client name, and it covers the firm.** A client that is
  reinstalled or added on a second machine registers itself again, so
  "Claude" can be several grants; **Disconnect** ends all of them for this
  firm. It touches nothing outside your firm.
* **Nothing is deleted.** Plans, verdicts, runs, the work log, coding rules
  and client knowledge stay exactly as they are — a disconnected agent's work
  remains part of the record. Reconnecting is the same install link.

The client keeps its own entry until you remove it there, and will report an
authorization error when it tries to use it. To tidy that up:

* **Claude** — **Customize → Connectors**, then remove Zeno or press
  **Connect** to authorize it again.
* **ChatGPT** — **Settings → Plugins**, then delete the Zeno plugin.
* **Claude Code** — `claude mcp remove zenofirm`, or `/mcp` then
  **Authenticate** to connect again.
* **Codex** — delete the `[mcp_servers.zenofirm]` block, or run
  `codex mcp login zenofirm` to reconnect.
* **Cursor and VS Code** — remove the server from `mcp.json`, or use the
  client's own login action to reconnect.

<Note>
  Disconnecting an AI client does not touch QuickBooks. Intuit access is
  separate, and is disconnected per company from the **Clients** page.
</Note>

If you think a client was connected without your knowledge, disconnect it and
then rotate the firm's connect code with [support](https://zenofirm.com/support)
— the code is the one credential that authorizes a client without a console
session.

## When it doesn't connect

* **The install link opens the client but nothing is prefilled.** — The client
  is out of date, or it opened a signed-out session. Sign in to it first and
  click the link again; failing that, add the endpoint by hand from the same
  section above.
* **Claude lists Zeno but the tools are missing.** — Open it in **Customize →
  Connectors**. If it says **You are not connected to Zeno yet**, press
  **Connect** and approve; adding and connecting are separate steps.
* **The browser shows "That connect code did not match a firm."** — Sign in
  at [app.zenofirm.com](https://app.zenofirm.com) first and retry the
  connection; the approval screen then uses your session instead of asking
  for a code.
* **The tools don't appear after connecting.** — Restart the client or start
  a new conversation. Clients read their server list at startup; in Claude
  Code, run `/mcp` to check the server's status. In ChatGPT, enable the plugin
  for that chat from the composer's **+** menu — installing it is not the same
  as switching it on.
* **ChatGPT offers no way to add a server.** — Developer mode is still off. The
  **+** appears only after you switch it on under **Settings → Plugins →
  Developer mode**.
* **ChatGPT shows no developer mode toggle.** — It needs a paid plan, and on
  Business or Enterprise workspaces an admin has to allow custom MCP
  connectors first. Look under **Settings → Plugins**; OpenAI moved it out of
  **Connectors**.
* **ChatGPT rejects the icon.** — PNG only, 256 × 256 or larger, 10 KB or less,
  which rules out most logo exports. Use
  [zenofirm-logo-256.png](https://zenofirm.com/brand/zenofirm-logo-256.png), or
  create the plugin without one and add it later.
* **ChatGPT loops on the sign-in screen.** — Something was entered under
  **Advanced OAuth settings**. Delete the plugin and create it again with
  **Authentication** on **OAuth**, leaving that panel closed.
* **The client connects but sees no companies.** — `qb_list_companies` is
  empty until the firm connects a QuickBooks company in the console's
  **Clients** page.
* **Writes are refused with a trial message.** — The trial has ended. Books,
  context, and history stay readable; subscribe in
  [Billing](https://app.zenofirm.com/billing) to resume actions.

Still stuck? [Contact support](https://zenofirm.com/support) with the client
name and the exact error text.
