h is a small agentic coding CLI written in Rust. It connects an OpenAI
Responses-compatible or Anthropic-compatible model to a local coding
environment, where the model can inspect a repository, edit files, run
commands, search code, fetch web pages, and ask the user for decisions.
The project is under active development, so its configuration and internal APIs may still change.
- Interactive terminal UI with streaming Markdown, syntax highlighting, diffs, tool activity, token estimates, and context usage.
- Clipboard image attachments for multimodal prompts, including keyboard and mouse removal controls.
- Headless mode for running a single prompt and printing the final response.
- Built-in tools for reading, writing, and editing files; searching with grep; fetching web pages; running Bash commands; and asking interactive questions.
- Blocking and background Bash commands, with persistent terminal sessions when
tmuxis available and a PTY fallback otherwise. - Bounded tool output: long Bash, grep, and fetch results are saved to temporary files and presented as compact previews.
- Session archives and interactive resume support.
- Automatic context compaction and lightweight summaries for older tool output.
- Preservation of provider-native reasoning and tool-call history.
- Slash commands with prefix completion:
/clearand/compact. - Local Skill discovery compatible with h, Codex, Claude Code, and the common
.agents/skillslayout. - Persistent user and project memory with bounded startup indexes and on-demand search, read, and write tools.
- Config-driven stdio MCP servers with automatic tool discovery and lifecycle management.
- Project and user instruction files for persistent guidance.
You can ask h to perform tasks such as:
- Explain an unfamiliar repository or trace a bug through the codebase.
- Implement a feature and update the relevant tests.
- Refactor code while preserving existing behavior.
- Run formatters, tests, builds, and other shell commands.
- Search source files and inspect large outputs without filling the context window.
- Fetch and summarize technical documentation.
- A recent stable Rust toolchain with Rust 2024 edition support.
- An OpenAI Responses-compatible or Anthropic-compatible API endpoint and model.
- A Unix-like operating system. The current Bash implementation uses Unix PTYs.
tmuxis optional, but enables the more capable persistent Bash backend.
Build and install the binary from the repository:
cargo install --path .For development, run it directly through Cargo:
cargo run --releaseh reads its configuration from ~/.h/config.toml. Create the directory and
configuration file before starting the CLI. Named profiles bundle an endpoint,
its model, and the reasoning effort; profile selects the default, and
--profile <id> overrides it for one run:
profile = "openai"
tool_summary_turn_interval = 8
[profiles.openai]
type = "openai"
name = "OpenAI"
base_url = "https://api.openai.com/v1"
bearer_token = "YOUR_API_KEY"
model = "gpt-5.6-sol"
reasoning_effort = "medium"reasoning_effort accepts none, minimal, low, medium, high, xhigh,
or max. Provider support for individual values depends on the selected model
and endpoint. context_window and auto_compact_token_limit are optional
globally and per profile; a profile's values win, then the global ones, then
the defaults (258000 / 220000).
compact_model is optional per profile. When set, context compaction runs on
that model instead of model — useful to point the summarization step at a
cheaper or faster model while the conversation itself stays on model. It
falls back to model when unset.
Anthropic-compatible endpoints use type = "anthropic". Set base_url to the
prefix before /v1/messages:
[profiles.deepseek]
type = "anthropic"
name = "DeepSeek"
base_url = "https://api.deepseek.com/anthropic"
auth_token = "YOUR_BEARER_TOKEN"
model = "deepseek-v4-flash"
reasoning_effort = "medium"Use api_key instead of auth_token for endpoints that authenticate through
the Anthropic x-api-key header.
The bearer token is currently stored directly in the configuration file. Keep the file private and do not commit it to a repository.
Add stdio MCP servers under [mcp.servers.<id>]:
[mcp.servers.search]
command = "node"
args = ["/path/to/search-server.mjs"]
cwd = "/path/to/server"
tools = ["query", "fetch"]
[mcp.servers.search.env]
API_KEY = "YOUR_API_KEY"Configured servers are enabled by default. Set enabled = false in a server
table to keep its configuration without starting it. By default, every
discovered tool is exposed. Set tools to an allowlist of remote tool names to
expose only that subset; startup fails if a configured name is not provided by
the server. Exposed tools are registered as <server>__<tool>, such as
search__query. Server and tool names must therefore contain only ASCII
letters, digits, underscores, and hyphens.
h fails startup when an enabled MCP server cannot start or list its tools,
rather than silently ignoring a configured integration. MCP subprocesses are
closed when the interactive or headless session finishes.
Start a new interactive session:
hRun one prompt without opening the TUI:
h -p "Explain the architecture of this repository"Headless sessions print only the final response and are not archived.
Replace all default system prompt injection for a new session:
h --instruction "You are a focused Rust reviewer." -p "Review src/main.rs"--instruction skips the harness prompt, persistent instruction files, Skill
catalog, Memory snapshot, and workspace information. Built-in and MCP tools
remain available. It cannot be combined with --resume.
Choose an archived session to resume:
h --resumeThe picker only lists sessions recorded under the selected profile's protocol
and provider; sessions from another upstream are hidden, and resuming one by id
is refused. --profile scopes the resume: to pick from or replay a session
archived under another profile, name it explicitly:
h --profile deepseek --resume
h --profile deepseek --resume <SESSION_ID>Resume a known session directly:
h --resume <SESSION_ID>Inside the TUI:
Alt+Entersubmits the prompt;Ctrl+Enteralso works in terminals that support an enhanced keyboard protocol. Plain Enter inserts a newline.- Paste an image with
Ctrl+V. Attached images appear below the prompt as thumbnails with[Image N ×]labels and can be removed with their×button or with Backspace while the text is empty. Kitty, Sixel, and iTerm2 graphics are detected automatically, with Unicode half-blocks as the fallback. Shift+Tabfocuses image attachments; Left/Right selects one, Backspace or Delete removes it, and Esc or Tab returns to text input.Esccancels the active turn.Ctrl+Cexits the application./cleararchives the current context and starts a new session./compactmanually compacts the current context.
h discovers SKILL.md packages from user and project directories under:
.agents/skills.claude/skills.codex/skills.h/skills
The same paths under the user's home directory are also searched. Only Skill
metadata is injected initially; the model reads the full SKILL.md when a task
matches it.
Persistent instructions can be placed in .h/AGENTS.md, ~/.h/AGENTS.md, or
~/.claude/CLAUDE.md.
.
├── src/ CLI entry point, configuration wiring, and logging
├── crates/h-core/ Agent runtime, context, providers, tools, and Skills
├── crates/h-mcp/ MCP configuration, stdio clients, and Agent tool adapters
├── crates/h-memory/ Persistent user and project memory
└── crates/h-tui/ Terminal UI and rendering
h-core is independent of the terminal UI so other frontends can reuse the
agent runtime in the future.
h stores persistent memory under ~/.h/memory. User memory applies across
repositories, while project memory is isolated by the current Git repository.
Only bounded index snapshots are injected at startup; the agent can search and
read every stored topic on demand. Memory topics are plain Markdown, and their
generated INDEX.md files can be rebuilt from topic metadata.
h can execute shell commands and modify files without an approval prompt.
Run it only in directories and with API endpoints that you trust, and review
important changes before committing them.