# Settings up headroom ai with opencode

> Source: <https://gist.github.com/gciluffo/12cd5f5015053a52d9cef6c8b9457b58>
> Published: 2026-07-25 14:49:21+00:00

A refined, battle-tested guide to successfully integrating `headroom-ai`

with `opencode`

for context compression and proxy routing, incorporating fixes for absolute path resolution and dynamic chunk binding.

Ensure you have `headroom`

installed locally and note its absolute path:

```
which headroom
# Example output: /Users/username/.local/bin/headroom
```

Navigate to your OpenCode configuration directory and install `headroom-ai`

and the required plugin package:

```
cd ~/.config/opencode
npm install headroom-ai
npm install @opencode-ai/plugin@latest
```

Since pre-compiled chunks must match the build hash, clone the repository and build the plugin from source:

```
rm -rf /tmp/headroom-build && mkdir -p /tmp/headroom-build
cd /tmp/headroom-build
git clone --filter=blob:none --sparse --depth=1 https://github.com/headroomlabs-ai/headroom.git .
git sparse-checkout set plugins/opencode
cd plugins/opencode
npm install
npm run build
```

Create the target directory structure and move the built distribution files:

```
PLUGIN=~/.config/opencode/plugins/headroom-opencode
SRC=/tmp/headroom-build/plugins/opencode

rm -rf "$PLUGIN" && mkdir -p "$PLUGIN/hook-shim"
cp "$SRC/package.json" "$PLUGIN/"
cp -R "$SRC/dist" "$PLUGIN/dist"
cp "$SRC/hook-shim/handler.js" "$PLUGIN/hook-shim/"
```

Create or verify a `package.json`

in both the plugin root and the hook-shim folder to enforce ESM (`"type": "module"`

):

```
# Plugin root package.json
cat > "$PLUGIN/package.json" <<'EOF'
{ "private": true, "type": "module" }
EOF

# Hook-shim package.json
cat > "$PLUGIN/hook-shim/package.json" <<'EOF'
{ "private": true, "type": "module" }
EOF
```

*Crucial:* Hardcoding a generic chunk name will break child-process interception. Use this snippet to automatically detect your build's specific hashed chunk name and write it into `handler.js`

:

```
CHUNK=$(ls "$PLUGIN/dist/chunk-"*.js | head -1 | xargs basename)
cat > "$PLUGIN/hook-shim/handler.js" <<EOF
import { installHeadroomTransport } from "../dist/$CHUNK";

const proxyUrl = process.env.HEADROOM_OPENCODE_TRANSPORT_PROXY_URL;
if (proxyUrl) {
  installHeadroomTransport({ proxyUrl });
}
EOF
```

**Warning:** OpenCode uses Bun's module resolver, which **never expands the ~ symbol**. Using

`~/.config/...`

will cause the plugin to be silently skipped. Always use full **absolute paths**:

```
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "/Users/YOUR_USERNAME/.config/opencode/plugins/headroom-opencode/dist/entry.opencode.js"
  ],
  "mcp": {
    "headroom": {
      "type": "local",
      "command": [
        "/Users/YOUR_USERNAME/.local/bin/headroom",
        "mcp",
        "serve"
      ],
      "enabled": true
    }
  }
}
```

*(Replace /Users/YOUR_USERNAME/ with your actual home directory path).*

- Start the Headroom proxy daemon in a separate terminal tab or background process:

```
headroom proxy &
```

- Launch OpenCode:

```
opencode
```

- Verify the proxy connection using the test script:
A

``` js
node --input-type=module -e "try { const res = await fetch('http://localhost:8787/v1/retrieve/000000000000000000000000', { signal: AbortSignal.timeout(2000) }); console.log(res.status, await res.text()); } catch (err) { console.error(err); process.exit(1); }"
```

`404 Entry not found`

response confirms the proxy is fully up and routing correctly.
