How to wire Claude Code, Codex CLI, opencode, OpenClaw, Hermes, or any other agent into Dory.
Dory is one shared memory service, not a per-agent library. Run the daemon over a markdown corpus, then point each agent at the same HTTP or MCP surface. Deployment URLs, corpus paths, and auth tokens are environment-specific and must stay outside the repo.
Agent-facing files:
| Surface | Path | Purpose |
|---|---|---|
| Shared agent skills | skills/dory-*/SKILL.md |
Portable wake/search/write/maintain/dream instructions for agents that support skill folders. |
| Shared policy snippet | scripts/agent-policy/dory-policy.md |
The global rule block installed into Claude Code, Codex CLI, and opencode rule files. |
| Agent installer | scripts/agent-policy/install.sh |
Idempotently registers the HTTP-backed MCP bridge, policy snippet, and Dory skill symlinks for Claude Code, Codex CLI, and opencode. |
| Claude/stdio bridge | scripts/claude-code/dory-mcp-http-bridge.py |
Stdio MCP compatibility process that forwards tools to a running Dory HTTP server. |
| Claude example config | scripts/claude-code/mcp.example.json |
Minimal HTTP-bridge MCP config. Replace URL/token for remote or TLS deployments. |
| Codex helper | scripts/codex/dory |
CLI wrapper that defaults to data/corpus and .dory/index in this repo. |
| OpenClaw plugin | packages/openclaw-dory/ |
Native OpenClaw memory-slot plugin package. |
| Hermes plugin | plugins/hermes-dory/ |
Hermes external memory provider package. |
| Live tool schema | GET /v1/tools |
HTTP-published MCP schema consumed by bridges and used as the contract source. |
Claude Code, Codex CLI, and opencode are rule and MCP clients. OpenClaw and Hermes are code-based clients configured through their own plugin/provider systems instead of the policy installer.
| Tool | MCP | HTTP | CLI | When to use |
|---|---|---|---|---|
dory_wake |
✓ | ✓ | ✓ | New session, post-compaction continuation, or real task switch — loads bounded hot context. |
dory_active_memory |
✓ | ✓ | ✓ | High-stakes or ambiguous replies — staged, task-specific retrieval. |
dory_search |
✓ | ✓ | ✓ | Find candidate sources. Use mode="exact" for unique markers. |
dory_get |
✓ | ✓ | ✓ | Read exact paths and hashes after search. |
dory_link |
✓ | ✓ | equivalents | Inspect neighbors, backlinks, or wikilink lint. CLI equivalents are neighbors, backlinks, and lint. |
dory_memory_write |
✓ | ✓ | ✓ | Preferred semantic write — subject is resolved, not path-first. |
dory_memory_propose |
✓ | ✓ | ✓ | Create a reviewable semantic write proposal with a dry-run preview. |
dory_memory_proposals |
✓ | ✓ | ✓ | List pending, applied, or rejected proposals. |
dory_memory_proposal_get |
✓ | ✓ | ✓ | Inspect a proposal before apply/reject. |
dory_memory_proposal_apply |
✓ | ✓ | ✓ | Promote a pending proposal after Dory checks that its route is still current. |
dory_memory_proposal_reject |
✓ | ✓ | ✓ | Archive a proposal that should not be promoted. |
dory_write |
✓ | ✓ | — | Exact-path markdown write when the target is known. |
dory_purge |
✓ | ✓ | ✓ | Guarded hard-delete for scratch and generated artifacts. |
dory_status |
✓ | ✓ | ✓ | Corpus, index, auth, and capability diagnostics. |
dory_research |
✓ | ✓ | ✓ | Bounded multi-source research artifact generation. |
dory_wakeonce at new session start, after context compaction, or at a real task switch. Pick the profile:codingfor project work (operational only),writingfor voice/content work (voice-first),privacyfor boundary-sensitive questions (boundary-only; do not treat it as a profile dump). Passprojectwhen the current project is known. If the wake block is still in context and the task has not changed, reuse it instead of calling wake again.dory_searchbefore any factual claim about projects, people, priorities, decisions, or current environment.dory_geton exact result paths before quoting or acting. It reads paths inside the configured Dory corpus, not arbitrary repo files cited as external evidence.dory_linkonly when relationships or backlinks matter. Bound dense project/core queries withmax_edges, and drop noisy families likelogs/sessions/viaexclude_prefixes. Responses includecount,total_count, andtruncatedso you can tell when the graph was capped.dory_active_memory(profile="coding|writing|privacy|personal|general", include_wake=false)when wake already ran and the reply needs task-specific retrieval. Prefer an explicit profile, passprojectorcwdso project state can be included, and passscope.session_keywhen the reply should use only the current session's recall evidence. If you passinclude_wake=true, active memory uses the profile's wake policy and avoids inlining unrelated personal context.
Treat wake as framing, not proof that every canonical file was loaded. Search + get is the authoritative read path.
Default search results include path, lines, snippet, evidence_class, confidence, and stale warnings. Debug-only internals (score, score_normalized, rank_score, and frontmatter) require debug=true; agents should trust the returned order instead of reading score fields. Prefer canonical/current evidence for current-state answers; treat inbox, raw, and session hits as supporting material unless the user explicitly asked for raw or recent material. Active memory may keep stale evidence as a fallback, but it prefers fresh durable hits when composing the returned block.
Write only when at least one of these is true:
- The user explicitly says remember, save, or update.
- A durable decision was made.
- Project state materially changed.
- A durable people, project, or current-truth fact was established.
Dry-run first when the route isn't obvious (dry_run=true). Inspect target_path, subject_ref, evidence_path, matched_by, preview, and message before committing. Include agent, session_id, or origin_surface when the write came from a specific client/session.
Prefer dory_memory_write for durable semantic writes. Keep subjects specific — a generic subject can resolve into an existing canonical page. Canonical target previews are labeled CANONICAL TARGET; live writes to canonical targets need allow_canonical=true after preview. Use force_inbox=true for tentative or review-needed material.
Use dory_memory_propose instead of a live write when the memory is plausible but needs review, when multiple agents are contributing shared context, or when the target is canonical and the agent is not sure it should commit. Proposals live under inbox/proposed/ with the dry-run route, preview, risk flags, source paths, and provenance. Review with dory_memory_proposal_get, then apply or reject. Apply re-runs the semantic route first and fails if the target no longer matches the stored dry run.
Use dory_write only when you know the exact path and have read the current hash with dory_get. Kinds: append, create, replace, forget. New files need frontmatter.title and frontmatter.type; use type: capture for inbox/**. replace and forget require expected_hash; forget also requires a reason.
forget retires memory but keeps the audit trail. Reserve dory_purge for exact generated, test, or scratch cleanup. Live purge needs a reason and a matching expected_hash.
HTTP write, purge, and semantic-write validation/backend failures return structured error details with code, message, and type fields. Agents should branch on detail.code instead of parsing free-form strings.
Start the server:
uv run dory-http --corpus-root <corpus> --index-root <index> --host 127.0.0.1 --port 8766Client environment:
export DORY_HTTP_URL=http://127.0.0.1:8766
export DORY_CLIENT_AUTH_TOKEN="$(uv run dory auth new codex)"When the server enforces tokens, clients must send:
Authorization: Bearer <token>
Browser /app and /wiki routes share the same login. /app is the Dory browser interface for status, proposals, settings, and wiki entry points. Browser login requires DORY_WEB_PASSWORD; without it, the login form returns 503 by design.
Native MCP:
uv run dory-mcp --mode stdioHTTP-backed bridge for hosts expecting a stdio MCP process:
python3 scripts/claude-code/dory-mcp-http-bridge.pyThe bridge reads DORY_HTTP_URL and DORY_CLIENT_AUTH_TOKEN from the environment. Default fallback is http://127.0.0.1:8766, so remote deployments need to set the URL explicitly.
By default the bridge runs one local session sync before dory_wake. That lets Claude see just-finished Codex/Claude/OpenClaw/Hermes sessions without waiting for the background shipper poll. Set DORY_SYNC_SESSIONS_ON_WAKE=false to skip this.
Restart open agent sessions after tool-schema changes because MCP hosts cache schemas per process. New sessions pull live schemas from /v1/tools.
From the repo root:
DORY_HTTP_URL=http://127.0.0.1:8766 ./scripts/agent-policy/install.shRegisters the HTTP-backed MCP bridge, inserts scripts/agent-policy/dory-policy.md into supported agent rule files, validates the bundled skills, and symlinks skills/dory-* into global skill folders. Idempotent.
Skill symlinks land in ~/.agents/skills, ~/.claude/skills, and ~/.codex/skills when the corresponding agent section is enabled. Flags: --dry-run, --skip-claude, --skip-codex, --skip-opencode, --skip-skills.
OpenClaw lives under packages/openclaw-dory/. Hermes lives under plugins/hermes-dory/. They use the same HTTP daemon and bearer-token model, but neither is installed by scripts/agent-policy/install.sh.
curl -X POST "$DORY_HTTP_URL/v1/wake" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"budget_tokens":1200,"profile":"coding","agent":"codex"}'
curl -X POST "$DORY_HTTP_URL/v1/search" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"active projects","k":5}'
curl -X POST "$DORY_HTTP_URL/v1/search" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"unique-marker","mode":"exact","k":5}'
curl -X POST "$DORY_HTTP_URL/v1/memory-write" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"action":"write","kind":"note","subject":"example-project","content":"Temporary note.","dry_run":true}'
curl -X POST "$DORY_HTTP_URL/v1/memory-write" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"action":"write","kind":"decision","subject":"example-project","content":"Ship by end of sprint.","allow_canonical":true}'
curl -X POST "$DORY_HTTP_URL/v1/memory-proposals" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"action":"write","kind":"fact","subject":"example-project","content":"Needs review before promotion.","proposal_id":"example-review"}'
curl -X POST "$DORY_HTTP_URL/v1/memory-proposals/apply" \
-H "Authorization: Bearer $DORY_CLIENT_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"proposal_id":"example-review","agent":"codex"}'This repo ships public-safe code, examples, and synthetic evals. Real corpus data, private eval questions, run artifacts, deployment domains, tokens, and machine-specific paths live outside the public tree.