Agent-assisted sessions
The session parsers reach into each tool's internal storage, and internals change. ingest_context inverts the direction: the harness's own agent formats its session against a published schema and pushes it in. The prompt is the adapter, which means every harness that speaks MCP is supported, including ones that don't exist yet. Free core.
The fallback ladder
| Rung | Mechanism | When | Tier |
|---|---|---|---|
| 1 | Automatic parsers (8 tools) | Default on supported harnesses; invisible | Pro |
| 2 | ingest_context + a pasted prompt | Parser unavailable, broken, or stale; any unsupported harness | Free core |
| 3 | Manual export/import | Everything else | Free core |
Parsers stay the polished default; ingest is the universal floor. If sessions look empty or stale in the dashboard, rung 2 is the fix, and the dashboard hands you the prompt.
Two doors, one schema: ingest_context (this page) is the enveloped bulk/agent door; save_session takes the same session fields directly and infers the harness from the connected client. Both feed the same store, and both understand threads and handoffs. See Threads & handoff.
How it works
- You paste a short prompt into whatever agent you're using (snippets below).
- The agent summarizes its own session and calls
ingest_context. - ctxfile validates strictly, redacts, stamps provenance, and stores the record locally. Malformed payloads come back with field-by-field errors the agent fixes itself.
- The digest appears in the
sessionsarray of the next snapshot, loudly labeled(agent-reported via ingest_context).
The schema, version 2
{
"ctxfile_ingest_schema": "2", // "1" payloads are still accepted
"source": {
"harness": "claude-code | cursor | codex | opencode | gemini-cli | aider | openclaw | hermes
| chatgpt | claude | grok | perplexity | le-chat | custom:<name>",
"harness_version": "optional"
},
"session": {
"session_id": "harness-native id if available (else ctxfile hashes the content)",
"started_at": "ISO 8601 or null",
"ended_at": "ISO 8601 or null",
"summary": "required: what the session did and why",
"key_decisions": ["..."],
"files_touched": ["..."],
"open_items": ["..."],
// v2: threads and lineage
"thread": "durable thread title, e.g. Q3 campaign (optional)",
"continues_from": "session_id of the predecessor session (optional)",
// v2: the handoff package; all six enforced when handoff is true
"handoff": false,
"state": "done / in progress / not started",
"gotchas": ["what the next agent would trip on"],
"artifacts": [{ "ref": "src/api.ts", "role": "endpoint being migrated" }],
"suggested_first_prompt": "the prompt whoever resumes should start from"
}
}Limits: summary up to 8,000 characters, list items up to 500 each, 20 ingests per minute (shared with save_session). Unknown fields are rejected, not ignored, so drifted prompts fail loudly instead of storing garbage. Version "1" payloads remain valid forever; they are v2 minus the thread and handoff fields. Threads, lineage, and the handoff contract are documented in Threads & handoff.
Provenance and review
ingest_context is a write path fed by LLM output, so every record carries provenance from day one: which harness, when, reported_by: agent, and a revision history on re-ingest. Downstream agents see the content labeled as agent-reported untrusted data, the same posture as everything else in a snapshot. Review and prune any time:
ctxfile ingest list # id, harness, session, revision, updated, summary ctxfile ingest rm <id> # delete one record
Dedup: records are identified by the harness's native session id (or a content hash). Re-ingesting the same session updates the record with history rather than duplicating it, and if a Pro parser reports the same session, the parser wins: higher-fidelity source.
Prompt snippets
Copy, paste into the agent, done. These are versioned with the schema; when a new harness ships, the "connector" is a markdown snippet, and community PRs for new harnesses are welcome.
Any MCP agent (generic)
Review this entire session from the beginning. Then call the ctxfile ingest_context tool with exactly this shape: - ctxfile_ingest_schema: "2" - source.harness: "custom:<your-tool-name>" (lowercase, digits, hyphens) - session.summary: a concise digest of what this session did and why - session.key_decisions: the choices that will matter next session - session.files_touched: paths you created or changed - session.open_items: what is unfinished or blocked - session.thread: the thread name, if I gave this work one If the tool returns a validation error, fix the listed fields and call it once more with the corrected payload.
Claude Code
Using our conversation so far, call the ctxfile ingest_context tool: set ctxfile_ingest_schema to "2", source.harness to "claude-code", and fill session.summary (what we did and why), session.key_decisions, session.files_touched, and session.open_items from this session. Include session.thread if I named this work. If validation fails, correct the listed fields and retry once.
Cursor
Summarize this Cursor session, then call the ctxfile ingest_context tool: ctxfile_ingest_schema "2", source.harness "cursor", session.summary with the digest, plus key_decisions, files_touched, and open_items arrays. On a validation error, fix the listed fields and call it again.
Codex CLI
Recall what this session accomplished, then call the ctxfile ingest_context tool: ctxfile_ingest_schema "2", source.harness "codex", session.summary with a concise digest, and key_decisions / files_touched / open_items arrays. If the tool rejects the payload, fix the fields it lists and retry once.
What this is not
- Not a replacement for the parsers: on supported harnesses the automatic path remains the Pro experience and wins conflicts.
- Not an open write API: ingest accepts session digests against this strict schema only. General writable context is the Team tier's design, behind permissions and audit.
- Not hosted anything: ingest is a local MCP tool, same trust boundary as the rest of ctxfile.