OpenCode plugin
@ringzero/opencode-mcp-guard hooks OpenCode’s tool.execute.before /
tool.execute.after lifecycle events: every MCP tool call is checked against
your policy and written to the
usage audit log. In enforce mode, dangerous or
unapproved calls are blocked before they run.
Install
Section titled “Install”Add the plugin to your project’s opencode.json (or the global
~/.config/opencode/opencode.json) — OpenCode installs it automatically
at startup:
{ "plugin": ["@ringzero/opencode-mcp-guard"]}Re-export the guard from a local plugin file — useful for pinning or patching:
export { RingzeroMcpGuard } from '@ringzero/opencode-mcp-guard'Configuration
Section titled “Configuration”-
Make sure a policy file is reachable by walking up from the project directory —
ringzero-mcp initbootstraps one from your currentopencode.jsonservers. -
Connect your org: org id (Settings → General) as
organizationin the policy; API key (Settings → API keys, scopemcp:upload) inRINGZERO_API_KEYif you sync usage. Local-only works without either. -
Restart OpenCode. The guard loads the policy once at startup and reads your
opencode.json[c]mcpblock to learn which servers exist.
The same environment switches as the CLI apply: RINGZERO_MCP_MODE overrides
the policy mode, RINGZERO_MCP_DISABLE=1 is the kill switch (allow
everything, still audit), RINGZERO_MCP_AUDIT_DIR moves the log.
Registry autosync
Section titled “Registry autosync”When a MCP Registry catalog is present, the
plugin applies a project-scope sync at startup — org-approved servers appear
in opencode.json without anyone running a command. Changes to
opencode.json take effect on the next restart (the plugin says so on
stderr when it applied any). Conflicts with hand-added servers are reported,
never overwritten; failures are fail-open; opt out with
RINGZERO_MCP_REGISTRY_AUTOSYNC=0.
How MCP calls are identified
Section titled “How MCP calls are identified”OpenCode names MCP tools <server>_<tool> — the guard matches tool names
against the server names configured in your opencode.json[c] mcp block
(longest name wins), so built-in tools like bash or edit are never
touched. Because the guard knows each server’s source from the config, the
allowlist matches by source glob or by name — unlike the Claude Code hook,
name-less allow entries work here.
Enforce vs warn
Section titled “Enforce vs warn”mode: "warn"— nothing is blocked; policy violations are audited withdecision: "warn"and a stderr note.mode: "enforce"— a matching dangerous pattern, or an unapproved server whenruntime.blockUnapprovedis true, makes the guard throw, which stops the tool call. The agent seesRingZero policy: server 'rogue' is not on the org allowlist (…)and can route around it or surface it to the dev.- Internal guard errors (unreadable policy, audit failures) always fail open — logged to stderr, call allowed.
Usage recording
Section titled “Usage recording”Records land in the same JSONL log as every other harness, with
"harness": "opencode":
{ "ts": "2026-07-26T15:22:47.019Z", "org": "org_9f3k", "harness": "opencode", "event": "pre", "sessionId": "ses_8f2…", "server": "github", "tool": "create_issue", "decision": "allow", "rule": null, "argsSha256": "b81d3c02…", "argsBytes": 388, "args": null, "cwd": "/work/acme-web", "policyPath": "/work/acme-web/.ringzero/mcp-policy.json", "policyMode": "enforce"}tool.execute.before produces the pre record (with the decision);
tool.execute.after produces the post record. Arguments are hashed by
default — see privacy defaults.
Limitations
Section titled “Limitations”- MCP tool identification is a naming heuristic; if OpenCode changes its
<server>_<tool>scheme, update the plugin (the match lives in one function and is covered by tests). - The policy is loaded at startup — restart OpenCode after editing it.
Configuration reference
Section titled “Configuration reference”| Where | Setting | Effect |
|---|---|---|
opencode.json | "plugin": ["@ringzero/opencode-mcp-guard"] | Loads the guard |
.ringzero/mcp-policy.json | mode, allow, runtime.*, audit.* | Full behavior — see Policy & allowlist |
| env | RINGZERO_MCP_MODE, RINGZERO_MCP_DISABLE, RINGZERO_MCP_AUDIT_DIR, RINGZERO_MCP_LOG_ARGS | Per-environment overrides |