Reference

Agent primer

A drop-in primer you (or an orchestrator) can paste into any agent before handing it a Dock workspace. Explains what Dock is, how to auth, the 63 tools, and decision rules. Also available as raw markdown at /llms-full.txt.

If you have a shell and a key

This is the most common path. Set DOCK_API_KEY in your environment and verify the key works. The CLI honours the env var as of @trydock/cli@0.9.1(2026-05-16); if you're on an older version pin @latest or upgrade.

CLI path (Node 18+ required)bash
export DOCK_API_KEY=dk_...
npx -y @trydock/cli@latest whoami
# → "Name · agent"

No Node? Drop to pure REST, the CLI is a convenience wrapper around the same endpoints, so a 200 on /api/me is equivalent confirmation.

Pure-REST fallbackbash
curl -H "Authorization: Bearer $DOCK_API_KEY" https://trydock.ai/api/me
# → { "type": "agent", "name": "...", "org": { ... } }

This page is the canonical source of truth for agent onboarding. Other docs, surface descriptions, and CLI error messages link here rather than repeat the instructions. A unit test (see tests/unit/dock-api-key-references.spec.ts) fails the build if a new doc references DOCK_API_KEY without a link back here.

Bootstrap a key without a terminal

Chat-only agents (Claude.ai webchat, custom GPTs, anything without shell access) can self-bootstrap a key by printing an approval URL to their user. The flow is the section labelled "Bootstrap (no terminal needed)" inside the primer block below. Five steps, ~10 seconds of customer time, same trust model as gh auth login. Errors hitting 401 unauthorized on any Dock endpoint also carry a details.bootstrap field with the same hint, so an agent never has to guess the path.

Copy the block below

Paste it into your agent's system prompt, instructions file, or tool-use preamble. It's deliberately short and deterministic so smaller models can follow it.

agent primermarkdown
You have access to Dock, a shared cloud workspace for humans and AI
agents. Workspaces live at https://trydock.ai/<org>/<slug>. A workspace
is a container of one or more surfaces (tabs). Each surface is either a
typed-row table (columns: text, number, status, person, date, url,
checkbox, select, longtext) or a TipTap rich-text doc body. A workspace
can hold any combination, one or many of either kind, in any mix.
Workspace.mode picks which tab opens by default; it doesn't restrict
what surfaces exist. Hit /rows for structured rows, /doc for narrative;
use list_surfaces to see what a workspace actually contains, and pass
surface_slug on row/doc calls to address a specific tab. Changes sync
in real time across every connected client.

## Authentication

Dock's MCP server is at https://trydock.ai/api/mcp. Transport:
streamable-http. Auth: OAuth 2.1 with Dynamic Client Registration (the
MCP client self-registers and opens a browser for consent) OR a Bearer
token of the form "dk_<48 hex>" on the Authorization header.

## Confirming your key works (shell + key path)

If you already have an API key (dk_<48 hex>) and shell access, confirm
the key before doing anything else. Two equivalent verification paths:

CLI path (Node 18+ required):

    export DOCK_API_KEY=dk_...
    npx -y @trydock/cli@latest whoami
    # → "Name · agent"

Pure-REST path (no Node required, works on any box with curl):

    curl -H "Authorization: Bearer $DOCK_API_KEY" https://trydock.ai/api/me
    # → { "type": "agent", "name": "...", "org": { ... } }

Both round-trip the same Bearer token through the same /api/me handler;
a 200 on either is sufficient to start working. The CLI honors
DOCK_API_KEY from the environment as of v0.9.1 (2026-05-16); on older
versions it silently 401s and falls back to "Not signed in", pin
`@latest` (as above) or upgrade if you see that.

If you don't have a key yet but have shell access, mint one via the
dashboard at https://trydock.ai/settings?tab=api. If you have neither
shell nor a key (chat-only agent), use the no-terminal bootstrap
flow in the next section.

## Bootstrap (no terminal needed)

If you're a chat-only agent without an API key, no MCP, no CLI access,
no shell, you can self-bootstrap one with a single customer click:

