mcppt 1.1.0__tar.gz → 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mcppt-1.1.0 → mcppt-3.0.0}/.github/workflows/ci.yml +2 -5
- {mcppt-1.1.0 → mcppt-3.0.0}/PKG-INFO +107 -100
- {mcppt-1.1.0 → mcppt-3.0.0}/README.md +106 -99
- mcppt-3.0.0/mcppt/__init__.py +1 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/cli.py +1 -1
- {mcppt-1.1.0 → mcppt-3.0.0}/pyproject.toml +1 -1
- {mcppt-1.1.0 → mcppt-3.0.0}/smoke_test.py +2 -2
- {mcppt-1.1.0 → mcppt-3.0.0}/vuln_server.py +3 -3
- mcppt-1.1.0/mcppt/__init__.py +0 -1
- {mcppt-1.1.0 → mcppt-3.0.0}/.gitignore +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/LICENSE +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/OPERATOR_GUIDE.md +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/app.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/docs/MCPTROTTER_ARTICLE.md +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/docs/MCPTROTTER_MEDIUM.md +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/docs/STUDY_GUIDE.md +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/docs/mcptrotter.jpeg +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/checks.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/core.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/report.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/server.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/shell.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/mcppt/tui.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/requirements.txt +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/test_report.md +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/test_server.log +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/test_server.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/tests/__init__.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/tests/test_checks.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/tests/test_core.py +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/wbs_mcppt_result.md +0 -0
- {mcppt-1.1.0 → mcppt-3.0.0}/wbs_scan_report.md +0 -0
|
@@ -64,17 +64,14 @@ jobs:
|
|
|
64
64
|
needs: build
|
|
65
65
|
runs-on: ubuntu-latest
|
|
66
66
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
67
|
-
environment:
|
|
68
|
-
name: pypi
|
|
69
|
-
url: https://pypi.org/project/mcppt/
|
|
70
|
-
permissions:
|
|
71
|
-
id-token: write # trusted publishing (no API key needed)
|
|
72
67
|
steps:
|
|
73
68
|
- uses: actions/download-artifact@v4
|
|
74
69
|
with:
|
|
75
70
|
name: dist
|
|
76
71
|
path: dist/
|
|
77
72
|
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
73
|
+
with:
|
|
74
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
78
75
|
|
|
79
76
|
# ── Create GitHub Release on version tag ───────────────────────────────────
|
|
80
77
|
release:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcppt
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: MCPTROTTER — MCP Security Framework: 31 automated checks + manual exploration shell
|
|
5
5
|
Project-URL: Homepage, https://github.com/gurudeepmallam-cmd/mcppt
|
|
6
6
|
Project-URL: Repository, https://github.com/gurudeepmallam-cmd/mcppt
|
|
@@ -30,7 +30,7 @@ Provides-Extra: ui
|
|
|
30
30
|
Requires-Dist: streamlit>=1.30; extra == 'ui'
|
|
31
31
|
Description-Content-Type: text/markdown
|
|
32
32
|
|
|
33
|
-
# MCPTROTTER — MCP
|
|
33
|
+
# MCPTROTTER — MCP Security Framework
|
|
34
34
|
|
|
35
35
|
<p align="center">
|
|
36
36
|
<img src="https://raw.githubusercontent.com/gurudeepmallam-cmd/mcppt/main/docs/mcptrotter.jpeg" alt="MCPTROTTER" width="380"/>
|
|
@@ -39,7 +39,7 @@ Description-Content-Type: text/markdown
|
|
|
39
39
|
<p align="center">
|
|
40
40
|
<img src="https://img.shields.io/pypi/v/mcppt?label=PyPI&color=orange"/>
|
|
41
41
|
<img src="https://img.shields.io/badge/python-3.10%2B-blue"/>
|
|
42
|
-
<img src="https://img.shields.io/badge/checks-
|
|
42
|
+
<img src="https://img.shields.io/badge/checks-31-red"/>
|
|
43
43
|
<img src="https://img.shields.io/badge/license-MIT-green"/>
|
|
44
44
|
<img src="https://img.shields.io/badge/part%20of-Bugtrotter-black"/>
|
|
45
45
|
</p>
|
|
@@ -51,19 +51,15 @@ Description-Content-Type: text/markdown
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
## What it
|
|
54
|
+
## What it is
|
|
55
55
|
|
|
56
|
-
MCPTROTTER is a
|
|
56
|
+
MCPTROTTER is a **security framework** for testing MCP (Model Context Protocol) servers. It works two ways:
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
- Prompt injection (direct, stored, poison-all fields)
|
|
60
|
-
- SSRF, command injection, path traversal
|
|
61
|
-
- Session entropy and replay attacks
|
|
62
|
-
- Tenant isolation and IDOR
|
|
63
|
-
- Tool poisoning and rug pulls
|
|
64
|
-
- Transport misconfigurations and secret leaks
|
|
58
|
+
**Manual exploration** — connect to any MCP server and interact with it the way an attacker would. Call tools directly, inspect schemas, fuzz parameters, read resources, send raw JSON-RPC methods. No scan needed. You control every request.
|
|
65
59
|
|
|
66
|
-
|
|
60
|
+
**Automated scanning** — run 31 security checks in under 60 seconds. Auth bypass, stored injection, replay attacks, session entropy, tenant isolation, tool poisoning, command injection, and more.
|
|
61
|
+
|
|
62
|
+
Both modes route through Burp Suite so you see every request in HTTP History and can follow up in Repeater.
|
|
67
63
|
|
|
68
64
|
---
|
|
69
65
|
|
|
@@ -107,29 +103,26 @@ python test_server.py
|
|
|
107
103
|
mcppt
|
|
108
104
|
```
|
|
109
105
|
|
|
110
|
-
You'll see:
|
|
111
106
|
```
|
|
112
107
|
__ __ ___ ___ _____ ____ ___ _____ _____ ___ ___
|
|
113
108
|
| \/ | / __|| _ \|_ _| _ \ / _ \_ _|_ _| __| _ \
|
|
114
109
|
| |\/| || (__| _/ | | | / | (_) || | | | | _|| /
|
|
115
110
|
|_| |_| \___||_| |_| |_|_\ \___/ |_| |_| |___|_|_\
|
|
116
111
|
|
|
117
|
-
MCP Pentest
|
|
112
|
+
MCP Pentest Framework v3.0 -- 31 checks + manual exploration
|
|
118
113
|
|
|
119
114
|
by Gurudeep Mallam
|
|
120
|
-
github : https://github.com/gurudeepmallam-cmd
|
|
121
|
-
linkedin: https://in.linkedin.com/in/mallam-gurudeep-7734941aa
|
|
122
|
-
|
|
123
|
-
type 'help' for commands, 'exit' to quit
|
|
124
115
|
|
|
125
|
-
|
|
116
|
+
Quick start: target <url> → connect → list → scan
|
|
117
|
+
Manual test: call <tool> <args> | raw <method> | fuzz <tool> <param> <type>
|
|
126
118
|
```
|
|
127
119
|
|
|
128
120
|
**Paste these commands one by one:**
|
|
129
121
|
```
|
|
130
122
|
target http://127.0.0.1:8888/mcp
|
|
131
123
|
token valid-token-abc123
|
|
132
|
-
|
|
124
|
+
connect
|
|
125
|
+
list
|
|
133
126
|
scan
|
|
134
127
|
findings
|
|
135
128
|
report demo.md
|
|
@@ -139,10 +132,10 @@ report demo.md
|
|
|
139
132
|
|
|
140
133
|
## Expected output — demo server scan
|
|
141
134
|
|
|
142
|
-
Running `scan` with token set produces this (
|
|
135
|
+
Running `scan` with token set produces this (under 60 seconds):
|
|
143
136
|
|
|
144
137
|
```
|
|
145
|
-
Duration:
|
|
138
|
+
Duration: ~45s Findings: 6 CRITICAL 6 HIGH 13 MEDIUM 3 LOW
|
|
146
139
|
```
|
|
147
140
|
|
|
148
141
|
| Severity | Check | Finding |
|
|
@@ -169,43 +162,80 @@ Duration: 6.7s Findings: 6 CRITICAL 6 HIGH 13 MEDIUM 3 LOW
|
|
|
169
162
|
|
|
170
163
|
---
|
|
171
164
|
|
|
172
|
-
## All commands
|
|
165
|
+
## All commands
|
|
173
166
|
|
|
167
|
+
### Setup
|
|
168
|
+
```
|
|
169
|
+
target <url> Set MCP server URL
|
|
170
|
+
token <bearer> Set primary auth token
|
|
171
|
+
token2 <bearer> Set second user token (IDOR / scope / tenant checks)
|
|
172
|
+
noverify Toggle SSL verification skip (needed for self-signed certs)
|
|
173
|
+
proxy <url|off> Set Burp proxy: proxy http://127.0.0.1:8080
|
|
174
|
+
verbose Toggle raw HTTP request/response logging
|
|
175
|
+
status Show current session configuration
|
|
174
176
|
```
|
|
175
|
-
Setup
|
|
176
|
-
target <url> Set MCP server URL
|
|
177
|
-
token <bearer> Set primary auth token
|
|
178
|
-
token2 <bearer> Set second user token (IDOR / scope / tenant checks)
|
|
179
|
-
noverify Toggle SSL verification skip (needed for self-signed certs)
|
|
180
|
-
proxy <url|off> Set Burp proxy: proxy http://127.0.0.1:8080
|
|
181
|
-
status Show current config before scanning
|
|
182
177
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
178
|
+
### Manual exploration
|
|
179
|
+
```
|
|
180
|
+
connect Test connection + show server name, version, capabilities
|
|
181
|
+
list List all tools the server exposes (names, schemas, params)
|
|
182
|
+
inspect <tool> Show full JSON schema for a specific tool
|
|
183
|
+
call <tool> [json] Call any tool directly with your own arguments
|
|
184
|
+
call get_notes
|
|
185
|
+
call get_user {"id": 1}
|
|
186
|
+
call save_note {"text": "test injection payload"}
|
|
187
|
+
raw <method> [params] Send any raw JSON-RPC method
|
|
188
|
+
raw tools/list
|
|
189
|
+
raw resources/list
|
|
190
|
+
raw sampling/createMessage {...}
|
|
191
|
+
resources [read <uri>] List resources or read a specific URI
|
|
192
|
+
prompts [get <name>] List prompts or get a specific prompt
|
|
193
|
+
headers Show HTTP response headers from the last request
|
|
194
|
+
```
|
|
189
195
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
196
|
+
### Targeted testing
|
|
197
|
+
```
|
|
198
|
+
fuzz <tool> <param> <type|file> Fuzz a specific tool parameter
|
|
199
|
+
|
|
200
|
+
Built-in wordlists:
|
|
201
|
+
sqli SQL injection payloads
|
|
202
|
+
xss XSS and template injection
|
|
203
|
+
traversal Path traversal (../etc/passwd, encoded variants)
|
|
204
|
+
cmd OS command injection (; id, $(id), | whoami)
|
|
205
|
+
ssrf SSRF targets (169.254.169.254, localhost)
|
|
206
|
+
ssti Server-side template injection
|
|
207
|
+
inject Prompt injection payloads for LLM tools
|
|
208
|
+
|
|
209
|
+
Custom: fuzz read_file path /path/to/payloads.txt
|
|
210
|
+
|
|
211
|
+
Examples:
|
|
212
|
+
fuzz get_user id sqli
|
|
213
|
+
fuzz save_note text inject
|
|
214
|
+
fuzz read_file path traversal
|
|
215
|
+
```
|
|
194
216
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
217
|
+
### Automated scan
|
|
218
|
+
```
|
|
219
|
+
scan Run all 31 checks
|
|
220
|
+
scan auth ssrf idor Run specific checks only
|
|
221
|
+
scan stored injection Mix and match any check names
|
|
222
|
+
```
|
|
200
223
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
224
|
+
### Findings
|
|
225
|
+
```
|
|
226
|
+
note <sev> <check> <title> [| detail] Manually log a finding
|
|
227
|
+
note HIGH manual_test Input reflected | seen in 500 response
|
|
228
|
+
findings Colour-coded findings table (scan + manual notes)
|
|
229
|
+
clear Clear findings and tool cache
|
|
230
|
+
report out.md Export Markdown report
|
|
231
|
+
report out.json Export JSON report
|
|
232
|
+
```
|
|
205
233
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
234
|
+
### AI analysis (optional)
|
|
235
|
+
```
|
|
236
|
+
ai claude sk-ant-... Configure Claude for analysis
|
|
237
|
+
ai openai sk-... Configure OpenAI GPT-4o
|
|
238
|
+
analyze Attack narrative + remediation priority from findings
|
|
209
239
|
```
|
|
210
240
|
|
|
211
241
|
---
|
|
@@ -238,7 +268,7 @@ Burp Suite → **Proxy → Proxy Settings**
|
|
|
238
268
|
|
|
239
269
|
Confirm the listener is `127.0.0.1:8080` (it is by default). No changes needed.
|
|
240
270
|
|
|
241
|
-
### Step 2 — Run
|
|
271
|
+
### Step 2 — Run through proxy
|
|
242
272
|
|
|
243
273
|
Inside the shell:
|
|
244
274
|
```
|
|
@@ -258,9 +288,11 @@ mcppt scan --url https://target.com/mcp --token eyJ... --proxy http://127.0.0.1:
|
|
|
258
288
|
|
|
259
289
|
Burp → **Proxy → HTTP History**
|
|
260
290
|
|
|
261
|
-
Every MCP tool call appears as a `POST /mcp` request.
|
|
291
|
+
Every MCP tool call appears as a `POST /mcp` request. You'll see `initialize`, `tools/list`, `tools/call` for each check. Manual commands (`call`, `raw`, `fuzz`) also appear here — every request MCPTROTTER makes goes through Burp.
|
|
292
|
+
|
|
293
|
+
### Step 4 — Send to Repeater for manual testing
|
|
262
294
|
|
|
263
|
-
|
|
295
|
+
Right-click any request → **Send to Repeater** (`Ctrl+R`).
|
|
264
296
|
|
|
265
297
|
```
|
|
266
298
|
POST /mcp HTTP/1.1
|
|
@@ -271,42 +303,17 @@ Content-Type: application/json
|
|
|
271
303
|
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_notes","arguments":{}}}
|
|
272
304
|
```
|
|
273
305
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
In HTTP History, right-click any request → **Send to Repeater** (or `Ctrl+R`).
|
|
277
|
-
|
|
278
|
-
Switch to the **Repeater** tab. You'll see the exact request MCPTROTTER sent.
|
|
279
|
-
|
|
280
|
-
**To keep the connection alive and replay successfully:**
|
|
281
|
-
|
|
282
|
-
1. Check the **Host** field matches your target (e.g. `127.0.0.1` port `8888` for demo server, or your real target host/port)
|
|
283
|
-
2. If targeting HTTP (not HTTPS), make sure the **lock icon** in Repeater shows unlocked — click it to toggle if needed
|
|
284
|
-
3. The MCP session ID in `mcp-session-id` header may expire — if you get a session error, re-initialize:
|
|
285
|
-
- Copy the `initialize` request from HTTP History into Repeater first
|
|
286
|
-
- Send it, copy the `mcp-session-id` from the response header
|
|
287
|
-
- Paste it into the header of your target request
|
|
288
|
-
4. Click **Send** — response appears on the right
|
|
289
|
-
|
|
290
|
-
**Modifying requests in Repeater:**
|
|
291
|
-
|
|
292
|
-
```json
|
|
293
|
-
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
|
|
294
|
-
"name":"get_user",
|
|
295
|
-
"arguments":{"id": 2}
|
|
296
|
-
}}
|
|
297
|
-
```
|
|
306
|
+
Change `"id": 2` to `"id": 1` to test IDOR. Swap the token to another user's. Modify `"name"` to call a different tool.
|
|
298
307
|
|
|
299
|
-
|
|
308
|
+
If you get a session error, copy the `initialize` request from HTTP History into Repeater first, send it, and copy the `mcp-session-id` header value into your target request.
|
|
300
309
|
|
|
301
310
|
### Step 5 — Fuzz with Intruder
|
|
302
311
|
|
|
303
|
-
Right-click
|
|
304
|
-
|
|
305
|
-
Highlight the value you want to fuzz (e.g. a tool parameter), click **Add §**. Load a wordlist (Burp's built-in fuzzing strings, or a custom injection list). Run the attack and sort by response length or status code to spot anomalies.
|
|
312
|
+
Right-click any Repeater request → **Send to Intruder**. Highlight the parameter value, click **Add §**, load a wordlist, run the attack.
|
|
306
313
|
|
|
307
314
|
---
|
|
308
315
|
|
|
309
|
-
## All
|
|
316
|
+
## All 31 checks
|
|
310
317
|
|
|
311
318
|
| # | Check | Severity | What it tests |
|
|
312
319
|
|---|---|---|---|
|
|
@@ -338,6 +345,9 @@ Highlight the value you want to fuzz (e.g. a tool parameter), click **Add §**.
|
|
|
338
345
|
| 26 | `tool_shadowing` | CRITICAL | Duplicate tool names, homoglyphs, name/desc mismatch |
|
|
339
346
|
| 27 | `sampling` | CRITICAL | `sampling/createMessage` accessible without auth |
|
|
340
347
|
| 28 | `schema_leak` | LOW | Sensitive field names / enum values in tool schemas |
|
|
348
|
+
| 29 | `http_method_confusion` | MEDIUM | GET/DELETE/PUT/PATCH accepted on MCP endpoint |
|
|
349
|
+
| 30 | `protocol_downgrade` | MEDIUM | Old protocol versions accepted, server version leaked |
|
|
350
|
+
| 31 | `batch_injection` | MEDIUM | JSON-RPC batch requests, unusual method name injection |
|
|
341
351
|
|
|
342
352
|
---
|
|
343
353
|
|
|
@@ -350,9 +360,13 @@ Highlight the value you want to fuzz (e.g. a tool parameter), click **Add §**.
|
|
|
350
360
|
| Check all response fields for injection | 30+ min | `scan poison_all` — 5s |
|
|
351
361
|
| Verify session ID entropy | 10 min | `scan session` — 2s |
|
|
352
362
|
| Check replay on every tool | 20 min | `scan replay` — 5s |
|
|
353
|
-
| Full
|
|
363
|
+
| Full 31-check assessment | 3–6 hours | `scan` — under 60s |
|
|
364
|
+
| Inspect tool schema before testing | 5 min reading docs | `inspect <tool>` — instant |
|
|
365
|
+
| Call a tool with custom payload | Set up in Burp Repeater | `call <tool> {"param": "payload"}` |
|
|
366
|
+
| Fuzz a parameter with 50 payloads | Intruder setup + run | `fuzz <tool> <param> sqli` — 30s |
|
|
367
|
+
| Test any JSON-RPC method directly | Build request in Repeater | `raw <method> <params>` |
|
|
354
368
|
|
|
355
|
-
MCPTROTTER gives you the baseline in
|
|
369
|
+
MCPTROTTER gives you the baseline in under 60 seconds and puts every request in Burp HTTP History. You spend your time on what matters: manually verifying findings in Repeater and chaining them into a demonstrated attack path.
|
|
356
370
|
|
|
357
371
|
---
|
|
358
372
|
|
|
@@ -364,8 +378,8 @@ MCPTROTTER is the public automated scanner extracted from **Bugtrotter** — a f
|
|
|
364
378
|
|
|
365
379
|
| Capability | MCPTROTTER | Bugtrotter |
|
|
366
380
|
|---|---|---|
|
|
367
|
-
| Automated MCP scan (
|
|
368
|
-
| Manual
|
|
381
|
+
| Automated MCP scan (31 checks) | ✓ | ✓ |
|
|
382
|
+
| Manual tool exploration framework | ✓ | ✓ |
|
|
369
383
|
| Chained exploit paths across tools | — | ✓ Full attack chain |
|
|
370
384
|
| SAST review of MCP server code | — | ✓ |
|
|
371
385
|
| Burp Suite MCP — business logic abuse | — | ✓ AI-driven |
|
|
@@ -374,27 +388,25 @@ MCPTROTTER is the public automated scanner extracted from **Bugtrotter** — a f
|
|
|
374
388
|
| Web / API / network pentesting | — | ✓ Full engagement |
|
|
375
389
|
| Final pentest report | Markdown export | Engagement-grade report |
|
|
376
390
|
|
|
377
|
-
**MCPTROTTER
|
|
391
|
+
**MCPTROTTER inside Bugtrotter:**
|
|
378
392
|
|
|
379
393
|
In Bugtrotter, MCPTROTTER runs as a registered MCP server. Claude Code or Claude Desktop calls it directly:
|
|
380
394
|
|
|
381
395
|
```
|
|
382
396
|
"Scan https://target.com/mcp for security issues and prioritise findings"
|
|
383
397
|
→ Claude calls scan_target tool
|
|
384
|
-
→ MCPTROTTER runs all
|
|
398
|
+
→ MCPTROTTER runs all 31 checks
|
|
385
399
|
→ Findings returned as structured JSON to Claude
|
|
386
400
|
→ Claude reasons over them, chains the critical ones, drafts the report section
|
|
387
401
|
```
|
|
388
402
|
|
|
389
403
|
No copy-paste. No context switching. The scan output feeds straight into the AI-driven engagement workflow — SSRF finding becomes an SSRF exploit attempt, auth bypass becomes a credential theft chain, stored injection becomes a demonstrated prompt hijack.
|
|
390
404
|
|
|
391
|
-
That's the difference: MCPTROTTER finds the candidates in 30 seconds. Bugtrotter turns the candidates into proven, chained, client-ready findings.
|
|
392
|
-
|
|
393
405
|
---
|
|
394
406
|
|
|
395
407
|
## Use MCPTROTTER as an MCP server itself
|
|
396
408
|
|
|
397
|
-
MCPTROTTER can
|
|
409
|
+
MCPTROTTER can expose its scan capability as tools that any MCP client (Claude Desktop, MCP Inspector, another agent) can call.
|
|
398
410
|
|
|
399
411
|
```bash
|
|
400
412
|
mcppt serve-mcp --port 8899
|
|
@@ -416,12 +428,7 @@ Tools exposed:
|
|
|
416
428
|
- `scan_target` — full scan, returns findings JSON
|
|
417
429
|
- `list_tools` — enumerate tools on any MCP server
|
|
418
430
|
- `call_tool` — call any tool on any MCP server
|
|
419
|
-
- `get_checks` — list all
|
|
420
|
-
|
|
421
|
-
Inspect with MCP Inspector:
|
|
422
|
-
```bash
|
|
423
|
-
npx @modelcontextprotocol/inspector http://127.0.0.1:8899/mcp
|
|
424
|
-
```
|
|
431
|
+
- `get_checks` — list all 31 checks with descriptions
|
|
425
432
|
|
|
426
433
|
---
|
|
427
434
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# MCPTROTTER — MCP
|
|
1
|
+
# MCPTROTTER — MCP Security Framework
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<img src="https://raw.githubusercontent.com/gurudeepmallam-cmd/mcppt/main/docs/mcptrotter.jpeg" alt="MCPTROTTER" width="380"/>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<img src="https://img.shields.io/pypi/v/mcppt?label=PyPI&color=orange"/>
|
|
9
9
|
<img src="https://img.shields.io/badge/python-3.10%2B-blue"/>
|
|
10
|
-
<img src="https://img.shields.io/badge/checks-
|
|
10
|
+
<img src="https://img.shields.io/badge/checks-31-red"/>
|
|
11
11
|
<img src="https://img.shields.io/badge/license-MIT-green"/>
|
|
12
12
|
<img src="https://img.shields.io/badge/part%20of-Bugtrotter-black"/>
|
|
13
13
|
</p>
|
|
@@ -19,19 +19,15 @@
|
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
## What it
|
|
22
|
+
## What it is
|
|
23
23
|
|
|
24
|
-
MCPTROTTER is a
|
|
24
|
+
MCPTROTTER is a **security framework** for testing MCP (Model Context Protocol) servers. It works two ways:
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
- Prompt injection (direct, stored, poison-all fields)
|
|
28
|
-
- SSRF, command injection, path traversal
|
|
29
|
-
- Session entropy and replay attacks
|
|
30
|
-
- Tenant isolation and IDOR
|
|
31
|
-
- Tool poisoning and rug pulls
|
|
32
|
-
- Transport misconfigurations and secret leaks
|
|
26
|
+
**Manual exploration** — connect to any MCP server and interact with it the way an attacker would. Call tools directly, inspect schemas, fuzz parameters, read resources, send raw JSON-RPC methods. No scan needed. You control every request.
|
|
33
27
|
|
|
34
|
-
|
|
28
|
+
**Automated scanning** — run 31 security checks in under 60 seconds. Auth bypass, stored injection, replay attacks, session entropy, tenant isolation, tool poisoning, command injection, and more.
|
|
29
|
+
|
|
30
|
+
Both modes route through Burp Suite so you see every request in HTTP History and can follow up in Repeater.
|
|
35
31
|
|
|
36
32
|
---
|
|
37
33
|
|
|
@@ -75,29 +71,26 @@ python test_server.py
|
|
|
75
71
|
mcppt
|
|
76
72
|
```
|
|
77
73
|
|
|
78
|
-
You'll see:
|
|
79
74
|
```
|
|
80
75
|
__ __ ___ ___ _____ ____ ___ _____ _____ ___ ___
|
|
81
76
|
| \/ | / __|| _ \|_ _| _ \ / _ \_ _|_ _| __| _ \
|
|
82
77
|
| |\/| || (__| _/ | | | / | (_) || | | | | _|| /
|
|
83
78
|
|_| |_| \___||_| |_| |_|_\ \___/ |_| |_| |___|_|_\
|
|
84
79
|
|
|
85
|
-
MCP Pentest
|
|
80
|
+
MCP Pentest Framework v3.0 -- 31 checks + manual exploration
|
|
86
81
|
|
|
87
82
|
by Gurudeep Mallam
|
|
88
|
-
github : https://github.com/gurudeepmallam-cmd
|
|
89
|
-
linkedin: https://in.linkedin.com/in/mallam-gurudeep-7734941aa
|
|
90
|
-
|
|
91
|
-
type 'help' for commands, 'exit' to quit
|
|
92
83
|
|
|
93
|
-
|
|
84
|
+
Quick start: target <url> → connect → list → scan
|
|
85
|
+
Manual test: call <tool> <args> | raw <method> | fuzz <tool> <param> <type>
|
|
94
86
|
```
|
|
95
87
|
|
|
96
88
|
**Paste these commands one by one:**
|
|
97
89
|
```
|
|
98
90
|
target http://127.0.0.1:8888/mcp
|
|
99
91
|
token valid-token-abc123
|
|
100
|
-
|
|
92
|
+
connect
|
|
93
|
+
list
|
|
101
94
|
scan
|
|
102
95
|
findings
|
|
103
96
|
report demo.md
|
|
@@ -107,10 +100,10 @@ report demo.md
|
|
|
107
100
|
|
|
108
101
|
## Expected output — demo server scan
|
|
109
102
|
|
|
110
|
-
Running `scan` with token set produces this (
|
|
103
|
+
Running `scan` with token set produces this (under 60 seconds):
|
|
111
104
|
|
|
112
105
|
```
|
|
113
|
-
Duration:
|
|
106
|
+
Duration: ~45s Findings: 6 CRITICAL 6 HIGH 13 MEDIUM 3 LOW
|
|
114
107
|
```
|
|
115
108
|
|
|
116
109
|
| Severity | Check | Finding |
|
|
@@ -137,43 +130,80 @@ Duration: 6.7s Findings: 6 CRITICAL 6 HIGH 13 MEDIUM 3 LOW
|
|
|
137
130
|
|
|
138
131
|
---
|
|
139
132
|
|
|
140
|
-
## All commands
|
|
133
|
+
## All commands
|
|
141
134
|
|
|
135
|
+
### Setup
|
|
136
|
+
```
|
|
137
|
+
target <url> Set MCP server URL
|
|
138
|
+
token <bearer> Set primary auth token
|
|
139
|
+
token2 <bearer> Set second user token (IDOR / scope / tenant checks)
|
|
140
|
+
noverify Toggle SSL verification skip (needed for self-signed certs)
|
|
141
|
+
proxy <url|off> Set Burp proxy: proxy http://127.0.0.1:8080
|
|
142
|
+
verbose Toggle raw HTTP request/response logging
|
|
143
|
+
status Show current session configuration
|
|
142
144
|
```
|
|
143
|
-
Setup
|
|
144
|
-
target <url> Set MCP server URL
|
|
145
|
-
token <bearer> Set primary auth token
|
|
146
|
-
token2 <bearer> Set second user token (IDOR / scope / tenant checks)
|
|
147
|
-
noverify Toggle SSL verification skip (needed for self-signed certs)
|
|
148
|
-
proxy <url|off> Set Burp proxy: proxy http://127.0.0.1:8080
|
|
149
|
-
status Show current config before scanning
|
|
150
145
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
146
|
+
### Manual exploration
|
|
147
|
+
```
|
|
148
|
+
connect Test connection + show server name, version, capabilities
|
|
149
|
+
list List all tools the server exposes (names, schemas, params)
|
|
150
|
+
inspect <tool> Show full JSON schema for a specific tool
|
|
151
|
+
call <tool> [json] Call any tool directly with your own arguments
|
|
152
|
+
call get_notes
|
|
153
|
+
call get_user {"id": 1}
|
|
154
|
+
call save_note {"text": "test injection payload"}
|
|
155
|
+
raw <method> [params] Send any raw JSON-RPC method
|
|
156
|
+
raw tools/list
|
|
157
|
+
raw resources/list
|
|
158
|
+
raw sampling/createMessage {...}
|
|
159
|
+
resources [read <uri>] List resources or read a specific URI
|
|
160
|
+
prompts [get <name>] List prompts or get a specific prompt
|
|
161
|
+
headers Show HTTP response headers from the last request
|
|
162
|
+
```
|
|
157
163
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
### Targeted testing
|
|
165
|
+
```
|
|
166
|
+
fuzz <tool> <param> <type|file> Fuzz a specific tool parameter
|
|
167
|
+
|
|
168
|
+
Built-in wordlists:
|
|
169
|
+
sqli SQL injection payloads
|
|
170
|
+
xss XSS and template injection
|
|
171
|
+
traversal Path traversal (../etc/passwd, encoded variants)
|
|
172
|
+
cmd OS command injection (; id, $(id), | whoami)
|
|
173
|
+
ssrf SSRF targets (169.254.169.254, localhost)
|
|
174
|
+
ssti Server-side template injection
|
|
175
|
+
inject Prompt injection payloads for LLM tools
|
|
176
|
+
|
|
177
|
+
Custom: fuzz read_file path /path/to/payloads.txt
|
|
178
|
+
|
|
179
|
+
Examples:
|
|
180
|
+
fuzz get_user id sqli
|
|
181
|
+
fuzz save_note text inject
|
|
182
|
+
fuzz read_file path traversal
|
|
183
|
+
```
|
|
162
184
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
185
|
+
### Automated scan
|
|
186
|
+
```
|
|
187
|
+
scan Run all 31 checks
|
|
188
|
+
scan auth ssrf idor Run specific checks only
|
|
189
|
+
scan stored injection Mix and match any check names
|
|
190
|
+
```
|
|
168
191
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
192
|
+
### Findings
|
|
193
|
+
```
|
|
194
|
+
note <sev> <check> <title> [| detail] Manually log a finding
|
|
195
|
+
note HIGH manual_test Input reflected | seen in 500 response
|
|
196
|
+
findings Colour-coded findings table (scan + manual notes)
|
|
197
|
+
clear Clear findings and tool cache
|
|
198
|
+
report out.md Export Markdown report
|
|
199
|
+
report out.json Export JSON report
|
|
200
|
+
```
|
|
173
201
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
202
|
+
### AI analysis (optional)
|
|
203
|
+
```
|
|
204
|
+
ai claude sk-ant-... Configure Claude for analysis
|
|
205
|
+
ai openai sk-... Configure OpenAI GPT-4o
|
|
206
|
+
analyze Attack narrative + remediation priority from findings
|
|
177
207
|
```
|
|
178
208
|
|
|
179
209
|
---
|
|
@@ -206,7 +236,7 @@ Burp Suite → **Proxy → Proxy Settings**
|
|
|
206
236
|
|
|
207
237
|
Confirm the listener is `127.0.0.1:8080` (it is by default). No changes needed.
|
|
208
238
|
|
|
209
|
-
### Step 2 — Run
|
|
239
|
+
### Step 2 — Run through proxy
|
|
210
240
|
|
|
211
241
|
Inside the shell:
|
|
212
242
|
```
|
|
@@ -226,9 +256,11 @@ mcppt scan --url https://target.com/mcp --token eyJ... --proxy http://127.0.0.1:
|
|
|
226
256
|
|
|
227
257
|
Burp → **Proxy → HTTP History**
|
|
228
258
|
|
|
229
|
-
Every MCP tool call appears as a `POST /mcp` request.
|
|
259
|
+
Every MCP tool call appears as a `POST /mcp` request. You'll see `initialize`, `tools/list`, `tools/call` for each check. Manual commands (`call`, `raw`, `fuzz`) also appear here — every request MCPTROTTER makes goes through Burp.
|
|
260
|
+
|
|
261
|
+
### Step 4 — Send to Repeater for manual testing
|
|
230
262
|
|
|
231
|
-
|
|
263
|
+
Right-click any request → **Send to Repeater** (`Ctrl+R`).
|
|
232
264
|
|
|
233
265
|
```
|
|
234
266
|
POST /mcp HTTP/1.1
|
|
@@ -239,42 +271,17 @@ Content-Type: application/json
|
|
|
239
271
|
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_notes","arguments":{}}}
|
|
240
272
|
```
|
|
241
273
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
In HTTP History, right-click any request → **Send to Repeater** (or `Ctrl+R`).
|
|
245
|
-
|
|
246
|
-
Switch to the **Repeater** tab. You'll see the exact request MCPTROTTER sent.
|
|
247
|
-
|
|
248
|
-
**To keep the connection alive and replay successfully:**
|
|
249
|
-
|
|
250
|
-
1. Check the **Host** field matches your target (e.g. `127.0.0.1` port `8888` for demo server, or your real target host/port)
|
|
251
|
-
2. If targeting HTTP (not HTTPS), make sure the **lock icon** in Repeater shows unlocked — click it to toggle if needed
|
|
252
|
-
3. The MCP session ID in `mcp-session-id` header may expire — if you get a session error, re-initialize:
|
|
253
|
-
- Copy the `initialize` request from HTTP History into Repeater first
|
|
254
|
-
- Send it, copy the `mcp-session-id` from the response header
|
|
255
|
-
- Paste it into the header of your target request
|
|
256
|
-
4. Click **Send** — response appears on the right
|
|
257
|
-
|
|
258
|
-
**Modifying requests in Repeater:**
|
|
259
|
-
|
|
260
|
-
```json
|
|
261
|
-
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
|
|
262
|
-
"name":"get_user",
|
|
263
|
-
"arguments":{"id": 2}
|
|
264
|
-
}}
|
|
265
|
-
```
|
|
274
|
+
Change `"id": 2` to `"id": 1` to test IDOR. Swap the token to another user's. Modify `"name"` to call a different tool.
|
|
266
275
|
|
|
267
|
-
|
|
276
|
+
If you get a session error, copy the `initialize` request from HTTP History into Repeater first, send it, and copy the `mcp-session-id` header value into your target request.
|
|
268
277
|
|
|
269
278
|
### Step 5 — Fuzz with Intruder
|
|
270
279
|
|
|
271
|
-
Right-click
|
|
272
|
-
|
|
273
|
-
Highlight the value you want to fuzz (e.g. a tool parameter), click **Add §**. Load a wordlist (Burp's built-in fuzzing strings, or a custom injection list). Run the attack and sort by response length or status code to spot anomalies.
|
|
280
|
+
Right-click any Repeater request → **Send to Intruder**. Highlight the parameter value, click **Add §**, load a wordlist, run the attack.
|
|
274
281
|
|
|
275
282
|
---
|
|
276
283
|
|
|
277
|
-
## All
|
|
284
|
+
## All 31 checks
|
|
278
285
|
|
|
279
286
|
| # | Check | Severity | What it tests |
|
|
280
287
|
|---|---|---|---|
|
|
@@ -306,6 +313,9 @@ Highlight the value you want to fuzz (e.g. a tool parameter), click **Add §**.
|
|
|
306
313
|
| 26 | `tool_shadowing` | CRITICAL | Duplicate tool names, homoglyphs, name/desc mismatch |
|
|
307
314
|
| 27 | `sampling` | CRITICAL | `sampling/createMessage` accessible without auth |
|
|
308
315
|
| 28 | `schema_leak` | LOW | Sensitive field names / enum values in tool schemas |
|
|
316
|
+
| 29 | `http_method_confusion` | MEDIUM | GET/DELETE/PUT/PATCH accepted on MCP endpoint |
|
|
317
|
+
| 30 | `protocol_downgrade` | MEDIUM | Old protocol versions accepted, server version leaked |
|
|
318
|
+
| 31 | `batch_injection` | MEDIUM | JSON-RPC batch requests, unusual method name injection |
|
|
309
319
|
|
|
310
320
|
---
|
|
311
321
|
|
|
@@ -318,9 +328,13 @@ Highlight the value you want to fuzz (e.g. a tool parameter), click **Add §**.
|
|
|
318
328
|
| Check all response fields for injection | 30+ min | `scan poison_all` — 5s |
|
|
319
329
|
| Verify session ID entropy | 10 min | `scan session` — 2s |
|
|
320
330
|
| Check replay on every tool | 20 min | `scan replay` — 5s |
|
|
321
|
-
| Full
|
|
331
|
+
| Full 31-check assessment | 3–6 hours | `scan` — under 60s |
|
|
332
|
+
| Inspect tool schema before testing | 5 min reading docs | `inspect <tool>` — instant |
|
|
333
|
+
| Call a tool with custom payload | Set up in Burp Repeater | `call <tool> {"param": "payload"}` |
|
|
334
|
+
| Fuzz a parameter with 50 payloads | Intruder setup + run | `fuzz <tool> <param> sqli` — 30s |
|
|
335
|
+
| Test any JSON-RPC method directly | Build request in Repeater | `raw <method> <params>` |
|
|
322
336
|
|
|
323
|
-
MCPTROTTER gives you the baseline in
|
|
337
|
+
MCPTROTTER gives you the baseline in under 60 seconds and puts every request in Burp HTTP History. You spend your time on what matters: manually verifying findings in Repeater and chaining them into a demonstrated attack path.
|
|
324
338
|
|
|
325
339
|
---
|
|
326
340
|
|
|
@@ -332,8 +346,8 @@ MCPTROTTER is the public automated scanner extracted from **Bugtrotter** — a f
|
|
|
332
346
|
|
|
333
347
|
| Capability | MCPTROTTER | Bugtrotter |
|
|
334
348
|
|---|---|---|
|
|
335
|
-
| Automated MCP scan (
|
|
336
|
-
| Manual
|
|
349
|
+
| Automated MCP scan (31 checks) | ✓ | ✓ |
|
|
350
|
+
| Manual tool exploration framework | ✓ | ✓ |
|
|
337
351
|
| Chained exploit paths across tools | — | ✓ Full attack chain |
|
|
338
352
|
| SAST review of MCP server code | — | ✓ |
|
|
339
353
|
| Burp Suite MCP — business logic abuse | — | ✓ AI-driven |
|
|
@@ -342,27 +356,25 @@ MCPTROTTER is the public automated scanner extracted from **Bugtrotter** — a f
|
|
|
342
356
|
| Web / API / network pentesting | — | ✓ Full engagement |
|
|
343
357
|
| Final pentest report | Markdown export | Engagement-grade report |
|
|
344
358
|
|
|
345
|
-
**MCPTROTTER
|
|
359
|
+
**MCPTROTTER inside Bugtrotter:**
|
|
346
360
|
|
|
347
361
|
In Bugtrotter, MCPTROTTER runs as a registered MCP server. Claude Code or Claude Desktop calls it directly:
|
|
348
362
|
|
|
349
363
|
```
|
|
350
364
|
"Scan https://target.com/mcp for security issues and prioritise findings"
|
|
351
365
|
→ Claude calls scan_target tool
|
|
352
|
-
→ MCPTROTTER runs all
|
|
366
|
+
→ MCPTROTTER runs all 31 checks
|
|
353
367
|
→ Findings returned as structured JSON to Claude
|
|
354
368
|
→ Claude reasons over them, chains the critical ones, drafts the report section
|
|
355
369
|
```
|
|
356
370
|
|
|
357
371
|
No copy-paste. No context switching. The scan output feeds straight into the AI-driven engagement workflow — SSRF finding becomes an SSRF exploit attempt, auth bypass becomes a credential theft chain, stored injection becomes a demonstrated prompt hijack.
|
|
358
372
|
|
|
359
|
-
That's the difference: MCPTROTTER finds the candidates in 30 seconds. Bugtrotter turns the candidates into proven, chained, client-ready findings.
|
|
360
|
-
|
|
361
373
|
---
|
|
362
374
|
|
|
363
375
|
## Use MCPTROTTER as an MCP server itself
|
|
364
376
|
|
|
365
|
-
MCPTROTTER can
|
|
377
|
+
MCPTROTTER can expose its scan capability as tools that any MCP client (Claude Desktop, MCP Inspector, another agent) can call.
|
|
366
378
|
|
|
367
379
|
```bash
|
|
368
380
|
mcppt serve-mcp --port 8899
|
|
@@ -384,12 +396,7 @@ Tools exposed:
|
|
|
384
396
|
- `scan_target` — full scan, returns findings JSON
|
|
385
397
|
- `list_tools` — enumerate tools on any MCP server
|
|
386
398
|
- `call_tool` — call any tool on any MCP server
|
|
387
|
-
- `get_checks` — list all
|
|
388
|
-
|
|
389
|
-
Inspect with MCP Inspector:
|
|
390
|
-
```bash
|
|
391
|
-
npx @modelcontextprotocol/inspector http://127.0.0.1:8899/mcp
|
|
392
|
-
```
|
|
399
|
+
- `get_checks` — list all 31 checks with descriptions
|
|
393
400
|
|
|
394
401
|
---
|
|
395
402
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.0.0"
|
|
@@ -193,7 +193,7 @@ def main() -> None:
|
|
|
193
193
|
_ensure_utf8()
|
|
194
194
|
parser = argparse.ArgumentParser(
|
|
195
195
|
prog="mcppt",
|
|
196
|
-
description="MCPTROTTER
|
|
196
|
+
description="MCPTROTTER v3.0 — MCP Pentest Tool | 31 automated security checks",
|
|
197
197
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
198
198
|
epilog=EPILOG,
|
|
199
199
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
MCPTROTTER Smoke Test —
|
|
3
|
+
MCPTROTTER Smoke Test — v3.0
|
|
4
4
|
=============================
|
|
5
5
|
Starts the vuln_server, runs MCPTROTTER against it, asserts expected findings.
|
|
6
6
|
|
|
@@ -128,7 +128,7 @@ EXPECTED = [
|
|
|
128
128
|
def main():
|
|
129
129
|
print()
|
|
130
130
|
print(f"{BOLD}{'=' * 58}{RESET}")
|
|
131
|
-
print(f"{BOLD} MCPTROTTER Smoke Test
|
|
131
|
+
print(f"{BOLD} MCPTROTTER Smoke Test v3.0{RESET}")
|
|
132
132
|
print(f"{BOLD}{'=' * 58}{RESET}")
|
|
133
133
|
print()
|
|
134
134
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
MCPTROTTER Vulnerable Demo Server —
|
|
3
|
+
MCPTROTTER Vulnerable Demo Server — v3.0
|
|
4
4
|
=========================================
|
|
5
|
-
A deliberately insecure MCP server that fires ALL
|
|
5
|
+
A deliberately insecure MCP server that fires ALL 31 MCPTROTTER checks.
|
|
6
6
|
Safe to run locally: simulated dangerous behaviors (no real command execution,
|
|
7
7
|
no real file reads, no real URL fetching).
|
|
8
8
|
|
|
@@ -562,7 +562,7 @@ def mcp():
|
|
|
562
562
|
if __name__ == "__main__":
|
|
563
563
|
print()
|
|
564
564
|
print("=" * 62)
|
|
565
|
-
print(" MCPTROTTER Vulnerable Demo Server
|
|
565
|
+
print(" MCPTROTTER Vulnerable Demo Server v3.0")
|
|
566
566
|
print(" URL : http://127.0.0.1:8888/mcp")
|
|
567
567
|
print(" Token: valid-token-abc123")
|
|
568
568
|
print(" Token2: other-token-xyz789")
|
mcppt-1.1.0/mcppt/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.1.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|