使用MCP
MCP服务器枚举工具。连接到任何兼容MCP的HTTP服务器,并列出其公开的工具、提示和资源,并允许您直接调用或模糊它们。
需求
- Python 3.8+
httpx
pip install -r requirements.txt______________________________________________________________________
用法
python NgenuMCP.py [options]
positional arguments:
url Target MCP endpoint (e.g. http://host:3000/mcp)
options:
-h, --help show this help message and exit
-H, --header KEY:VALUE
Extra HTTP header, repeatable
-o FILE Output file for JSON results (default: stdout)
--ping Ping the server instead of enumerating
--no-init Skip MCP initialize handshake
--raw Print raw JSON output
enumeration filters:
-to Enumerate tools only
-po Enumerate prompts only
-ro Enumerate resources only
verbosity:
-vt Verbose: show full tool schemas
-vp Verbose: show full prompt arguments
-vr Verbose: show full resource details
-vv Verbose: show full detail for everything
calling:
--call-tool NAME Call a tool by name
--call-prompt NAME Get a prompt by name
--call-resource URI Read a resource by URI
--args JSON Arguments as JSON object for --call-tool / --call-prompt
fuzzing:
--fuzz-it Enable fuzzing mode
--fuzz-target TARGET What to fuzz: tool | prompt | resource (default: resource)
--fuzz-uri URI_TEMPLATE
URI template with @@FUZZ1 / @@FUZZn placeholders (resource fuzzing)
--fuzz-args JSON Args template with @@FUZZ1 / @@FUZZn placeholders (tool/prompt fuzzing).
Accepts a JSON string or a path to a text file.
-w, --wordlist FILE Wordlist file, repeatable — 1st -w feeds @@FUZZ1, 2nd feeds @@FUZZ2, nth feeds @@FUZZn
--threads N Number of threads for fuzzing (default: 4)
--show-output Show response content for HIT results
--show-miss Show failed fuzz attempts (miss results)______________________________________________________________________
枚举
基本枚举——列出服务器公开的所有内容:
python NgenuMCP.py http://target:3000/mcp枚举特定类别:
python NgenuMCP.py http://target:3000/mcp -to # tools only
python NgenuMCP.py http://target:3000/mcp -po # prompts only
python NgenuMCP.py http://target:3000/mcp -ro # resources only详细--显示完整的模式和参数详细信息:
python NgenuMCP.py http://target:3000/mcp -vt # full tool input schemas
python NgenuMCP.py http://target:3000/mcp -vp # full prompt arguments
python NgenuMCP.py http://target:3000/mcp -vr # full resource metadata
python NgenuMCP.py http://target:3000/mcp -vv # everything verbose使用身份验证标头:
python NgenuMCP.py http://target:3000/mcp -H "Authorization:Bearer "
python NgenuMCP.py http://target:3000/mcp -H "X-Api-Key:secret" -H "X-Tenant:corp"将输出保存到文件:
python NgenuMCP.py http://target:3000/mcp -o results.json # formatted output to file
python NgenuMCP.py http://target:3000/mcp --raw # raw JSON to stdoutPing/连接检查:
python NgenuMCP.py http://target:3000/mcp --ping跳过MCP初始化握手(对于没有握手的服务器很有用):
python NgenuMCP.py http://target:3000/mcp --no-init______________________________________________________________________
召唤
调用工具
# Tool with required arguments
python NgenuMCP.py http://target:3000/mcp --call-tool port_scan --args "{\"host\":\"10.0.0.1\"}"
# Tool with multiple arguments
python NgenuMCP.py http://target:3000/mcp --call-tool port_scan --args "{\"host\":\"10.0.0.1\",\"ports\":\"22,80,443\"}"
# Tool with no required arguments
python NgenuMCP.py http://target:3000/mcp --call-tool whoami
# Save result to file
python NgenuMCP.py http://target:3000/mcp --call-tool dns_resolve --args "{\"domain\":\"example.com\"}" -o out.json
# Raw JSON response
python NgenuMCP.py http://target:3000/mcp --call-tool whois_lookup --args "{\"target\":\"example.com\"}" --raw呼叫提示
# Prompt with required argument
python NgenuMCP.py http://target:3000/mcp --call-prompt recon_report --args "{\"target\":\"example.com\"}"
# Prompt with multiple arguments
python NgenuMCP.py http://target:3000/mcp --call-prompt attack_surface --args "{\"domain\":\"example.com\",\"include_subdomains\":true}"
# Save to file
python NgenuMCP.py http://target:3000/mcp --call-prompt vuln_summary --args "{\"findings\":\"open port 22, weak SSH config\"}" -o report.json阅读资源
# Static resource — use the exact URI from enumeration
python NgenuMCP.py http://target:3000/mcp --call-resource "file:///wordlists/common.txt"
python NgenuMCP.py http://target:3000/mcp --call-resource "config://server/settings"
# Template resource — substitute the variable in the URI yourself
# Template: file:///reports/{scan_id}.json → fill in scan_id
python NgenuMCP.py http://target:3000/mcp --call-resource "file:///reports/abc123.json"
# Template: db://users/{user_id}/profile → fill in user_id
python NgenuMCP.py http://target:3000/mcp --call-resource "db://users/42/profile"
# Template: file:///internal/{filename}.txt → fill in filename
python NgenuMCP.py http://target:3000/mcp --call-resource "file:///internal/credentials.txt"
# Save resource content to file
python NgenuMCP.py http://target:3000/mcp --call-resource "file:///reports/pentest_report.pdf" -o report.json______________________________________________________________________
模糊测试
Fuzzing迭代单词表 @@FUZZn 位置标记并尝试所有组合(笛卡尔积)。支持三个目标: 资源 URI, 工具 论点,以及 提示 论据。
结果代码
| 代码 | 含义 |
|---|---|
[HIT] | 有效响应--返回资源内容,或成功执行工具/提示 |
[MAYBE] | 请求已到达服务器,但导致执行级错误——这可能很有趣 |
[miss] | 未找到、参数错误或响应文本包含“未找到”短语 |
[MAYBE] 值得手动调查——服务器处理了输入,但服务器端出了问题(例如,一个存在但崩溃的处理程序)。
[miss] 涵盖了服务器返回包含以下短语的文本的硬错误和软遗漏 "not found", "does not exist",或 "no such file".
______________________________________________________________________
占位符语法
使用 @@FUZZ1, @@FUZZ2, … @@FUZZn 作为URI或JSON参数模板中任何位置的占位符。第n期 -w 单词列表提要 @@FUZZn。如果提供的单词表少于标记,则重复使用最后一个单词表。
资源URI模板:
file:///internal/@@FUZZ1.txt # single marker
file:///@@FUZZ1/@@FUZZ2/secret.txt # two markers — cartesian product工具/提示参数模板(JSON):
{"host": "@@FUZZ1", "ports": "@@FUZZ2"}
{"host": "@@FUZZ1", "port": @@FUZZ2}JSON字符串引号内的标记在替换后仍然是字符串。无引号标记采用被替换单词的JSON类型(例如。@@FUZZ2→80变为整数80).
______________________________________________________________________
资源模糊
通过迭代文件名、路径或完整URI来模糊资源URI。
# Fuzz a filename in a URI template
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-uri "file:///internal/@@FUZZ1.txt" -w names.txt
# Full-URI wordlist (each line tried as-is)
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-uri "@@FUZZ1" -w NgenuMCP/wordlists/resources.txt
# Path traversal
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-uri "file:///app/@@FUZZ1" -w traversal.txt
# Multi-marker — 2 wordlists, all combinations tried
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-uri "db://@@FUZZ1/@@FUZZ2/profile" \
-w users.txt -w actions.txt______________________________________________________________________
工具模糊
使用JSON模板的Fuzz工具参数。将模板作为字符串或 .json 文件。工具名称设置为 --call-tool.
# Inline JSON template — fuzz the host argument
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-target tool --call-tool port_scan \
--fuzz-args '{"host":"@@FUZZ1","ports":"80,443"}' \
-w hosts.txt
# JSON file template — fuzz host and port simultaneously
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-target tool --call-tool port_scan \
--fuzz-args args_template.json \
-w hosts.txt -w ports.txtargs_template.json (端口为未加引号的整数):
{"host": "@@FUZZ1", "port": @@FUZZ2}______________________________________________________________________
快速模糊
Fuzz以相同的方式提示参数——使用 --fuzz-target prompt 和 --call-prompt.
python NgenuMCP.py http://target:3000/mcp --fuzz-it \
--fuzz-target prompt --call-prompt recon_report \
--fuzz-args '{"target":"@@FUZZ1"}' \
-w domains.txt______________________________________________________________________
常见选项
# Show response content inline for every HIT
... --show-output
# Also show miss results
... --show-miss
# More threads
... --threads 20
# Save all results to a JSON file
... -o fuzz_results.json
# Raw JSON to stdout
... --rawJSON输出格式 (-o / --raw):
{
"target": "tool",
"name": "port_scan",
"fuzz_template": "{\"host\":\"@@FUZZ1\",\"port\":@@FUZZ2}",
"results": [
{
"label": "@@FUZZ1=127.0.0.1 | @@FUZZ2=80",
"injected_args": {"host": "127.0.0.1", "port": 80},
"status": "HIT",
"response": { ... }
}
]
}资源模糊输出使用 uri_template 而不是 name/fuzz_template/injected_args.
______________________________________________________________________
内置单词表
位于 NgenuMCP/wordlists/:
| 文件 | 使用 |
|---|---|
resources.txt | 完整资源URI——与 --fuzz-uri "@@FUZZ1" |
hosts.txt | 常见的内部主机名和IP |
ports.txt | 通用端口 |
domains.txt | 用于提示/工具模糊测试的域名 |
resources.txt 盖子:
- 标准Linux/Windows文件路径
- 路径遍历:
../,URL编码(%2F,%2e%2e),双重编码(%252F),反斜杠,Unicode过长 - 空字节注入(
%00) - 协议方案:
config://,db://,memory://,base64://,env://,s3://,http:// - 云元数据端点(AWS IMDS、GCP元数据)
______________________________________________________________________
运输支持
| 服务器类型 | 传输 | 支持 |
|---|---|---|
| FastMCP/MCP SDK | 可流式HTTP(SSE) | 是 |
| 自定义/纯HTTP | JSON响应 | 是 |
______________________________________________________________________
项目结构
NgenuMCP/
├── NgenuMCP/
│ ├── __init__.py
│ ├── client.py EnumClient — core MCP JSON-RPC client
│ ├── const.py RPC method definitions
│ ├── display.py All print/output functions
│ ├── handlers/
│ │ ├── enum.py Enumeration handler
│ │ ├── call.py Call tool/prompt/resource handler
│ │ └── fuzz.py Fuzzing logic and runner
│ └── wordlists/
│ └── resources.txt Built-in resource URI wordlist
├── tests/
│ ├── servers/
│ │ ├── stdlib_server.py Minimal stdlib MCP server (no deps)
│ │ └── fastmcp_server.py FastMCP server with tools/prompts/resources
│ ├── test_client.py Unit tests — EnumClient (mocked HTTP)
│ ├── test_fuzz.py Unit tests — fuzz handler and helpers
│ ├── test_display.py Unit tests — all print/output functions
│ └── test_integration.py Integration tests (live servers)
├── NgenuMCP.py Entry point — run this
├── pyproject.toml
└── requirements.txt______________________________________________________________________
运行测试
安装开发依赖项:
pip install -e ".[dev]"运行完整套件(单元+集成,自动启动实时服务器):
pytest只运行单元测试(不需要实时服务器,速度快):
pytest tests/test_client.py tests/test_fuzz.py tests/test_display.py仅运行集成测试:
pytest tests/test_integration.pyWindows注意事项: 如果pytest不在PATH上,请直接使用venv: ``bash venv/Scripts/pytest ``手动启动FastMCP测试服务器:
python tests/servers/fastmcp_server.py
# Listening at http://127.0.0.1:5173/mcp