Skip to the content.

OpenCode + fak Integration Guide

This guide shows how to put fak in front of OpenCode, the open-source terminal coding agent. Every tool call OpenCode proposes is adjudicated by the kernel before it runs: denied by structure, repaired, or quarantined.

OpenCode auto-loads the repo’s AGENTS.md — the same file Codex reads — for project context, combined with the CONTRIBUTING.md instruction declared in the repo’s opencode.json; AGENTS.md points back here.

Integration paths

Prerequisites

git clone https://github.com/anthony-chaudhary/fak && cd fak
go build -o fak ./cmd/fak
./fak version

Path 1 — Dedicated launcher: fak opencode

The fastest way to run guarded OpenCode:

fak opencode                            # interactive OpenCode guarded by fak
fak opencode --dry-run                  # preview the guarded command
fak opencode --probe "Use bash to echo ok" # one-shot probe turn
fak opencode --local                    # auto-detect local model server (Ollama, LM Studio, Qwen3.6)
fak opencode --base-url http://127.0.0.1:8001/v1  # point at a custom /v1 upstream

fak opencode injects OPENAI_BASE_URL=http://127.0.0.1:<port>/v1 into the child process only, enforces the capability floor over OpenCode’s tool dialect (bash, read, write, edit, grep, glob, todowrite, task, question, skill), and records an audit journal.

Path 2 — Dogfood scripts

Windows (PowerShell):

.\scripts\dogfood-opencode.ps1 --dry-run
.\scripts\dogfood-opencode.ps1 --probe "Reply with pong"
.\scripts\dogfood-opencode.ps1 --smoke
.\scripts\dogfood-opencode.ps1 --print-env

macOS / Linux:

./scripts/dogfood-opencode.sh --dry-run
./scripts/dogfood-opencode.sh --probe "Reply with pong"
./scripts/dogfood-opencode.sh --smoke
./scripts/dogfood-opencode.sh --print-env

Path 3 — MCP server

Add a local MCP server to OpenCode’s config (opencode.json):

{
  "mcp": {
    "fak": {
      "type": "local",
      "command": ["fak", "serve", "--stdio", "--policy", "examples/opencode-policy.json"]
    }
  }
}

Progressive Disclosure & Deferral: By default, fak serve uses progressive disclosure on MCP tools/list (--defer-tools=true), advertising the lean 4-tool bootstrap set (fak_adjudicate, fak_syscall, fak_read, fak_tools_search). In OpenCode, tools are exposed under the fak_fak_* prefix. The model discovers deferred capabilities on demand via fak_tools_search and routes execution through fak_syscall. If eager full advertisement of all 20+ tools is ever desired, pass --defer-tools=false (or set FAK_ABLATE_MCP_TOOL_FILTER=1).

Path 4 — OpenAI-compatible gateway

./fak serve \
  --addr 127.0.0.1:8080 \
  --provider openai \
  --base-url http://localhost:11434/v1 \
  --model qwen2.5-coder:7b \
  --policy examples/customer-support-readonly-policy.json

Configure an OpenCode OpenAI-compatible provider with base URL http://127.0.0.1:8080/v1. Verify:

curl http://127.0.0.1:8080/healthz

Reproduce a denial offline

./fak preflight \
  --tool write_file \
  --args '{"path":".env","content":"x"}' \
  --policy examples/customer-support-readonly-policy.json
# verdict=DENY reason=POLICY_BLOCK

Disabling workspace snapshotting in large repositories (#11144)

By default, OpenCode captures workspace snapshots across turns and tool executions by running background git diffs and staging operations to record undo checkpoints. In large repositories or repos with large working trees, this default causes severe performance degradation and resource waste:

To eliminate this overhead, disable workspace snapshotting explicitly in opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "snapshot": false
}

Setting "snapshot": false:

  1. Prevents OpenCode from taking redundant background git diff snapshots between turns.
  2. Stops SQLite database bloat, keeping session state lightweight.
  3. Removes disk hammering and file-tree scanning overhead, ensuring fast, deterministic tool execution.

In fak, this invariant is guarded across the codebase:

Reasoning Effort Profiles & Subagent Delegation (#11146)

Modern reasoning models (such as Gemini 3.8 Flash or similar frontier thinking models) support configurable thinking effort variants. However, configuring reasoning effort globally across an entire agent harness creates severe operational trade-offs:

The problem: global high-effort latency penalty

Setting "variant": "high" globally across all agents introduces a massive latency penalty:

The solution: tiered reasoning profiles

To balance snappy turn latency with deep analytical power, OpenCode configurations establish tiered reasoning profiles across built-in agents and specialized subagents:

In opencode.json (or ~/.config/opencode/opencode.jsonc):

{
  "$schema": "https://opencode.ai/config.json",
  "agent": {
    "general": {
      "variant": "default"
    },
    "explore": {
      "variant": "default"
    },
    "deep-reason": {
      "variant": "high",
      "description": "High-reasoning subagent for deep architectural analysis, frozen ABI changes, or complex debugging"
    }
  }
}

Dynamic overrides and CLI control

When a full session demands elevated reasoning effort without subagent switching:

  1. CLI variant override: Pass --variant at launch to override the baseline for the entire session:
    opencode run --variant high "Refactor concurrency lock ordering in internal/kernel"
    
  2. Interactive model picker & variant selection: In the OpenCode interactive TUI, press /model or use the model picker dialog to select reasoning effort variants (default, high, low) dynamically for the active session.

Fleet workers use account-bound launch

For unattended super-loop/fleet work, do not run XDG_CONFIG_HOME=... opencode run directly. Use fak fleet-accounts launch|exec, supply the task tier, and use --allow-tier3-narrow only for explicitly narrow tier-3 work. Hard engineering work cannot be overridden onto a restricted tier-3 OpenCode seat.

Skill portability: importing skills into OpenCode (#10689, #10690, #10691)

OpenCode natively supports the portable Agent Skills standard, enabling seamless skill reuse across Claude Code, OpenAI Codex, and OpenCode:

1. Skill locations and formats

Harness Discovery location Format
Claude Code .claude/skills/<name>/SKILL.md Canonical semantic body + Claude frontmatter
OpenAI Codex .agents/skills/<name>/SKILL.md Agent Skills standard (generated adapter / native)
OpenCode opencode.json -> skills.paths (.agents/skills) Agent Skills standard / portable bundle

2. Bundling and synchronization with fak-project-assets

cmd/fak-project-assets serves as the portable skill bundler:

In opencode.json, point skills.paths at the synced portable bundle:

{
  "skills": {
    "paths": [".agents/skills"]
  }
}

3. Access control and frontmatter mediation

Claude Code frontmatter fields (disable-model-invocation, user-invocable, allowed-tools) are dropped by OpenCode’s parser. In fak, this gap is bridged cleanly:

  1. Metadata Acknowledgment: Skills with load-bearing Claude frontmatter specify metadata.opencode: agent-permission or metadata.opencode: claude-only. Verified via python tools/skill_frontmatter_lint.py --check.
  2. Re-expression in opencode.json: Per-skill invocation gates are re-expressed in opencode.json under permission.skill:
    {
      "permission": {
     "skill": {
       "phased-plan": "deny"
     }
      }
    }
    

4. Round-trip demonstration

A skill authored for Codex or Claude is synchronized via fak-project-assets sync, loaded into OpenCode via skills.paths, and governed by fak’s MCP capability floor (fak_adjudicate).

Cross-references

License

Apache-2.0