Originally published on IndieSeek.
Qwen Code 0.22.2 Node REPL: enable the standalone MCP server without mistaking it for a sandbox
Quick answer
Qwen Code 0.22.2, released on August 26, 2026, lists the persistent Node.js REPL as a standalone MCP server. The package is @qwen-code/node-repl-mcp@0.1.0, requires Node.js 22 or newer, and exposes three opt-in tools: node_repl, node_repl_reset, and node_repl_add_node_module_dir.
The important boundary is authority, not installation. The REPL runs a real Node.js child process. Its VM context separates lifecycle and namespace, but it is not an operating-system sandbox. Imported packages and most Node built-ins use ordinary process authority and inherit the parent environment. Enable it only for a trusted workspace, under an identity that holds no credentials you would refuse to give the agent.
Who this is for
This guide is for developers upgrading Qwen Code who want persistent JavaScript state for data inspection, automation, Computer Use, or package experiments. It is also useful to teams reviewing an MCP configuration before allowing an AI coding agent to execute real Node code.
This is a different task from shrinking Qwen Code's registered and auto-approved tools. The earlier Qwen Code 0.22 permission checklist covers tool visibility, approval, and containment. This guide covers the authority and acceptance boundary of one external MCP server.
What changed—and what did not
The 0.22.2 release notes mark the Node REPL delivery as a breaking change. The linked official pull request adds an independent package instead of registering three tools in Qwen Code core. It also says core is unchanged relative to the main branch and describes the server as opt-in through mcpServers. That means you should not infer that every 0.22.2 user automatically receives a Node execution tool, or that a previously stable built-in tool was removed from all installations.
The official package contract is:
| Surface | Confirmed behavior | Boundary to preserve |
|---|---|---|
node_repl |
Runs JavaScript with top-level await; bindings persist between calls |
A timeout, cancellation, reset, or crash replaces the kernel and loses bindings |
node_repl_reset |
Discards bindings and module state | Registered module roots remain |
node_repl_add_node_module_dir |
Adds an absolute node_modules root for bare-package resolution |
It widens resolution; it does not reduce runtime authority |
| Output | Use nodeRepl.write, nodeRepl.emitImage, or captured console.*
|
Plain expression values are not returned automatically |
| Modules | Dynamic await import() is supported; package entrypoints keep singleton caching |
Static top-level imports are rejected |
| Isolation | Dedicated child process and VM context | Not an OS sandbox; built-ins and imported packages keep ordinary Node authority |
A safe six-stage rollout
1. Pin both moving parts
Record Qwen Code and server versions independently. At the time checked for this article, npm marks @qwen-code/qwen-code@0.22.2 and @qwen-code/node-repl-mcp@0.1.0 as latest.
Avoid an unbounded npx -y ... in CI or a long-lived agent profile. Resolve and review the package first, then pin the executable through a lockfile, a controlled install directory, or an exact package spec. A Qwen Code rollback should not silently leave a different REPL server version running.
2. Start with a disposable workspace and low-authority identity
Create a synthetic repository with no production .env, cloud credentials, signing keys, browser profile, or writable parent directories. Run Qwen Code under a dedicated OS user or container when the workflow touches untrusted prompts or packages.
The package denies direct process and node:process imports, but its own description warns that other built-ins and packages retain ordinary Node authority. Treat that denial as a narrow API choice, not a security wall.
3. Make the MCP grant explicit
Use a workspace-specific configuration and an exact cwd:
{
"mcpServers": {
"node-repl": {
"command": "npx",
"args": ["-y", "@qwen-code/node-repl-mcp@0.1.0"],
"cwd": "/absolute/path/to/disposable-workspace"
}
}
}
Do not add QWEN_NODE_REPL_ROOTS unless a specific package-resolution test requires it. Each entry expands readable roots and must be an absolute path. Keep execution approval separate from server registration; an MCP server being visible does not make every cell appropriate to auto-approve.
4. Run eight payload-safe canaries
Use synthetic values and no external side effects:
| Canary | Expected evidence |
|---|---|
| Tool inventory | Exactly the three documented tools appear |
| Persistent binding | Define const x = 40, then print x + 2 in a second call |
| Explicit output | A bare expression stays silent; nodeRepl.write returns text |
| Dynamic import | A reviewed local module loads through await import()
|
| Reset |
node_repl_reset makes the prior binding undefined |
| Timeout recovery | A bounded long cell is terminated and the old kernel state is gone |
| Module-root denial | A relative path or non-node_modules path is rejected |
| Authority boundary | A harmless built-in probe proves this is real Node, then the rollout remains isolated |
Do not turn the authority canary into secret discovery, network scanning, or a write outside the fixture workspace.
5. Separate durable inputs from ephemeral REPL state
Persistent bindings are convenient, not durable storage. Keep the source cell, input hash, package versions, and accepted result in normal project artifacts. Any cell needed after reset must be replayable from reviewed source. Do not make an invisible binding the only copy of a migration decision or generated output.
6. Promote by task, not by novelty
Allow the server only when persistent real-Node execution materially reduces repeated setup. Keep ordinary shell commands or a restricted evaluator for one-shot work. Roll back immediately if the server resolves packages outside the intended root, inherits unexpected credentials, loses kernel state without a detectable failure, or cannot be gated by your approval policy.
Decision tree
Does the task need state across JavaScript calls?
no -> use a narrower one-shot tool
yes -> does it require real Node packages or N-API?
no -> prefer a restricted evaluator
yes -> are workspace, identity, environment, and approvals isolated?
no -> do not enable the server
yes -> pin both versions
-> run eight canaries
-> keep cells replayable
-> canary one trusted workflow
Common mistakes
- Reading "VM context" as an OS sandbox.
- Assuming the release-note breaking label means the server is enabled for everyone.
- Using floating
latestversions for Qwen Code and the MCP package. - Pointing
cwdat a home directory or a repository containing production credentials. - Expanding
QWEN_NODE_REPL_ROOTSfor convenience without reviewing the new readable path. - Treating persistent bindings as durable evidence.
- Auto-approving every
node_replcall because the MCP server itself was approved.
Copyable rollout record
date / owner:
Qwen Code version / Node REPL MCP version / Node version:
config scope / cwd / OS identity:
environment and credential boundary:
extra module roots:
tool inventory / persistence / output / import:
reset / timeout / path denial / authority canary:
approval policy / allowed task:
artifact and replay location:
canary percentage / rollback command:
Building something? Take a 60-sec game break. Score to rank your product or profile on tapto.top and get more exposure—free, no signup.
FAQ
Is the Node REPL automatically enabled after upgrading Qwen Code?
The official pull request describes it as an independent, opt-in MCP server configured through mcpServers. Verify your actual tool inventory instead of assuming availability from the version number.
Does blocking process make it safe for untrusted code?
No. The official README explicitly says imported packages and other built-ins run with ordinary Node authority and inherit the parent environment. Use an OS-level boundary when inputs are untrusted.
Will state survive a timeout or reset?
No. Timeout, cancellation, reset, or a crash replaces the kernel and discards bindings. Keep important cells and outputs in replayable project artifacts.
Top comments (0)