Skip to content

Getting Started

Pick your use case — each takes under 5 minutes.


A. Scan MCP servers for vulnerabilities (munio scan)

Section titled “A. Scan MCP servers for vulnerabilities (munio scan)”
Terminal window
pipx install munio
Terminal window
munio scan --server "npx -y @modelcontextprotocol/server-filesystem /tmp"

8 scan layers (L1 schema, L2 heuristic, L2.5/L2.6 ML classifiers, L3 static, L4 Z3 formal, L5 compositional, L7 source) detect prompt injection, path traversal, SSRF, command injection, and cross-tool data flows.

Terminal window
munio scan --config ~/.cursor/mcp.json
Terminal window
munio scan # Discovers configs from Claude Desktop, Cursor, Windsurf, VS Code
Terminal window
# JSON
munio scan --server "..." --format json
# SARIF 2.1.0 (GitHub Code Scanning, VS Code SARIF Viewer)
munio scan --server "..." --format sarif -O report.sarif
Terminal window
munio scan --server "..." --details # Tool names, fixes, Z3 counterexamples

B. Scan configs for supply chain risks (munio config-scan)

Section titled “B. Scan configs for supply chain risks (munio config-scan)”

Static analysis of MCP config files — no server connections needed.

Terminal window
munio config-scan

Auto-discovers configs from known client locations. Or scan a specific file:

Terminal window
munio config-scan --config ~/.cursor/mcp.json

10 checks (SC_001 through SC_010):

CheckRisk
SC_001Unpinned npm/bunx packages (dependency hijack)
SC_002Dangerous environment variables
SC_003Typosquatting of known MCP packages
SC_004Unscoped npm packages (higher hijack risk)
SC_005Shell metacharacters in command arguments
SC_006Absolute path binaries in command
SC_007Unencrypted HTTP URLs
SC_008Docker images without digest pinning
SC_009Hardcoded credentials in env values
SC_010Insecure file permissions
Terminal window
munio config-scan --details # Fix suggestions per server
munio config-scan --trust-project # Include project-level configs
munio config-scan --format sarif -O config-report.sarif # SARIF output

C. Analyze cross-server attack chains (munio compose)

Section titled “C. Analyze cross-server attack chains (munio compose)”

Detect multi-hop attack chains that span MCP server boundaries.

Terminal window
# From pre-fetched schemas
munio compose --schemas-dir ./schemas
# From a config file (connects to servers)
munio compose --config ~/.cursor/mcp.json
Terminal window
munio compose --schemas-dir ./schemas --format markdown # For PRs/issues
munio compose --schemas-dir ./schemas --format json -O chains.json

Findings include signal quality: high (confirmed dangerous data flow), medium (plausible chain), low (theoretical). Use --details to see chain details and capability classifications.


Add a verification proxy between your MCP client and any MCP server. Zero code changes.

Terminal window
# See current MCP server status
munio status
# Auto-wrap all discovered servers
munio init
# Undo changes
munio restore

munio init edits MCP client configs (Claude Desktop, Cursor, etc.) to route server commands through the munio gate proxy.

Prefix the server command with munio gate -- in your MCP client config:

{
"mcpServers": {
"filesystem": {
"command": "munio",
"args": [
"gate", "--",
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"
]
}
}
}

Every tools/call is verified against YAML constraints. Dangerous calls are blocked. Safe calls pass through with sub-millisecond overhead.

Terminal window
munio gate --packs generic,filesystem -- npx @server # Specific constraint packs
munio gate --mode shadow -- npx @server # Log only, do not block
munio gate --log /tmp/munio.jsonl -- npx @server # JSON audit log
munio stats # Runtime statistics

from munio import Guard
guard = Guard(constraints="generic")
result = guard.check(tool="http_request", args={"url": "https://evil.com/steal"})
result.allowed # False
result.violations # [Violation(message="URL contains blocked domain", ...)]

Wrappers for LangChain, CrewAI, OpenAI Agents SDK, and MCP:

from munio.adapters import langchain_tool_wrapper, crewai_tool_wrapper
safe_tool = langchain_tool_wrapper(my_tool, guard)
Terminal window
munio check '{"tool": "exec", "args": {"command": "rm -rf /"}}' -c generic
Terminal window
munio serve --host 0.0.0.0 --port 8000
# POST /verify with {"tool": "exec", "arguments": {"command": "rm -rf /"}}

All verification uses the same YAML constraint format:

name: block-dangerous-urls
category: ASI02
action: http_request
check:
type: denylist
field: url
values: ["evil.com", "169.254.169.254", "metadata.google.internal"]
match: contains
on_violation: block
severity: critical
TypeDescription
denylistBlock if field matches any value
allowlistBlock if field does NOT match any value
thresholdBlock if numeric field exceeds bounds
regex_denyBlock if field matches regex pattern
regex_allowBlock if field does NOT match regex
compositeMulti-variable arithmetic expression
rate_limitBlock if call rate exceeds limit in time window
sequence_denyBlock if tool call sequence matches banned pattern

See Constraint Authoring for the full guide.