One command. Any provider. Full control over Claude CLI.
Stop juggling environment variables and config files.
Claudy lets you switch between Anthropic, Z.AI, OpenRouter, Ollama, and custom endpoints with a single command — keeping credentials, config modes, and Claude frameworks cleanly isolated per profile.
Hit a usage limit? Exit the session and resume the exact same conversation on another provider.
Multi-provider · Config isolation · Channel bridge · Local agent bridge · Usage analytics
🇰🇷 한국어 • 🇨🇳 中文 • 🇯🇵 日本語 • 🇩🇪 Deutsch • 🇫🇷 Français • 🇪🇸 Español • 🇮🇳 हिन्दी • 🇧🇷 Português • 🇮🇩 Bahasa • 🇸🇦 العربية
| Feature | Why it matters | |
|---|---|---|
| 🔄 | Multi-provider launch | Switch across Anthropic, Z.AI, OpenRouter, Ollama, and custom endpoints in one command |
| 📦 | Config modes | Isolate CLAUDE.md, settings, skills, and agents per mode — no cross-contamination |
| 🔗 | Agent MCP bridge | Delegate tasks from Claude Code to Codex, Aider, and 20+ other agents |
| 💬 | Channel bridge | Run Telegram, Slack, and Discord bots with interactive permission prompts |
| 📊 | Usage analytics | Track token usage, costs, and tool patterns with a local Tauri dashboard |
| 🔐 | Safe process control | SIGINT/SIGTERM forwarding, atomic config writes, 0600 credential storage |
| 🔀 | Cross-provider session continuity | Out of credits? Exit and resume the same conversation on another provider — history is repaired automatically |
| 🫴 | Cross-CLI session handoff | Quota exhausted in Codex or Antigravity? claudy handoff extracts the session and seeds a new Claude session with it |
| 🛡️ | Egress guard | claudy --guard <profile> — local DLP proxy strips image blocks and redacts leaked secrets before anything leaves the machine |
| 🛠️ | Operational UX | Install, update, uninstall, doctor, ping — everything from one binary |
Your Anthropic plan ran out, or your Z.AI credits did. The conversation doesn't die with it — exit the session, relaunch on another provider, and resume exactly where you left off:
# 1. Exit the current session (/exit or Ctrl+D)
# 2. Resume the most recent session in this directory, on another provider
claudy zai --continue
# ...or resume a specific session
claudy anthropic --resume <session-id>Same working directory, same config mode, same conversation history — only the provider changes. Both directions work (Anthropic → Z.AI and Z.AI → Anthropic).
What happens under the hood: providers write session files slightly differently, and the Anthropic API rejects the whole history with HTTP 400 when it sees a shape it did not produce. Before the Claude process starts, claudy silently repairs the session file so cross-provider resume just works. No manual step, nothing to remember. It fixes:
| Written by | Symptom on resume | Repair |
|---|---|---|
| Z.AI / GLM | thinking block with an empty signature |
converted to plain text (reasoning preserved as readable context) |
| Z.AI / GLM | OpenAI-style call_<hex> tool-use ids |
remapped to toolu_*, paired tool_result updated |
| Z.AI / GLM | non-conforming server_tool_use ids |
remapped to srvtoolu_* |
| OpenRouter | gen-<epoch>-<slug> message ids replayed as previous_message_id |
remapped to msg_* |
The OpenRouter case is self-propagating if left alone: the CLI records its own 400 error as a synthetic assistant message with a UUID id, which then becomes the next previous_message_id and fails again.
Never automatic. Claudy does not detect quota exhaustion and never switches providers on its own. You decide when to exit and where to resume.
Manual repair: if a resume still fails (for example with 400 Invalid signature in thinking block), repair the session explicitly:
# Interactive — list flagged sessions, pick one
claudy session sanitize
# Filter by project name
claudy session sanitize --project book-forge
# Sanitize all flagged sessions at once
claudy session sanitize --all --yesOutput example:
Sessions needing sanitization
──────────────────────────────────────────────────────────────────────────────────
# Project Session ID Age Last message Fixes
──────────────────────────────────────────────────────────────────────────────────
1 book-forge ad2f38c0 2d oss-dist 스킬로 book-forge 프로젝트… 7
2 obsidian-forge 17e75a8c 5d LaunchAgent 설정 구현… 12
──────────────────────────────────────────────────────────────────────────────────
Select session to sanitize (or "Sanitize ALL"):
The session file is updated atomically; already-conforming sessions are not touched. A session that is still running is skipped with a warning rather than overwritten — exit it first.
Channel bridge: when a Telegram/Slack/Discord session resumes, the channel server applies the same conversion automatically before spawning the Claude process — and /sessions lists recent sessions with switch buttons.
Limitation: session continuity depends on the conversation history being compatible. Switching providers mid-session may cause subtle context shifts even after sanitization.
Cross-provider resume only works inside the Claude CLI — Codex and Antigravity keep their own session stores in their own formats, so --resume cannot load them. When those CLIs run out of quota, claudy handoff extracts a conversation digest from the foreign session and seeds a new Claude session with it:
# Interactive — lists codex + agy sessions for the current directory
claudy handoff
# Under a specific profile (any profile prefix works)
claudy zai handoff
# Most recent session across both CLIs, no picker
claudy zai handoff -c
# Pick among the 5 most recent sessions
claudy handoff -r
# Restrict to one CLI; preview the digest without launching
claudy handoff codex -c --print
claudy handoff agy -c --print
# A specific session id
claudy handoff --id <session-id>-c mirrors Claude's --continue (most recent) and -r mirrors --resume (choose) — but over the foreign session stores. --yolo and any other unrecognized flags are forwarded to the Claude session verbatim.
What gets extracted: the original user prompts (verbatim, capped), assistant replies and tool activity (truncated to one-liners), the final assistant state, and the workspace path — rendered into a single prompt under a 16 KiB budget. Codex rollout files are parsed natively. Antigravity's session DB is an undocumented format, so claudy reads it best-effort (a generic protobuf string scan plus the prompt history index) and falls back to prompts-only when the layout changes.
The new Claude session starts in the same working directory with the digest as its first message — it reviews the conversation summary plus the current repo state (git status/git diff are suggested to it) and continues from there. This is a context handoff, not a bit-for-bit resume: expect the model to re-verify details rather than replay them.
Flags: [codex|agy] positional source (scan both when omitted) · -c, --continue (most recent session) · -r, --resume (pick among the 5 most recent) · --id <session-id> (skip the picker) · --cwd <dir> (default: current directory; falls back to all sessions when nothing matches) · --profile <p> (or a profile prefix: claudy zai handoff) · --print (stdout only) · --yolo (pass --dangerously-skip-permissions to Claude; other unknown flags forward verbatim).
A third-party gateway sees everything — the whole session as plain text, and any binary the model needs to look at (screenshots, local image reads) uploaded as base64. Some gateways re-upload those binaries to their own storage buckets without telling you. --guard puts a local reverse proxy between the Claude CLI and the provider: request bodies are inspected and rewritten before they leave the machine, responses stream back untouched.
claudy --guard zai # any position works: claudy zai --guard does too
claudy --guard zai work # combines with modes as usualOn startup claudy prints where the proxy is listening:
[claudy] guard active: 127.0.0.1:53467 -> https://api.z.ai/api/anthropic (images stripped, secrets scanned)
What it does to each request:
| Detection | Default action | Detail |
|---|---|---|
{"type":"image"} content blocks (message content, system arrays, nested tool_result content) |
replaced with a text placeholder | the binary never reaches the gateway, so it cannot be re-uploaded |
Credentials — sk-ant-*/sk-* keys, AKIA/ASIA AWS keys, gh* GitHub tokens, Slack xox*, Stripe/Figma tokens, private-key headers, DB connection strings |
token replaced with [REDACTED:<kind>] |
spans never touch quotes/JSON structure, so the request stays parseable |
Authorization: Bearer headers, key=value/"key": "value" pairs |
secret part replaced | minimum lengths suppress prose false positives |
| Korean PII — RRN (checksum-validated) | replaced with [REDACTED:rrn] |
severity-Critical floor: structurally certain PII never egresses unredacted (allow mode downgrades it to warn) |
| Korean PII — bank accounts, mobile numbers · local filesystem paths | warn-only (ledger entry, forwarded untouched) | redacting paths would break coding sessions; the ledger still records them |
| non-JSON or unparseable bodies | passed through + ledger warning | fail-open: never blocks on scanner limitations |
Detection is powered by llm-kernel's dlp L1 scan (18 rules with a benign-corpus false-positive gate).
Clean requests are forwarded byte-identical. Every request is logged to ~/.claudy/guard/ledger.jsonl (method, path, upstream host, byte counts, findings) — previews are masked (sk-a****f789), raw secret material is never written.
Policy lives under guard: in config.yaml:
guard:
strip_images: true # replace image blocks before egress
on_secret: redact # allow | redact | warn | block
trusted_providers: [native] # findings on others add a re-route advisoryblock refuses the request with a 400 and never contacts the upstream. trusted_providers drives a one-time advisory (stderr + ledger) suggesting a trusted provider when sensitive content is detected on an untrusted one — switching providers mid-session is impossible, so it stays a suggestion.
Limitations: vision is intentionally broken under --guard (the model sees a placeholder — that is the point); rare false positives can redact key-shaped strings inside legitimate content (e.g. AKIA-like runs inside large base64 blobs); the channel bridge and handoff launches do not go through the guard yet.
Claudy was inspired by Clother, a Go-based multi-provider launcher for Claude CLI. Z.AI has been the most thoroughly tested provider. If you run into any issues with other providers, please open an issue.
| Provider | Status | Notes |
|---|---|---|
| Built-in (Anthropic) | ✅ Tested | Default |
| Z.AI | ✅ Tested | |
| OpenRouter alias | ✅ Tested | Verified by the maintainer |
| Ollama | ✅ Tested | Verified by the maintainer |
| Custom endpoint | ✅ Tested | Verified by the maintainer |
1. Install
macOS / Linux:
brew install epicsagas/tap/claudyNo Homebrew? Use the installer script:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/epicsagas/claudy/releases/latest/download/install.sh | shWindows:
irm https://github.com/epicsagas/claudy/releases/latest/download/install.ps1 | iexVia Rust toolchain:
cargo binstall claudy # pre-built binary (fast)
cargo install claudy # build from source2. Configure
claudy install # initialize dirs, config, secrets
echo 'ANTHROPIC_API_KEY=your-key' >> ~/.claudy/secrets.env3. Launch
claudy # default provider
claudy zai # Z.AI provider
claudy openrouter sonnet # OpenRouter alias4. Update
brew upgrade claudy # Homebrew
claudy update # built-in updater
# or re-run the installer script / cargo binstall claudy@latest
claudy --versionProvider credentials
| Variable | Provider |
|---|---|
ANTHROPIC_API_KEY |
Anthropic (native) |
ZAI_API_KEY |
Z.AI |
ZAI_CN_API_KEY |
Z.AI China |
MINIMAX_API_KEY |
MiniMax |
MINIMAX_CN_API_KEY |
MiniMax China |
KIMI_API_KEY |
Kimi K2 |
MOONSHOT_API_KEY |
Moonshot AI |
ARK_API_KEY |
VolcEngine |
DEEPSEEK_API_KEY |
DeepSeek |
MIMO_API_KEY |
Xiaomi MiMo |
ALIBABA_API_KEY |
Alibaba Coding Plan |
OPENROUTER_API_KEY |
OpenRouter (all aliases) |
Custom providers use the api_key_env variable defined in their custom_providers entry.
config.yaml schema
All configuration lives in ~/.claudy/config.yaml. Only add the sections you need — defaults are used for anything omitted.
Full reference: docs/config.md
# Provider overrides — override default model and model tiers per provider
provider_overrides:
zai:
model: "glm-5.1"
model_tiers:
haiku: "glm-4.7" # → ANTHROPIC_DEFAULT_HAIKU_MODEL
sonnet: "glm-5.1" # → ANTHROPIC_DEFAULT_SONNET_MODEL
opus: "glm-5" # → ANTHROPIC_DEFAULT_OPUS_MODEL
# OpenRouter aliases — invoke as: claudy or <alias>
openrouter_aliases:
kimi: "moonshotai/kimi-k2.5"
sonnet: "anthropic/claude-sonnet-4"
# Custom Anthropic-compatible providers — invoke as: claudy <slug>
custom_providers:
my-llm:
name: "my-llm"
display_name: "My Custom LLM"
base_url: "https://my-llm.com/api/anthropic"
api_key_env: "MY_LLM_API_KEY"
default_model: "my-model-v1"
# Compaction policy
compaction:
auto_compact: true # default: true
threshold: 0.8 # 0.0–1.0, default: 0.8
# Per-model context window overrides
model_settings:
deepseek-chat:
max_context_tokens: 64000
# Channel bridge — non-interactive alternative to `claudy channel add`
channel:
enabled_platforms: ["telegram"]
listen_addr: "127.0.0.1:3456"
default_profile: "zai"
platform_profiles:
telegram: "zai"
platform_allowed_users:
telegram: ["user_id_1"]
max_concurrent_sessions: 0 # 0 = unlimited
stream_timeout_secs: 1800
# Agent overrides
agents:
aider:
binary: "aider"
args: ["--message", "{prompt}"]
timeout: 300
# Egress guard (claudy --guard <profile>)
guard:
strip_images: true # default: true
on_secret: redact # allow | redact | warn | block
trusted_providers: ["native"] # default: ["native"]A launch target that resolves provider metadata + auth strategy (built-in provider, OpenRouter alias, or custom provider).
A named Claude config directory at ~/.claudy/modes/<name>/.
When you run:
claudy <profile> <mode> [args...]Claudy sets:
CLAUDE_CONFIG_DIR=~/.claudy/modes/<mode>/so Claude reads mode-specific config files.
Modes are also a natural fit for dedicated Claude frameworks and toolkits that ship their own CLAUDE.md, skills, agents, or settings — such as gstack, superpowers, ecc, our own epic-harness (a self-evolving Claude Code plugin), or any custom harness. Instead of polluting your default config, isolate each framework in its own mode:
# Create a dedicated mode for the framework
claudy mode create gstack
# Copy or symlink the framework's config into the mode directory
cp -r /path/to/gstack/.claude/. ~/.claudy/modes/gstack/
# Launch Claude with that framework active
claudy <profile> gstackEach mode directory is a self-contained CLAUDE_CONFIG_DIR, so frameworks never conflict with each other or with your default setup.
Pairs with epic-harness. Claudy owns the operational layer — provider switching, config isolation, channel/agent bridges — while epic-harness (3 commands, 26 auto-trigger skills, self-evolving from your failure patterns) adds agent intelligence. Same
epicsagasfamily; a clean split of concerns across modes.
Command Reference
claudy ls(alias:list): list configured/resolved profiles.claudy setup [provider](alias:config): interactive provider setup.claudy show <profile>(alias:info): show resolved provider details.claudy ping [profile](alias:test): test provider connectivity.claudy doctor(alias:status): show version, paths, and profile count.claudy sync(alias:install): install/synchronize claudy binary.claudy update: update claudy.claudy uninstall: remove installed files.claudy mode <action> [name]: manage Claude config modes.claudy channel <subcommand>: manage channel bridge.claudy mcp: run as MCP server for agent bridge.claudy analytics <subcommand>: usage analytics dashboard.claudy session sanitize: fix sessions with invalid thinking blocks from non-Anthropic providers.claudy [profile] handoff [codex|agy] [-c|-r]: continue a quota-exhausted codex/agy session in a new Claude session.
claudy mode create <name>
claudy mode ls
claudy mode remove <name>Mode name rule: [a-z0-9][a-z0-9_-]* (mode is reserved).
claudy channel serve [--profile <profile>] [--listen <host:port>]
claudy channel start [--profile <profile>] [--listen <host:port>]
claudy channel stop
claudy channel restart [--profile <profile>] [--listen <host:port>]
claudy channel status
claudy channel add <telegram|slack|discord>
claudy channel remove <telegram|slack|discord>
claudy channel enable
claudy channel disablechannel add guides you through bot token, allowed users, profile, and mode mapping.
| Platform | Ingestion | Interactive buttons | Notes |
|---|---|---|---|
| Telegram | Long-polling + webhook | Inline keyboard | Most complete |
| Slack | Event subscription webhook | Block Kit actions | HMAC-SHA256 verified |
| Discord | Interaction webhook | Action row components | Ed25519 verified |
Once running, the bot responds to these commands in chat:
/help— Show available commands/cancel— Cancel current task/model— Change Claude model (interactive buttons)/yolo— Toggle auto-allow permissions/status— Show session status, profile, mode, git branch, and token usage/sessions— List recent Claude sessions (with switch buttons)/projects— List projects (with browse buttons)/new— Start a new session/history— Show recent session history
Send any other text to talk directly to Claude.
When Claude requests approval to use a tool (run a command, edit a file, etc.), the bot sends an interactive Allow/Deny prompt to your chat. Tapping a button sends the response back to Claude and processing continues automatically.
Store channel credentials in ~/.claudy/secrets.env (see Provider credentials for full format):
TELEGRAM_BOT_TOKEN=...
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...
DISCORD_BOT_TOKEN=...
DISCORD_APPLICATION_ID=...
DISCORD_PUBLIC_KEY=...Run claudy mcp to start a stdio-based MCP server that lets Claude Code delegate tasks to other locally installed AI coding agents.
claudy mcp run # Start the MCP server (called by Claude Code)
claudy mcp install # Register claudy as an MCP server in Claude Code settings
claudy mcp uninstall # Remove claudy from Claude Code MCP settingsclaudy mcp install automatically registers itself in ~/.claude/settings.json. When you create a mode with claudy mode create <name>, it also registers in the mode's settings file. No manual configuration needed.
To register manually (or in a project-level .claude/settings.json):
{
"mcpServers": {
"claudy": {
"command": "claudy",
"args": ["mcp"]
}
}
}Claude Code will see an ask_agent tool that exposes all installed agents.
Once registered, Claude Code can delegate tasks like this:
> Ask codex to write unit tests for the parser module
> Ask aider to refactor the database layer
Claude Code selects the appropriate agent, passes the prompt, and returns the result. You can also specify a working directory:
{ "agent": "codex", "prompt": "Explain this module", "working_directory": "/path/to/project" }# Check if claudy is registered
cat ~/.claude/settings.json | grep -A3 claudy
# Test the MCP server manually
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | claudy mcp run| Agent | Binary | Headless command |
|---|---|---|
| Codex CLI | codex |
codex exec "..." |
| Cursor Agent | agent |
agent -p "..." --output-format text |
| Antigravity | agy |
agy -p "..." |
| GitHub Copilot | copilot |
copilot -p "..." |
| OpenCode | opencode |
opencode run "..." |
| Cline | cline |
cline -y "..." |
| Aider | aider |
aider --message "..." |
| Goose | goose |
goose run "..." |
| Amp | amp |
amp --non-interactive "..." |
| Droid | droid |
droid exec "..." |
| Kiro | kiro-cli |
kiro-cli chat --no-interactive --trust-all-tools "..." |
| Junie | junie |
junie "..." |
| Kimi Code | kimi |
kimi "..." |
| Mistral Vibe | vibe |
vibe "..." |
| Qwen Code | qwen-code |
qwen-code "..." |
| Crush | crush |
crush "..." |
| Groq Code | groq-code |
groq-code --prompt "..." |
| Plandex | plandex |
plandex tell "..." |
| Kilo Code | kilo |
kilo "..." |
| OpenHands | openhands |
openhands "..." |
Add agents in ~/.claudy/config.yaml under the agents key (see Configuration for full schema):
agents:
my-agent:
binary: "my-agent"
args: ["--prompt", "{prompt}", "--no-interactive"]
description: "My custom agent"
timeout: 180Same key as a built-in agent overrides its defaults. {prompt} in args is replaced with the actual task.
Note: The analytics feature is still a work in progress. Token counts, cost estimates, and other metrics may not be fully accurate. Expect refinements in upcoming releases.
claudy analytics dashboard # Open local analytics dashboard (Tauri 2)
claudy analytics ingest # Ingest session data from ~/.claude/projects/
claudy analytics ingest --full # Re-ingest all files (ignore checkpoints)
claudy analytics ingest --project my-project # Ingest specific project
claudy analytics recommend # Show usage recommendations in CLI
claudy analytics export # Export analytics data (JSON, default 30 days)
claudy analytics export --format csv --days 7 # Export as CSV for last 7 days
claudy analytics sync-pricing # Sync model pricing from models.dev and Anthropic pricing page
claudy analytics recalculate # Recalculate all costs using the latest pricing data
claudy analytics insights # Generate compact JSON insights summary (default: 7 days)
claudy analytics insights --days 14 # Analyze last 14 days
claudy analytics insights --from 2026-04-01 --to 2026-04-30 # Specific date range
claudy analytics insights --project my-project # Filter by projectThe fastest way to analyze your usage is directly inside Claude Code. The analytics-insights skill is automatically available — just ask naturally:
> /analytics-insights
> /analytics-insights last 2 weeks
> analyze my usage patterns
> 사용 패턴 분석해줘
Claude runs claudy analytics insights, analyzes the JSON, and returns a structured report with:
- Cost trends — daily/weekly spend with spike detection
- Model distribution — which models you use and what they cost per session
- Tool patterns — most-used tools, error rates, efficiency observations
- Cache performance — hit ratio and estimated savings
- Actionable recommendations — specific suggestions like "route simple tasks to turbo" with estimated dollar savings
Example output (see docs/examples/analytics-insights-sample.json for raw data):
#### Summary
81 sessions, $481 total spend at an average of $68.7/day. Costs trending
sharply upward — last 3 weekdays averaged $97/day.
#### Recommendations
1. Route simple tasks to glm-5-turbo — est. savings: ~$90/month
2. Investigate $1.91/turn outlier session (6x average cost-per-turn)
3. Reduce harness overhead — TaskCreate/Update accounted for ~1,000 calls
No manual commands, no context switching. Ask Claude about your usage and get answers instantly.
- Tokens: Detailed trends of input, output, and cache tokens over the last 30 days, grouped by model and date.
- Tools: Distribution analysis showing which tools Claude uses most frequently, including call counts, error rates, and average execution time.
- Cost: Real-time estimation of usage costs based on actual token pricing, including daily/weekly/monthly forecasts and trend detection (increasing/stable/decreasing).
- Tips (Recommendations): Data-driven optimization advice, such as detecting high-cost sessions, suggesting Haiku for simple tasks, and identifying long conversations that could benefit from context summarization.
- Projects: Automatically maps cryptic session UUIDs to human-readable project folder names for better context.
Data is stored in a local SQLite database under ~/.claudy/analytics/. The dashboard runs as a high-performance local Tauri 2 + Svelte app. Use the [Sync] button in the dashboard to instantly refresh data from your Claude CLI history.
claudy analytics dashboard
By default, Claudy stores data under:
~/.claudy/
Important files/directories:
config.yaml: provider + channel + agent configuration.secrets.env: provider/bot credentials.launchers.json: launcher/symlink manifest.modes/: Claude config modes.session-patches/: session patch storage.channel/: channel runtime state (pid, sessions, audit log).analytics/: analytics SQLite database and checkpoints.cache/update.json: update metadata cache.
CLAUDY_HOME: override the Claudy home directory (default:~/.claudy).CLAUDE_CONFIG_DIR: set automatically by Claudy when launching with a mode.
claudy setup
claudy <profile>claudy mode create work
claudy <profile> work --yolo
--yolois claudy's shorthand for--dangerously-skip-permissions.
Frameworks like gstack, superpowers, ecc, or our epic-harness ship their own CLAUDE.md, skills, and agents. Keep them isolated:
# One-time setup: create the mode and seed it with the framework config
claudy mode create gstack
cp -r /path/to/gstack/.claude/. ~/.claudy/modes/gstack/
# Daily use: launch Claude with the framework active
claudy <profile> gstackSwitch between frameworks without touching your default config:
claudy <profile> gstack # gstack framework active
claudy <profile> superpowers # superpowers framework active
claudy <profile> # your default config, unchanged# 1) Ensure MCP is registered (happens automatically on first `claudy mcp`)
claudy mcp
# 2) In Claude Code, ask it to delegate to any installed agent:
# "Ask codex to analyze this error"
# "Ask aider to refactor the auth module"claudy doctor
claudy pingprofile not recognized: runclaudy lsand choose a listed profile ID.not configuredprofile: runclaudy setup <provider>to add credentials.- Channel status unhealthy: run
claudy channel status, then restart withclaudy channel stopandclaudy channel start. - Channel bot not responding: check
~/.claudy/channel/logs/server.logfor errors. Verify bot token in~/.claudy/secrets.envand thatallowed_usersincludes your chat user ID. - Permission prompt not appearing: ensure Claude CLI is not running with
--dangerously-skip-permissions. The prompt only triggers when Claude needs explicit approval for tool use. - Binary not found after install: see the PATH note in the Verify section.
- Agent not showing in MCP: ensure the agent binary is on
PATH(e.g.which codex). Only installed agents appear intools/list. - Agent timeout: increase timeout in
config.yamlagents field (default: 120s). - MCP not registered: run
claudy mcponce manually, or check~/.claude/settings.jsonfor themcpServers.claudyentry. - Agent output truncated: agent stdout is capped at 10MB. For large outputs, redirect the agent to write to a file instead.
- Analytics data missing: run
claudy analytics ingestto populate from~/.claude/projects/. Use--fullto re-ingest everything. 400 Invalid signature in thinking blockwhen resuming: the session was created with a non-Anthropic provider (e.g. Z.AI). Runclaudy session sanitizeto convert the invalid thinking blocks, then resume normally.
cargo build
cargo test
cargo fmt
cargo clippy -- -D warnings
# Test analytics backend (uses local DB)
cargo run --example test_dashboard --features analytics-ui
# Launch analytics dashboard (requires analytics-ui feature)
cargo run --features analytics-ui -- analytics dashboardclaudy does not maintain a separate roadmap document; direction is tracked through issues, milestones, and this section.
Active focus
- Usage Analytics (work in progress) — token counts and cost estimates are not
yet fully accurate; refinements are planned for upcoming releases. The
/analytics-insightsintegration and dashboard are the primary surface here. - Channel resilience — hardening transient-API (529/429/503) recovery and
cross-provider session continuity. Recent work gated recovery on the
stream-json
is_errorflag and separated the transient/context-limit budgets; follow-ups improve observability of the recovery path.
Recently shipped (0.5.0)
- Self-scheduling analytics ingestion (
analytics schedule), archive fallback, and a freshness check (analytics status) — fixes a silent ~7.5-week ingestion freeze (#52) - Turn-duplication dedup gate (
UNIQUE(session_id, turn_number)) and incrementalbyte_offsetresume, so the hourly scheduler stops re-parsing whole files (#52, #53) - Session-level cost/duration totals preserved across incremental resume (#54)
- Four previously-stubbed aggregation metrics exposed via the insights path
Recently shipped (0.4.0)
- Opt-in shell-environment loading for spawned processes (
CLAUDY_SHELL_ENV) (#41) - Symlinked project-directory resolution (#40)
llm-kernel0.10 → 0.20 alignment (#42) andquick-xmlsecurity advisory clearance
If you want to propose or track a feature, please open an issue with the
enhancement label.
Contributions are welcome! Here is how to get started:
- Fork the repository and create a feature branch.
- Make your changes with tests where appropriate.
- Run
cargo test && cargo clippy -- -D warningsbefore submitting. - Open a Pull Request at https://github.com/epicsagas/claudy.
Bug reports and feature requests are welcome via GitHub Issues.
This project was inspired by Clother, a Go-based multi-provider launcher for Claude CLI. Claudy is an independent Rust implementation, redesigned from the ground up with RAII-based session guards, signal forwarding, launcher symlinks, and deep ecosystem integrations including a full-featured Channel Bridge (Telegram/Slack/Discord), the Agent MCP Bridge for cross-agent delegation, and a high-performance Analytics Dashboard built with Tauri 2. These additions reflect Claudy's transition from a simple launcher to a comprehensive operational toolkit for Claude CLI users.