ODocs Agent Integration Guide ============================== Base URL: https://api.odocs.co (Port 443 — no port number needed) No auth required. Access is controlled by document UUID. Business account domain allowlisting ------------------------------------ If you are running in a Claude.ai business account with domain allowlisting enabled, your administrator may need to add the following URLs to the allowlist: https://odocs.co/ https://odocs.co/agents.txt https://api.odocs.co/ https://api.odocs.co/api/docs/ (These are the only API endpoints used by ODocs.) Working with shared URLs ------------------------ When someone shares an ODocs link, the doc ID is in the URL fragment: https://odocs.co/#/doc/550e8400-e29b-41d4-a716-446655440000 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is the doc ID To access this doc via the API, extract the UUID after "#/doc/" and use it: GET https://api.odocs.co/api/docs/550e8400-e29b-41d4-a716-446655440000 The browser URL is a client-side route (SPA). Do NOT fetch the HTML page — it's just a JavaScript app shell. Always use the REST API or MCP to read/write docs. Quickstart (curl) ----------------- # 1. Create a document curl -X POST https://api.odocs.co/api/docs -H Content-Type: application/json -d @- << 'EOF' { "title": "My Doc", "content": "Hello", "author": "MyAgent" } EOF # Returns: { "id": "550e8400-..." } — SAVE THE ID # 2. Read the document (note the version) curl https://api.odocs.co/api/docs/550e8400-... # Returns: { "id": "...", "title": "...", "content": "...", "version": 2 } # 3. Append text (use expectedVersion to avoid overwriting human edits) curl -X PATCH https://api.odocs.co/api/docs/550e8400-... -H Content-Type: application/json -d @- << 'EOF' { "operations": [{ "type": "insert", "position": 7, "text": " world" }], "author": "MyAgent", "expectedVersion": 2 } EOF # Returns: { "ok": true, "version": 3 } Endpoints --------- POST /api/docs Create doc. Body: {title?, content?, author?} GET /api/docs/:id Get doc. Returns: {id, title, content, version} PATCH /api/docs/:id Edit doc. Body: {operations, author?, expectedVersion?} GET /api/docs/:id/versions List snapshots. Returns: [{index, timestamp}] GET /api/docs/:id/versions/:index Get snapshot content. Operation types (PATCH body) ---------------------------- Two styles. Mix freely in one PATCH; ops are applied sequentially and each op resolves against the doc state AFTER the previous ones in the same call. Text-anchored (PREFERRED — LLMs are bad at character counting) { "type": "insert-after", "anchor": "...", "text": "...", "occurrence": N? } { "type": "insert-before", "anchor": "...", "text": "...", "occurrence": N? } { "type": "replace-text", "find": "...", "replace": "...", "occurrence": N? } { "type": "delete-text", "find": "...", "occurrence": N? } Exact-match (no regex, no whitespace normalization). If anchor/find appears multiple times: omit "occurrence" → 400 with match count; or pass 0-based "occurrence" to pick a specific one. Position-based (use only if you already know exact character offsets) { "type": "insert", "position": N, "text": "..." } { "type": "delete", "position": N, "length": N } { "type": "replace", "position": N, "length": N, "text": "..." } Position semantics: N is a UTF-16 code unit offset (same as JavaScript String.length / .indexOf). ASCII chars = 1 unit each; em-dash and most accented Latin = 1 unit; emoji like 🎉 = 2 units (surrogate pair). If your text has non-BMP chars (emoji etc.), compute positions programmatically rather than estimating, or use the text-anchored ops above which sidestep position arithmetic entirely. Examples -------- # Fix a missing list item — anchor lets you skip counting characters curl -X PATCH https://api.odocs.co/api/docs/$ID \ -H Content-Type:application/json \ -d '{ "operations": [ { "type": "insert-after", "anchor": "Item 1\n", "text": "Item 2\n" } ], "author": "MyAgent" }' # Rename a term throughout (unique match → no occurrence needed) curl -X PATCH https://api.odocs.co/api/docs/$ID \ -H Content-Type:application/json \ -d '{ "operations": [ { "type": "replace-text", "find": "good", "replace": "excellent" } ] }' # Multiple matches → disambiguate with 0-based occurrence curl -X PATCH https://api.odocs.co/api/docs/$ID \ -H Content-Type:application/json \ -d '{ "operations": [ { "type": "replace-text", "find": "foo", "replace": "bar", "occurrence": 1 } ] }' Error codes ----------- 400 Bad request — missing fields, unknown op type, position out of bounds 404 Document not found 409 Version mismatch — re-read and retry 429 Rate limited — back off and retry Rate limits ----------- POST /api/docs: 10/min per IP All other endpoints: 60/min per IP Conflict detection ------------------ Always use expectedVersion when editing existing docs. Workflow: 1. GET /api/docs/:id → get version N 2. Compute your operations 3. PATCH with expectedVersion: N 4. If 409: re-read, recompute, retry Doc lifecycle ------------- Docs are EPHEMERAL — RAM only. By design (draw.io-style: no account, no save button). Typical lifetime: ~24 hours after the last edit or last live viewer disconnects, whichever is later. Docs may also be lost on server restart. If you need to keep something, download a markdown export. MCP Server ---------- Agents that support the MCP (Model Context Protocol) can connect directly. Endpoint: https://api.odocs.co/mcp Auth: None (rate limited by IP, same as REST API) Protocol: MCP over Streamable HTTP (not stdio) Protocol handshake (3 steps, required on every new session): 1. POST /mcp with initialize (no session header) Headers: Content-Type: application/json, Accept: application/json, text/event-stream Body: {"jsonrpc":"2.0","id":1,"method":"initialize", "params":{"protocolVersion":"2024-11-05","capabilities":{}, "clientInfo":{"name":"my-agent","version":"1.0"}}} Response has mcp-session-id header — SAVE THIS 2. POST /mcp with notifications/initialized (with mcp-session-id header) Body: {"jsonrpc":"2.0","method":"notifications/initialized"} (no "id" field — notifications don't get responses) 3. POST /mcp with tools/call or tools/list (with mcp-session-id header) All subsequent requests include: mcp-session-id: Tools available: create-document Create doc. Args: title(required), author?, content? Returns: {id, url, title} get-document Full doc + version. Args: id(required) Returns: {id, title, content, version, url} patch-document Edit doc. Args: id, operations(required), author?, expectedVersion? Supports text-anchored ops (insert-after, insert-before, replace-text, delete-text) and position-based ops (insert, delete, replace) — see PATCH op section above. Returns: {ok, version} list-versions Version history. Args: id(required) Returns: {versions:[{index,timestamp}]} get-version Get content of a specific version snapshot. Args: id(required), index(required) Call list-versions first to find the index you want. Returns: {timestamp, title, content} get-instructions Returns this agents.txt content (the full integration guide). Useful for MCP-only clients that landed without visiting the frontend. Args: none. NOTE: no list-documents tool — doc UUIDs are capability tokens. Knowing the UUID = access. No enumeration endpoint by design. Errors: JSON-RPC errors in {error:{code,message}}. Tool errors: isError flag in result content. Example MCP create-doc flow: 1. POST /mcp + initialize → response mcp-session-id header 2. POST /mcp + notifications/initialized (with session header) → 202 3. POST /mcp + tools/call (name:create-document, args:{title:"My Doc"}) → 200, returns {id:"550e8400-...",url:"/#/doc/550e8400-...",title:"My Doc"} Workflows --------- Create and share (REST or MCP): 1. POST /api/docs {title:"Spec"} → {id:"..."} 2. Return the URL: https://odocs.co/#/doc/ 3. Agent or human edits at that URL — all changes sync in real time Read-then-patch safely (avoid overwriting human edits): 1. GET /api/docs/:id → {version: N} 2. Compute your operations 3. PATCH /api/docs/:id {operations:[...], expectedVersion: N} 4. If 409: re-read (get new version), recompute, retry Read-then-patch in MCP: 1. tools/call get-document → note version in response 2. tools/call patch-document with expectedVersion from step 1 3. If error includes "409" or "version mismatch": retry from step 1 Version history: 1. GET /api/docs/:id/versions → list of snapshots 2. GET /api/docs/:id/versions/:index → content at that snapshot (MCP: use list-versions tool; individual snapshots via REST) Agent docs URL -------------- https://odocs.co/agents.txt (this file — plain text, curl-friendly)