Skip to content
Conduit

mcp server

mcpmoat

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

Ducarv/mcpmoatcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 27, 2026

mcpmoat

CI Release Go version License

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

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

Status: early release, v0.1.0. The YAML tool rules (tool poisoning and shadowing) do not run yet, so a clean scan (exit code 0) does not mean that the tools are safe. The config checks and the rug-pull check do run. See what this does not do.

Features

  • Offline. 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.
  • 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 (next release, not in v0.1.0). 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@v0.1.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. See docs/pins.md.

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

Ignore a finding. Use --ignore or a .mcpmoat-ignore file. A cloned repository can hide findings with its own .mcpmoat-ignore, so read it first. The file cannot drop pin findings or, from the next release, LLM findings. Only --ignore can. See docs/ignore.md.

mcpmoat scan --ignore MOAT-T4-003

Rate tools with an LLM (next release; build from dev to try it). 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 clean scan (exit code 0) does not mean that the tools are safe. The tool rules do not run yet.

The full list 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 public research by Invariant Labs and the OWASP MCP Top 10.

Built by Ducarv. See the contributors.

License

Apache-2.0

↑↓ navigate openesc close