Use ctxindex from an agent
Give any shell-capable agent deterministic context access through the CLI.
ctxindex integrates with agents through its CLI. Claude Code, Codex, OpenClaw, and any other agent that can execute shell commands can use the same deterministic interface.
Use ctxindex with an installed binary. From the repository root during development, replace it with bun cli.
Why the CLI is the integration surface
There is no ctxindex MCP server. The CLI already provides the properties an agent integration needs:
- deterministic commands, escaped low-token text, and compact
--format jsonoutput; - stable exit codes for branching and recovery;
- one provider-neutral vocabulary across mail, calendars, files, and extension-defined domains;
- registry-derived descriptions of loaded Profiles, Source Adapters, fields, formats, and Actions.
An MCP server or agent-specific adapter would duplicate that contract and introduce another surface that could drift. Keep agent policy, approval, and multi-step reasoning in the agent; use ctxindex for context access and typed provider Actions.
Start by discovering the loaded interface
Do not hard-code kinds, Source options, formats, or Action schemas when the registry can report them.
ctxindex describe --full --format json
ctxindex source list --format json
ctxindex describe profile mail.message --format json
ctxindex describe adapter google.calendar --format jsondescribe is especially important when external Extensions are loaded: they can add Profiles and Source Adapters without adding provider-specific commands.
For an agent that supports portable skills, install the exact skill embedded in the CLI release:
ctxindex docs get-skill --output ./SKILL.mdThe skill teaches command composition; describe remains the live authority for definitions contributed by the Extensions installed on that machine.
Compose a read workflow
Search with an explicit scope
ctxindex search "quarterly planning" \
--realm company \
--kind mail.message \
--format jsonAn omitted --realm searches across all Realms. An explicit Realm is exact; there is no implicit global Realm.
Select a Ref from the JSON result
Search results return stable ctx:// Refs. Preserve the Ref rather than reconstructing provider identifiers.
Retrieve the complete Resource
ctxindex get 'ctx://01J00000000000000000000000/message/stable-message-id' --format jsonget returns locally materialized content when available and otherwise asks the owning Source Adapter to retrieve it.
Traverse related messages when needed
ctxindex thread 'ctx://01J00000000000000000000000/message/stable-message-id' --format jsonUse the returned thread to summarize a conversation or establish reply context. Do not infer a thread by grouping subjects yourself.
Compose a Draft workflow
Inspect the Action before generating input:
ctxindex describe action mail.message.draft.create \
--source company-mail \
--format jsonThen validate the agent's proposed content against the returned schema and invoke the Action through one explicit mailbox Source:
cat > /tmp/ctxindex-draft.json <<'JSON'
{
"to": ["recipient@example.com"],
"subject": "Project update",
"bodyText": "The project is ready for review."
}
JSON
ctxindex action run mail.message.draft.create \
--source company-mail \
--input /tmp/ctxindex-draft.json \
--format jsonThe result includes the normalized Draft Resource Ref. Text composed in an agent conversation is not a Draft until this provider-persisting Action succeeds. ctxindex does not send mail.
For a threaded reply, first use get to materialize a complete parent in the same selected Source. Then use the strict reply branch; it accepts only the parent Ref and body text:
ctxindex get 'ctx://01J00000000000000000000000/message/stable-message-id' --format json
ctxindex action run mail.message.draft.create \
--source company-mail \
--input '{"replyToRef":"ctx://01J00000000000000000000000/message/stable-message-id","bodyText":"Thanks for the update."}' \
--format jsonReply Draft updates require the complete local Draft and parent in that Source and must repeat the Draft's immutable replyToRef. The reply update branch accepts exactly {ref, replyToRef, bodyText}; it does not accept recipient or subject overrides. See Mail workflows for both complete update shapes.
Choose output for the consumer
Use --format text on search, get, thread, Artifact list, status, and Source, Realm, Account, OAuth App, and Extension inventories when an agent benefits from fewer repeated JSON keys: collections are escaped TSV and get is a complete labeled Resource envelope with compact nested payload JSON. TSV uses \N only for null and escapes literal backslashes. Use --format json (or -f json) when the caller needs typed structured fields. Omitted output selection is destination-aware: pretty on a TTY, text through a pipe.
Pretty output is terminal-width-aware and switches long rows, including Microsoft message Refs, to vertical cards without ellipsizing values. Refs remain opaque and copyable in every mode.
Agent execution rules
- Select
--format textfor deterministic low-token reads or--format jsonfor typed envelopes; never scrape pretty output. - Check the process exit code before consuming output.
- Keep Source selection explicit for Actions.
- Preserve per-origin warnings from search; one provider failure can coexist with valid results from other origins.
- Use
describeoutput as the authority for loaded vocabulary and input schemas.