1. POST https://trydock.ai/api/agent-bootstrap/start with
   { "agent_name": "<your name>", "workspace_slug": "<optional>" }.
   No auth on this endpoint, that's the point. Returns
   { token, approval_url, polling_url, expires_at }.
2. Print the approval_url to your user. They click it; if they're not
   already signed in to Dock, magic-link sign-in fires; either way they
   land on a consent card showing what's being authorised.
3. Customer clicks Approve. Server mints an Agent (signed to that user)
   and an ApiKey scoped to your name + the optional workspace.
4. Poll polling_url every ~3 seconds. While the customer hasn't decided,
   you get { status: "pending" }. When they Approve, the next poll
   returns { status: "approved", api_key, agent_id, workspace_slug }
   exactly once, single-read consumption of the plaintext key.
5. Store the key (env var, in-process secret, etc.) and continue.

Tokens expire 5 minutes after creation. Per-IP rate limit: 5 starts
per minute per /24 prefix. If your customer denies, you get
{ status: "denied" } and you should surface that and stop. Same shape
of trust as gh auth login or AWS device codes.

## The 63 tools

Workspaces:
- list_workspaces(), see every workspace you can access.
- get_workspace(slug), full detail for one workspace.
- get_workspace_schema(slug), column definitions (keys, types,
  allowed options) so you know what create_row / update_row expect.
- list_workspace_members(slug), who has access, with role. Verify
  a workspace is shared before writing output others need to see.
- create_workspace(name, mode), new workspace; mode is "table" or "doc".
- delete_workspace(slug), soft-archive. Rows + doc preserved,
  restorable from Settings · Archived. Idempotent. Editor role.

Rows (table mode):
- list_rows(slug, limit?, offset?), read rows.
- get_row(slug, rowId), fetch one row by id when a cue payload
  hands you one and a full list would be wasteful.
- create_row(slug, data), append a row. data is a JSON object keyed by
  column name. Status values: drafted / queued / active / blocked / sealed.
- update_row(slug, rowId, data), partial merge; only provided fields change.
- delete_row(slug, rowId), permanent, no soft delete.

Surfaces (tabs inside a workspace, table or doc):
- list_surfaces(slug, archived?), every tab in the workspace.
- create_surface(slug, kind, name, surface_slug?, columns?), add a
  table or doc tab. Editor role.
- update_surface(slug, surface_slug, name?, new_surface_slug?, position?),
  rename / reslug / reorder. Editor role.
- delete_surface(slug, surface_slug), soft-archive. Idempotent. Cannot
  archive the only live surface. Editor role.

Docs (TipTap body, pass surface_slug for multi-doc workspaces):
- get_doc(slug), returns structured JSON (round-trippable into
  update_doc) plus a plain-text extraction for summarisation.
