# Qwen Code Tool-Call Control & Audit — Install Guide

Install ACP for Qwen Code via its native hooks. Every tool call — shell, file edits, MCP — policy-checked before it runs, with an audit record and output scanning. One command, one file: ~/.qwen/settings.json.

# Govern Qwen Code with Agentic Control Plane

<p style="font-size:17px;line-height:1.6;color:var(--acp-text);max-width:660px;margin:8px 0 6px;">See, control, and price <strong>every tool call Qwen Code makes</strong> — shell, file edits, MCP — from one dashboard. Qwen Code's hooks are <a href="/controls/qwen-code">Claude Code's contract</a>, so this is the same hook, one file.</p>

## TL;DR

```sh
curl -sf https://agenticcontrolplane.com/install.sh | bash
```

The installer detects Qwen Code (`~/.qwen` or `qwen` on your PATH), merges `PreToolUse` and `PostToolUse` hooks plus the ACP MCP connector into `~/.qwen/settings.json`, and opens your browser once to provision a workspace and save the key to `~/.acp/credentials`. Restart Qwen Code. Every tool call is governed from the next session.

## What the installer writes

```json
{
  "hooks": {
    "PreToolUse":  [{ "matcher": "*", "hooks": [{ "type": "command", "name": "acp", "command": "env ACP_CLIENT=qwen-code node $HOME/.acp/govern.mjs", "timeout": 5000 }] }],
    "PostToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "name": "acp", "command": "env ACP_CLIENT=qwen-code node $HOME/.acp/govern.mjs", "timeout": 5000 }] }]
  },
  "mcpServers": { "acp": { "command": "sh", "args": ["-c", "exec npx -y mcp-remote https://api.agenticcontrolplane.com/mcp --header \"Authorization: Bearer $(cat ~/.acp/credentials)\""] } }
}
```

Existing hooks and MCP servers are preserved; re-running the installer replaces only its own entries. The user-level file is used because project-level hooks require folder trust and user-level hooks do not. If `disableAllHooks` is set, the installer warns and nothing runs until it is removed.

## How it works

- **Before each call** (`PreToolUse`): the hook sends the tool name and arguments to your workspace policy and returns `allow`, `ask` or `deny`. A deny is `permissionDecision: "deny"` with the reason shown to the model. An ask prompts you in the interactive session; in headless runs Qwen Code resolves it to a deny, by its own rule.
- **After each call** (`PostToolUse`): the tool output is recorded and scanned, and the session's model usage is priced from the transcript.
- **Every mode.** The hook runs in `plan`, `default`, `auto-edit`, `auto` and `yolo`. Qwen Code's own approval mode decides whether it prompts; the hook decides whether the call runs.
- **Fail-open by default.** If the gateway is unreachable, attended sessions continue with a loud warning and the lapse is logged locally; set `echo closed > ~/.acp/failmode` to fail closed instead.

## Verified

Wired inside a fresh Linux container under the Terminal-Bench runner on 2026-09-03 with Qwen Code 0.23.0: the hook fired on the first tool call and the session appeared in the workspace's runs API under the `qwen-code` client name.

## Uninstall

Remove the two `acp` entries under `hooks` and the `acp` entry under `mcpServers` in `~/.qwen/settings.json`.
