Skip to content
DucarvPublic

About

Personal MCP firewall: offline scanner for malicious or tampered MCP servers (Go CLI)

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

mcpmoat

CI Release Go version License

An offline-first scanner for malicious or tampered MCP servers, built for the individual developer.

mcpmoat scan in a terminal: the first scan finds tool poisoning and shadowing, then a changed tool shows as a rug pull with a diff.

mcpmoat finds the MCP servers that Claude Code, Cursor and Codex load on your machine, reads the tools they expose, and checks them for tool poisoning, shadowing, rug pulls, dangerous config and typosquatting.

Status: v1.0.0. scan runs the config checks and the rug-pull check. When it connects to the servers, it also applies the tool poisoning and shadowing rules to the description and the input schema of each tool. A clean scan (exit code 0) does not mean that the tools are safe. See what this does not do.

Features

  • Offline-first. No account and no telemetry. It connects only to the servers you configured, and to an LLM provider only if you use --llm.
  • Checks the config. It flags plaintext secrets, unpinned packages, insecure URLs, auto-install flags and look-alike package names.
  • Checks the tools. It flags hidden instructions, invisible characters, exfiltration and shadowing in the description and the input schema of each tool.
  • Catches rug pulls. It pins every tool and reports a tool that changes, appears or goes away.
  • Built for CI. Exit code 0, 1 or 2, a --fail-on threshold, and one JSON document with --json.
  • Optional LLM rating. Off by default. With --llm, tool names and descriptions leave your machine.

Install

brew install --cask Ducarv/tap/mcpmoat                      # macOS and Linux
go install github.com/Ducarv/mcpmoat/cmd/mcpmoat@v1.0.0    # needs Go 1.27 or later

You can also download an archive from the releases page. docs/install.md has all methods. The macOS binaries are not notarized yet, and the Homebrew tap gets stable releases only. Run mcpmoat version to check the install. Here is how to verify a download.

Quick start

mcpmoat scan

scan starts each stdio server in your configs, with the command your client already runs. To read the configs only, run mcpmoat scan --no-connect first. scan prints a server table, a summary and the findings, worst first. A shortened sample:

SUMMARY
  github (claude-code, global): ok, 12 tools, 0 findings
  files (cursor, global): ok, 4 tools, 1 finding

FINDINGS
HIGH (1)
  MOAT-T4-002  Plaintext secret in config
    Server: files (cursor, global)
    Where: env GITHUB_TOKEN
    Fix: Move the secret out of the config: use an environment variable reference ...

More about the output: docs/scan-output.md.

Usage

Scan the config only. This starts no server and reads no pins.

mcpmoat scan --no-connect

Fail a build on findings. Exit code 1 means a finding that is not ignored is at or above --fail-on (default high). Exit code 2 means an error, and it wins over 1. See docs/exit-codes.md and docs/ci.md.

mcpmoat scan --fail-on medium

Read the report as JSON.

mcpmoat scan --json | jq '.findings[] | {rule_id, server}'

Check for a rug pull. A scan pins the tools of each new server. Later runs show a diff when they change. Review the diff, then accept it with the digest that scan prints. An accept does not make the new text safe: a tool poisoning finding on the new text stays after the accept. See docs/pins.md.

mcpmoat pin --accept <server> --expect <digest>

Ignore a finding. Use --ignore. scan reads a .mcpmoat-ignore file in the working directory only with --use-ignore-file, because a cloned repository can hide findings with its own file. Use the flag only with a file that you trust. The file cannot drop pin findings, LLM findings or the findings that say the analysis stopped early or that findings were left out (MOAT-T1-023, MOAT-T1-024 and MOAT-T4-005). Only --ignore can. See docs/ignore.md.

mcpmoat scan --ignore MOAT-T4-003

Rate tools with an LLM. This sends tool names and descriptions to the provider. Set MCPMOAT_LLM_API_KEY first. See docs/llm.md.

mcpmoat scan --llm

What this does not do

  • It does not guarantee safety. It has false positives and false negatives.
  • It does not analyse server source code, so it does not find malware inside a server.
  • It does not protect against prompt injection in content the agent reads.
  • scan starts your configured stdio servers. It passes them only a few env variables, but this is not a sandbox: a server runs as you and can read your files and use the network. It never starts a server from an untrusted project file.
  • A server can show mcpmoat a different tool list than it shows your AI client (cloaking). mcpmoat does not name itself. It sends the name of the client that owns the config, but a server can still tell it apart. A server that never answers an unknown list request shows as timeout. The pins cover only what mcpmoat sees.
  • A clean scan (exit code 0) does not mean that the tools are safe. The tool rules find only known patterns, and they do not run with --no-connect. The check that compares the tools of two servers for shadowing does not run in scan yet (#200).

The full list, with the detail on cloaking, is in docs/limits.md.

Documentation

docs/README.md is the index. Start with Install, Scan output, Pins and rug pulls, Exit codes and Use mcpmoat in CI. For the design, read Architecture and the requirements.

Contributing

Clone the repo, branch from dev and open your pull request against dev. main holds released code. CONTRIBUTING.md explains the checks, and docs/writing-rules.md shows how to add a rule. Build with go build -o mcpmoat ./cmd/mcpmoat. To report a vulnerability, read SECURITY.md.

Credits

The threat model builds on the tool poisoning research of Invariant Labs and on the OWASP MCP Top 10.

Built by Ducarv. See the contributors.

License

Apache-2.0

About

Personal MCP firewall: offline scanner for malicious or tampered MCP servers (Go CLI)

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages