Qwen Code
CLIAlibaba
An open-source AI coding agent for the terminal, forked from Gemini CLI and optimized for Qwen-Coder models.
MCP
SupportedMCP servers configured under the mcpServers key in settings.json. Supports stdio, SSE, and Streamable HTTP transports, OAuth 2.0, per-server tool filtering, discovery timeouts, and the qwen mcp CLI for managing entries.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.qwen/settings.json | Project | json | mcpServers |
~/.qwen/settings.jsonUser scope is the default for qwen mcp add. | Global | json | mcpServers |
Fields
| Field | Type | Description |
|---|---|---|
command | string | Path to the executable for stdio transport. One of command, url, or httpUrl is required. |
args | string[] | Command-line arguments for stdio transport. |
url | string | SSE endpoint URL (legacy transport; prefer httpUrl when the server supports both). |
httpUrl | string | Streamable HTTP endpoint URL. |
headers | record<string, string> | Custom HTTP headers when using url or httpUrl. |
env | record<string, string> | Environment variables for the server process. Supports $VAR_NAME / ${VAR_NAME} expansion. |
cwd | string | Working directory for stdio transport. |
timeout | number | Tool-call timeout in milliseconds (default 600,000 = 10 minutes). |
discoveryTimeoutMs | number | Cap on the initial discovery handshake. Defaults: 30s for stdio servers, 5s for remote HTTP/SSE servers. |
trust | boolean | When true, bypasses all tool call confirmations for this server. Default false. |
includeTools | string[] | Allowlist of tool names to expose from this server. |
excludeTools | string[] | Denylist of tool names; takes precedence over includeTools. |
oauth | { enabled?, clientId?, clientSecret?, authorizationUrl?, tokenUrl?, scopes?, redirectUri?, tokenParamName?, audiences? } | OAuth configuration; endpoints are auto-discovered if omitted. redirectUri defaults to http://localhost:7777/oauth/callback. |
Capabilities
Examples
{
"mcpServers": {
"pythonTools": {
"command": "python",
"args": ["-m", "my_mcp_server", "--port", "8080"],
"cwd": "./mcp-servers/python",
"env": { "API_KEY": "${EXTERNAL_API_KEY}" },
"timeout": 15000
}
}
}{
"mcpServers": {
"httpServerWithAuth": {
"httpUrl": "http://localhost:3000/mcp",
"headers": { "Authorization": "Bearer your-api-token" },
"timeout": 5000
}
}
}- •Prefer httpUrl (Streamable HTTP) over url (SSE) for remote servers; stdio uses command/args.
- •Servers are discovered progressively in the background; per-server discoveryTimeoutMs defaults to 30s (stdio) or 5s (remote).
- •The mcp settings object (mcp.allowed / mcp.excluded) globally allow- or deny-lists servers, with glob pattern support.
- •Manage servers via qwen mcp add/remove or the interactive /mcp dialog.
- •OAuth tokens are stored in ~/.qwen/mcp-oauth-tokens.json (plaintext, mode 0600); set QWEN_CODE_FORCE_ENCRYPTED_FILE_STORAGE=true for keychain or encrypted storage.
- •MCP resources are referenced in messages with @server:uri syntax.
Skills
SupportedSKILL.md Agent Skills discovered from personal (~/.qwen/skills/), project (.qwen/skills/), and extension directories. Model-invoked by default, user-invocable as /<skill-name>, with optional path gating and priority ordering.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.qwen/skills/<name>/SKILL.mdProject skills, shared with the team via git. | Project | markdown | — |
~/.qwen/skills/<name>/SKILL.mdPersonal skills, available across all projects. | Global | markdown | — |
Fields
| Field | Type | Description |
|---|---|---|
name* | string | Non-empty identifier of Unicode letters/digits plus _ : . - (whitespace and slashes are rejected). |
description* | string | What the skill does and when to use it; drives model-side discovery. |
priority | number | Optional; higher values sort earlier in the /skills listing only. Unset behaves like 0. |
paths | string[] | Glob patterns that gate model discovery until a tool call touches a matching file. |
user-invocable | boolean | Set false to hide the skill from /<skill-name> and the /skills picker (model-only). Default true. |
disable-model-invocation | boolean | Set true to hide the skill from the model while keeping user invocation. Default false. |
Examples
---
name: tsx-helper
description: React TSX component helper
paths:
- 'src/**/*.tsx'
- 'packages/*/src/**/*.tsx'
---
# TSX Helper
## Instructions
Provide clear, step-by-step guidance for Qwen Code.- •Skills are model-invoked based on the description; /<skill-name> invokes one explicitly and /skills opens the interactive panel.
- •paths: globs (picomatch, relative to project root) keep a skill out of the model's listing until a tool call touches a matching file; once activated it stays active for the session.
- •Extensions can bundle skills in their skills/ directory, declared in qwen-extension.json.
- •Changes to SKILL.md take effect on the next session start.
Rules
SupportedQWEN.md instruction files (global, project, and personal-local tiers) loaded at session start, plus automatic auto-memory the agent writes itself and an opt-in git-shared team memory tier.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
QWEN.mdProject root; applies to the whole team when committed. | Project | markdown | — |
.qwen/QWEN.local.mdPersonal, project-specific instructions; keep out of git. | Project | markdown | — |
~/.qwen/QWEN.mdPersonal instructions across all projects. | Global | markdown | — |
.qwen/team-memory/Opt-in git-shared auto-memory tier (memory.enableTeamMemory); one file per memory plus a MEMORY.md index. | Project | markdown | — |
Fields
| Field | Type | Description |
|---|---|---|
memory.enableManagedAutoMemory | boolean | settings.json toggle for automatic memory saving (default true). |
memory.enableManagedAutoDream | boolean | settings.json toggle for periodic background memory cleanup. |
memory.enableTeamMemory | boolean | Enable the git-shared .qwen/team-memory/ tier (default false). |
memory.enableTeamMemorySync | boolean | Best-effort git sync of team memory at session start (default false). |
Examples
See @README.md for project overview.
# Conventions
- Always use pnpm, not npm.
- Git workflow: @docs/git-workflow.md- •Qwen Code also reads an existing AGENTS.md in the repository, so instructions do not need to be duplicated.
- •Reference other files from QWEN.md with @path/to/file; relative paths resolve from the QWEN.md file itself.
- •/init generates a starter QWEN.md; /memory opens the memory panel; /remember and /forget edit auto-memory directly.
- •Auto-memory (on by default) stores markdown notes in ~/.qwen/projects/<project>/memory/; /dream triggers cleanup.
- •Team memory (.qwen/team-memory/, off by default via memory.enableTeamMemory) shares durable project knowledge through git, with secret scanning on writes.
- •.qwen/QWEN.local.md must be gitignored manually; it loads after the shared project QWEN.md.
Hooks
SupportedLifecycle hooks configured under the hooks key in settings.json, with four executor types: shell command, HTTP POST, registered function (internal), and LLM prompt. Hooks can inject context, block tools, and audit the session across a wide event set.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.qwen/settings.json | Project | json | hooks |
~/.qwen/settings.json | Global | json | hooks |
Fields
| Field | Type | Description |
|---|---|---|
matcher | string | Regex filtering the trigger (tool id, subagent type, session source, etc.) depending on the event. |
sequential | boolean | Run hooks in this group in order instead of in parallel. |
hooks[].type* | "command" | "http" | "prompt" | Hook executor type (function type exists but is internal-only). |
hooks[].command | string | Shell command to execute (command hooks). Receives event JSON on stdin. |
hooks[].url | string | Target URL for HTTP hooks; event JSON is sent as the POST body. |
hooks[].headers | record<string, string> | HTTP request headers; supports ${VAR} interpolation limited to allowedEnvVars. |
hooks[].allowedEnvVars | string[] | Whitelist of environment variables allowed in HTTP hook URLs/headers. |
hooks[].timeout | number | Timeout: milliseconds for command hooks (default 60000), seconds for HTTP hooks (default 600). |
hooks[].async | boolean | Command hooks only: run in the background without blocking; results surface next turn. |
hooks[].env | record<string, string> | Environment variables for command hooks. |
hooks[].shell | "bash" | "powershell" | Shell used to run command hooks. |
hooks[].name | string | Friendly name for logging. |
hooks[].statusMessage | string | Status message displayed while the hook executes. |
hooks[].once | boolean | HTTP hooks only: execute at most once per event per session. |
Examples
{
"hooks": {
"PreToolUse": [
{
"matcher": "^run_shell_command$",
"hooks": [
{
"type": "command",
"command": "$QWEN_PROJECT_DIR/.qwen/hooks/security-check.sh",
"name": "security-check",
"timeout": 10000
}
]
}
]
}
}{
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "http",
"url": "http://127.0.0.1:8080/hooks/pre-tool-use",
"headers": { "Authorization": "Bearer ${HOOK_API_KEY}" },
"allowedEnvVars": ["HOOK_API_KEY"],
"timeout": 10
}
]
}
]
}
}- •Command hooks receive JSON on stdin and reply via stdout; exit code 2 blocks the action with stderr as feedback to the model.
- •HTTP hooks POST the event JSON to a URL with SSRF protection, URL allowlists, and env var interpolation restricted to allowedEnvVars.
- •Matchers are regexes against tool ids, subagent types, or session sources; empty string or * matches all. Some events (UserPromptSubmit, Stop, Todo*) take no matcher.
- •Hooks run in parallel by default; sequential: true enforces ordered execution. Command hooks can set async: true for non-blocking background runs.
- •Project-level hooks require trusted folder status.
- •Function hooks are used internally by the Skill system and are not a public configuration API.
Commands
SupportedCustom slash commands as Markdown files with optional YAML frontmatter under .qwen/commands/ (TOML format is deprecated but still read). Subdirectories create namespaced names, and prompts support {{args}}, !{...} shell execution, and @{...} file injection.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.qwen/commands/<name>.mdProject commands; git/commit.md becomes /git:commit. | Project | markdown | — |
~/.qwen/commands/<name>.mdUser commands, available in every project. | Global | markdown | — |
Fields
| Field | Type | Description |
|---|---|---|
description | string | Optional frontmatter field shown in /help; the Markdown body after the frontmatter is the prompt. |
prompt* | string | Deprecated TOML format only: the prompt sent to the model. In Markdown commands the body serves this role. |
Examples
---
description: Generate Commit message based on staged changes
---
Please generate a Commit message based on the following diff:
!{git diff --staged}- •Project commands override user commands of the same name.
- •Markdown is the recommended format; legacy TOML files still work and trigger an automatic migration prompt.
- •Processing order: @{file} injection first, then !{shell} blocks (with confirmation dialog and shell escaping), then {{args}} substitution.
- •Without {{args}}, provided arguments are appended to the prompt after two newlines.
- •MCP server prompts also appear as slash commands (labeled MCP: <server>).
Settings
SupportedLayered settings.json files (system defaults, user, project, system overrides) organized into category objects like general, ui, model, context, tools, security, mcp, memory, and hooks. Legacy flat settings are migrated automatically.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.qwen/settings.jsonProject settings; override user settings. | Project | json | — |
~/.qwen/settings.jsonUser settings for all sessions. | Global | json | — |
/etc/qwen-code/settings.jsonSystem overrides beating user and project settings (Linux). Windows: C:\ProgramData\qwen-code\settings.json; macOS: /Library/Application Support/QwenCode/settings.json. | Enterprise | json | — |
/etc/qwen-code/system-defaults.jsonSystem-wide defaults with the lowest precedence (Linux); Windows and macOS analogues exist. | Enterprise | json | — |
Fields
| Field | Type | Description |
|---|---|---|
general | object | General behavior: preferredEditor, vimMode, enableAutoUpdate, language, chatRecording, voice options. |
model | object | Model selection and generation configuration. |
context | object | Context loading and file filtering (.gitignore / .qwenignore handling). |
mcpServers | record<string, object> | MCP server definitions (see the MCP surface). |
mcp | { allowed?, excluded? } | Global MCP allow/deny lists with glob pattern support. |
hooks | object | Lifecycle hook configuration (see the Hooks surface). |
memory | { enableManagedAutoMemory?, enableManagedAutoDream?, enableTeamMemory?, enableTeamMemorySync? } | Auto-memory and team memory toggles (see the Rules surface). |
ui | object | Terminal UI: theme, customThemes, statusLine, banner and footer options. |
output | { format?: "text" | "json", showTimestamps?: boolean } | CLI output format options. |
Examples
{
"general": { "vimMode": true },
"memory": { "enableTeamMemory": true },
"mcpServers": {
"my-server": {
"httpUrl": "http://localhost:3000/mcp"
}
}
}- •Precedence (low to high): defaults, system defaults file, user, project, system settings file, environment variables, command-line arguments.
- •String values may reference environment variables with $VAR_NAME or ${VAR_NAME} syntax.
- •System paths can be overridden with QWEN_CODE_SYSTEM_SETTINGS_PATH and QWEN_CODE_SYSTEM_DEFAULTS_PATH.
- •Authentication (API keys, model providers) is configured separately; see the official auth docs.