Agents (ACP + HTTP)
Interoperability without boredom. Lock-in kills trust.
Hash speaks two protocols so you can:
- Run ACP agents such as Claude Code or Gemini CLI
- Run Ollama-style HTTP model servers such as Ollama or vLLM
- Switch without changing your workflow
ACP (Agent Client Protocol)
For agents that run as local processes. Uses JSON-RPC 2.0 over stdin/stdout.
transport = "stdio"
command = "claude-agent-acp"
Claude Setup
ANTHROPIC_API_KEY with an API key from the Anthropic Developer Console, or use your Claude subscription: if you have ever logged into the Claude Code CLI, the adapter picks up those OAuth credentials from the macOS Keychain automatically. Subscription login is validated on macOS only.To use Claude with Hash, install the ACP adapter. It bundles the Claude Agent SDK, so there is nothing else to install:
Using an API key? Set ANTHROPIC_API_KEY in your environment (e.g., in ~/.hashrc). Already logged into the Claude Code CLI with a subscription? No further setup needed on macOS.
Upgrading from an older Hash? The previous adapter package @zed-industries/claude-code-acp has been renamed to @agentclientprotocol/claude-agent-acp, and the executable is now claude-agent-acp (was claude-code-acp). Update your command in config.toml accordingly.
Gemini CLI Setup
Google's Gemini CLI supports ACP natively with an experimental flag. First, install the Gemini CLI:
Then configure Hash to use Gemini with the --experimental-acp flag:
command = "gemini"
args = ["--experimental-acp"]
Alternatively, you can use: command = "gemini --experimental-acp"
When to use ACP
- Claude Code, Gemini CLI, or any tool with ACP support
- You want the agent to have full context (files, git, etc.)
- Session persistence matters
Behavior
- Lazy connect: connects on first
??use - One session per shell instance
- Conversation follow-ups reuse the same ACP session, so the agent keeps its context between turns
- Closed on shell exit
Selecting a model
ACP agents can advertise the models they support over the protocol. When they do, Hash shows which one is active and lets you switch between them, no restart required. Your choice sticks for the rest of the shell session.
See the active model
The agent status line shows the current model in square brackets while it works:
When the agent reports no model (some stdio agents, or the HTTP transport), the brackets are simply omitted.
List and switch with model
Run the built-in model command with no arguments to open an interactive picker:
> Default (recommended) (current)
Sonnet
Sonnet (1M context)
Haiku
[↑/↓: move] [Enter: select] [Esc: cancel]
Prefer to skip the picker? Select or list directly:
model --list # print the choices; current one marked with *
Good to know
- The selection lasts for the current shell session and is re-applied automatically if the agent reconnects.
- Model listing is ACP-only. With the HTTP transport the model is fixed by
modelin your config. - If an agent exposes no model option,
modeltells you so and the status line shows no brackets. - Turn the command off with
disable_builtins = ["model"]under[shell].
HTTP transport
For Ollama-style HTTP model servers. Hash sends an Ollama /api/generaterequest shape and reads the response field.
HTTP agents are stateless, so conversation follow-ups include a compact transcript of the previous turns instead of reusing a session.
transport = "http"
url = "http://localhost:11434/api/generate"
model = "codellama:13b"
When to use HTTP
- Ollama or compatible local model servers
- Self-hosted inference
- You want full control over the model
Named agents
Use [agent.<name>] tables when you want to keep multiple agent definitions in one config and switch with [agent].default.
default = "ollama"
timeout = "120s"
allowed_commands_scope = "project"
[agent.claude]
transport = "stdio"
command = "claude-agent-acp"
[agent.gemini]
transport = "stdio"
command = "gemini"
args = ["--experimental-acp"]
[agent.ollama]
transport = "http"
url = "http://localhost:11434/api/generate"
model = "codellama:13b"
headers = { Authorization = "Bearer token" }
Agent config options
default = "claude-agent-acp" # Selected named agent, or label for flat config
command = "claude-agent-acp" # ACP agent command
timeout = "120s" # Max response wait (default: 120s)
allowed_commands_scope = "project" # project, global, or session
# HTTP transport (alternative)
# transport = "http"
# url = "http://localhost:11434/api/generate"
# model = "codellama:13b"
# headers = { Authorization = "Bearer token" }
Debug checklist
| Symptom | Check |
|---|---|
| "command not found" | Is command in your PATH? |
| Timeout | Increase timeout, check model is loaded |
| Empty response | Check model name matches server |
| Auth errors | Check ANTHROPIC_API_KEY is set, or that your Claude Code CLI login is still valid |
| Slow startup | Normal — ACP connects lazily on first ?? |
Check the agent command works directly in your terminal before configuring it in Hash.