--- name: ctxd-client description: Use when an LLM agent needs to read or update project context via the Context Dossier (CTXD) daemon. Covers OAuth authentication, MCP tool discovery, read-only and write endpoints, and the workflow for keeping project context current. version: 1.0.0 author: Hermes Agent license: MIT platforms: - linux - macos metadata: hermes: tags: - context-management - ctxd - mcp-client - oauth - project-context related_skills: - project-context-management - native-mcp --- # CTXD Client — LLM Agent Guide Use when an LLM agent (Claude Desktop, Codex CLI, Hermes, custom harness) needs to read or update project context stored in Context Dossier (CTXD). ## Overview CTXD is a single source of truth for multi-harness project context. It exposes: - **Public MCP** (`/mcp`) — OAuth read + write (scope-gated) on the public host - **Hermes / automation** — same `http://:9091/mcp` with `CTXD_API_KEY` (full tool surface) Public host: `https://ctxd.cubecraftlabs.com` (OAuth + MCP + landing page + dashboard). ## Connection URLs | Surface | URL | Auth | |---------|-----|------| | Public OAuth MCP (read + write) | `https://ctxd.cubecraftlabs.com/mcp` | OAuth `ctxd.read` and/or `ctxd.write` | | Legacy aliases | `/readonly/mcp`, `/oauth/mcp` | Same behavior as `/mcp` for OAuth | | OAuth discovery | `https://ctxd.cubecraftlabs.com/.well-known/oauth-authorization-server` | Public | | DCR registration | `POST https://ctxd.cubecraftlabs.com/oauth/register` | Public | | Landing page | `https://ctxd.cubecraftlabs.com/` | Public | ## OAuth Flow 1. **Discover** the authorization server metadata at `/.well-known/oauth-authorization-server` 2. **Register** a client via `POST /oauth/register` (DCR) with your redirect URI 3. **Authorize** — open `/oauth/authorize` in a browser; an admin must approve 4. **Exchange** the authorization code for tokens at `POST /oauth/token` 5. **Use** the access token as `Authorization: Bearer ` on MCP connections (Streamable HTTP for read; SSE for write — see Connection URLs) ### Scopes | Scope | Grants | |-------|--------| | `ctxd.read` | `list_projects`, `get_project_context`, `search_context`, `get_project_tags`, `list_files`, `get_file`, `get_client_guide` | | `ctxd.write` | `update_file`, `set_project_tags`, `sync_to_project`, `get_client_guide` | Request both scopes for full read+write in **one connector**: `scope=ctxd.read ctxd.write` **Admin:** In the Web UI → Admin → OAuth clients, set **allowed scopes** per client (create form or **scopes** on an existing row). Tokens cannot exceed what the client is allowed, even if the user requests more at authorize time. ### Redirect URIs by Platform | Platform | Redirect URI | |----------|-------------| | Claude Desktop | `https://claude.ai/api/mcp/auth_callback` | | Claude Code | `http://localhost:5555/oauth/callback` | | Codex CLI | `http://localhost:7777/oauth/callback` | | Custom | Your app's documented OAuth callback | ### Token Lifetime Access tokens expire per server config (default ~1 hour). Refresh tokens are issued alongside access tokens. Use `POST /oauth/token` with `grant_type=refresh_token` to rotate. ## MCP Tools ### First Call — Always | Tool | Description | |------|-------------| | `get_client_guide` | Return the locked LLM-CLIENT.MD guide. **Call this first in every session.** No arguments. Covers OAuth, MCP tools, read/write endpoints, version-checked updates, and error handling. | The guide lives in the `ctxd-docs` project as `LLM-CLIENT.MD`. It is **locked** — cannot be updated or deleted by any MCP/API client. If you need the guide updated, ask an admin to edit it via the Web UI. ### Read-only tools (require `ctxd.read` on the same connector) | Tool | Description | |------|-------------| | `list_projects` | All projects with version numbers | | `get_project_context` | Compiled markdown of all context files for a project | | `search_context` | FTS5 full-text search across all projects | | `get_project_tags` | Metadata tags for a project | | `list_files` | All context files in a project (multi-file mode) | | `get_file` | Single file with metadata header | ### Write tools (require `ctxd.write` on the same connector) | Tool | Description | |------|-------------| | `update_file` | Update a single context file with optimistic version checking | | `set_project_tags` | Replace all metadata tags for a project | | `sync_to_project` | Write CONTEXT.MD as AGENTS.md + symlinks to project root | ## Workflow: Reading Context ``` 1. get_client_guide() → read the locked client guide first 2. list_projects() → find the project slug 3. get_project_context(project_id) → read compiled context or list_files() + get_file() → read individual files ``` The compiled view returns all files concatenated with `## FILENAME` headers and a metadata block at the top. ## Workflow: Updating Context ``` 1. get_file(project_id, file_path) → get current content + version 2. update_file(project_id, file_path, content, base_version) → base_version must match current version (optimistic locking) → returns {"ok": true, "version": N+1} or {"ok": false, "error": "version_conflict"} 3. On conflict: re-read, merge, retry ``` ### What to Update - **CONTEXT.MD** — canonical project overview (synced as AGENTS.md to repos) - **DECISIONS.MD** — architecture decisions, rationale - **RUNBOOKS.MD** — deploy, troubleshoot, operate procedures - **PROMPTS.MD** — project-specific prompts for different harnesses - **GLOSSARY.MD** — project-specific terms, acronyms ### What NOT to Put in Context - Session progress logs (use session_search or audit trail) - Temporary TODO state - Single-session debugging notes - Secrets, keys, tokens ## Locked Files | File | Protection | |------|-----------| | `CONTEXT.MD` | Cannot delete — canonical synced file | | `LLM-CLIENT.MD` | Cannot update or delete — locked client guide | Both return `403 cannot_update_locked` on PUT and `400 cannot_delete_context` on DELETE. ## Discipline 1. **Call `get_client_guide()` first** in every session 2. **Read context at the start of every session** for the project you're working on 3. **Update context immediately** when a durable fact changes — not "next session" 4. **Use `base_version`** to avoid overwriting concurrent edits 5. **Don't put session progress in project context** — that's what session history is for ## Error Handling | Error | Meaning | Action | |-------|---------|--------| | `version_conflict` | Someone else updated the file | Re-read, merge, retry with new `base_version` | | `not_found` | Project or file doesn't exist | Check slug spelling; create project via Web UI | | `invalid_grant` | OAuth token expired or wrong scope | Refresh token or re-authorize with correct scope | | `forbidden` | Wrong scope for the tool | Request `ctxd.write` for write tools; `ctxd.read` for read tools (same MCP URL) | | `cannot_delete_context` | Tried to delete CONTEXT.MD or LLM-CLIENT.MD | Protected file — update content instead | | `cannot_update_locked` | Tried to update LLM-CLIENT.MD | Locked guide — ask admin to update via Web UI | ## Verification Checklist - [ ] OAuth client registered with correct redirect URI - [ ] Admin approved the authorization (browser session or approval key) - [ ] Access token obtained with `ctxd.read` (and `ctxd.write` for updates) - [ ] `get_client_guide` returns the LLM client guide - [ ] `list_projects` returns expected projects - [ ] `get_project_context` returns compiled markdown with metadata header - [ ] `update_file` succeeds with correct `base_version` - [ ] Audit log shows the write operation