Skip to content

Halyard CLI

Ask about this page ChatGPT Gemini Claude

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.

The package is @halyard/cli and the binary is halyard. Install it globally, or run it once without installing:

Terminal window
npm i -g @halyard/cli
Terminal window
pnpm dlx @halyard/cli
Terminal window
halyard login

login 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:

Terminal window
export HALYARD_TOKEN=sk_halyard_…
Terminal window
halyard setup

setup (alias init) writes the MCP server config for each client it supports:

ClientWhat setup writes
Claude CodeRegisters the halyard HTTP server
CursorUpserts halyard in .cursor/mcp.json, preserving existing servers
CodexAdds [mcp_servers.halyard] to ~/.codex/config.toml

Preview the changes without writing anything:

Terminal window
halyard setup --dry-run
Terminal window
halyard sync

sync 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:

ClientWhere sessions are read fromMetrics captured
Claude Code~/.claude/projects/**/*.jsonlCost, 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
OpenCodeLocal OpenCode store, via opencode exportCost (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
Terminal window
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.

Terminal window
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.

ClientHook 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.

Set HALYARD_TOKEN to an API key in the environment. Keys are bound to one organization, so mint one per environment:

Terminal window
halyard api-keys create --name "my-repo-claude-web"
EnvironmentWhere to set HALYARD_TOKEN
Claude Code on the webThe repo’s environment → Environment variables
Codex CloudEnvironment variables (not Secrets — those are removed before the agent runs)
Cursor cloud agentsDashboard → Cloud Agents → Secrets
GitHub Copilot coding agentRepo settings → Secrets and variables → Agents
GitHub Actions and other CIsecrets.HALYARD_TOKEN, plus a final if: always() step that runs halyard sync

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.