@protolabsai/proto 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +203 -0
- package/README.md +286 -0
- package/dist/bundled/adversarial-verification/SKILL.md +98 -0
- package/dist/bundled/brainstorming/SKILL.md +171 -0
- package/dist/bundled/coding-agent-standards/SKILL.md +67 -0
- package/dist/bundled/dispatching-parallel-agents/SKILL.md +193 -0
- package/dist/bundled/executing-plans/SKILL.md +77 -0
- package/dist/bundled/finishing-a-development-branch/SKILL.md +213 -0
- package/dist/bundled/loop/SKILL.md +61 -0
- package/dist/bundled/qc-helper/SKILL.md +151 -0
- package/dist/bundled/qc-helper/docs/_meta.ts +30 -0
- package/dist/bundled/qc-helper/docs/common-workflow.md +571 -0
- package/dist/bundled/qc-helper/docs/configuration/_meta.ts +10 -0
- package/dist/bundled/qc-helper/docs/configuration/auth.md +366 -0
- package/dist/bundled/qc-helper/docs/configuration/memory.md +0 -0
- package/dist/bundled/qc-helper/docs/configuration/model-providers.md +542 -0
- package/dist/bundled/qc-helper/docs/configuration/qwen-ignore.md +55 -0
- package/dist/bundled/qc-helper/docs/configuration/settings.md +652 -0
- package/dist/bundled/qc-helper/docs/configuration/themes.md +160 -0
- package/dist/bundled/qc-helper/docs/configuration/trusted-folders.md +61 -0
- package/dist/bundled/qc-helper/docs/extension/_meta.ts +9 -0
- package/dist/bundled/qc-helper/docs/extension/extension-releasing.md +121 -0
- package/dist/bundled/qc-helper/docs/extension/getting-started-extensions.md +299 -0
- package/dist/bundled/qc-helper/docs/extension/introduction.md +303 -0
- package/dist/bundled/qc-helper/docs/features/_meta.ts +18 -0
- package/dist/bundled/qc-helper/docs/features/approval-mode.md +263 -0
- package/dist/bundled/qc-helper/docs/features/arena.md +218 -0
- package/dist/bundled/qc-helper/docs/features/checkpointing.md +77 -0
- package/dist/bundled/qc-helper/docs/features/commands.md +312 -0
- package/dist/bundled/qc-helper/docs/features/headless.md +318 -0
- package/dist/bundled/qc-helper/docs/features/hooks.md +343 -0
- package/dist/bundled/qc-helper/docs/features/language.md +139 -0
- package/dist/bundled/qc-helper/docs/features/lsp.md +453 -0
- package/dist/bundled/qc-helper/docs/features/mcp.md +281 -0
- package/dist/bundled/qc-helper/docs/features/sandbox.md +241 -0
- package/dist/bundled/qc-helper/docs/features/scheduled-tasks.md +139 -0
- package/dist/bundled/qc-helper/docs/features/skills.md +289 -0
- package/dist/bundled/qc-helper/docs/features/sub-agents.md +307 -0
- package/dist/bundled/qc-helper/docs/features/token-caching.md +29 -0
- package/dist/bundled/qc-helper/docs/ide-integration/_meta.ts +4 -0
- package/dist/bundled/qc-helper/docs/ide-integration/ide-companion-spec.md +182 -0
- package/dist/bundled/qc-helper/docs/ide-integration/ide-integration.md +144 -0
- package/dist/bundled/qc-helper/docs/integration-github-action.md +241 -0
- package/dist/bundled/qc-helper/docs/integration-jetbrains.md +81 -0
- package/dist/bundled/qc-helper/docs/integration-vscode.md +39 -0
- package/dist/bundled/qc-helper/docs/integration-zed.md +72 -0
- package/dist/bundled/qc-helper/docs/overview.md +64 -0
- package/dist/bundled/qc-helper/docs/quickstart.md +273 -0
- package/dist/bundled/qc-helper/docs/reference/_meta.ts +4 -0
- package/dist/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +72 -0
- package/dist/bundled/qc-helper/docs/reference/sdk-api.md +524 -0
- package/dist/bundled/qc-helper/docs/support/Uninstall.md +42 -0
- package/dist/bundled/qc-helper/docs/support/_meta.ts +6 -0
- package/dist/bundled/qc-helper/docs/support/tos-privacy.md +112 -0
- package/dist/bundled/qc-helper/docs/support/troubleshooting.md +123 -0
- package/dist/bundled/receiving-code-review/SKILL.md +226 -0
- package/dist/bundled/requesting-code-review/SKILL.md +115 -0
- package/dist/bundled/review/SKILL.md +123 -0
- package/dist/bundled/subagent-driven-development/SKILL.md +292 -0
- package/dist/bundled/subagent-driven-development/code-quality-reviewer-prompt.md +27 -0
- package/dist/bundled/subagent-driven-development/implementer-prompt.md +113 -0
- package/dist/bundled/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/dist/bundled/systematic-debugging/SKILL.md +305 -0
- package/dist/bundled/test-driven-development/SKILL.md +396 -0
- package/dist/bundled/using-git-worktrees/SKILL.md +223 -0
- package/dist/bundled/using-superpowers/SKILL.md +117 -0
- package/dist/bundled/verification-before-completion/SKILL.md +147 -0
- package/dist/bundled/writing-plans/SKILL.md +159 -0
- package/dist/bundled/writing-skills/SKILL.md +716 -0
- package/dist/cli.js +483432 -0
- package/dist/sandbox-macos-permissive-closed.sb +32 -0
- package/dist/sandbox-macos-permissive-open.sb +27 -0
- package/dist/sandbox-macos-permissive-proxied.sb +37 -0
- package/dist/sandbox-macos-restrictive-closed.sb +93 -0
- package/dist/sandbox-macos-restrictive-open.sb +96 -0
- package/dist/sandbox-macos-restrictive-proxied.sb +98 -0
- package/dist/vendor/ripgrep/COPYING +3 -0
- package/dist/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/dist/vendor/tree-sitter/tree-sitter-bash.wasm +0 -0
- package/dist/vendor/tree-sitter/tree-sitter.wasm +0 -0
- package/package.json +143 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Connect Qwen Code to tools via MCP
|
|
2
|
+
|
|
3
|
+
Qwen Code can connect to external tools and data sources through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction). MCP servers give Qwen Code access to your tools, databases, and APIs.
|
|
4
|
+
|
|
5
|
+
## What you can do with MCP
|
|
6
|
+
|
|
7
|
+
With MCP servers connected, you can ask Qwen Code to:
|
|
8
|
+
|
|
9
|
+
- Work with files and repos (read/search/write, depending on the tools you enable)
|
|
10
|
+
- Query databases (schema inspection, queries, reporting)
|
|
11
|
+
- Integrate internal services (wrap your APIs as MCP tools)
|
|
12
|
+
- Automate workflows (repeatable tasks exposed as tools/prompts)
|
|
13
|
+
|
|
14
|
+
> [!tip]
|
|
15
|
+
>
|
|
16
|
+
> If you’re looking for the “one command to get started”, jump to [Quick start](#quick-start).
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
Qwen Code loads MCP servers from `mcpServers` in your `settings.json`. You can configure servers either:
|
|
21
|
+
|
|
22
|
+
- By editing `settings.json` directly
|
|
23
|
+
- By using `qwen mcp` commands (see [CLI reference](#qwen-mcp-cli))
|
|
24
|
+
|
|
25
|
+
### Add your first server
|
|
26
|
+
|
|
27
|
+
1. Add a server (example: remote HTTP MCP server):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
qwen mcp add --transport http my-server http://localhost:3000/mcp
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
2. Open MCP management dialog to view and manage servers:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
qwen mcp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
3. Restart Qwen Code in the same project (or start it if it wasn’t running yet), then ask the model to use tools from that server.
|
|
40
|
+
|
|
41
|
+
## Where configuration is stored (scopes)
|
|
42
|
+
|
|
43
|
+
Most users only need these two scopes:
|
|
44
|
+
|
|
45
|
+
- **Project scope (default)**: `.qwen/settings.json` in your project root
|
|
46
|
+
- **User scope**: `~/.qwen/settings.json` across all projects on your machine
|
|
47
|
+
|
|
48
|
+
Write to user scope:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
qwen mcp add --scope user --transport http my-server http://localhost:3000/mcp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> [!tip]
|
|
55
|
+
>
|
|
56
|
+
> For advanced configuration layers (system defaults/system settings and precedence rules), see [Settings](../configuration/settings).
|
|
57
|
+
|
|
58
|
+
## Configure servers
|
|
59
|
+
|
|
60
|
+
### Choose a transport
|
|
61
|
+
|
|
62
|
+
| Transport | When to use | JSON field(s) |
|
|
63
|
+
| --------- | ----------------------------------------------------------------- | ------------------------------------------- |
|
|
64
|
+
| `http` | Recommended for remote services; works well for cloud MCP servers | `httpUrl` (+ optional `headers`) |
|
|
65
|
+
| `sse` | Legacy/deprecated servers that only support Server-Sent Events | `url` (+ optional `headers`) |
|
|
66
|
+
| `stdio` | Local process (scripts, CLIs, Docker) on your machine | `command`, `args` (+ optional `cwd`, `env`) |
|
|
67
|
+
|
|
68
|
+
> [!note]
|
|
69
|
+
>
|
|
70
|
+
> If a server supports both, prefer **HTTP** over **SSE**.
|
|
71
|
+
|
|
72
|
+
### Configure via `settings.json` vs `qwen mcp add`
|
|
73
|
+
|
|
74
|
+
Both approaches produce the same `mcpServers` entries in your `settings.json`—use whichever you prefer.
|
|
75
|
+
|
|
76
|
+
#### Stdio server (local process)
|
|
77
|
+
|
|
78
|
+
JSON (`.qwen/settings.json`):
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"mcpServers": {
|
|
83
|
+
"pythonTools": {
|
|
84
|
+
"command": "python",
|
|
85
|
+
"args": ["-m", "my_mcp_server", "--port", "8080"],
|
|
86
|
+
"cwd": "./mcp-servers/python",
|
|
87
|
+
"env": {
|
|
88
|
+
"DATABASE_URL": "$DB_CONNECTION_STRING",
|
|
89
|
+
"API_KEY": "${EXTERNAL_API_KEY}"
|
|
90
|
+
},
|
|
91
|
+
"timeout": 15000
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
CLI (writes to project scope by default):
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
qwen mcp add pythonTools -e DATABASE_URL=$DB_CONNECTION_STRING -e API_KEY=$EXTERNAL_API_KEY \
|
|
101
|
+
--timeout 15000 python -m my_mcp_server --port 8080
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### HTTP server (remote streamable HTTP)
|
|
105
|
+
|
|
106
|
+
JSON:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"mcpServers": {
|
|
111
|
+
"httpServerWithAuth": {
|
|
112
|
+
"httpUrl": "http://localhost:3000/mcp",
|
|
113
|
+
"headers": {
|
|
114
|
+
"Authorization": "Bearer your-api-token"
|
|
115
|
+
},
|
|
116
|
+
"timeout": 5000
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
CLI:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
qwen mcp add --transport http httpServerWithAuth http://localhost:3000/mcp \
|
|
126
|
+
--header "Authorization: Bearer your-api-token" --timeout 5000
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### SSE server (remote Server-Sent Events)
|
|
130
|
+
|
|
131
|
+
JSON:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"mcpServers": {
|
|
136
|
+
"sseServer": {
|
|
137
|
+
"url": "http://localhost:8080/sse",
|
|
138
|
+
"timeout": 30000
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
CLI:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
qwen mcp add --transport sse sseServer http://localhost:8080/sse --timeout 30000
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Safety and control
|
|
151
|
+
|
|
152
|
+
### Trust (skip confirmations)
|
|
153
|
+
|
|
154
|
+
- **Server trust** (`trust: true`): bypasses confirmation prompts for that server (use sparingly).
|
|
155
|
+
|
|
156
|
+
### Tool filtering (allow/deny tools per server)
|
|
157
|
+
|
|
158
|
+
Use `includeTools` / `excludeTools` to restrict tools exposed by a server (from Qwen Code’s perspective).
|
|
159
|
+
|
|
160
|
+
Example: include only a few tools:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"filteredServer": {
|
|
166
|
+
"command": "python",
|
|
167
|
+
"args": ["-m", "my_mcp_server"],
|
|
168
|
+
"includeTools": ["safe_tool", "file_reader", "data_processor"],
|
|
169
|
+
"timeout": 30000
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Global allow/deny lists
|
|
176
|
+
|
|
177
|
+
The `mcp` object in your `settings.json` defines global rules for all MCP servers:
|
|
178
|
+
|
|
179
|
+
- `mcp.allowed`: allow-list of MCP server names (keys in `mcpServers`)
|
|
180
|
+
- `mcp.excluded`: deny-list of MCP server names
|
|
181
|
+
|
|
182
|
+
Example:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"mcp": {
|
|
187
|
+
"allowed": ["my-trusted-server"],
|
|
188
|
+
"excluded": ["experimental-server"]
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Troubleshooting
|
|
194
|
+
|
|
195
|
+
- **Server shows “Disconnected” in `qwen mcp list`**: verify the URL/command is correct, then increase `timeout`.
|
|
196
|
+
- **Stdio server fails to start**: use an absolute `command` path, and double-check `cwd`/`env`.
|
|
197
|
+
- **Environment variables in JSON don’t resolve**: ensure they exist in the environment where Qwen Code runs (shell vs GUI app environments can differ).
|
|
198
|
+
|
|
199
|
+
## Reference
|
|
200
|
+
|
|
201
|
+
### `settings.json` structure
|
|
202
|
+
|
|
203
|
+
#### Server-specific configuration (`mcpServers`)
|
|
204
|
+
|
|
205
|
+
Add an `mcpServers` object to your `settings.json` file:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
// ... file contains other config objects
|
|
209
|
+
{
|
|
210
|
+
"mcpServers": {
|
|
211
|
+
"serverName": {
|
|
212
|
+
"command": "path/to/server",
|
|
213
|
+
"args": ["--arg1", "value1"],
|
|
214
|
+
"env": {
|
|
215
|
+
"API_KEY": "$MY_API_TOKEN"
|
|
216
|
+
},
|
|
217
|
+
"cwd": "./server-directory",
|
|
218
|
+
"timeout": 30000,
|
|
219
|
+
"trust": false
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Configuration properties:
|
|
226
|
+
|
|
227
|
+
Required (one of the following):
|
|
228
|
+
|
|
229
|
+
| Property | Description |
|
|
230
|
+
| --------- | ------------------------------------------------------ |
|
|
231
|
+
| `command` | Path to the executable for Stdio transport |
|
|
232
|
+
| `url` | SSE endpoint URL (e.g., `"http://localhost:8080/sse"`) |
|
|
233
|
+
| `httpUrl` | HTTP streaming endpoint URL |
|
|
234
|
+
|
|
235
|
+
Optional:
|
|
236
|
+
|
|
237
|
+
| Property | Type/Default | Description |
|
|
238
|
+
| ---------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
239
|
+
| `args` | array | Command-line arguments for Stdio transport |
|
|
240
|
+
| `headers` | object | Custom HTTP headers when using `url` or `httpUrl` |
|
|
241
|
+
| `env` | object | Environment variables for the server process. Values can reference environment variables using `$VAR_NAME` or `${VAR_NAME}` syntax |
|
|
242
|
+
| `cwd` | string | Working directory for Stdio transport |
|
|
243
|
+
| `timeout` | number<br>(default: 600,000) | Request timeout in milliseconds (default: 600,000ms = 10 minutes) |
|
|
244
|
+
| `trust` | boolean<br>(default: false) | When `true`, bypasses all tool call confirmations for this server (default: `false`) |
|
|
245
|
+
| `includeTools` | array | List of tool names to include from this MCP server. When specified, only the tools listed here will be available from this server (allowlist behavior). If not specified, all tools from the server are enabled by default. |
|
|
246
|
+
| `excludeTools` | array | List of tool names to exclude from this MCP server. Tools listed here will not be available to the model, even if they are exposed by the server.<br>Note: `excludeTools` takes precedence over `includeTools` - if a tool is in both lists, it will be excluded. |
|
|
247
|
+
| `targetAudience` | string | The OAuth Client ID allowlisted on the IAP-protected application you are trying to access. Used with `authProviderType: 'service_account_impersonation'`. |
|
|
248
|
+
| `targetServiceAccount` | string | The email address of the Google Cloud Service Account to impersonate. Used with `authProviderType: 'service_account_impersonation'`. |
|
|
249
|
+
|
|
250
|
+
<a id="qwen-mcp-cli"></a>
|
|
251
|
+
|
|
252
|
+
### Manage MCP servers with `qwen mcp`
|
|
253
|
+
|
|
254
|
+
You can always configure MCP servers by manually editing `settings.json`, but the CLI is usually faster.
|
|
255
|
+
|
|
256
|
+
#### Adding a server (`qwen mcp add`)
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
qwen mcp add [options] <name> <commandOrUrl> [args...]
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
| Argument/Option | Description | Default | Example |
|
|
263
|
+
| ------------------- | ------------------------------------------------------------------- | ------------------ | ----------------------------------------- |
|
|
264
|
+
| `<name>` | A unique name for the server. | — | `example-server` |
|
|
265
|
+
| `<commandOrUrl>` | The command to execute (for `stdio`) or the URL (for `http`/`sse`). | — | `/usr/bin/python` or `http://localhost:8` |
|
|
266
|
+
| `[args...]` | Optional arguments for a `stdio` command. | — | `--port 5000` |
|
|
267
|
+
| `-s`, `--scope` | Configuration scope (user or project). | `project` | `-s user` |
|
|
268
|
+
| `-t`, `--transport` | Transport type (`stdio`, `sse`, `http`). | `stdio` | `-t sse` |
|
|
269
|
+
| `-e`, `--env` | Set environment variables. | — | `-e KEY=value` |
|
|
270
|
+
| `-H`, `--header` | Set HTTP headers for SSE and HTTP transports. | — | `-H "X-Api-Key: abc123"` |
|
|
271
|
+
| `--timeout` | Set connection timeout in milliseconds. | — | `--timeout 30000` |
|
|
272
|
+
| `--trust` | Trust the server (bypass all tool call confirmation prompts). | — (`false`) | `--trust` |
|
|
273
|
+
| `--description` | Set the description for the server. | — | `--description "Local tools"` |
|
|
274
|
+
| `--include-tools` | A comma-separated list of tools to include. | all tools included | `--include-tools mytool,othertool` |
|
|
275
|
+
| `--exclude-tools` | A comma-separated list of tools to exclude. | none | `--exclude-tools mytool` |
|
|
276
|
+
|
|
277
|
+
#### Removing a server (`qwen mcp remove`)
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
qwen mcp remove <name>
|
|
281
|
+
```
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Sandbox
|
|
2
|
+
|
|
3
|
+
This document explains how to run Qwen Code inside a sandbox to reduce risk when tools execute shell commands or modify files.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Before using sandboxing, you need to install and set up Qwen Code:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @qwen-code/qwen-code
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To verify the installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
qwen --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Overview of sandboxing
|
|
20
|
+
|
|
21
|
+
Sandboxing isolates potentially dangerous operations (such as shell commands or file modifications) from your host system, providing a security barrier between the CLI and your environment.
|
|
22
|
+
|
|
23
|
+
The benefits of sandboxing include:
|
|
24
|
+
|
|
25
|
+
- **Security**: Prevent accidental system damage or data loss.
|
|
26
|
+
- **Isolation**: Limit file system access to project directory.
|
|
27
|
+
- **Consistency**: Ensure reproducible environments across different systems.
|
|
28
|
+
- **Safety**: Reduce risk when working with untrusted code or experimental commands.
|
|
29
|
+
|
|
30
|
+
> [!note]
|
|
31
|
+
>
|
|
32
|
+
> **Naming note:** Some sandbox-related environment variables may have used the `GEMINI_*` prefix historically. All new environment variables use the `QWEN_*` prefix.
|
|
33
|
+
|
|
34
|
+
## Sandboxing methods
|
|
35
|
+
|
|
36
|
+
Your ideal method of sandboxing may differ depending on your platform and your preferred container solution.
|
|
37
|
+
|
|
38
|
+
### 1. macOS Seatbelt (macOS only)
|
|
39
|
+
|
|
40
|
+
Lightweight, built-in sandboxing using `sandbox-exec`.
|
|
41
|
+
|
|
42
|
+
**Default profile**: `permissive-open` - restricts writes outside the project directory, but allows most other operations and outbound network access.
|
|
43
|
+
|
|
44
|
+
**Best for**: Fast, no Docker required, strong guardrails for file writes.
|
|
45
|
+
|
|
46
|
+
### 2. Container-based (Docker/Podman)
|
|
47
|
+
|
|
48
|
+
Cross-platform sandboxing with complete process isolation.
|
|
49
|
+
|
|
50
|
+
By default, Qwen Code uses a published sandbox image (configured in the CLI package) and will pull it as needed.
|
|
51
|
+
|
|
52
|
+
The container sandbox mounts your workspace and your `~/.qwen` directory into the container so auth and settings persist between runs.
|
|
53
|
+
|
|
54
|
+
**Best for**: Strong isolation on any OS, consistent tooling inside a known image.
|
|
55
|
+
|
|
56
|
+
### Choosing a method
|
|
57
|
+
|
|
58
|
+
- **On macOS**:
|
|
59
|
+
- Use Seatbelt when you want lightweight sandboxing (recommended for most users).
|
|
60
|
+
- Use Docker/Podman when you need a full Linux userland (e.g., tools that require Linux binaries).
|
|
61
|
+
- **On Linux/Windows**:
|
|
62
|
+
- Use Docker or Podman.
|
|
63
|
+
|
|
64
|
+
## Quickstart
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Enable sandboxing with command flag
|
|
68
|
+
qwen -s -p "analyze the code structure"
|
|
69
|
+
|
|
70
|
+
# Or enable sandboxing for your shell session (recommended for CI / scripts)
|
|
71
|
+
export QWEN_SANDBOX=true # true auto-picks a provider (see notes below)
|
|
72
|
+
qwen -p "run the test suite"
|
|
73
|
+
|
|
74
|
+
# Configure in settings.json
|
|
75
|
+
{
|
|
76
|
+
"tools": {
|
|
77
|
+
"sandbox": true
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
> [!tip]
|
|
83
|
+
>
|
|
84
|
+
> **Provider selection notes:**
|
|
85
|
+
>
|
|
86
|
+
> - On **macOS**, `QWEN_SANDBOX=true` typically selects `sandbox-exec` (Seatbelt) if available.
|
|
87
|
+
> - On **Linux/Windows**, `QWEN_SANDBOX=true` requires `docker` or `podman` to be installed.
|
|
88
|
+
> - To force a provider, set `QWEN_SANDBOX=docker|podman|sandbox-exec`.
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
### Enable sandboxing (in order of precedence)
|
|
93
|
+
|
|
94
|
+
1. **Environment variable**: `QWEN_SANDBOX=true|false|docker|podman|sandbox-exec`
|
|
95
|
+
2. **Command flag / argument**: `-s`, `--sandbox`, or `--sandbox=<provider>`
|
|
96
|
+
3. **Settings file**: `tools.sandbox` in your `settings.json` (e.g., `{"tools": {"sandbox": true}}`).
|
|
97
|
+
|
|
98
|
+
> [!important]
|
|
99
|
+
>
|
|
100
|
+
> If `QWEN_SANDBOX` is set, it **overrides** the CLI flag and `settings.json`.
|
|
101
|
+
|
|
102
|
+
### Configure the sandbox image (Docker/Podman)
|
|
103
|
+
|
|
104
|
+
- **CLI flag**: `--sandbox-image <image>`
|
|
105
|
+
- **Environment variable**: `QWEN_SANDBOX_IMAGE=<image>`
|
|
106
|
+
|
|
107
|
+
If you don’t set either, Qwen Code uses the default image configured in the CLI package (for example `ghcr.io/qwenlm/qwen-code:<version>`).
|
|
108
|
+
|
|
109
|
+
### macOS Seatbelt profiles
|
|
110
|
+
|
|
111
|
+
Built-in profiles (set via `SEATBELT_PROFILE` env var):
|
|
112
|
+
|
|
113
|
+
- `permissive-open` (default): Write restrictions, network allowed
|
|
114
|
+
- `permissive-closed`: Write restrictions, no network
|
|
115
|
+
- `permissive-proxied`: Write restrictions, network via proxy
|
|
116
|
+
- `restrictive-open`: Strict restrictions, network allowed
|
|
117
|
+
- `restrictive-closed`: Maximum restrictions
|
|
118
|
+
- `restrictive-proxied`: Strict restrictions, network via proxy
|
|
119
|
+
|
|
120
|
+
> [!tip]
|
|
121
|
+
>
|
|
122
|
+
> Start with `permissive-open`, then tighten to `restrictive-closed` if your workflow still works.
|
|
123
|
+
|
|
124
|
+
### Custom Seatbelt profiles (macOS)
|
|
125
|
+
|
|
126
|
+
To use a custom Seatbelt profile:
|
|
127
|
+
|
|
128
|
+
1. Create a file named `.qwen/sandbox-macos-<profile_name>.sb` in your project.
|
|
129
|
+
2. Set `SEATBELT_PROFILE=<profile_name>`.
|
|
130
|
+
|
|
131
|
+
### Custom Sandbox Flags
|
|
132
|
+
|
|
133
|
+
For container-based sandboxing, you can inject custom flags into the `docker` or `podman` command using the `SANDBOX_FLAGS` environment variable. This is useful for advanced configurations, such as disabling security features for specific use cases.
|
|
134
|
+
|
|
135
|
+
**Example (Podman)**:
|
|
136
|
+
|
|
137
|
+
To disable SELinux labeling for volume mounts, you can set the following:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
export SANDBOX_FLAGS="--security-opt label=disable"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Multiple flags can be provided as a space-separated string:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
export SANDBOX_FLAGS="--flag1 --flag2=value"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Network proxying (all sandbox methods)
|
|
150
|
+
|
|
151
|
+
If you want to restrict outbound network access to an allowlist, you can run a local proxy alongside the sandbox:
|
|
152
|
+
|
|
153
|
+
- Set `QWEN_SANDBOX_PROXY_COMMAND=<command>`
|
|
154
|
+
- The command must start a proxy server that listens on `:::8877`
|
|
155
|
+
|
|
156
|
+
This is especially useful with `*-proxied` Seatbelt profiles.
|
|
157
|
+
|
|
158
|
+
For a working allowlist-style proxy example, see: [Example Proxy Script](/developers/examples/proxy-script).
|
|
159
|
+
|
|
160
|
+
## Linux UID/GID handling
|
|
161
|
+
|
|
162
|
+
On Linux, Qwen Code defaults to enabling UID/GID mapping so the sandbox runs as your user (and reuses the mounted `~/.qwen`). Override with:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
export SANDBOX_SET_UID_GID=true # Force host UID/GID
|
|
166
|
+
export SANDBOX_SET_UID_GID=false # Disable UID/GID mapping
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Troubleshooting
|
|
170
|
+
|
|
171
|
+
### Common issues
|
|
172
|
+
|
|
173
|
+
**"Operation not permitted"**
|
|
174
|
+
|
|
175
|
+
- Operation requires access outside sandbox.
|
|
176
|
+
- On macOS Seatbelt: try a more permissive `SEATBELT_PROFILE`.
|
|
177
|
+
- On Docker/Podman: verify the workspace is mounted and your command doesn’t require access outside the project directory.
|
|
178
|
+
|
|
179
|
+
**Missing commands**
|
|
180
|
+
|
|
181
|
+
- Container sandbox: add them via `.qwen/sandbox.Dockerfile` or `.qwen/sandbox.bashrc`.
|
|
182
|
+
- Seatbelt: your host binaries are used, but the sandbox may restrict access to some paths.
|
|
183
|
+
|
|
184
|
+
**Java not available in Docker sandbox**
|
|
185
|
+
|
|
186
|
+
The official Qwen Code Docker image is intentionally minimal to keep the image small, secure, and fast to pull. Different users require different language runtimes (Java, Python, Node.js, etc.), and bundling all environments into a single image is not practical. Therefore, Java is **not included by default** in the Docker sandbox.
|
|
187
|
+
|
|
188
|
+
If your workflow requires Java, you can extend the base image by creating a `.qwen/sandbox.Dockerfile` in your project:
|
|
189
|
+
|
|
190
|
+
```dockerfile
|
|
191
|
+
FROM ghcr.io/qwenlm/qwen-code:latest
|
|
192
|
+
|
|
193
|
+
RUN apt-get update && \
|
|
194
|
+
apt-get install -y openjdk-17-jre && \
|
|
195
|
+
apt-get clean && \
|
|
196
|
+
rm -rf /var/lib/apt/lists/*
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Then rebuild the sandbox image:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
QWEN_SANDBOX=docker BUILD_SANDBOX=1 qwen -s
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
For more details on customizing the sandbox, see [Customizing the sandbox environment](/developers/tools/sandbox).
|
|
206
|
+
|
|
207
|
+
**Network issues**
|
|
208
|
+
|
|
209
|
+
- Check sandbox profile allows network.
|
|
210
|
+
- Verify proxy configuration.
|
|
211
|
+
|
|
212
|
+
### Debug mode
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
DEBUG=1 qwen -s -p "debug command"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Note:** If you have `DEBUG=true` in a project's `.env` file, it won't affect the CLI due to automatic exclusion. Use `.qwen/.env` files for Qwen Code-specific debug settings.
|
|
219
|
+
|
|
220
|
+
### Inspect sandbox
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Check environment
|
|
224
|
+
qwen -s -p "run shell command: env | grep SANDBOX"
|
|
225
|
+
|
|
226
|
+
# List mounts
|
|
227
|
+
qwen -s -p "run shell command: mount | grep workspace"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Security notes
|
|
231
|
+
|
|
232
|
+
- Sandboxing reduces but doesn't eliminate all risks.
|
|
233
|
+
- Use the most restrictive profile that allows your work.
|
|
234
|
+
- Container overhead is minimal after the first pull/build.
|
|
235
|
+
- GUI applications may not work in sandboxes.
|
|
236
|
+
|
|
237
|
+
## Related documentation
|
|
238
|
+
|
|
239
|
+
- [Configuration](../configuration/settings): Full configuration options.
|
|
240
|
+
- [Commands](../features/commands): Available commands.
|
|
241
|
+
- [Troubleshooting](../support/troubleshooting): General troubleshooting.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Run Prompts on a Schedule
|
|
2
|
+
|
|
3
|
+
> Use `/loop` and the cron scheduling tools to run prompts repeatedly, poll for status, or set one-time reminders within a Qwen Code session.
|
|
4
|
+
|
|
5
|
+
Scheduled tasks let Qwen Code re-run a prompt automatically on an interval. Use them to poll a deployment, babysit a PR, check back on a long-running build, or remind yourself to do something later in the session.
|
|
6
|
+
|
|
7
|
+
Tasks are session-scoped: they live in the current Qwen Code process and are gone when you exit. Nothing is written to disk.
|
|
8
|
+
|
|
9
|
+
> **Note:** Scheduled tasks are an experimental feature. Enable them with `experimental.cron: true` in your [settings](../configuration/settings.md), or set `QWEN_CODE_ENABLE_CRON=1` in your environment.
|
|
10
|
+
|
|
11
|
+
## Schedule a recurring prompt with /loop
|
|
12
|
+
|
|
13
|
+
The `/loop` [bundled skill](skills.md) is the quickest way to schedule a recurring prompt. Pass an optional interval and a prompt, and Qwen Code sets up a cron job that fires in the background while the session stays open.
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
/loop 5m check if the deployment finished and tell me what happened
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Qwen Code parses the interval, converts it to a cron expression, schedules the job, and confirms the cadence and job ID. It then immediately executes the prompt once — you don't have to wait for the first cron fire.
|
|
20
|
+
|
|
21
|
+
### Interval syntax
|
|
22
|
+
|
|
23
|
+
Intervals are optional. You can lead with them, trail with them, or leave them out entirely.
|
|
24
|
+
|
|
25
|
+
| Form | Example | Parsed interval |
|
|
26
|
+
| :---------------------- | :------------------------------------ | :--------------------------- |
|
|
27
|
+
| Leading token | `/loop 30m check the build` | every 30 minutes |
|
|
28
|
+
| Trailing `every` clause | `/loop check the build every 2 hours` | every 2 hours |
|
|
29
|
+
| No interval | `/loop check the build` | defaults to every 10 minutes |
|
|
30
|
+
|
|
31
|
+
Supported units are `s` for seconds, `m` for minutes, `h` for hours, and `d` for days. Seconds are rounded up to the nearest minute since cron has one-minute granularity. Intervals that don't divide evenly into their unit, such as `7m` or `90m`, are rounded to the nearest clean interval and Qwen Code tells you what it picked.
|
|
32
|
+
|
|
33
|
+
### Loop over another command
|
|
34
|
+
|
|
35
|
+
The scheduled prompt can itself be a command or skill invocation. This is useful for re-running a workflow you've already packaged.
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
/loop 20m /review-pr 1234
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Each time the job fires, Qwen Code runs `/review-pr 1234` as if you had typed it.
|
|
42
|
+
|
|
43
|
+
### Manage loops
|
|
44
|
+
|
|
45
|
+
`/loop` also supports two subcommands for managing existing jobs:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
/loop list
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Lists all scheduled jobs with their IDs and cron expressions.
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
/loop clear
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Cancels all scheduled jobs at once.
|
|
58
|
+
|
|
59
|
+
## Set a one-time reminder
|
|
60
|
+
|
|
61
|
+
For one-shot reminders, describe what you want in natural language instead of using `/loop`. Qwen Code schedules a single-fire task that deletes itself after running.
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
remind me at 3pm to push the release branch
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
in 45 minutes, check whether the integration tests passed
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Qwen Code pins the fire time to a specific minute and hour using a cron expression and confirms when it will fire.
|
|
72
|
+
|
|
73
|
+
## Manage scheduled tasks
|
|
74
|
+
|
|
75
|
+
Ask Qwen Code in natural language to list or cancel tasks, or reference the underlying tools directly.
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
what scheduled tasks do I have?
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
cancel the deploy check job
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Under the hood, Qwen Code uses these tools:
|
|
86
|
+
|
|
87
|
+
| Tool | Purpose |
|
|
88
|
+
| :----------- | :-------------------------------------------------------------------------------------------------------------- |
|
|
89
|
+
| `CronCreate` | Schedule a new task. Accepts a 5-field cron expression, the prompt to run, and whether it recurs or fires once. |
|
|
90
|
+
| `CronList` | List all scheduled tasks with their IDs, schedules, and prompts. |
|
|
91
|
+
| `CronDelete` | Cancel a task by ID. |
|
|
92
|
+
|
|
93
|
+
Each scheduled task has an 8-character ID you can pass to `CronDelete`. A session can hold up to 50 scheduled tasks at once.
|
|
94
|
+
|
|
95
|
+
## How scheduled tasks run
|
|
96
|
+
|
|
97
|
+
The scheduler checks every second for due tasks and enqueues them when the session is idle. A scheduled prompt fires between your turns, not while Qwen Code is mid-response. If Qwen Code is busy when a task comes due, the prompt waits until the current turn ends.
|
|
98
|
+
|
|
99
|
+
All times are interpreted in your local timezone. A cron expression like `0 9 * * *` means 9am wherever you're running Qwen Code, not UTC.
|
|
100
|
+
|
|
101
|
+
### Jitter
|
|
102
|
+
|
|
103
|
+
To avoid every session hitting the API at the same wall-clock moment, the scheduler adds a small deterministic offset to fire times:
|
|
104
|
+
|
|
105
|
+
- **Recurring tasks** fire up to 10% of their period late, capped at 15 minutes. An hourly job might fire anywhere from `:00` to `:06`.
|
|
106
|
+
- **One-shot tasks** scheduled for the top or bottom of the hour (minute `:00` or `:30`) fire up to 90 seconds early.
|
|
107
|
+
|
|
108
|
+
The offset is derived from the task ID, so the same task always gets the same offset. If exact timing matters, pick a minute that is not `:00` or `:30`, for example `3 9 * * *` instead of `0 9 * * *`, and the one-shot jitter will not apply.
|
|
109
|
+
|
|
110
|
+
### Three-day expiry
|
|
111
|
+
|
|
112
|
+
Recurring tasks automatically expire 3 days after creation. The task fires one final time, then deletes itself. This bounds how long a forgotten loop can run. If you need a recurring task to last longer, cancel and recreate it before it expires.
|
|
113
|
+
|
|
114
|
+
One-shot tasks do not expire on a timer — they simply delete themselves after firing once.
|
|
115
|
+
|
|
116
|
+
## Cron expression reference
|
|
117
|
+
|
|
118
|
+
`CronCreate` accepts standard 5-field cron expressions: `minute hour day-of-month month day-of-week`. All fields support wildcards (`*`), single values (`5`), steps (`*/15`), ranges (`1-5`), and comma-separated lists (`1,15,30`).
|
|
119
|
+
|
|
120
|
+
| Example | Meaning |
|
|
121
|
+
| :------------- | :--------------------------- |
|
|
122
|
+
| `*/5 * * * *` | Every 5 minutes |
|
|
123
|
+
| `0 * * * *` | Every hour on the hour |
|
|
124
|
+
| `7 * * * *` | Every hour at 7 minutes past |
|
|
125
|
+
| `0 9 * * *` | Every day at 9am local |
|
|
126
|
+
| `0 9 * * 1-5` | Weekdays at 9am local |
|
|
127
|
+
| `30 14 15 3 *` | March 15 at 2:30pm local |
|
|
128
|
+
|
|
129
|
+
Day-of-week uses `0` or `7` for Sunday through `6` for Saturday. When both day-of-month and day-of-week are constrained (neither is `*`), a date matches if either field matches — this follows standard vixie-cron semantics.
|
|
130
|
+
|
|
131
|
+
Extended syntax like `L`, `W`, `?`, and name aliases such as `MON` or `JAN` is not supported.
|
|
132
|
+
|
|
133
|
+
## Limitations
|
|
134
|
+
|
|
135
|
+
Session-scoped scheduling has inherent constraints:
|
|
136
|
+
|
|
137
|
+
- Tasks only fire while Qwen Code is running and idle. Closing the terminal or letting the session exit cancels everything.
|
|
138
|
+
- No catch-up for missed fires. If a task's scheduled time passes while Qwen Code is busy on a long-running request, it fires once when Qwen Code becomes idle, not once per missed interval.
|
|
139
|
+
- No persistence across restarts. Restarting Qwen Code clears all session-scoped tasks.
|