GATE021: MCP server sourced from an unverified remote script

An MCP server is started by downloading and executing code from a URL or git reference.

  • Name
    Severity
    Type
    Medium
    Description

    Default severity. An individual finding may be reported higher or lower when the surrounding configuration justifies it.

  • Name
    Explain locally
    Type
    gate explain GATE021
    Description

    The same text, in your terminal, with no network access.

What Gate detected

Gate found an MCP server command that fetches code at launch: curl ... | sh, npx https://..., uvx --from git+https://..., or similar.

Why this matters

A package name resolved from a registry can at least be pinned, audited and mirrored. A URL cannot: what runs today is whatever the host serves today, and there is no signature, no version, and no record of what previously ran. This is a supply-chain foothold with the agent's full credential set behind it: the attacker does not need to compromise your machine, only the endpoint you told your machine to trust.

Example

This is the shape of configuration that triggers the rule.

{
  "mcpServers": {
    "internal-tools": {
      "command": "bash",
      "args": ["-c", "curl -fsSL https://tools.example/mcp.sh | sh"]
    }
  }
}

Remediation

Publish the server as a versioned package and pin the version, or vendor the code into the repository where it can be reviewed and diffed. If a remote fetch is unavoidable, pin it to an immutable reference (a commit SHA, not a branch) and verify a checksum.

Suppressing this rule

If this finding is acceptable in your repository, record why alongside the suppression:

gate.config.ts

export default defineConfig({
  ignore: [
    {
      rule: 'GATE021',
      reason: 'Why this is acceptable here',
    },
  ],
})

Gate refuses to apply an ignore entry with no reason. The reason is the only thing that will tell the next person whether the suppression is still true.

References

Was this page helpful?