protect-mcp 0.4.6 → 0.5.1
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.
- package/README.md +152 -161
- package/dist/chunk-IAJJA5IW.mjs +827 -0
- package/dist/{chunk-VF3OCG4D.mjs → chunk-IUFFDQYZ.mjs} +15 -583
- package/dist/chunk-UEHLYOJY.mjs +321 -0
- package/dist/chunk-V52W3XIN.mjs +582 -0
- package/dist/{chunk-VIA2B65K.mjs → chunk-YKM6W6T7.mjs} +4 -2
- package/dist/cli.js +1452 -100
- package/dist/cli.mjs +205 -10
- package/dist/hook-patterns.d.mts +41 -0
- package/dist/hook-patterns.d.ts +41 -0
- package/dist/hook-patterns.js +348 -0
- package/dist/hook-patterns.mjs +13 -0
- package/dist/hook-server.d.mts +38 -0
- package/dist/hook-server.d.ts +38 -0
- package/dist/hook-server.js +1211 -0
- package/dist/hook-server.mjs +8 -0
- package/dist/{http-transport-XCHIKTYG.mjs → http-transport-GXIXLVJQ.mjs} +2 -1
- package/dist/index.d.mts +194 -1
- package/dist/index.d.ts +194 -1
- package/dist/index.js +1181 -22
- package/dist/index.mjs +35 -19
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -1,62 +1,127 @@
|
|
|
1
1
|
# protect-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Enterprise security gateway for MCP servers and Claude Code hooks. Signed receipts, Cedar policies, and swarm-aware audit trails.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick Start — Claude Code
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Two commands. Every tool call is receipted.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
#
|
|
11
|
-
npx
|
|
10
|
+
# 1. Generate hooks, keys, Cedar policy, and /verify-receipt skill
|
|
11
|
+
npx protect-mcp init-hooks
|
|
12
12
|
|
|
13
|
-
#
|
|
14
|
-
npx protect-mcp
|
|
13
|
+
# 2. Start the hook server
|
|
14
|
+
npx protect-mcp serve
|
|
15
|
+
```
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
npx protect-mcp init
|
|
17
|
+
Open Claude Code in the same project. Every tool call is now intercepted, evaluated, and signed.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
npx protect-mcp --policy protect-mcp.json -- node my-server.js
|
|
19
|
+
### What `init-hooks` creates
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
| File | Purpose |
|
|
22
|
+
|------|---------|
|
|
23
|
+
| `.claude/settings.json` | Hook config (PreToolUse, PostToolUse, + 9 lifecycle events) |
|
|
24
|
+
| `keys/gateway.json` | Ed25519 signing keypair (auto-gitignored) |
|
|
25
|
+
| `policies/agent.cedar` | Starter Cedar policy — customize to your needs |
|
|
26
|
+
| `protect-mcp.json` | JSON policy with signing + rate limits |
|
|
27
|
+
| `.claude/skills/verify-receipt/SKILL.md` | `/verify-receipt` skill for Claude Code |
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
### Architecture
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Claude Code → POST /hook → protect-mcp (Cedar + sign) → response
|
|
33
|
+
↓
|
|
34
|
+
.protect-mcp-log.jsonl
|
|
35
|
+
.protect-mcp-receipts.jsonl
|
|
27
36
|
```
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
- **PreToolUse**: synchronous Cedar policy check → deny blocks the tool
|
|
39
|
+
- **PostToolUse**: async receipt signing → zero latency impact
|
|
40
|
+
- **deny is architecturally final** — it cannot be overridden by the model or other hooks
|
|
41
|
+
|
|
42
|
+
### Endpoints
|
|
43
|
+
|
|
44
|
+
| Method | Path | Description |
|
|
45
|
+
|--------|------|-------------|
|
|
46
|
+
| POST | `/hook` | Claude Code hook endpoint |
|
|
47
|
+
| GET | `/health` | Server status, policy info, signer info |
|
|
48
|
+
| GET | `/receipts` | Recent signed receipts |
|
|
49
|
+
| GET | `/receipts/latest` | Most recent receipt |
|
|
50
|
+
| GET | `/suggestions` | Auto-generated Cedar policy fix suggestions |
|
|
51
|
+
| GET | `/alerts` | Config tamper detection alerts |
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
### Verify receipts
|
|
32
54
|
|
|
55
|
+
```bash
|
|
56
|
+
# Inside Claude Code:
|
|
57
|
+
/verify-receipt
|
|
58
|
+
|
|
59
|
+
# From terminal:
|
|
60
|
+
curl http://127.0.0.1:9377/receipts/latest | jq .
|
|
61
|
+
npx protect-mcp receipts
|
|
62
|
+
|
|
63
|
+
# Check policy suggestions:
|
|
64
|
+
curl http://127.0.0.1:9377/suggestions | jq .
|
|
33
65
|
```
|
|
34
|
-
|
|
66
|
+
|
|
67
|
+
## Quick Start — MCP Server Wrapper
|
|
68
|
+
|
|
69
|
+
Wrap any stdio MCP server as a transparent proxy:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Shadow mode — log every tool call, enforce nothing
|
|
73
|
+
npx protect-mcp -- node my-server.js
|
|
74
|
+
|
|
75
|
+
# Enforce mode with policy
|
|
76
|
+
npx protect-mcp --policy protect-mcp.json --enforce -- node my-server.js
|
|
77
|
+
|
|
78
|
+
# Generate keys + config template
|
|
79
|
+
npx protect-mcp init
|
|
35
80
|
```
|
|
36
81
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
82
|
+
## How It Works
|
|
83
|
+
|
|
84
|
+
protect-mcp evaluates every tool call against a policy (JSON, Cedar, or external PDP), signs the decision as an Ed25519 receipt, and logs the result.
|
|
85
|
+
|
|
86
|
+
**Two integration modes:**
|
|
41
87
|
|
|
42
|
-
|
|
88
|
+
| Mode | Transport | Use Case |
|
|
89
|
+
|------|-----------|----------|
|
|
90
|
+
| Hook Server | HTTP (`npx protect-mcp serve`) | Claude Code, agent swarms |
|
|
91
|
+
| Stdio Proxy | stdin/stdout (`npx protect-mcp -- ...`) | Claude Desktop, Cursor, any MCP client |
|
|
43
92
|
|
|
44
|
-
|
|
93
|
+
**Three policy engines:**
|
|
45
94
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
95
|
+
| Engine | Config | Notes |
|
|
96
|
+
|--------|--------|-------|
|
|
97
|
+
| JSON | `--policy policy.json` | Simple per-tool rules |
|
|
98
|
+
| Cedar | `--cedar ./policies/` | Local WASM evaluation via `@cedar-policy/cedar-wasm` |
|
|
99
|
+
| External PDP | `policy_engine: "external"` | OPA, Cerbos, or any HTTP PDP |
|
|
51
100
|
|
|
52
|
-
##
|
|
101
|
+
## Swarm Tracking
|
|
53
102
|
|
|
54
|
-
|
|
103
|
+
In multi-agent sessions, protect-mcp automatically tracks the swarm topology.
|
|
55
104
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
105
|
+
**11 hook events handled:**
|
|
106
|
+
|
|
107
|
+
| Event | Type | Description |
|
|
108
|
+
|-------|------|-------------|
|
|
109
|
+
| `PreToolUse` | Sync | Cedar/policy evaluation before tool execution |
|
|
110
|
+
| `PostToolUse` | Async | Receipt signing after tool execution |
|
|
111
|
+
| `SubagentStart` / `SubagentStop` | Lifecycle | Worker agent spawn/completion |
|
|
112
|
+
| `TaskCreated` / `TaskCompleted` | Lifecycle | Coordinator task assignment |
|
|
113
|
+
| `SessionStart` / `SessionEnd` | Lifecycle | Session lifecycle with sandbox detection |
|
|
114
|
+
| `TeammateIdle` | Lifecycle | Agent utilization monitoring |
|
|
115
|
+
| `ConfigChange` | Security | Tamper detection for `.claude/settings.json` |
|
|
116
|
+
| `Stop` | Lifecycle | Finalization + policy suggestion summary |
|
|
117
|
+
|
|
118
|
+
Each receipt includes:
|
|
119
|
+
- `swarm.agent_id`, `swarm.agent_type`, `swarm.team_name`
|
|
120
|
+
- `timing.tool_duration_ms`, `timing.hook_latency_ms`
|
|
121
|
+
- `payload_digest` (SHA-256 hash for payloads >1KB)
|
|
122
|
+
- `deny_iteration` (retry count after denial)
|
|
123
|
+
- `sandbox_state` (enabled/disabled/unavailable)
|
|
124
|
+
- OpenTelemetry `otel_trace_id` and `otel_span_id`
|
|
60
125
|
|
|
61
126
|
## Policy File
|
|
62
127
|
|
|
@@ -73,34 +138,50 @@ These are important before you roll this out or talk to users:
|
|
|
73
138
|
"key_path": "./keys/gateway.json",
|
|
74
139
|
"issuer": "protect-mcp",
|
|
75
140
|
"enabled": true
|
|
76
|
-
},
|
|
77
|
-
"credentials": {
|
|
78
|
-
"internal_api": {
|
|
79
|
-
"inject": "env",
|
|
80
|
-
"name": "INTERNAL_API_KEY",
|
|
81
|
-
"value_env": "INTERNAL_API_KEY"
|
|
82
|
-
}
|
|
83
141
|
}
|
|
84
142
|
}
|
|
85
143
|
```
|
|
86
144
|
|
|
87
|
-
###
|
|
145
|
+
### Cedar Policies
|
|
146
|
+
|
|
147
|
+
Cedar deny decisions are **authoritative** — they cannot be overridden.
|
|
148
|
+
|
|
149
|
+
```cedar
|
|
150
|
+
// Allow read-only tools
|
|
151
|
+
permit(
|
|
152
|
+
principal,
|
|
153
|
+
action == Action::"MCP::Tool::call",
|
|
154
|
+
resource == Tool::"Read"
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// Block destructive tools
|
|
158
|
+
forbid(
|
|
159
|
+
principal,
|
|
160
|
+
action == Action::"MCP::Tool::call",
|
|
161
|
+
resource == Tool::"delete_file"
|
|
162
|
+
);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When a tool is denied, protect-mcp auto-suggests the minimal Cedar `permit()` rule via `GET /suggestions`.
|
|
166
|
+
|
|
167
|
+
## CVE-Anchored Policy Packs
|
|
88
168
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
169
|
+
Each prevents a real attack:
|
|
170
|
+
|
|
171
|
+
| Policy | Incident | OWASP |
|
|
172
|
+
|--------|----------|-------|
|
|
173
|
+
| `clinejection.json` | CVE-2025-6514: MCP OAuth proxy hijack (437K environments) | A01, A03 |
|
|
174
|
+
| `terraform-destroy.json` | Autonomous Terraform agent destroys production | A05, A06 |
|
|
175
|
+
| `github-mcp-hijack.json` | Prompt injection via crafted GitHub issue | A01, A02, A03 |
|
|
176
|
+
| `data-exfiltration.json` | Agent data theft via outbound tool abuse | A02, A04 |
|
|
177
|
+
| `financial-safe.json` | Unauthorized financial transaction | A05, A06 |
|
|
95
178
|
|
|
96
|
-
|
|
179
|
+
Cedar equivalents available in `policies/cedar/`.
|
|
97
180
|
|
|
98
181
|
## MCP Client Configuration
|
|
99
182
|
|
|
100
183
|
### Claude Desktop
|
|
101
184
|
|
|
102
|
-
Add to `claude_desktop_config.json`:
|
|
103
|
-
|
|
104
185
|
```json
|
|
105
186
|
{
|
|
106
187
|
"mcpServers": {
|
|
@@ -121,146 +202,56 @@ Add to `claude_desktop_config.json`:
|
|
|
121
202
|
|
|
122
203
|
Same pattern — replace the server command with `protect-mcp` wrapping it.
|
|
123
204
|
|
|
124
|
-
## CLI
|
|
205
|
+
## CLI Commands
|
|
125
206
|
|
|
126
207
|
```
|
|
127
|
-
protect-mcp [options] -- <command> [args...]
|
|
128
|
-
protect-mcp init
|
|
129
|
-
|
|
130
208
|
Commands:
|
|
209
|
+
serve Start HTTP hook server for Claude Code (port 9377)
|
|
210
|
+
init-hooks Generate Claude Code hook config + skill + sample Cedar policy
|
|
211
|
+
quickstart Zero-config onboarding: init + demo + show receipts
|
|
131
212
|
init Generate Ed25519 keypair + config template
|
|
132
|
-
|
|
133
|
-
|
|
213
|
+
demo Start a demo server wrapped with protect-mcp
|
|
214
|
+
doctor Check your setup: keys, policies, verifier, connectivity
|
|
215
|
+
trace <id> Visualize the receipt DAG from a given receipt_id
|
|
216
|
+
status Show tool call statistics from the decision log
|
|
217
|
+
digest Generate a human-readable summary of agent activity
|
|
134
218
|
receipts Show recent persisted signed receipts
|
|
135
219
|
bundle Export an offline-verifiable audit bundle
|
|
220
|
+
simulate Dry-run a policy against recorded tool calls
|
|
221
|
+
report Generate a compliance report from an audit bundle
|
|
136
222
|
|
|
137
223
|
Options:
|
|
138
224
|
--policy <path> Policy/config JSON file
|
|
139
|
-
--
|
|
225
|
+
--cedar <dir> Cedar policy directory
|
|
140
226
|
--enforce Enable enforcement mode (default: shadow)
|
|
227
|
+
--port <port> HTTP server port (default: 9377 for serve)
|
|
141
228
|
--verbose Enable debug logging
|
|
142
|
-
--help Show help
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Programmatic Hooks
|
|
146
|
-
|
|
147
|
-
The library also exposes the primitives that are not yet wired into the default CLI path:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import {
|
|
151
|
-
ProtectGateway,
|
|
152
|
-
loadPolicy,
|
|
153
|
-
evaluateTier,
|
|
154
|
-
meetsMinTier,
|
|
155
|
-
resolveCredential,
|
|
156
|
-
initSigning,
|
|
157
|
-
signDecision,
|
|
158
|
-
queryExternalPDP,
|
|
159
|
-
buildDecisionContext,
|
|
160
|
-
createAuditBundle,
|
|
161
|
-
} from 'protect-mcp';
|
|
162
229
|
```
|
|
163
230
|
|
|
164
|
-
|
|
165
|
-
- manifest admission before a session starts
|
|
166
|
-
- an external PDP (OPA, Cerbos, or a generic HTTP webhook)
|
|
167
|
-
- custom credential-brokered integrations
|
|
168
|
-
- audit bundle export around your own receipt store
|
|
169
|
-
|
|
170
|
-
## Decision Logs and Receipts
|
|
231
|
+
## Decision Logs
|
|
171
232
|
|
|
172
233
|
Every tool call emits structured JSON to `stderr`:
|
|
173
234
|
|
|
174
235
|
```json
|
|
175
|
-
[PROTECT_MCP] {"v":2,"tool":"read_file","decision":"allow","reason_code":"
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
When signing is configured, a signed receipt follows:
|
|
179
|
-
|
|
180
|
-
```json
|
|
181
|
-
[PROTECT_MCP_RECEIPT] {"v":2,"type":"decision_receipt","algorithm":"ed25519","kid":"...","issuer":"protect-mcp","issued_at":"2026-03-22T00:00:00Z","payload":{"tool":"read_file","decision":"allow","policy_digest":"...","mode":"shadow","request_id":"..."},"signature":"..."}
|
|
236
|
+
[PROTECT_MCP] {"v":2,"tool":"read_file","decision":"allow","reason_code":"cedar_allow","policy_digest":"a1b2c3...","mode":"enforce","hook_event":"PreToolUse","timing":{"hook_latency_ms":1},"otel_trace_id":"..."}
|
|
182
237
|
```
|
|
183
238
|
|
|
184
|
-
|
|
185
|
-
Verify in browser: [scopeblind.com/verify](https://scopeblind.com/verify)
|
|
239
|
+
When signing is configured, a signed receipt is persisted to `.protect-mcp-receipts.jsonl`.
|
|
186
240
|
|
|
187
241
|
## Audit Bundles
|
|
188
242
|
|
|
189
|
-
The package exports a helper for self-contained audit bundles:
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"format": "scopeblind:audit-bundle",
|
|
194
|
-
"version": 1,
|
|
195
|
-
"tenant": "my-service",
|
|
196
|
-
"receipts": ["..."],
|
|
197
|
-
"verification": {
|
|
198
|
-
"algorithm": "ed25519",
|
|
199
|
-
"signing_keys": ["..."]
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Use `createAuditBundle()` around your own collected signed receipts.
|
|
205
|
-
|
|
206
|
-
## Philosophy
|
|
207
|
-
|
|
208
|
-
- **Shadow first.** See what agents are doing before you enforce anything.
|
|
209
|
-
- **Receipts beat dashboard-only logs.** Signed artifacts should be independently verifiable.
|
|
210
|
-
- **Keep the claims tight.** The default CLI path does not yet do everything the long-term architecture will support.
|
|
211
|
-
- **Layer on top of existing auth.** Don't rip out your stack just to add control and evidence.
|
|
212
|
-
|
|
213
|
-
## Incident-Anchored Policy Packs
|
|
214
|
-
|
|
215
|
-
Ship with protect-mcp — each prevents a real attack:
|
|
216
|
-
|
|
217
|
-
| Policy | Incident | OWASP Categories |
|
|
218
|
-
|--------|----------|-----------------|
|
|
219
|
-
| `clinejection.json` | CVE-2025-6514: MCP OAuth proxy hijack (437K environments) | A01, A03 |
|
|
220
|
-
| `terraform-destroy.json` | Autonomous Terraform agent destroys production | A05, A06 |
|
|
221
|
-
| `github-mcp-hijack.json` | Prompt injection via crafted GitHub issue | A01, A02, A03 |
|
|
222
|
-
| `data-exfiltration.json` | Agent data theft via outbound tool abuse | A02, A04 |
|
|
223
|
-
| `financial-safe.json` | Unauthorized financial transaction | A05, A06 |
|
|
224
|
-
|
|
225
|
-
Cedar-native policies are also available in `policies/cedar/`:
|
|
226
|
-
|
|
227
|
-
| Policy | Purpose |
|
|
228
|
-
|--------|---------|
|
|
229
|
-
| `clinejection.cedar` | Cedar equivalent of the clinejection JSON policy |
|
|
230
|
-
| `terraform-destroy.cedar` | Cedar equivalent of the terraform-destroy JSON policy |
|
|
231
|
-
| `spending-authority.cedar` | Spending authority controls — caps per-tool transaction amounts and requires elevated tiers for high-value operations |
|
|
232
|
-
|
|
233
243
|
```bash
|
|
234
|
-
|
|
235
|
-
npx protect-mcp --policy node_modules/protect-mcp/policies/clinejection.json -- node server.js
|
|
236
|
-
|
|
237
|
-
# Cedar policy (requires @cedar-policy/cedar-wasm)
|
|
238
|
-
npx protect-mcp --policy node_modules/protect-mcp/policies/cedar/spending-authority.cedar --enforce -- node server.js
|
|
244
|
+
npx protect-mcp bundle --output audit.json
|
|
239
245
|
```
|
|
240
246
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
## BYOPE: External Policy Engines
|
|
244
|
-
|
|
245
|
-
Supports OPA, Cerbos, Cedar (AWS AgentCore), and generic HTTP endpoints:
|
|
246
|
-
|
|
247
|
-
```json
|
|
248
|
-
{
|
|
249
|
-
"policy_engine": "hybrid",
|
|
250
|
-
"external": {
|
|
251
|
-
"endpoint": "http://localhost:8181/v1/data/mcp/allow",
|
|
252
|
-
"format": "cedar",
|
|
253
|
-
"timeout_ms": 200,
|
|
254
|
-
"fallback": "deny"
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
```
|
|
247
|
+
Self-contained offline-verifiable bundle with receipts + signing keys. Verify with `npx @veritasacta/verify`.
|
|
258
248
|
|
|
259
249
|
## Standards & IP
|
|
260
250
|
|
|
261
251
|
- **IETF Internet-Draft**: [draft-farley-acta-signed-receipts-00](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/) — Signed Decision Receipts for Machine-to-Machine Access Control
|
|
262
252
|
- **Patent Status**: 4 Australian provisional patents pending (2025-2026) covering decision receipts with configurable disclosure, tool-calling gateway, agent manifests, and portable identity
|
|
263
253
|
- **Verification**: MIT-licensed — `npx @veritasacta/verify --self-test`
|
|
254
|
+
- **Microsoft AGT Integration**: [PR #667](https://github.com/microsoft/agent-governance-toolkit/pull/667) — Cedar policy bridge for Agent Governance Toolkit
|
|
264
255
|
|
|
265
256
|
## License
|
|
266
257
|
|