@smartpolicy/mcp 0.1.0

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 ADDED
@@ -0,0 +1,102 @@
1
+ # SmartPolicy MCP Server
2
+
3
+ The interface AI agents use to consume the protocol. TypeScript, official MCP SDK,
4
+ viem for chain access. Also exposes the same surface as REST for non-MCP clients.
5
+
6
+ ## Tool surface (v0 target)
7
+
8
+ | Tool | Description | Pricing |
9
+ |---|---|---|
10
+ | `policy_check` | "May subject S perform action A under policy N?" → allow/deny + reasons. Maps 1:1 to `PolicyRegistry.isAllowed` — same answer on-chain and off | free |
11
+ | `policy_get` | Policy metadata, members, admins, issuers, action rules, conditions | free |
12
+ | `grant_issue` | Issue an EIP-712 signed grant (server must be an authorized issuer for the policy) | x402 (USDC per call) |
13
+ | `policy_create` | Build the create-policy transaction; either submit it or return calldata for the caller's own wallet to sign | x402 + on-chain fee |
14
+ | `policy_update` | Membership / condition / expiry changes, same pattern | x402 + on-chain fee |
15
+
16
+ ## Auth & payments
17
+
18
+ - Session auth: SIWE (EIP-4361). No bare address headers — possession of the key
19
+ must be proven by signature.
20
+ - Metering: x402 (HTTP 402 payment flow, USDC on Base) on the paid tools.
21
+ - Self-hosting is supported and documented; a self-hosted server registers its own
22
+ issuer address on the policies it serves. The hosted instance has no protocol
23
+ privileges.
24
+
25
+ ## State
26
+
27
+ - Event index of the Registry (SQLite to start) — the server never scans chain
28
+ state on the hot path.
29
+ - Nonce issuance for grants.
30
+ - No custody of user funds, ever. The server's only key is its grant-issuer key.
31
+
32
+ ## Status
33
+
34
+ **v0 packaged and field-tested (stdio transport).** Tools: `policy_check`,
35
+ `policy_get`, `grant_issue` (returns a paste-ready `castTuple`),
36
+ `grant_issuer_info`, `policy_create`, `policy_update`. Plus a CLI subcommand:
37
+ `npx smartpolicy-mcp deploy` bootstraps PolicyRegistry + GrantVerifier on any
38
+ chain from bytecode embedded in the package. Zero-config default targets the
39
+ public Ethereum Sepolia deployment. Write tools return unsigned calldata —
40
+ this server never holds user keys; its only key is the optional grant-issuer
41
+ key. Validated by two unaided fresh-agent execution tests (see PLAN.md
42
+ decision log, 2026-06-12).
43
+
44
+ **HTTP transport + x402 metering shipped (2026-07-05):** `smartpolicy-mcp serve`
45
+ runs Streamable HTTP (stateless) on `SMARTPOLICY_PORT` (default 3402):
46
+ `POST /mcp` + `GET /healthz`. Setting `SMARTPOLICY_X402_PAY_TO` enables x402
47
+ metering (USDC, `exact` scheme) on `grant_issue`/`policy_create`/`policy_update`
48
+ only — reads are always free. Price via `SMARTPOLICY_X402_PRICE_USDC`
49
+ (default 0.001); facilitator via `SMARTPOLICY_X402_FACILITATOR` (default
50
+ `https://x402.org/facilitator`, keyless testnet — use a CDP facilitator for
51
+ mainnet). Smoke test: `npm run smoke:http` against a running server.
52
+ Remaining: SIWE sessions, event indexer, settled-payment e2e test.
53
+
54
+ Windows note: never call `process.exit()` while viem keep-alive sockets are
55
+ open — libuv UV_HANDLE_CLOSING assertion crash; let the event loop drain.
56
+
57
+ ## Running
58
+
59
+ ```bash
60
+ npm install
61
+ SMARTPOLICY_RPC_URL=... # default http://127.0.0.1:8545
62
+ SMARTPOLICY_CHAIN_ID=... # default 31337
63
+ SMARTPOLICY_REGISTRY=0x... # required: PolicyRegistry address
64
+ SMARTPOLICY_VERIFIER=0x... # required: GrantVerifier address
65
+ SMARTPOLICY_ISSUER_KEY=0x... # optional: enables grant_issue
66
+ npm start
67
+ ```
68
+
69
+ Claude Code / MCP client config:
70
+
71
+ ```json
72
+ {
73
+ "mcpServers": {
74
+ "smartpolicy": {
75
+ "command": "npx",
76
+ "args": ["tsx", "<path>/mcp/src/index.ts"],
77
+ "env": { "SMARTPOLICY_REGISTRY": "0x...", "SMARTPOLICY_VERIFIER": "0x..." }
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ ## End-to-end integration test
84
+
85
+ With anvil running and contracts deployed (`contracts/script/Deploy.s.sol`):
86
+
87
+ ```bash
88
+ npm run integration
89
+ ```
90
+
91
+ Proves the full loop: create policy → membership/action-rule checks → issue an
92
+ EIP-712 grant in TypeScript → verify + consume it on-chain → replay rejected →
93
+ revocation is instant. This also pins the EIP-712 domain compatibility between
94
+ `src/grants.ts` and `GrantVerifier.sol` — if either side changes, this fails.
95
+
96
+ ## Implementation notes
97
+
98
+ - `policyId` tool inputs are string/number, never JSON-Schema-incompatible
99
+ bigint (a bigint zod schema silently breaks `tools/list` in the MCP SDK).
100
+ - Actions are plain names ("withdraw") hashed with keccak256, matching the
101
+ `keccak256("withdraw")` convention in protected contracts; 0x-prefixed
102
+ bytes32 values pass through unchanged.