MCP shell-launch config

Check H16 · agent family · severity CRITICAL · automatic · one of the 18 Hugging Face checks

The question this check asks: does a checked-in MCP or agent settings file in this repository — .mcp.json, .cursor/mcp.json, the files under .claude/ — define a command that fetches something from the network and runs it?

Why it matters

H16 is the same detection function as GitHub's C20, run against a Hugging Face repository's file list. This class executes before the trust prompt, and the CVEs that establish it are about the agent, not the hosting platform: in CVE-2025-59536 (CVSS 8.7) Claude Code ran project code from .claude/settings.json and .mcp.json before the user had accepted the dialog asking whether to trust the folder, fixed in 1.0.111. In CVE-2025-64109 (CVSS 8.8) the Cursor CLI auto-executed the commands in .cursor/mcp.json with no confirmation at all. Neither CVE cares whether the folder that was opened came from a git clone of a GitHub repository or a checkout of a Hugging Face Space — an MCP server definition is, by design, a command your agent's launcher will run as you, wherever the file sits.

How RepoGates scores it

H16 fetches each configuration file a repository ships — the same set H14 names — parses the JSON, and reads the command lines it defines: command plus args, joined. A line fires when it both fetches (curl, wget, Invoke-WebRequest and its aliases) and executes what it fetched: a pipe into a shell, an inline bash -c "curl … && ./x", or PowerShell's iex — identical logic to C20, applied to a different file source. The finding is CRITICAL, costs 30 points, and quotes the offending line. Because any CRIT finding drives the score to 0, a repository that trips only this check reads BLOCK. The scoring engine's shared evidence note for H14–H17: “same functions/penalties as C18–C21 — reuse those check pages' scoring language, applied to the HF file list instead of the GitHub one.” Unparseable JSON yields nothing, deliberately: a launcher would not read it either.

False positives we know about

None recorded specifically against Hugging Face repositories — the one legitimate npx -y configuration C20 cites, and the react/react allowlist false positive that reshaped C20's parsing to read only command lines rather than matching keywords anywhere in the file, are both GitHub measurements and we do not restate them as Hub numbers. What the 12 September 2026 measurement of the top 100 most-downloaded Hugging Face models does show: 0 BLOCK results across all 100, and since any CRIT finding forces the score to 0 and the verdict to BLOCK, that rules out H16 firing on any of them alongside every other CRIT row. H16 fired 0 times in that measurement. The parsing discipline C20 learned from the react/react false positive — reading only command and args fields rather than scanning raw text — applies to H16 unchanged, since it is a property of how the check reads JSON, not of which platform served it.

What this check does not cover

It sees the launch line, not the server. A plain npx some-package runs code from a registry too — the package is the payload in that case — and does not fire, because nothing in the line fetches a URL. What the launched server does once running is invisible here. Configuration outside the repository, and configuration under a filename we do not read, are not seen. Nor is a fetch-and-run that lives in an agent instruction file's prose rather than a command field.

And RepoGates as a whole gates browser downloads only — it does not see git clone, package managers, curl, huggingface_hub, or fetches made by AI agents outside the browser; a Python from_pretrained() call is never a shell line any hook sees. It reads the configuration before the download; it does not see the agent launch the server. This page, like every check page, exposes no globals a script running on it could read.

Check it yourself

Without installing anything: open .mcp.json and .cursor/mcp.json on the repository's Files tab and read every command and args as a shell line. With the Hub's raw file endpoint and jq:

curl -s https://huggingface.co/ORG/NAME/raw/main/.mcp.json \
  | jq -r '.mcpServers | to_entries[] | "\(.key): \(.value.command) \(.value.args // [] | join(" "))"'

Then, per the standard: patch your agent to a version that asks before running project configuration, and disable project-scoped MCP autoload until you trust the checkout. Any line containing curl, bash -c, iex or npx -y deserves a second read before that.

Questions

Does an MCP config that runs npx fire this check? Not on its own, for the same reason it does not on GitHub's C20: launching a package with npx is how most legitimate MCP servers start. The check fires when a single command line both fetches from the network — curl, wget, Invoke-WebRequest — and executes what it fetched: a pipe into a shell, an inline bash -c that fetches and runs, or PowerShell's iex. The finding shows you the exact line.

Why would a Hugging Face Space even have an MCP config? A Space is a full application repository — Gradio, Streamlit or a Docker container — and anyone developing one locally with an AI coding agent can commit the same .mcp.json or .claude/ settings files a GitHub project would. The file format and the risk are identical; only the hosting platform differs.

Does RepoGates stop a git clone or huggingface_hub download? No. RepoGates gates browser-initiated downloads only. It does not see git clone, huggingface_hub, huggingface-cli, curl, or a Python from_pretrained() call. It reads the configuration before the download; it does not see the agent launch the server.

Related checks

H14 Agent config files — the files this check parses · H17 Credential redirect — the same files pointing an API base URL or key somewhere else · H9 Custom code on load — pre-trust execution one layer down, inside the model's own loading code rather than its agent configuration · C20 MCP shell-launch config (GitHub) — the same function, reading a git tree instead of the Hub's file list.

Add RepoGates to Chrome Pricing

Numbers on this page: CVE-2025-59536 and CVE-2025-64109 as published; the 12 September 2026 measurement of the top 100 most-downloaded Hugging Face models (0 BLOCK, 28 REVIEW, 72 PASS), published on the malicious models intelligence page; weights from the product's scoring table.