agentsec · Tools · mcpbundle

Offline · stdlib-only · MIT

mcpbundle: detect risky install manifests for MCP servers in AI agents


Offline auditor for MCP server packaging manifests: MCP Bundle manifest.json files (inside a .mcpb archive, the legacy .dxt format, or loose) and MCP Registry server.json entries.

What it detects

Offline auditor for MCP server packaging manifests: MCP Bundle manifest.json files (inside a .mcpb archive, the legacy .dxt format, or loose) and MCP Registry server.json entries.

These are the files an MCP server author ships so a client can install the server in one click. The client trusts them to decide what command to run, which package version to fetch, which settings to ask the user for, and where to send tokens. mcpbundle reads them before you install or publish and flags inline secrets, credential prompts that are not marked sensitive, shell-wrapped or pipe-to-shell launch commands, unpinned packages, cleartext or internal remotes, privileged container arguments, whole-disk directory defaults, injection-shaped tool text, and missing provenance.

Standard library only. It never installs anything, never extracts archives to disk (it reads manifest.json from the zip in memory), and never contacts a registry.

Rules

RuleSeverityWhat it flags
MB01criticalSecret-shaped literal in env, a user_config default, an environment-variable or header value/default, or URL userinfo (masked in output)
MB02highCredential-like user_config without "sensitive": true, or a credential-like environment variable / header without is_secret
MB03high / criticalLaunch through sh -c, bash -c, cmd /c, powershell -Command, or a shell runtime_hint; critical when a download is piped into an interpreter (`curl ... \
MB04high / mediumUnpinned package: npx/uvx without an exact version, registry version missing/latest/range, untagged container image; medium for an mcpb package with no file_sha256
MB05highhttp:// remote, transport, or registry URL on a non-loopback host
MB06high--privileged, --network/--pid/--ipc host, --cap-add, unconfined security options, or mounting /, /etc, /root, /home, ~ or docker.sock
MB07mediumDirectory default or argument of /, ~, $HOME, C:\, %USERPROFILE%
MB08medium / highInjection-shaped phrases in tool, prompt, setting or server descriptions; high for hidden zero-width, bidi or TAG Unicode
MB09medium / highRemote on a private, internal-suffix, or link-local address; high for cloud metadata
MB10lowMissing provenance (author, repository, license for bundles; repository for server.json)
MB11lowtools_generated / prompts_generated set, so the declared list is not the full surface
MB12infoInventory line per manifest

Usage

python3 mcpbundle.py examples/risky                 # text report, exit 1 (high+ findings)
python3 mcpbundle.py examples/clean --min-severity low
python3 mcpbundle.py my-server.mcpb                 # reads manifest.json from the archive
python3 mcpbundle.py . --json                       # walk a repo for manifest.json / server.json
python3 mcpbundle.py server.json --sarif > mcpbundle.sarif
cat server.json | python3 mcpbundle.py -
python3 mcpbundle.py --list-rules

After pip install of the kit, the same options work as agentsec mcpbundle …. Every tool also accepts --help and almost every tool accepts --json.

Example output

All secrets in examples/ are obviously fake (FAKE-EXAMPLE-...).

$ python3 mcpbundle.py examples/risky/manifest.json
examples/risky/manifest.json:13  CRITICAL MB01  env FILES_API_TOKEN ships a literal secret (FAKE…****)  [/server/mcp_config/env/FILES_API_TOKEN]
examples/risky/manifest.json:11  CRITICAL MB03  downloads and pipes into an interpreter  [/server/mcp_config]
examples/risky/manifest.json:19  HIGH     MB02  credential-like setting 'api_key' is not marked "sensitive": true (stored and shown in plaintext)  [/user_config/api_key]
examples/risky/manifest.json:23  MEDIUM   MB08  injection-shaped phrase: 'Before using any other tool'  [/tools/0/description]
...

SARIF and CI

agentsec mcpbundle path/to/input --sarif > mcpbundle.sarif

# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
  with:
    tools: mcpbundle
    paths: path/to/input
    fail-on: high

SARIF 2.1.0 can be uploaded to GitHub code scanning. The composite action writes per-tool reports under agentsec-sarif/ by default.

OWASP mapping

Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.

Known limits

server/index.js; mcpbundle does not read or execute server code (use mcpsink for Python MCP server source).

and may flag long non-secret values under credential-like names.

matches the archive, or that the repository is genuine.

Full source, tests, and fixtures: tools/mcpbundle/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.