Under the Hood

For your Agent,
more than just an interface

Four channels in, block-level contracts that edit precisely, version snapshots to roll back to. Every one of these is running in production today.

Read the API docs
Ways In

More than one way
in

Install once, and it handles the rest. All four paths lead to the same API.

MCP

Plug in and go

One command for Claude Code or Cursor — 14 document tools available immediately. Clients that support resources can even mount your documents as context.

claude mcp add doco -- npx -y --package doco-agent-cli doco mcp
Skill

Teach it the rules

Read first, track versions, write with If-Match, re-read on collision — the safe-write rules live in a file, not improvised from a prompt.

npx -y --package doco-agent-cli doco skill install
CLI

Edit like a local file

Pull a section into $EDITOR; saving writes it back automatically. Versioning and conflict retries are handled inside the command — add --json in scripts to consume the output.

npx -y --package doco-agent-cli doco edit <docId> --heading "部署流程"
API

Or write your own

Block-level reads and writes, batch transactions, search, rollback — every endpoint is open. Works with any language, any framework.

curl -H "Authorization: Bearer $DOCO_TOKEN" \
  $DOCO_BASE_URL/api/v1/documents/:id/blocks
MCP tools
doco_whoamidoco_list_knowledge_basesdoco_get_treedoco_list_documentsdoco_get_documentdoco_update_documentdoco_create_documentdoco_get_blocksdoco_patch_blockdoco_insert_blocksdoco_delete_blockdoco_batch_editdoco_searchdoco_upload_attachment

doco login uses browser authorization, just like gh auth login.

Protocol

No need to swallow the whole document,
just the block you want to change

Read block by block

Every block has a stable, position-independent ID — still the same block after drag, collapse, or cross-device sync. Fetch the whole block tree, or keep block anchors in Markdown.

Write precisely

Insert, replace, and delete only touch that one block. Multi-edit goes through /batch as a single transaction — all or nothing; create operations carry an idempotency key so retries never write twice.

No lost words on collision

Writes must carry If-Match; a version mismatch returns 409 — re-read, merge, and resubmit. A snapshot is taken automatically before every write.

1 · Read the blocks, note the version
curl -H "Authorization: Bearer $DOCO_TOKEN" \
  https://doco.example/api/v1/documents/spec-v2/blocks
# 200 · 4 blocks · ETag "sha256:9f2c…"
2 · Replace only the “Deployment Flow” block
curl -X PATCH .../blocks/block_01JXK3F7… \
  -H 'If-Match: "sha256:9f2c…"' \
  -d '{"node":{"type":"paragraph",…}}'
# 200 · new version "sha256:a41d…"
3 · Version mismatch? Re-read, merge, don't overwrite
409 conflict → re-GET → merge → retry
  broke it: POST /versions/12/rollback
Traceable

See what changed,
and roll back if it breaks

What you were owed before letting it loose.

Auto-snapshot on every write

A snapshot is saved before each write, so you can see exactly which block changed.

One click back to the last change

Pick any version and roll back, with concurrency protection on the way back.

Ask questions on a block

Comments anchor to specific blocks — no need to rewrite from scratch.

GET /api/v1/documents/:id/versionsPOST /api/v1/documents/:id/versions/:seq/rollbackPOST /api/v1/documents/:id/batchGET /api/v1/search
Architecture

Humans and Agents,
walk the same path

API writes aren't a side channel — they land in the same Yjs document as the editor, which is why they never overwrite each other.

Browser-local

IndexedDB is the primary store — writable offline; the Yjs document is the single source of truth.

Incremental sync

A Hocuspocus long connection exchanges only binary deltas, never the whole document.

Server-side persistence

API writes enter the same Yjs document and go through the same merge path as the editor.