mcp-tool-gateway
README.md
# ๐ mcp-tool-gateway
A **secure tool-execution plane for agentic AI** โ an MCP-style tool server fronted
by a gateway that enforces **identity (JWT + scopes), quota (token-bucket rate
limiting), and safety (prompt-injection inspection)**, ingests downstream APIs from
**OpenAPI**, and writes a structured **audit log**. Pure Python, zero dependencies.
> Mirrors the secure agent tool-execution plane I run in production (MCP / OpenAPI
> behind API governance, JWT validation, Entra-style scope propagation, and prompt
> inspection) โ the controls that let agentic systems clear banking compliance audits.
## Request lifecycle
```
agent tool call โโถ โโโโโโโโโโโโโโโโโโโโโโโโโ SecureToolGateway โโโโโโโโโโโโโโโโโโโโโโโโ
(+ JWT) โ 1 authenticate (HS256 verify, exp) โ
โ 2 rate limit (per-principal token bucket) โ
โ 3 authorize (tool.required_scope โ principal.scopes) โ
โ 4 inspect IN (prompt-injection / exfiltration / cmd-injection) โ
โ 5 execute (MCP server: tools/list ยท tools/call) โ
โ 6 inspect OUT + audit log โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## Components
| Module | Responsibility |
|--------|----------------|
| `jwt_auth` | HS256 JWT encode/verify (from scratch), `exp` check, `Principal` with scope helpers |
| `rate_limit` | `TokenBucket` + per-principal `RateLimiter` |
| `inspection` | Rule-based `Inspector` (instruction-override, exfiltration, command-injection, role-spoofing) with severity-based blocking |
| `mcp` | `MCPServer` implementing `tools/list` and `tools/call` over JSON-RPC |
| `openapi` | `tools_from_openapi` โ auto-register downstream API operations as MCP tools |
| `audit` | Append-only structured `AuditLog` |
| `gateway` | `SecureToolGateway` wiring auth โ quota โ authz โ inspection โ execute โ audit |
## Quickstart
```bash
python examples/run_gateway.py
```
Output demonstrates: an authorized call, a **missing-scope** rejection, a **blocked
prompt-injection** payload, an **invalid token**, and the populated audit trail.
```python
from mcp_gateway import MCPServer, MCPTool, SecureToolGateway, encode
server = MCPServer()
server.register(MCPTool("get_trade_status", "...", schema,
handler=lambda trade_id: "ACK", required_scope="trades:read"))
gw = SecureToolGateway(server=server, secret="...")
token = encode({"sub": "agent-1", "scopes": ["trades:read"]}, "...")
gw.handle({"id": 1, "method": "tools/call",
"params": {"name": "get_trade_status", "arguments": {"trade_id": "T-1"}}}, token)
```
## Security properties
- **Fail-closed**: missing scope, bad signature, expired token, or a high-severity
finding all reject before the tool ever executes.
- **Defense in depth**: inputs *and* outputs are inspected; everything is audited.
- **Least privilege**: per-tool `required_scope`, per-principal quota.
## Tests
```bash
pip install pytest && pytest -q
```
Covers JWT round-trip + tamper detection, scope enforcement, injection blocking,
rate limiting, and inspector severity.
## Tech
Python 3.10+ ยท stdlib only (optional: `pytest`)
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues