logbook/Docs

Connecting agents

This is the reference for wiring a coding agent — Claude Code and any other MCP client — to a logbook project. It covers minting API keys, the per-project connection URLs, the exact .mcp.json and claude mcp add shapes, the monorepo pattern, legacy tokens, every authentication error you can hit, and the security model that guarantees an agent can never write into the wrong backlog.

For the human side — signing up, the onboarding wizard, inviting teammates — see Getting started.

The model in one sentence

The key decides WHO, the URL decides WHERE. An org API key authenticates the connection as a member of your organization; the project slug in the connection URL fixes which project that connection reads and writes. Scope is static per connection, so misfiling into another project is structurally impossible — there is no per-call project parameter to get wrong.

API keys

Keys are lgbk_… bearer tokens minted at the organization level. One key authenticates an agent as you for every project in the org; which project a given connection touches is decided entirely by the URL it connects to, never by the key.

Minting a key

  1. Open Settings → API tokens.
  2. Enter a label (defaults to claude-code) and click Generate key.
  3. The full token is shown once, under a "Copy now — shown only once" notice. Copy it immediately. Only a SHA-256 hash and a short prefix (lgbk_ plus the next several characters, displayed as lgbk_xxxxxxxx…) are stored; the raw token is never retrievable again. If you lose it, revoke it and mint a new one.

The Settings list shows each key's prefix, label, and last-used time (stamped on every authenticated MCP request). Creating a project or running the one-paste setup prompt also mints a fresh org key as a convenience, so you rarely generate one by hand.

Connection URLs

Under the keys, Settings lists a connection URL per project:

https://logbook.gvy.ai/api/mcp/<project-slug>

One URL per project, each with a copy button. Pair any org key with a project's URL to connect an agent to that project. Same key, different URLs, different projects. The slug is the project's globally unique, URL-safe identifier derived from its name.

Connecting Claude Code

The one-command path

From inside the repository you want to track:

claude mcp add --transport http logbook \
  https://logbook.gvy.ai/api/mcp/<project-slug> \
  --header "Authorization: Bearer lgbk_your_token_here"

This is exactly the command logbook generates for you in Settings → Connect Claude Code and in the setup prompt shown when you create a project. The server is named logbook; the transport is http; the token rides in an Authorization: Bearer header. Add --scope user to register the server for every repository on your machine instead of just the current one.

The .mcp.json path

To check the connection into a repository (so every agent working there picks it up), write a .mcp.json at the repo root:

{
  "mcpServers": {
    "logbook": {
      "type": "http",
      "url": "https://logbook.gvy.ai/api/mcp/<project-slug>",
      "headers": {
        "Authorization": "Bearer lgbk_your_token_here"
      }
    }
  }
}

This is the file form of the claude mcp add command above: type: "http" matches --transport http, url is the project connection URL, and the Authorization header carries the org token. Name the server entry after the project it points at (see the monorepo pattern below for why this matters).

Both forms are equivalent. Use the command for a quick local connection; use .mcp.json when the connection should live with the code.

What ships with the connection

Once connected, the agent gains the logbook toolset — reading, creating, updating, and crossing off backlog items — plus two planning prompts that Claude Code surfaces as slash commands:

  • /mcp__logbook__plan-work — an intake interview that turns a rough idea into well-formed items, checks prior art, decides log vs epic, and files the plan in one call only after you approve it.
  • /mcp__logbook__enrich-log — a gap audit that pulls an existing item, checks it against the quality bar, asks only about the gaps, and applies fixes on approval.

The slash-command prefix follows the server name you chose. If you name the server logbook, the commands are /mcp__logbook__plan-work and /mcp__logbook__enrich-log; if you name it after a project (for example billing), they become /mcp__billing__plan-work and so on. These prompts travel with the token — no installation, versioned server-side, always in sync with the tools.

Hearing about assignments

To have an agent pick up new assignments and notes at the start of every session, add a Claude Code SessionStart hook in the consuming repo that prompts a check_inbox (or briefing) call. Notes, status changes, and assignments addressed to you land there.

The monorepo pattern

In a monorepo where different directories map to different logbook projects, use directory-scoped .mcp.json files so an agent only ever sees the backlog for the project it is working in.

my-monorepo/
├── apps/
│   ├── billing/
│   │   └── .mcp.json      # url: …/api/mcp/billing,  server name: "billing"
│   └── web/
│       └── .mcp.json      # url: …/api/mcp/web,      server name: "web"

Each .mcp.json carries that project's connection URL and one server entry named after the project:

{
  "mcpServers": {
    "billing": {
      "type": "http",
      "url": "https://logbook.gvy.ai/api/mcp/billing",
      "headers": { "Authorization": "Bearer lgbk_your_token_here" }
    }
  }
}

An agent invoked inside apps/billing/ connects only to the billing project and sees only its items, labels, and team; an agent in apps/web/ sees only web. The same org key appears in both files — the URL is what separates them. Naming each server entry after its project keeps the slash commands and tool namespaces unambiguous when an agent's working directory spans more than one config.