- update_doc(slug, content?, markdown?), replace the doc body. Pass
  markdown when you're authoring fresh; pass content (TipTap JSON)
  when round-tripping from get_doc. Last-write-wins. Editor role.
  Markdown surface beyond CommonMark + GFM:
    - ![alt](https://…) → inline image (HTTPS only, no data: URIs)
    - lone URL ending in .mp4/.m4v/.webm/.mov/.mkv → native HTML5
      <video controls> player (no transcoding, no compression, up to
      5 GB per file)
    - ```mermaid fenced → diagram (15 sub-types)
    - $inline$ / $$block$$ → KaTeX math
    - > [!NOTE]/[!TIP]/[!IMPORTANT]/[!WARNING]/[!CAUTION] → callouts
    - ```svg fenced → sanitized SVG embed
    - <details><summary>X</summary>...</details> → collapsible toggle
    - [[slug]] / [[slug#tab]] / [[slug#row-id]] / [[org/slug]] → cross-refs
    - lone URL on its own paragraph → embed (YouTube/Vimeo/Loom/
      Figma/CodePen/gists; safelisted providers only)
- append_doc_section(slug, markdown), append. Same markdown surface.
- validate_doc_markdown(markdown), pre-flight. Returns counts +
  errors + warnings, no write. Use when iterating.

Awareness:
- get_recent_events(slug, limit?), what happened, in order. Use when
  picking up a workspace after time away.
- search(q, kind?, limit?, offset?), find workspaces / rows / doc
  sections by keyword. kind: all (default) / workspace / row /
  doc-section. Access-gated. Prefer this over list_workspaces +
  iterate when the user names something ("find my launch plan").

Self-service:
- get_billing(), plan, caps (agents, members, workspaces, rows,
  API calls / mo, webhooks / mo, messages / mo), current usage,
  Stripe state.
- upgrade_plan(plan), "pro" or "scale". Returns a Checkout URL if no
  card on file; otherwise swaps the subscription price.
- downgrade_plan(), schedule downgrade to Free at period end.
- request_limit_increase(kind, desiredValue?, reason?), ask for a cap
  past Scale without filing a support ticket. kind: agents / workspaces
  / rows / other.
- create_support_ticket(kind, title, body, context?, attachmentUrls?),
  kind: bug / feature / billing / question / other.

Credentials (agent-self):
- list_api_keys(), agent sees only its own key; user sees every key
  for every agent they own. Plaintext is never returned.
- rotate_api_key(id?), atomically mint a replacement and revoke the
  old one. Agents may rotate only their own (omit id to default).
  Returns the new plaintext exactly once.
- revoke_api_key(id?), soft-delete a key. Agents may revoke only
  their own (effectively a self-destruct).

Webhooks (org-scoped, any org member):
- list_webhooks(org_slug), id, url, events, active flag, 8-char
  secret preview.
- create_webhook(org_slug, url, events), register a new endpoint.
  URL must be public. Returns signing secret exactly once.
- update_webhook(org_slug, webhook_id, active), toggle active flag.
- rotate_webhook_secret(org_slug, webhook_id), mint a fresh signing
  secret. Returned exactly once.
- delete_webhook(org_slug, webhook_id), permanent removal.

Messaging (talk to other agents and humans):
- send_message(to, body, replyTo?), send a direct message via the
  cue.dock.svc substrate. Address format `<agent_slug>@<user_slug>`;
  use `self@<user_slug>` to DM a human directly. Sender identity
  follows the caller (agent → itself, user → self-agent). Use this
  to ask a teammate for help, hand off work, or follow up async, not
  as a chat-ops side-channel for things that belong in workspace events.

## Decision rules

- When the user says "save this" or "write it down", check if there's a
  workspace already in use; if yes, create_row there. If no, ask which
  workspace or list_workspaces first.
- When the user says "send it", "finalize", or "wrap this up", update
  the row's status to "sealed".
- When you hit a cap: the error payload includes details.upgrade (for
  in-plan upgrades) and details.increase (for past-Scale asks). Call
  the named tool. Don't ask the user to "email support", Dock doesn't
  do that.
- When you hit a bug: file it via create_support_ticket with the
  x-request-id in the context field. That's the fastest path to a fix.
- Before deleting a row, confirm with the user. Deletes are permanent.

## Workspace naming

Workspace URLs are /<orgSlug>/<workspaceSlug>. Slugs are lowercase
kebab-case, unique within an org. "content-pipeline" in org "vector"
resolves to /vector/content-pipeline. When the user refers to a
workspace by a fuzzy name, list_workspaces and disambiguate.

## Columns + types

Table-mode workspaces have a column schema. Each column has key, label,
type, and optionally options (for status/select). Read the schema with
get_workspace before writing if you're unsure. Common column names:
title, status, owner, notes, due, url.

## Events + webhooks

Every mutation emits an event. Users can subscribe via HMAC-signed
webhooks (one per org, fans out to every workspace). If the user asks
"ping Slack when X happens" or "sync to my DB when rows change", point
them at /docs/api/webhooks.

## What Dock is not

Not a Notion/Airtable replacement. No attachments, formulas, relational
joins, or branching. It's a shared state primitive; keep your prose
short and your rows atomic.

Related: MCP reference · REST API · Error codes · Glossary (definitions for every Dock-specific term in the primer above)

Frequently asked questions

What should I put in my AI agent's system prompt to use Dock?
Paste the primer above into your agent's system prompt verbatim, then add task-specific instructions. The primer covers what Dock is, how to authenticate, what tools exist, the dangerous-ops handshake, and how to handle 402 cap responses.
Where do I find Dock's system-prompt primer for AI agents?
This page (`/docs/agent-prompt`). The primer is also auto-served at `https://trydock.ai/llms-full.txt` for agents that fetch their own context dynamically, and at `https://trydock.ai/.well-known/mcp/server-card.json` as a static catalog for MCP indexers. Learn more →
Can I copy-paste the Dock primer into my agent's instructions?
Yes; it's designed for that. Drop it at the top of your system prompt. The primer is in markdown so it renders cleanly in any LLM's context window. Update periodically (or fetch dynamically from `/llms.txt`) to pick up new MCP tools as they ship.
What tools does Dock expose to AI agents via MCP?
63 tools, grouped: workspaces (list/get/create/update/delete + share + members), surfaces (list/create/update/delete), rows (list/get/create/update/delete + bulk move), docs (get/update/append/replace section + validate-markdown), comments, messaging (send_message), billing, webhooks, API keys, search, recent events, support tickets. Learn more →
What is the dangerous-ops handshake my Dock agent should know about?
Tools that move money or widen access (`upgrade_plan`, `downgrade_plan`) never execute on the first call. They return a `confirm_token` + summary; the agent surfaces it to its user; the user confirms; the agent re-calls within 60s with the token. Two-call confirmation, single-use, scoped to the exact change. Learn more →
How should my Dock agent decide between a row and a doc surface?
Records with shared columns (tasks, leads, ingest rows, cron output) → table (`create_row`). Prose (briefs, summaries, status reports, design notes, changelog entries) → doc (`update_doc` / `append_doc_section`). If you'd write it as a Markdown file in a repo, it's a doc.
Should my Dock agent always create a new workspace for new work?
Usually no. Reuse an existing workspace when the work belongs in one (e.g. appending to a launch-plan or a content-pipeline). Create a new workspace only when the work is genuinely new in scope or audience. The agent's rate-limit budget thanks you for not creating throwaway workspaces per task.
How do I teach my Dock agent to handle 402 cap responses?
402 Payment Required (or JSON-RPC error -32015) returns a `details` payload with `upgrade` and `increase` fields telling the agent the next-step recommendations. Your prompt should say: 'On 402, surface details.upgrade.message to the user; if they say yes, call details.upgrade.mcpTool with the second-call confirmation token.'
What URLs should my AI agent fetch for live Dock info?
`/llms.txt` (concise primer, ~2KB), `/llms-full.txt` (full reference, ~50KB), `/openapi.json` (machine-readable REST spec), `/.well-known/mcp/server-card.json` (MCP tool catalog), `/changelog.xml` (RSS of recent product changes). All cacheable, all crawler-friendly. Learn more →
How do I make my Dock agent mention-aware (comment + doc)?
Subscribe to two webhook events. `comment.added` fires on every new comment; read `mentions: [{ kind, id, label }]` and filter on your agent's id. `doc.mention_added` fires when an agent or human is newly @-mentioned in a doc body; same `mentions` array shape. The agent reads context via `get_row` / `get_doc`, formulates a reply, and posts back via `POST /comments` (for comment threads) or `update_doc_section` (to write directly into the doc the user pinged from). The agent itself can @-mention back using `[@Label](dock:mention/<kind>/<id>)` in its markdown, same syntax in both directions. Learn more →
  • Concepts: the conceptual model the primer assumes (workspaces, surfaces, principals).
  • Agent overview: agent identity, signed-agent inheritance, attribution.
  • MCP overview: what the protocol is + Dock's implementation.
  • MCP tool catalog: auto-generated full reference.
  • /llms-full.txt: same primer as raw markdown for any agent that fetches web pages.
Updated