The Halyard CLI scaffolds MCP client configs and syncs your coding-session logs back to Halyard as knowledge. For developers who want to wire up multiple clients at once, or feed agent sessions into the knowledge base. It is one on-ramp among several — you can also configure each client by hand from its own page.
Install
Section titled “Install”The package is @halyard/cli and the binary is halyard. Install it globally, or run it once without installing:
npm i -g @halyard/clipnpm dlx @halyard/cliAuthenticate
Section titled “Authenticate”halyard loginlogin runs a browser-based PKCE OAuth flow and writes your credentials to ~/.halyard/credentials.json.
For headless or CI environments, skip the browser flow by setting a token instead:
export HALYARD_TOKEN=sk_halyard_…Scaffold client configs
Section titled “Scaffold client configs”halyard setupsetup (alias init) writes the MCP server config for each client it supports:
| Client | What setup writes |
|---|---|
| Claude Code | Registers the halyard HTTP server |
| Cursor | Upserts halyard in .cursor/mcp.json, preserving existing servers |
| Codex | Adds [mcp_servers.halyard] to ~/.codex/config.toml |
Preview the changes without writing anything:
halyard setup --dry-runSync session logs
Section titled “Sync session logs”halyard syncsync discovers local coding-agent sessions, uploads them, and Halyard turns each one into searchable knowledge plus a per-person work imprint — cost (USD), turns, duration, token usage, and tool activity land as an agent_session_completed work event alongside your PRs and tickets. It tracks what it has already sent in ~/.halyard/sync-state.json so re-runs only pick up new or changed sessions.
Supported clients:
| Client | Where sessions are read from | Metrics captured |
|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl | Cost, turns, duration, tokens (incl. cache), tools |
| Codex CLI | ~/.codex/sessions/ | Cost, turns, duration, tokens, tools |
| Gemini CLI | ~/.gemini/tmp/<project>/chats/ | Cost, turns, duration, tokens (incl. cache), tools |
| OpenCode | Local OpenCode store, via opencode export | Cost (as computed by OpenCode), turns, duration, tokens, tools |
| GitHub Copilot CLI | ~/.copilot/session-store.db (needs Node ≥ 22.13) | Turns, duration, tokens, tools; cost where the model is priced |
Cost is computed server-side from per-model token counts using a maintained pricing table (the same LiteLLM catalog the wider ecosystem uses); when a client reports its own cost (OpenCode), that figure wins. Models missing from the table are surfaced in the session’s metadata rather than silently priced at zero-ish guesses.
Not supported: Cursor (its local store carries no token or cost data), Windsurf (no local transcript store), and Amp (cloud-first storage). Anything else can still be pushed with --provider other.
Flags:
--provider— limit the sync to one provider’s sessions (claude,codex,gemini,opencode,copilot)--dry-run— show what would be ingested without sending anything
Push a single session
Section titled “Push a single session”halyard push <file> --provider <provider> --session-id <id>push ingests one session file directly. Both sync and push send to the ingest endpoint /api/v1/sessions/ingest.
Upload every session automatically
Section titled “Upload every session automatically”halyard setup --org <your-org-slug>setup writes a launcher, .halyard/hook.sh, and session-start / session-end hook config for Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode and Grok Build. Each hook runs halyard hook, which uploads the transcript that just finished at session end and, at session start, sweeps the repo’s earlier transcripts that never uploaded. Commit the generated files and every clone of the repo gets the behaviour; re-running setup is idempotent.
| Client | Hook config written |
|---|---|
| Claude Code | .claude/settings.json |
| Codex | .codex/hooks.json |
| Cursor | .cursor/hooks.json |
| Gemini CLI | .gemini/settings.json |
| GitHub Copilot CLI | .github/hooks/halyard-session-upload.json |
| OpenCode | .opencode/plugins/halyard-session-upload.ts |
| Grok Build | .grok/hooks/halyard-session-upload.json |
halyard hook authenticates with HALYARD_TOKEN (environment, then the repo’s .env) or halyard login, and refuses login credentials scoped to another organization when the repo declares one (--org, or HALYARD_ORG_SLUG in .env). It never blocks the agent and logs to ~/.halyard/hooks.log.
Upload happens at session end, not on every turn: the ingest endpoint keeps the first upload it sees for a session id, so a mid-session upload would freeze the session at that point.
The Halyard plugin for Claude Code and Codex runs the same command for any repo that enables the plugin.
Cloud and CI
Section titled “Cloud and CI”Set HALYARD_TOKEN to an API key in the environment. Keys are bound to one organization, so mint one per environment:
halyard api-keys create --name "my-repo-claude-web"| Environment | Where to set HALYARD_TOKEN |
|---|---|
| Claude Code on the web | The repo’s environment → Environment variables |
| Codex Cloud | Environment variables (not Secrets — those are removed before the agent runs) |
| Cursor cloud agents | Dashboard → Cloud Agents → Secrets |
| GitHub Copilot coding agent | Repo settings → Secrets and variables → Agents |
| GitHub Actions and other CI | secrets.HALYARD_TOKEN, plus a final if: always() step that runs halyard sync |
Verify
Section titled “Verify”After halyard setup, open a configured client and ask the agent to identify you:
Use Halyard to tell me who I am.Expect a whoami call returning your user and organization. If the tools do not appear, see Troubleshooting.