Skip to main content

Local-first static auditor for risky MCP and agent-tool repository patterns.

Project description

mcp-riskmap

CI mcp-riskmap Release License: MIT

mcp-riskmap is a local-first static auditor for MCP and agent-tool repositories. It looks for risky MCP configuration, shell-enabled tool handlers, prompt-injection-like tool descriptions, and missing maintainer guidance without starting untrusted MCP servers.

This project is intentionally small and conservative. It is designed for maintainers who want a quick review signal in local development, pull requests, and GitHub Code Scanning.

Why this exists

MCP servers often expose tools that can touch files, shells, networks, credentials, or local developer state. Reference servers and community examples are useful, but each maintainer still needs a threat model and basic safeguards before sharing configs or accepting tool changes.

mcp-riskmap focuses on static signals that are cheap to review:

  • MCP config that starts through cmd, powershell, bash, or sh
  • Remote install pipelines such as curl ... | sh or curl ... | iex
  • Secret-like environment variables passed into MCP servers
  • Python subprocess(..., shell=True), os.system, eval, and exec
  • JavaScript child_process.exec and spawn(..., { shell: true })
  • Tool text that looks like model-control prompt injection
  • Missing AGENTS.md, SECURITY.md, or LICENSE

Install

From a checkout:

python -m pip install -e .

From GitHub:

python -m pip install "git+https://github.com/vawkdh-job/mcp-riskmap.git@v0.1.2"

For development without installing:

$env:PYTHONPATH = "src"
python -m mcp_riskmap.cli scan examples/unsafe-mcp-server
python -m mcp_riskmap.cli --version

Usage

mcp-riskmap scan .
mcp-riskmap scan . --format json
mcp-riskmap scan . --format markdown --output report.md
mcp-riskmap scan . --format sarif --output results.sarif --fail-on high
mcp-riskmap scan . --exclude "examples/**" --exclude "tests/**"

--fail-on high returns exit code 1 when at least one finding is high or critical.

Use --exclude for reviewed fixture directories, generated output, or intentionally unsafe examples that should not block CI.

Examples

  • examples/unsafe-mcp-server/ contains intentionally risky MCP config and tool-handler patterns for scanner demonstrations.
  • examples/safe-mcp-server/ contains a safer file-read pattern using a resolved base directory boundary check.

Example output

SEVERITY  RULE                       LOCATION      MESSAGE
--------  -------------------------  ------------  ------------------------------------------------
CRITICAL  MCP-CONFIG-REMOTE-INSTALL  mcp.json:5    MCP server 'unsafe-demo' downloads and executes...
HIGH      PY-SHELL-TRUE              server.py:6   A Python tool handler can pass input through a shell.
HIGH      JS-CHILD-PROCESS-EXEC      server.js:4   A JavaScript tool handler can pass input through a shell.

Output formats

  • table: compact terminal output
  • json: automation-friendly structured output
  • markdown: issue and release-note friendly report
  • sarif: GitHub Code Scanning compatible output

Structured outputs redact secret-like evidence values before writing JSON or SARIF.

Reviewed suppressions

If a maintainer reviews a finding and accepts the risk, add a narrow suppression on the same line or the previous line:

# mcp-riskmap: ignore PY-SHELL-TRUE
subprocess.run(command, shell=True)

Use rule-specific suppressions where possible. mcp-riskmap: ignore suppresses all rules on the next line and should be reserved for generated or documented fixture code.

GitHub Action

This repository includes a composite GitHub Action:

name: mcp-riskmap

on:
  pull_request:
  push:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v4
      - uses: vawkdh-job/mcp-riskmap@v0.1.2
        with:
          path: .
          format: sarif
          output: mcp-riskmap.sarif
          fail-on: high
          exclude: |
            examples/**
            tests/**
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: mcp-riskmap.sarif

Safety stance

mcp-riskmap does not execute MCP servers. It reads files and reports static findings. That means it will miss runtime-only behavior, but it is safer for quick review of unknown configs and pull requests.

Why static only?

Some MCP scanners inspect live tool descriptions by starting configured servers. That can be useful, but it is risky when a reviewer is looking at an unknown repository or pull request. mcp-riskmap is meant to run earlier in the review flow: it reads files, flags obvious risk, and produces review artifacts without executing commands from the target project.

Compared with dynamic scanners

mcp-riskmap is not a replacement for dynamic MCP inspection. It is a first-pass guardrail for maintainers who need quick review signals in CI and code review.

Area mcp-riskmap Dynamic scanners
Starts scanned MCP servers No Often yes
Safe for unknown PRs Designed for this Depends on sandboxing
CI/SARIF friendly Yes Depends on tool
Runtime behavior coverage Limited Better
Static source/config review Primary focus Varies

Current limitations

  • Rules are conservative regex/static checks, not full taint analysis.
  • The scanner does not inspect live MCP tool responses.
  • Secret detection is key-name based and does not do high-entropy scanning.
  • JavaScript and Python analyzers focus on common high-risk patterns first.

Roadmap

  • Add more MCP client config locations.
  • Detect unsafe filesystem writes and path traversal candidates.
  • Add rule severity profiles.
  • Add Semgrep-compatible pattern export.

See ROADMAP.md for issue-sized milestones.

OpenAI Codex for OSS fit

This project is intended to be maintained as an open-source security and maintainer automation tool. It includes tests, CI, SARIF output, examples, security docs, contribution guidance, AGENTS.md, and tagged releases.

Codex/API credits would be useful for reviewing rule changes, generating regression tests, triaging issues, improving documentation, and producing release notes. AI output should be reviewed by maintainers before merge.

See docs/codex-for-oss.md for application-specific maintainer workflow notes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_riskmap-0.1.2.tar.gz (19.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_riskmap-0.1.2-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file mcp_riskmap-0.1.2.tar.gz.

File metadata

  • Download URL: mcp_riskmap-0.1.2.tar.gz
  • Upload date:
  • Size: 19.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_riskmap-0.1.2.tar.gz
Algorithm Hash digest
SHA256 4c1317d841d747ced97ce58d3f02962a3142d7a7ebbf51ffdb8e1007d3ff5d55
MD5 bedf8908846bd9c30df51798d00db523
BLAKE2b-256 19a05e41cde849e96912ae961c1ea079027958a30c84dcfb852a989bd9315c94

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_riskmap-0.1.2.tar.gz:

Publisher: publish-pypi.yml on vawkdh-job/mcp-riskmap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_riskmap-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: mcp_riskmap-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 20.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_riskmap-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d09379982368a961fed5c4eac465d26b1c5f86ca8176acf233297d2104dd1059
MD5 e5993453a8dba57c879617b3eea95c46
BLAKE2b-256 644ef7ff0c39218de322596bc6351279158f85f46b042a31a91af9433744665a

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_riskmap-0.1.2-py3-none-any.whl:

Publisher: publish-pypi.yml on vawkdh-job/mcp-riskmap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page