Howto — Run a Haiku Claude Agent via ACP in Obsidian¶
Configure the locally-installed claude-agent-acp adapter to run as a separate Claude agent inside Obsidian's Agent Client plugin, pinned to Haiku, isolated from the default Claude Code instance.
This guide is self-contained — every command, env var, settings field, and config file you need is below.
Why do this¶
- Cheap, fast model for low-stakes vault work (triage, formatting, lookups, quick rewrites)
- Runs alongside your default Sonnet/Opus instance without overriding global settings
- Isolated config dir means experimental tweaks (effort, permissions, allowed tools) don't bleed into your main agent
Background — what the layers do¶
Obsidian Agent Client plugin (ACP client)
│ spawns process, passes env vars + args
▼
claude-agent-acp (locally installed binary)
│ thin ACP transport adapter; loads SDK
▼
Claude Agent SDK (same engine as Claude Code)
│ reads CLAUDE_CONFIG_DIR/settings.json + env
▼
Anthropic API → Haiku 4.5
Key idea: the ACP adapter is transport only. Model selection, effort level, permissions, tool restrictions — all of that uses the standard Claude Code env vars and settings.json, exactly as if you were running Claude Code directly. No ACP-specific config language exists.
Precedence order (highest wins):
- Environment variables (set in plugin env block)
--modelCLI flag (if plugin allows passing args)modelfield in settings.json (resolved viaCLAUDE_CONFIG_DIR)- Account default
Setup — 4 steps¶
Step 1: Locate your claude-agent-acp binary¶
The path is whatever you installed. Common cases:
| Install method | Typical path |
|---|---|
| npm global | run which claude-agent-acp to find it (often ~/.npm-global/bin/claude-agent-acp or /usr/local/bin/claude-agent-acp) |
| npm local in a project | <project>/node_modules/.bin/claude-agent-acp |
| Cloned from source | node /path/to/claude-agent-acp/dist/index.js |
Note this absolute path — you'll paste it into the Obsidian plugin in Step 3.
Step 2: Create the isolated Haiku config dir¶
Run in WSL terminal:
mkdir -p /mnt/d/OBS/brncx-skills/99-TMP/claude-haiku-config
Then create /mnt/d/OBS/brncx-skills/99-TMP/claude-haiku-config/settings.json with this content:
{
"model": "haiku",
"availableModels": ["haiku", "sonnet"],
"effortLevel": "low",
"env": {
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5"
}
}
What each field does:
| Field | Purpose |
|---|---|
model: "haiku" |
Active model when the session starts |
availableModels |
Restricts the /model picker. Drop "sonnet" for Haiku-only |
effortLevel: "low" |
Matches Haiku's fast/cheap intent (note: effort levels currently only affect Opus 4.7/4.6 and Sonnet 4.6 — harmless on Haiku) |
env.ANTHROPIC_DEFAULT_HAIKU_MODEL |
Pins the haiku alias to a specific model version so it doesn't drift on future Anthropic releases |
Optional fields you might add:
{
"permissions": {
"allow": ["Read", "Glob", "Grep"],
"deny": ["Bash"]
},
"statusLine": {
"type": "command",
"command": "echo '🟡 HAIKU AGENT'"
}
}
Step 3: Configure the Obsidian Agent Client plugin¶
Open Obsidian → Settings → Community plugins → Agent Client → (your Claude agent entry, or add a new one).
| Field | Value |
|---|---|
| Name | Claude Haiku (or whatever you want shown in the picker) |
| Command / Path | the absolute path from Step 1 |
| Arguments | (leave empty) |
| Working directory | usually your vault root: /mnt/d/OBS/brncx-skills |
| Environment variables | see env block below |
Env block — one KEY=VALUE per line:
CLAUDE_CONFIG_DIR=/mnt/d/OBS/brncx-skills/99-TMP/claude-haiku-config
ANTHROPIC_MODEL=haiku
Why both:
- CLAUDE_CONFIG_DIR — points the SDK at your isolated settings.json so this agent's tweaks don't leak into other Claude Code instances
- ANTHROPIC_MODEL=haiku — belt-and-braces; env wins over settings.json on precedence, so even if the config dir isn't picked up, Haiku is still active
Step 4: Restart Obsidian and verify¶
Restart Obsidian (the plugin reads env at process spawn time). Open the Agent Client panel, start a session with the Haiku agent, and run:
| Command | What it confirms |
|---|---|
/model |
Active model — should show Haiku |
/status |
Account info + which config file is loaded |
If the picker shows Sonnet/Opus instead of Haiku, the plugin isn't passing CLAUDE_CONFIG_DIR through. Two fallbacks:
Fallback A — env-only. Drop CLAUDE_CONFIG_DIR and rely on ANTHROPIC_MODEL=haiku alone. You lose the isolated settings.json, but the model pin works.
Fallback B — wrap in a shell script. If the plugin doesn't expose an env block at all, create /mnt/d/OBS/brncx-skills/99-TMP/SCRIPTS/claude-agent-acp-haiku.sh:
#!/usr/bin/env bash
export CLAUDE_CONFIG_DIR=/mnt/d/OBS/brncx-skills/99-TMP/claude-haiku-config
export ANTHROPIC_MODEL=haiku
exec /absolute/path/to/claude-agent-acp "$@"
Make it executable: chmod +x /mnt/d/OBS/brncx-skills/99-TMP/SCRIPTS/claude-agent-acp-haiku.sh
Point the plugin's Command field at the script instead of the binary.
Run two agents side-by-side¶
Duplicate the agent entry in the Obsidian plugin. Same binary path, different env block:
| Agent | CLAUDE_CONFIG_DIR |
ANTHROPIC_MODEL |
Use for |
|---|---|---|---|
| Default Sonnet/Opus | (unset — uses your normal config) | (unset) | Real work |
| Haiku | …/99-TMP/claude-haiku-config |
haiku |
Quick tasks, triage, lookups |
Each runs as a separate ACP server process — fully isolated, no cross-contamination.
Full env var reference¶
These are the env vars the Claude Agent SDK / Claude Code reads. Set any of them in the Obsidian plugin's env block:
| Variable | Effect |
|---|---|
ANTHROPIC_MODEL |
Active model alias or full ID (haiku, sonnet, opus, claude-haiku-4-5, claude-opus-4-7[1m], etc.) |
ANTHROPIC_DEFAULT_HAIKU_MODEL |
What the haiku alias resolves to |
ANTHROPIC_DEFAULT_SONNET_MODEL |
What the sonnet alias resolves to |
ANTHROPIC_DEFAULT_OPUS_MODEL |
What the opus alias resolves to |
CLAUDE_CONFIG_DIR |
Path to a folder containing settings.json (isolates from default config) |
CLAUDE_CODE_EFFORT_LEVEL |
low / medium / high / xhigh / max / auto (Opus 4.7/4.6, Sonnet 4.6 only) |
CLAUDE_CODE_SUBAGENT_MODEL |
Model used by spawned subagents |
CLAUDE_CODE_DISABLE_1M_CONTEXT |
Set 1 to remove 1M context options from picker |
DISABLE_PROMPT_CACHING |
Set 1 to disable prompt caching globally |
DISABLE_PROMPT_CACHING_HAIKU |
Set 1 to disable prompt caching for Haiku only |
ANTHROPIC_BASE_URL |
Custom API endpoint (LLM gateway, Bedrock proxy, etc.) |
ANTHROPIC_CUSTOM_MODEL_OPTION |
Adds a custom entry to the /model picker |
Deprecated: ANTHROPIC_SMALL_FAST_MODEL — use ANTHROPIC_DEFAULT_HAIKU_MODEL instead.
Full settings.json reference¶
Fields you can add to the settings.json under CLAUDE_CONFIG_DIR:
{
"model": "haiku",
"availableModels": ["haiku", "sonnet"],
"effortLevel": "low",
"env": {
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5"
},
"permissions": {
"allow": ["Read", "Glob", "Grep", "Edit"],
"deny": ["Bash(rm *)", "Bash(git push *)"]
},
"modelOverrides": {
"claude-haiku-4-5": "your-custom-id-or-arn"
},
"statusLine": {
"type": "command",
"command": "/path/to/statusline-script.sh"
}
}
| Field | Purpose |
|---|---|
model |
Initial model on session start |
availableModels |
Allowlist for the /model picker; merges across user/project/managed settings |
effortLevel |
Default reasoning effort |
env |
Extra env vars applied when this config is loaded |
permissions.allow / permissions.deny |
Tool allowlist / denylist (supports patterns like Bash(git push *)) |
modelOverrides |
Map Anthropic model IDs to provider-specific IDs (Bedrock ARNs, Vertex names) |
statusLine |
Custom status line shown above the prompt |
Model alias quick reference¶
| Alias | Resolves to (Anthropic API) |
|---|---|
haiku |
Claude Haiku 4.5 |
sonnet |
Claude Sonnet 4.6 |
opus |
Claude Opus 4.7 |
sonnet[1m] |
Sonnet 4.6 with 1M context |
opus[1m] |
Opus 4.7 with 1M context |
opusplan |
Opus in plan mode → Sonnet in execution |
default |
Resolves to your account's tier default |
best |
Currently equivalent to opus |
Troubleshooting¶
| Symptom | Fix |
|---|---|
/model shows Sonnet/Opus, not Haiku |
Plugin not passing env. Use Fallback B (shell-script wrapper) |
| Picker is empty / picker shows wrong models | Check availableModels in settings.json — array might be too restrictive |
| Adapter fails to start | Run the binary path manually in a terminal — confirms it works outside Obsidian |
| Settings changes don't apply | Restart Obsidian — the ACP server only reads config at spawn time |
| Both agents share state | They shouldn't if CLAUDE_CONFIG_DIR is different — verify by running /status in each |
| Effort level setting ignored | Effort only affects Opus 4.7/4.6 and Sonnet 4.6 — Haiku doesn't support it |
References¶
- Claude Code model configuration: https://code.claude.com/docs/en/model-config
- claude-agent-acp repo: https://github.com/agentclientprotocol/claude-agent-acp
- ACP protocol spec: https://agentclientprotocol.com