Because scope is fixed by config rather than by runtime arguments, the risk of writing into the wrong backlog moves entirely to config-review time, where it is visible and reviewable.

Legacy project-bound tokens

Before org keys, every token was hard-bound to a single project (project_id set, no org). These legacy tokens still work but are no longer minted by any current UI path — mint org keys instead. They differ from org keys in where they are valid:

Org keyLegacy project token
Bound toan organizationone project
Valid on /api/mcp/<slug>any project in the org (slug picks it)only when the slug is its own project
Valid on bare /api/mcpno — returns a 400 with the slug listyes — resolves to its bound project
Minted bySettings, project setuppre-migration only

Legacy tokens appear in Settings → Legacy tokens, labeled legacy — bound to <project>, and remain revocable. They keep working on the bare /api/mcp endpoint (no slug), where scope equals their bound project. There is no forced migration; revoke them once nothing uses them.

Note that the codebase retains the internal createApiToken function that mints legacy project tokens, but no Settings action, onboarding step, or project-setup flow calls it — all of those now issue org keys via createOrgApiToken. In practice, the only legacy tokens in existence are ones created before the org-key migration.

Authentication errors

Every error is a self-describing JSON body with an error field, meant to be read by the agent that hit it so it can self-correct. The important ones:

Org key on the bare /api/mcp path — 400

An org key has no default project, so the bare path cannot resolve one. The response lists the org's project slugs so the agent knows exactly where to reconnect:

This is an org key — it has no default project. Connect to
/api/mcp/<project-slug>; this org has: billing, web.

The JSON body also includes a machine-readable projects array of the slugs. The fix is always to append the intended slug to the URL.

Legacy token, wrong slug — 403

A legacy project token used on a slug that is not its own:

This token is bound to the "billing" project and cannot act on "web".
Use /api/mcp/billing or the bare /api/mcp endpoint.

Org key, slug not in this org — 404

No project with slug "web" in this token's organization.

The same 404 is returned whether the slug does not exist at all or belongs to a different organization — a slug in another tenant is not probeable with your key.

Missing or unrecognized token — 401

No bearer header:

Unauthorized. Pass a logbook API token: Authorization: Bearer lgbk_…
(generate one in Settings).

Token not found (revoked, mistyped, or from another instance):

Unauthorized. This logbook API token is not recognized — generate a fresh one
in Settings.

Revoking a key

Revoke any key — org or legacy — from Settings → API tokens with the × button beside it. Revocation is scoped to your active organization: the delete only touches keys the org owns (org keys) or legacy keys bound to one of the org's projects, so a stray id from another tenant is a no-op. Any connection still using a revoked key immediately begins failing authentication with the 401 "not recognized" error above. To rotate a key, mint a new one, update your .mcp.json or re-run claude mcp add, then revoke the old one.

Security model

Three properties hold by construction:

  • The URL decides WHERE. The project a connection acts on is fixed by the slug in its URL and cannot change mid-session. There is no per-tool project argument, so there is nothing an agent can pass to reach across projects.
  • The key decides WHO. An org key proves organization membership; that is the entire authorization it grants. It carries no per-project or per-role permissions beyond "a member of this org."
  • Writes never cross projects. An org key on /api/mcp/<slug> is honored only if that slug's project belongs to the key's organization; otherwise it is a 404. A legacy token is honored only on its own project. The org-ownership check is the tenant boundary, and it is enforced on every request before any tool runs.

Two deliberate consequences: there is intentionally no cross-project write surface on a single connection (the ambiguity logbook refuses), and slugs live in the URL path — visible in every config file, greppable, and reviewable — rather than hidden in a header or query string.

Every write an agent makes is attributed in the activity feed as claude (<your name>), using the name on the logbook user the key belongs to, so agent edits are always distinguishable from human ones.

The toolset at a glance

An agent connected to a project can:

  • Survey — backlog_stats (call first for any audit), list_backlog, get_my_work, briefing (session-start: inbox, your items, scoreboard), team_summary, list_team, list_labels, history_for_files.
  • Read one or many items — pull_item (preferred, optional claim), pull_items (batch), get_item, get_document.
  • Create — create_item, create_items (batch, all-or-nothing validation), create_label.
  • Update — update_item, update_items (batch), add_task, complete_task, add_note, link_items, attach_document, archive_done_items.
  • Set up — link_repo (register a GitHub repo with the project).

Item creation is subject to the org's plan limits (the free plan caps logs); a capped org receives a structured upgrade_required error from create_item / create_items with the usage numbers and an upgrade URL. Reads and updates are never gated. Tool names, parameters, and calibrations are documented in each tool's own MCP description, which the agent sees on connection.

Where to go next

  • Getting started — the human path: accounts, orgs, the onboarding wizard, projects, and teams.