Security posture scanner and passive gateway for Model Context Protocol (MCP) servers — see what your AI agents can actually do.
Project description
pramiti-mcp-gateway
See what your AI agents can actually do.
An open-source security posture scanner for Model Context Protocol (MCP) servers. Point it at a server's tools and it tells you, in two minutes, which ones let an agent take dangerous actions — writes, irreversible operations, sensitive-data exfiltration, and arbitrary-execution power — with zero infrastructure and no changes to anything you run.
MCP gives AI agents hands. This tells you what those hands can reach.
$ pramiti-mcp-gateway scan tools.json
MCP Security Posture
============================================================
9 tools scanned | read 3 write 6 unknown 0
severity: critical 4 high 1 medium 1 low 1 info 2
------------------------------------------------------------
[CRIT] internal_db.export_patient_records
Changes state; effects are hard to reverse; touches sensitive/regulated data; grants broad or unconstrained capability.
signals: irreversible:export, sensitive:patient, sensitive:medical, overbroad:no-input-schema
[CRIT] internal_db.run_sql
Changes state; effects are hard to reverse; grants broad or unconstrained capability.
signals: irreversible:execute, irreversible:run, overbroad:sql, overbroad:arbitrary
[CRIT] payments.transfer_funds
Changes state; effects are hard to reverse; touches sensitive/regulated data.
[HIGH] github.delete_repository
[MED ] github.create_pull_request
[LOW ] payments.list_transactions
[INFO] github.get_file_contents
------------------------------------------------------------
Top risk: CRITICAL. These tools let an agent take high-impact actions.
Gate them before giving an agent write access.
Why this exists
An MCP server can expose a delete_repository, a transfer_funds, or a
run_sql tool right next to a harmless search. When you connect an AI agent
to it, the agent can call any of them — and if the agent is prompt-injected, it
will be talked into calling the wrong one. Prompt-level defenses don't help
here: the danger isn't what the agent says, it's what it can do.
Before you can gate agent actions, you have to see them. This scanner is the "see them" step, and it's free.
Install
# zero dependencies — run it with no install:
uvx pramiti-mcp-gateway scan tools.json
# or
pipx run pramiti-mcp-gateway scan tools.json
# or install it:
pip install pramiti-mcp-gateway
# to scan your live servers by connecting to them, add the 'connect' extra:
pip install 'pramiti-mcp-gateway[connect]'
Usage
scan takes a JSON manifest of MCP tools — the shape an MCP tools/list
response returns — and classifies each tool's action risk:
pramiti-mcp-gateway scan tools.json # human-readable report
pramiti-mcp-gateway scan tools.json --json # machine-readable JSON
cat tools.json | pramiti-mcp-gateway scan - # read from stdin
Accepted manifest shapes:
// a raw tools/list result
{ "tools": [ { "name": "delete_repo", "description": "...", "inputSchema": {} } ] }
// a bare list of tools
[ { "name": "get_file", "description": "..." } ]
// multiple servers at once
{ "servers": { "github": { "tools": [ ... ] }, "payments": { "tools": [ ... ] } } }
Scan your live servers (--config)
Point it at your MCP client config — the mcpServers shape used by Claude
Desktop, Cursor, and others — and it connects to each server, enumerates its
real tools, and scans them. Both local (stdio) and remote (SSE / streamable
HTTP) servers are supported.
pramiti-mcp-gateway scan --config ~/.config/claude/claude_desktop_config.json
pramiti-mcp-gateway scan --config mcp.json --timeout 15 --json
// mcp.json
{
"mcpServers": {
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] },
"payments": { "url": "https://mcp.internal.example.com/sse" }
}
}
tools/list is a read-only protocol call and never executes a tool. Scanning a
stdio server does start its process (the only way to speak the protocol to
it), so --config connects only to servers you configured. A server that fails
(bad command, unreachable URL, timeout) produces a warning and is skipped — one
bad server never aborts the scan. Live connect needs the connect extra; the
offline manifest scan stays dependency-free.
Watch live traffic (passive gateway)
Put the gateway between an agent and its MCP server. It forwards every call unchanged — it never blocks, so there is zero production risk — and appends a signed, hash-chained record of each tool call. Install it by pointing your agent's config at the gateway instead of the server:
{
"mcpServers": {
"github": {
"command": "pramiti-mcp-gateway",
"args": ["proxy", "--server-name", "github", "--records", "github.jsonl",
"--", "npx", "-y", "@modelcontextprotocol/server-github"]
}
}
}
pramiti-mcp-gateway keygen # one-time: Ed25519 signing key
pramiti-mcp-gateway posture github.jsonl # what did my agents actually do?
pramiti-mcp-gateway verify github.jsonl # is the evidence intact & signed?
posture reports risk over time — calls by severity, by server, and the
most-called risky tools. verify recomputes the hash chain and checks every
Ed25519 signature offline, so anyone can confirm the log wasn't altered. Raw
tool arguments are never stored — only their sha256 — so the evidence log
never becomes a place secrets leak to.
See it in action: python examples/demo.py runs a compromised agent trying
to exfiltrate PHI through a real MCP server, and shows the gateway catching and
proving it. (Needs pip install 'pramiti-mcp-gateway[gateway]'.)
Use it as a CI gate
Fail a build if any tool is at or above a severity — so a new high-risk tool can't land in your agent's reach without review:
pramiti-mcp-gateway scan tools.json --fail-on high
# exit code 2 if any tool is 'high' or 'critical'
How it classifies (and its limits)
The scanner reads only what a tool declares about itself — its name, description, and input schema. From that it scores four axes and rolls them into one severity:
| Axis | What it means |
|---|---|
| Access | read / write / unknown |
| Reversibility | can the effect be undone? (delete, transfer, send, export → no) |
| Sensitivity | does it touch regulated / sensitive data? (PHI, PII, cards, credentials) |
| Breadth | does it grant arbitrary power? (SQL, shell, exec, or a write with no schema) |
It is a heuristic and it is deliberately fail-loud: an unclassifiable write is flagged for review, never waved through. It cannot know a server's real runtime behavior, so treat a clean report as "no declared red flags," not a proof of safety. It is deterministic — the same tool always scores the same way — so results are safe to diff in CI.
Roadmap
- Live connect (
scan --config) — connect to your configured MCP servers, enumerate their real tools, and scan them. ✅ shipped - Passive gateway (
proxy+posture) — sit between an agent and its MCP servers, log and sign every tool call, and report posture over time. No blocking, no production risk. ✅ shipped - Verify (
verify) — check the signed record chain offline. ✅ shipped
Seeing vs. stopping — Praxom
This gateway lets you see what your agents can do and prove what they did. It is deliberately passive: it never blocks a call, so there is zero production risk in running it. That is the free half of the problem.
The other half is stopping the wrong action before it executes — and doing it deterministically, even when the model is prompt-injected. That is Praxom, the commercial control plane this scanner is carved from. Same doctrine (assume breach; enforce outside the model), one step further.
| This gateway (free, OSS) | Praxom (commercial) | |
|---|---|---|
| Scan tool risk (offline + live) | ✅ | ✅ |
| Passive log + Ed25519-sign every call | ✅ | ✅ |
| Verify the record chain offline | ✅ | ✅ |
| Block / rewrite / escalate an action before it runs | — | ✅ |
| Policy engine (business rules, per tool, per agent) | — | ✅ |
| The injection backstop — decisions key off the tool's real risk, not the agent's claims | — | ✅ |
| Hash-chained attestation with WORM anchoring | — | ✅ |
| Compliance evidence (EU AI Act, DORA, SOC 2) | — | ✅ |
The gateway is the front door: run it, see your agent action surface, and when you need to enforce it, Praxom picks up where this leaves off.
→ getpramiti.com · book a walkthrough or see the injection-backstop demo.
License
MIT © Pramiti Labs
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pramiti_mcp_gateway-0.1.0.tar.gz.
File metadata
- Download URL: pramiti_mcp_gateway-0.1.0.tar.gz
- Upload date:
- Size: 32.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b043ad13abfac8cdab036d588e8ceeeda97d2f46c16976ca0f80d67e6a664a0e
|
|
| MD5 |
47455d44c05fac104e75c32b5c9757cc
|
|
| BLAKE2b-256 |
8d1c8e020c4a45d8d406e38832add046f3c66ceb1c34ddea1bc7c9c2067172ec
|
Provenance
The following attestation bundles were made for pramiti_mcp_gateway-0.1.0.tar.gz:
Publisher:
publish.yml on vasamsetty86/pramiti-mcp-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pramiti_mcp_gateway-0.1.0.tar.gz -
Subject digest:
b043ad13abfac8cdab036d588e8ceeeda97d2f46c16976ca0f80d67e6a664a0e - Sigstore transparency entry: 2204525244
- Sigstore integration time:
-
Permalink:
vasamsetty86/pramiti-mcp-gateway@ba9596758973a35affe4d4f1b5d7482ce6c5fe42 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vasamsetty86
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ba9596758973a35affe4d4f1b5d7482ce6c5fe42 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pramiti_mcp_gateway-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pramiti_mcp_gateway-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc922453860907210073fd1658cf9557e3ba0f68851acdb64c080917863d7ffa
|
|
| MD5 |
8f1d12873c42161d1b116e859b152238
|
|
| BLAKE2b-256 |
454937d16bedbc96ec66c5bacbc5650d6f09894c5173e640a0afc3c62f8401d6
|
Provenance
The following attestation bundles were made for pramiti_mcp_gateway-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on vasamsetty86/pramiti-mcp-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pramiti_mcp_gateway-0.1.0-py3-none-any.whl -
Subject digest:
fc922453860907210073fd1658cf9557e3ba0f68851acdb64c080917863d7ffa - Sigstore transparency entry: 2204525271
- Sigstore integration time:
-
Permalink:
vasamsetty86/pramiti-mcp-gateway@ba9596758973a35affe4d4f1b5d7482ce6c5fe42 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vasamsetty86
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ba9596758973a35affe4d4f1b5d7482ce6c5fe42 -
Trigger Event:
push
-
Statement type: