Pick your surface
| Your harness | Use | Why |
|---|---|---|
| Inner-loop shell work (Claude Code, terminal agents, scripts) | The CLI, plus the forked skills in Claude Code | --json machine output, -o <file> keeps large payloads out of your context window, stable exit codes to branch on |
| Chat or IDE assistant (Cursor, Windsurf, any MCP client) | The remote MCP server at /mcp | Zero install, streamable HTTP, two tools: caesar_search and caesar_read |
| Building an application | Python SDK or TypeScript SDK; caesar-search/ai for Vercel AI SDK agents | Typed clients with retries built in; caesarTools() is a drop-in tool set |
| Everything else | Raw HTTP — spec served at /openapi/public.json on the API host | See the API reference |
Same three verbs everywhere
| Verb | REST | CLI | MCP | SDKs |
|---|---|---|---|---|
| Search | POST /v1/search | caesar-search search | caesar_search | client.search() |
| Read | POST /v1/document | caesar-search read | caesar_read | client.read() |
| Feedback | POST /v1/feedback | caesar-search feedback | not exposed | client.feedback() |
Conventions that hold on every surface
Wire fields are snake_case
doc_id, search_id, max_results, start_char, canonical_url — exactly as the API returns them. No surface converts to camelCase. Do not expect docId in any response.
One set of verbosity presets
verbosity (REST/SDKs), --format (CLI search), and response_format (MCP, AI SDK tools) are the same presets. Use compact in agent loops — it is the token-efficient choice. standard adds quotable passages; full adds provenance. See response shaping.
| Surface | Parameter | Values | Default |
|---|---|---|---|
| REST / SDKs | response.verbosity / verbosity | ids_only, compact, standard, full | standard |
| CLI | --format | ids_only, compact, standard, full | standard |
| MCP | response_format | compact, standard, full (ids_only falls back to compact) | compact |
| AI SDK tools | response_format | compact, standard, full | compact |
max_results is 1-50
REST and SDKs default to 10 and reject out-of-range values with400 validation_error. The CLI also defaults to 10 but rejects out-of-range values locally before any request is sent (bad_input, exit 2). MCP defaults to 8 and silently clamps out-of-range values into 1-50. The AI SDK tools (caesarTools()) also default to 8, like MCP.
Continue truncated reads with start_char
A truncated read reportstruncated: true with start_char and char_count (nested under content on REST/CLI/SDKs, top-level over MCP). Continue from start_char + char_count:
max_chars. A non-zero start_char forces full_document selection so offsets stay contiguous — a query passed alongside it will not excerpt.
Preserve identifiers, cite only returned URLs
doc_id and search_id are stable handles: thread them verbatim between search, read, and feedback. Cite only URLs the API returned (canonical_url, url, source_url) — never construct or guess a URL.
Errors and retries
All API errors use one envelope:X-RateLimit-Reset header says when the window resets. Do not retry other 4xx. The CLI mirrors errors as a JSON envelope on stderr and exits 2 (bad input), 3 (auth), 4 (API error), or 5 (timeout) — branch on exit codes, not output. See errors and rate limits.
Keyless works
CAESAR_API_KEY is optional. Keyless requests run on the anonymous tier (30 requests/second per IP on staging). A present-but-invalid key returns 401 invalid_api_key — it never falls back to anonymous. See authentication.
Close the loop with feedback
After acting on results, send feedback — it improves ranking. Useresult_helpful when a result answered the task and stale_result when content was outdated, with the search_id and doc_id you got back:
Install
Install for agents
Copy-paste install blocks per environment — Claude Code, MCP clients, skills directories, shell agents, the Vercel AI SDK, and raw HTTP — each with a verification step.