# protocol — On-demand knowledge for AI agents Succinct markdown-native, intelligent, searchable, auto-indexing, trigger-sensitive, impulse-based knowledge and task tracking. Fetch when you need it, discard when done. ## Why Three things developers reach for and three places they fail: - **Skills** — bloat the preload. You pay context tax for tools you never call this session, and you have to predict what you'll need before the work starts. - **File-based memory** (`CLAUDE.md`, `.cursorrules`, `.ai/` folders) — lives in one repo, has no search, no triggers, no version history, and can't be shared across projects. - **File-based tasks** (`TODO.md`, sticky-note files) — no auto-indexing, no triggers that wake them up at the right moment, no cross-session visibility. Protocols are the same markdown you'd write anyway, but on a backend that AI-extracts tags + triggers + a summary, full-text-indexes every version, and serves them on demand. Trigger-sensitive entries surface when the situation matches; impulse-flagged entries track initiatives that activate when their condition fires. ## Install (once) This is the only call that uses raw `curl` — you don't have `curly` yet: ```bash curl -sL https://api.protocol.supply/@protocol/install.md ``` The install protocol walks you through installing `curly` (a tiny service-aware curl wrapper) and dropping a token in `~/.curly.conf`. After that, every protocol call is `curly protocol `. ## Why curly, not curl Tokens go in `~/.curly.conf`, never on the command line. That protects against shell-history, `ps aux`, and agent-transcript leaks that ad-hoc `curl -H "Authorization: Bearer ..."` calls produce — every command an agent runs is loggable, and a token in argv is a durable disclosure. Anonymous reads still work for discovery (this file, public docs, public repos), so an agent can learn protocol.supply without a token. But for any real session — your private repos, ingested content, impulse tracking — the token is what unlocks them. `curly` keeps that token off the wire and out of every transcript. ## Cheat Sheet ```bash curly protocol bootstrap # Load core protocols at session start curly protocol "bootstrap?include=@{repo}/{slug}" # Bootstrap + inline a specific protocol (project context, etc.) curly protocol "bootstrap?topic=" # Bootstrap + append a per-user topic section # Discover — the four filesystem-equivalent verbs # URL after /ls and /find is a ref fragment (prefix of the canonical ref grammar) curly protocol /ls # List accessible repos (`ls /`) curly protocol /ls/@{repo} # List entries in a repo curly protocol /ls/@{repo}/{path} # List entries under a path curly protocol /ls/@{repo}/{path}/{slug}_/ # List children + files of an entry curly protocol "/find?name=*foo*" # Locate by name glob across all (`find -name`) curly protocol "/find/@{repo}/{path}?name=*foo*" # Locate scoped to a ref fragment curly protocol "/@{repo}/{slug}?peek=true" # Peek — metadata only, no body (`stat`) curly protocol "search?q=" # Full-text search (`grep -r`) curly protocol @{repo}/{slug} # Fetch one protocol curly protocol "@{repo}/{slug}?max=200t" # Fetch LLM-condensed to ~200 tokens curly protocol "fetch?include=@a/x,@b/y" # Batch fetch (no core, just the listed refs) curly protocol llms.txt # This file curly protocol /@{your-user-id}/log/append -X POST -d '{"text":"…"}' # Append a block to a protocol (daily log, ADR) curly protocol /impulse/{id}/append -X POST -d '{"text":"…"}' # Append to an impulse's content curly protocol /impulse/{id}/digest -X POST -d '{"action":"…"}' # Append a structured audit entry ``` ### Composing your bootstrap — `?include=` `?topic=` `?repos=` `?tags=` The bootstrap response is composable. Stack params to shape exactly what loads: | Param | What it adds | Example | |-------|--------------|---------| | `?include=@repo/slug,…` | **Inline specific protocols** alongside the core (canonical refs only — bare slugs rejected as ambiguous) | `bootstrap?include=@agentsite/project` | | `?topic=name,…` | Append per-user topic sections (entries in your personal repo tagged `metadata.bootstrap_topic`) | `bootstrap?topic=business,personal` | | `?repos=slug,…` | Override the default bootstrap repo set (also available as a path segment: `/bootstrap/protocol,wildeagency`) | `bootstrap?repos=protocol,wildeagency` | | `?tags=name,…` | Include up to 20 entries from default repos whose `metadata.tags` match any of these | `bootstrap?tags=testing,review` | | `?header=0` | Suppress the leading HTML-comment header (byte-perfect output for caching / hashing) | `bootstrap?header=0` | All composable: `bootstrap?topic=business&include=@protocol/devour-competitor`. Dedup runs across core + include + topic sections so the same protocol isn't inlined twice. For a persistent "always include these" list with per-row depth control, use the bootstrap editor at `/settings/bootstrap` — it pins to your account and applies to every `/bootstrap` call automatically. Leading `/` on `` is optional. Search operators: `tag:testing` `repo:protocol` `-deprecated` `"exact phrase"`. Write surface: `@protocol/append` (cookbook covering all three) and `@protocol/protocol-api` (full reference). Section anchoring is case-insensitive by default. ### Sizing your fetch — `?max=N[unit]` (never `| head`) Agent harnesses (Claude Code, others) silently truncate command output around 200 lines. `curly protocol @protocol/spec | head -200` chops the back half of any fetch without telling you what was lost — you build on half a document and don't know it. **Rule:** ask the server for less, don't truncate locally. `?max=N` returns an LLM-condensed version sized to your budget and emits cut metadata so you can see what happened. ```bash # Wrong — silent truncation, no signal what was cut curly protocol @protocol/spec | head -200 # Right — server condenses to fit, structure preserved curly protocol "@protocol/spec?max=200" # 200 lines curly protocol "@protocol/spec?max=2000t" # 2000 tokens ``` Response carries `condensed: true`, `effective: `, `source_chars: ` so you know it was shrunk and by how much. Same cache backs bootstrap include rows — repeat fetches are warm. **Units.** Bare number = lines (matches `head -N` reflex). Suffix overrides: | Form | Unit | Ladder (quantized down) | |------|------|-------------------------| | `?max=50` | lines (default) | {3, 10, 20, 50, 100, 200, 500, 1000} | | `?max=200t` | tokens | {50, 200, 400, 1000, 2000, 4000, 10000, 20000} | | `?max=1600c` | characters | {200, 800, 1600, 4000, 8000, 16000, 40000, 80000} | Values between steps round down. Above the top → full content. Omit `?max` for full. In lines mode the line count is a strict cap (clients downstream may be truncating); tokens/chars are soft (+/- 15%). ## Public Repos | Repo | What's in it | |------|--------------| | `@protocol` | Core workflow protocols — bootstrap, search, install, orchestrate, looping, chunking, debugging, etc. | | `@integrations` | Service-aware patterns — `curly` wrapper, GitHub, Notion, Apify, Linear, n8n, Slack | | `@skills` | Anthropic Agent Skills converted to protocols — searchable + on-demand instead of preloaded | | `@knowledge` | Distilled knowledge artifacts (frameworks, facts, summaries) extracted from long-form sources | | `@content` | Long-form content summaries — slugs follow `-` | Browse one repo: `curly protocol /repo/{slug}/entries`. Search across all: `curly protocol "search?q="` (no repo filter = everything). ## Private + Team Repos Beyond the public catalog, every account gets private repos for content scoped to you or your team. Common uses: - **Agent memory** — accumulated context (preferences, past decisions, learned patterns) so your agent doesn't start cold every session - **Per-agent memory** — separate repos per agent (one per user_id) so contexts don't collide - **Per-agent tasks** — impulse-flagged entries track initiatives an agent is working on; they surface when their trigger condition fires - **Shared agent task board** — a team repo where multiple agents (or humans) coordinate via impulses, with version history on every change - **Repeating processes** — deploy checklist, code-review flow, incident runbook stored as protocols the agent fetches reflexively Create a repo: `curly protocol repo -X POST -d '{"slug":"my-repo","visibility":"private"}'`. Grant team access: `curly protocol repo/{slug}/members -X POST -d '{"email":"teammate@x.com","role":"member"}'`. Tokens are repo-scoped — a token only sees repos its owner has access to. ## Taxonomy Each entry carries metadata used by search and the trigger map: - **`tags`** — categorical labels (`testing`, `auth`, `ci`, etc.). Filter with `tag:`. - **`triggers`** — phrases that should make an agent reach for this protocol (`"stuck on a bug"`, `"before merging"`). - **`aliases`** — alternate refs that resolve to the same entry. - **`type`** — `protocol` (workflow), `appendix` (reference), `knowledge` (distilled artifact). - **`impulse`** — when `true`, the entry is an initiative/task being tracked — surfaces when its trigger condition fires. (Use the dashboard to manage; agents see them via bootstrap when relevant.) The bootstrap response includes a trigger map (situation → protocol) so agents pick the right protocol without having to search first. ## Agent Integration Drop this into CLAUDE.md / .cursorrules / system prompt so your agent reaches for protocols on demand. **Minimal:** ``` ## protocol — On-demand knowledge Use curly to fetch protocols on demand: - Bootstrap at session start: curly protocol bootstrap - Search when stuck: curly protocol "search?q=" - Fetch a specific protocol: curly protocol @repo/slug ``` **Project-specific** — point at your project's protocol so every session boots with the right context. Combine with a topic to also pull in your personal flavor (dev / business / personal / …): ``` Important! Start every session or after every clear with: curly protocol 'bootstrap?topic=dev&include=@agentsite/project' Then read workspace/spec.md for project context. ``` `?include=` is canonical refs only (`@repo/slug`); `?topic=` resolves to entries in your personal repo tagged `metadata.bootstrap_topic = `. See "Composing your bootstrap" above for the full param list. Substitute `@agentsite/project` with whatever protocol carries your project's session-start context. Platform-specific setup (Claude Code skill, OpenClaw skill, Cursor, ChatGPT): ```bash curly protocol @protocol/agent-config-integration ``` ## Endpoints Reads default to markdown; send `Accept: application/json` (or append `?format=json`) for the JSON shape. The legacy `.md` URL suffix still works as an explicit alias. | Method | Path | Description | |--------|------|-------------| | GET | /bootstrap | Core protocols + index | | GET | /ls | List accessible repos (filesystem `ls /`) | | GET | /ls/{reff} | List under a ref fragment (`@repo[/path][/parent_/sub]`) | | GET | /find?name= | Locate entries by name glob across all accessible | | GET | /find/{reff}?name= | Locate scoped to a ref fragment | | GET | /@{repo}/{slug} | Fetch protocol by ref | | GET | /@{repo}/{slug}?peek=true | Peek — entry metadata only, no body | | GET | /search?q= | Full-text search | | GET | /fetch?include= | Batch fetch (comma-separated refs) | | POST | /entry | Create entry (returns entry + AI review) | | PUT | /entry/{id} | Update entry (creates new version) | | PATCH | /entry/{id} | Patch content: `{old_string, new_string, replace_all?}` | | POST | /ingest | Ingest raw content → structured knowledge | Full reference (auth, repos, members, ingest options, rate limits): ```bash curly protocol @protocol/protocol-api ``` ## Bootstrap (edit on behalf of the user) The user's bootstrap shapes what every agent in their account loads at session start. As an agent, you can read it and propose edits — adding a protocol you keep fetching, demoting one nobody reads, or provisioning a fresh user's stack from scratch. POSTs are idempotent: repeating the same `(kind, ref)` returns the existing row with `existed: true`. | Method | Path | What it does | |--------|------|--------------| | GET | /user/bootstrap/config | List the user's includes | | POST | /user/bootstrap/config | Add one include — `{kind, ref, depth?, label?}` (idempotent — repeating returns existing) | | PATCH | /user/bootstrap/config/{id} | Update enabled/depth/label/ordinal | | DELETE | /user/bootstrap/config/{id} | Remove | | PUT | /user/bootstrap/config/order | Reorder — `{ids: [...]}` | | GET | /user/bootstrap/catalog | Available section types | | GET | /user/bootstrap/preview | Composed bootstrap + token estimate | | GET | /user/bootstrap/suggestions | Adds suggested from the user's fetch + search history | `kind` ∈ `protocol | repo | section`. `depth` ∈ `title | short | full`. `short` is the sensible default. See `@protocol/bootstrap-edit` for the agent discipline (when to add, when to demote, how to confirm). ## Comments (file feedback / suggestions / wins) When you hit friction, find a missing feature, or notice a magic moment worth recording — file a comment. It goes to the user's own triage queue (and on escalation, to platform support) with the surrounding context preserved so a human can act without back-and-forth. ```bash curly protocol /comment -X POST -d '{ "type": "bug", "title": "Search returns raw imports without --type filter", "body": "Tried /search?q=lupus expecting filtered hits. Got 7 raw imports.", "target": { "kind": "endpoint", "ref": "/search/entries" } }' ``` `type` ∈ `comment | suggestion | bug | feature_request | change_request | win | magic_moment`. `target` accepts either a concrete ashid (`{id: "entr_…"}`, kind derived from the prefix — works for entries, impulses, repos, bootstrap includes, anything ashid-prefixed) or an abstract pointer (`{kind: "platform" | "site" | "endpoint" | "error" | …, ref: "free-form pointer"}`). For entry targets, an optional `anchor` ({section, quote, lineStart, lineEnd}) pins the comment to a specific section/line. | Method | Path | What it does | |--------|------|--------------| | POST | /comment | File a comment | | GET | /comment/mine | Your filings (filter: type, status, context, targetId, targetRef) | | GET | /comment/by-target?targetRef=… | Comments on a specific target | | GET | /comment/{id} | Fetch one | | PATCH | /comment/{id} | Edit title/body/anchor/metadata | | POST | /comment/{id}/escalate | Forward to platform support | | POST | /comment/{id}/triage | Mark acknowledged | | POST | /comment/{id}/resolve | Close | | DELETE | /comment/{id} | Remove | See `@protocol/comment` for the agent-side filing discipline (what to include in the body, when to escalate vs resolve locally). ## Protocol Refs `@{repo}/{slug}` returns markdown by default. Send `Accept: application/json` (or append `?format=json`) for the JSON shape. The legacy `.md` URL suffix still works as an explicit alias. Examples: `@protocol/orchestrate`, `@mycompany/auth`. ## Rate Limits 100 req/hour per token. Headers: `X-RateLimit-Remaining`, `X-RateLimit-Reset`. Limit hit = HTTP 429 with `Retry-After`.