Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者提供的说明(英文原文)
Defense-in-depth for MCP stdio servers: shell-injection guard, AST audit CLI, RCE blocking.
这三项永远不会合并成一个分数:意见、测量和人气是不同的东西。
我们还没有为它写通俗的介绍。下面是我们从注册中心读取到的事实。
选择你使用的 AI 应用,然后复制设置。
你需要
你用的是哪个应用?
在上方选择你的应用。我们会记住它,下次按钮会显示“安装到 …”。
打开 Claude Desktop → Settings → Developer → Edit Config,把下面的内容粘贴到 claude_desktop_config.json
{
"mcpServers": {
"stdio-shellguard": {
"command": "npx",
"args": [
"-y",
"mcp-stdio-shellguard"
]
}
}
}在终端中运行这条命令
claude mcp add stdio-shellguard -- npx -y mcp-stdio-shellguard粘贴到项目中的 .cursor/mcp.json,或 ~/.cursor/mcp.json
{
"mcpServers": {
"stdio-shellguard": {
"command": "npx",
"args": [
"-y",
"mcp-stdio-shellguard"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
粘贴到项目中的 .vscode/mcp.json
{
"servers": {
"stdio-shellguard": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mcp-stdio-shellguard"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
这个服务器在你的电脑上运行,而 ChatGPT 只能连接互联网上的服务器。请选择其他应用。
你的选择通过 Cookie 保存在这台设备上,无需账户。
这些设置是根据作者在注册中心的条目生成的。如果 README 的写法不同,请以 README 为准。
它在你的电脑上运行;安装后,工具列表会显示在你的 AI 应用中。
我们检查的是任何人都能看到的信息;我们没有阅读代码。不适用的检查项不计入总数。 · 检查于 2026年11月6日
注册名称已通过域名 studiomeyer.io 验证(注册中心会核实域名所有权)
我们还没有从 GitHub 读取这个仓库
我们还没有从 GitHub 读取这个仓库
它在你的电脑上运行,没有互联网端点
在你的电脑上运行,改用本地设置
它在你的电脑上运行;我们只能读取互联网端点的工具列表
与注册中心里这个分类中所有活跃的服务器比较。只有当发布者拥有该仓库时,星标数才计入。
它在 1 项适用的基础检查中通过了 1 项。我们没有阅读代码。在添加密钥或令牌之前,请先看看这个服务器要求哪些权限,并使用只具备所需权限的密钥。
注册中心没有列出必需的密钥,不过有些服务器会在首次使用时要求你登录。
它在你的电脑上运行。你的 AI 应用会在需要时启动它,数据不会经过作者的服务器(除非它自己调用在线服务)。
GitHub 仓库最后更新于–,最新版本(0.1.3)于4天前进入注册中心。
支持 MCP 的应用,例如 Claude Desktop、Claude Code、Cursor 和 VS Code。你的电脑上还需要有 Node.js。
同一分类中有:Spec Driven Development, Remote Desktop Commander, Safe Fetch
同一分类中其他作者的服务器,按星标数排序。
如何看卡片:★ GitHub 星标i三大支柱:评价 · 检查 · 使用情况i更新 = 最新版本发布到注册中心的时间i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
MCP server for fetching URLs, safe against SSRF, DNS rebinding, and redirect-to-internal attacks.
按原文从作者的仓库复制。PopNx MCP 没有审查或背书其内容。HTML、图片和脚本已被移除。链接会离开本站。
Part of the [StudioMeyer MCP Stack](https://studiomeyer.io) — Built in Mallorca 🌴 · ⭐ if you use it
Defense-in-depth bundle for MCP stdio servers. Wraps child_process.exec/spawn with allowlist + sandbox + replay-detection, plus an AST audit CLI (mcp-shellguard-audit) that scans MCP server sources for unsanitized shell calls. Closes the Ox-Security MCP stdio-RCE class (200k vulnerable servers, May 2026 disclosure).
@modelcontextprotocol/sdk ^1.29.0npm install mcp-stdio-shellguard
Or run the audit CLI directly without installing:
npx -y -p mcp-stdio-shellguard mcp-shellguard-audit scan ./src
Version 0.1.3 includes the dependency bundle described below.
The package ships @typescript-eslint/typescript-estree plus TypeScript and the required parser dependency closure through bundledDependencies. A root-only npm override does not constrain an installed package's dependency tree; the included closure carries the checked versions to consumers. The bundle preparation checks @typescript-eslint/typescript-estree 8.72.1 and minimatch 11.0.3, then changes only the parser manifest dependency range from minimatch ^10.2.2 to ^11.0.3. Third-party source files and package version numbers are unchanged. The AST audit calls typescript-estree.parse directly, with TypeScript included explicitly to satisfy the parser dependency tree; no ESLint runtime is required.
The measured archive is approximately 4.92 MB compressed and 26.04 MB unpacked (decimal MB). Bundling increases download and disk use; a security update to an included dependency requires an updated package archive.
For maintenance, run npm ci and npm run test:consumer from the repository checkout. npm pack runs prepack automatically: it builds the package and prepares the declared bundle. The consumer check packs twice, verifies identical bytes, installs the actual archive in a fresh project, checks npm ls and both dependency audits, and exercises the installed CLI or runtime. Review dependency updates together with the locked bundle and license proofs before distributing a new archive. The archive's dist/bundled-dependencies.json records the bundle and manifest adjustments.
Three layers, opt-in piecewise:
guardExec / guardSpawn you call from your own MCP server. Default-deny allowlist, sandbox profiles, replay window.mcp-shellguard-audit scan walks the AST, reports 12 anti-patterns from LOW (no timeout) to CRITICAL (exec(\...${userInput}...\)).mcp-stdio-shellguard-demo exposes 8 tools so the MCP Inspector / Claude Desktop can drive the bundle directly.| Tool | Type | Purpose |
|---|---|---|
guard_exec | destructive | Defended child_process.exec. Forces args[] vector, allowlist + sandbox + replay. Returns stdout, stderr, exitCode, canonicalHash, isReplay, trustTier. |
guard_spawn | destructive | Defended child_process.spawn. Returns SHA-256 hashes of stdout/stderr instead of full bodies. Hard-rejects shell:true. |
register_allowlist | mutating | Register a tool name with executable + args regex. Without registration the default-deny applies. |
audit_source | read-only | Scan a TS/JS path for shell-injection anti-patterns. Returns AuditFinding[] + summary. |
audit_report | read-only | Format an audit result as markdown / json / SARIF 2.1.0. |
replay_check | read-only | Compute canonical SHA-256 hash for an invocation and report whether it's already in the replay window. |
sandbox_status | read-only | Report active sandbox profile + concrete limits + cgroup-v2 active flag. |
trust_tier | read-only | Derive LOW/MEDIUM/HIGH/CRITICAL tier for a registered tool plus improvement hints. |
| Profile | Timeout | Max stdout | Max stderr | FD budget | cgroup-v2 |
|---|---|---|---|---|---|
strict | 5 s | 1 MB | 256 KB | 32 | yes (cpu/memory) |
standard (default) | 30 s | 10 MB | 1 MB | 256 | yes |
permissive | 5 min | 100 MB | 10 MB | 1024 | no |
Caller can tighten via timeoutMs / fdBudget per call. Caller cannot widen beyond the profile.
| Tier | Condition |
|---|---|
| LOW | tool not registered (default-deny) |
| MEDIUM | registered but argsPatterns empty (any args allowed) |
| HIGH | argsPatterns set but sandbox or replay tracker inactive |
| CRITICAL | argsPatterns + sandbox + replay all active |
Lift LOW → CRITICAL by registering the tool + setting argsPatterns + running through guardExec/guardSpawn (which always activate sandbox + replay).
import {
AllowlistRegistry, ReplayWindow, guardExec, } from "mcp-stdio-shellguard";
const registry = new AllowlistRegistry(); const replay = new ReplayWindow();
registry.register({ toolName: "git-log", executable: "/usr/bin/git", argsPatterns: ["^log$", "^--oneline$", "^-n$", "^\\d+$"], sandboxProfile: "strict", });
const result = await guardExec( { toolName: "git-log", command: "/usr/bin/git", args: ["log", "--oneline", "-n", "10"], }, { registry, replay }, );
console.log(result.stdout); // → commit lines console.log(result.trustTier); // → "CRITICAL" console.log(result.canonicalHash); // → 64-char SHA-256
mcp-shellguard-audit scan ./src
mcp-shellguard-audit scan ./src --format sarif --output audit.sarif mcp-shellguard-audit scan ./src --severity-floor HIGH # CI gate
Exit codes:
0 clean (no findings at-or-above floor)1 findings present2 parse / IO errorsCustom ignoreGlobs passed to scanPath or the audit_source MCP tool accept at most 128 strings. Each string is limited to 1024 UTF-16 code units and 16 unescaped opening grouping characters ((, {, [). Inputs above these budgets raise a controlled error before matching.
| ID | Severity | Triggers on |
|---|---|---|
exec_template_literal_with_input | CRITICAL | child_process.exec(\ls ${x}\) |
exec_dynamic_string | CRITICAL | child_process.exec(cmd) |
exec_sync_dynamic_string | CRITICAL | child_process.execSync(cmd) |
eval_near_child_process | CRITICAL | eval(...) |
function_constructor_near_child_process | CRITICAL | new Function(...) |
spawn_dynamic_file_args | HIGH | spawn(bin, userArgs) |
exec_file_dynamic | HIGH | execFile(bin, ...) |
shell_true_option | HIGH | { shell: true } |
os_system_equivalent | HIGH | Deno.run / Bun.spawn |
spawn_literal_dynamic_args | MEDIUM | spawn('git', userArgs) |
unbounded_buffer | LOW | exec without maxBuffer |
missing_timeout | LOW | exec/spawn without timeout |
The scanner resolves *renamed* child_process bindings before matching, so the dangerous shapes below are caught even when the call goes through an alias rather than a literal child_process.exec:
const execAsync = promisify(exec); execAsync(...${x})import cp from "node:child_process"; cp.exec(...${x})const { exec: sh } = require("child_process"); sh(...${x})import { exec as run } from "node:child_process"; run(...)Synchronous variants (spawnSync, execFileSync) share their async rules, and shell_true_option also fires on a string shell ({ shell: "/bin/sh" }) or a dynamic shell value — not just the literal { shell: true }. A promisify of a non-child_process function, a destructure off another module, and { shell: false } stay clean (no false positives).
// shellguard:ignore-next-line — suppress one finding// shellguard:ignore-file — suppress whole file (rare; prefer per-line)Ox-Security disclosed (2026-05) that 200k+ MCP stdio servers wrap child_process.exec with template literals carrying user input straight from LLM tool args. LiteLLM v1.83.6 was the canonical example (CVE patched in 1.83.7). This bundle is the defensive-security counterpart: a drop-in guard + scanner that closes the class. Inspired by AWS Linux seccomp + Chromium sandbox tiers.
HOOK_RECIPES.md — Claude Code hook recipes that auto-block dangerous tool callsCHANGELOG.md — release historyMIT — Copyright (c) 2026 Matthias Meyer (StudioMeyer)
Bundled dependencies retain their complete upstream license texts in the archive. The package license applies to this project's own code; bundled third-party packages retain their respective terms. The consumer check verifies each approved package version's full license file, or its complete README license section, against pinned content hashes from integrity-verified official npm artifacts. Whitespace and line-ending differences are accepted; missing, empty or partial legal text is rejected.