@kaditang/402sentinel-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.
Files changed (3) hide show
  1. package/README.md +64 -0
  2. package/dist/index.js +105 -0
  3. package/package.json +27 -0
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # 402sentinel-mcp
2
+
3
+ An MCP tool that lets your AI agent **check an x402 counterparty's risk before it
4
+ pays**. One tool, `assess_counterparty`: give it a payTo address, get back a
5
+ 0–100 risk score + an `allow` / `review` / `block` decision, scored from on-chain
6
+ settlement behaviour on Base (address age, facilitator-aware payer diversity,
7
+ settlement maturity) with honest confidence/coverage.
8
+
9
+ It's a thin client for the hosted service at **https://402sentinel.com** — the
10
+ scoring model and facilitator-identification logic live server-side (closed); this
11
+ package only forwards the request and pays for it, so it's open source.
12
+
13
+ ## Install
14
+
15
+ ```sh
16
+ npm i -g @kaditang/402sentinel-mcp
17
+ ```
18
+
19
+ ## Configure
20
+
21
+ Add to your MCP client (Claude Desktop, Cursor, etc.):
22
+
23
+ ```jsonc
24
+ {
25
+ "mcpServers": {
26
+ "402sentinel": {
27
+ "command": "402sentinel-mcp",
28
+ "env": {
29
+ "CLIENT_PRIVATE_KEY": "0x... // a Base wallet with USDC in its Circle Gateway balance"
30
+ }
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Each assessment costs **$0.01**, paid automatically in USDC via x402 (Circle
37
+ Gateway, gas-free on Base) from the configured wallet.
38
+
39
+ ## Use
40
+
41
+ The agent calls it before authorizing a payment:
42
+
43
+ ```
44
+ assess_counterparty({
45
+ target: { payto_address: "0x..." },
46
+ payment_context: { amount: 10, asset: "USDC" },
47
+ policy: { block_at_score: 70, review_at_score: 40 }
48
+ })
49
+ → { decision: "review", risk_score: 52, confidence: 0.41, coverage: {...}, dimensions: [...], recommendation: "..." }
50
+ ```
51
+
52
+ - `block` → don't pay
53
+ - `review` → cap exposure / escrow
54
+ - `allow` → proceed
55
+
56
+ ## Disclaimer
57
+
58
+ Algorithmic risk signal, informational only — **not advice, not an endorsement,
59
+ and not an accusation** about any party. Scores are probabilistic estimates from
60
+ limited public on-chain data and heuristics, and may misclassify. Do your own due
61
+ diligence; don't rely on it as your sole basis to pay or refuse. See
62
+ https://402sentinel.com/terms.
63
+
64
+ MIT.
package/dist/index.js ADDED
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 402Sentinel MCP — thin, open-source client.
4
+ *
5
+ * Exposes one tool, `assess_counterparty`, that an agent calls BEFORE paying an
6
+ * x402 counterparty. It pays $0.01 (x402, Circle Gateway on Base) to the hosted
7
+ * 402sentinel.com scoring service and returns a 0-100 risk score + allow/review/
8
+ * block decision. The scoring model / facilitator logic live server-side
9
+ * (closed); this client only forwards + pays, so it's safe to open-source.
10
+ *
11
+ * Config (env):
12
+ * CLIENT_PRIVATE_KEY — a Base wallet with USDC in its Circle Gateway balance
13
+ * (it pays $0.01 per assessment). Required.
14
+ * SENTINEL_URL — override base URL (default https://402sentinel.com).
15
+ */
16
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
17
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
19
+ import { GatewayClient } from "@circle-fin/x402-batching/client";
20
+ const BASE = (process.env.SENTINEL_URL ?? "https://402sentinel.com").replace(/\/$/, "");
21
+ const RAW_PK = process.env.CLIENT_PRIVATE_KEY ?? "";
22
+ const TOOLS = [
23
+ {
24
+ name: "assess_counterparty",
25
+ description: "Assess the risk of an x402 counterparty (a payTo address) BEFORE paying. Returns a 0-100 risk_score and an allow/review/block decision relative to your policy, scored from on-chain settlement behaviour on Base (address age, facilitator-aware payer diversity, settlement maturity) with honest confidence/coverage. Call this before authorizing any x402 payment above your risk threshold. Costs $0.01 (paid automatically in USDC).",
26
+ inputSchema: {
27
+ type: "object",
28
+ required: ["target"],
29
+ properties: {
30
+ target: {
31
+ type: "object",
32
+ required: ["payto_address"],
33
+ properties: {
34
+ payto_address: { type: "string", description: "Chain address that will receive the payment" },
35
+ resource_url: { type: "string", description: "The x402 resource/endpoint URL (optional)" },
36
+ network: { type: "string", description: "CAIP-2 chain id, e.g. eip155:8453 (optional)" },
37
+ },
38
+ },
39
+ payment_context: {
40
+ type: "object",
41
+ properties: {
42
+ amount: { type: "number", description: "Payment amount you're about to make" },
43
+ asset: { type: "string", description: "e.g. USDC" },
44
+ },
45
+ },
46
+ policy: {
47
+ type: "object",
48
+ properties: {
49
+ block_at_score: { type: "number", description: "risk >= this => block (default 70)" },
50
+ review_at_score: { type: "number", description: "risk >= this => review (default 40)" },
51
+ min_confidence: { type: "number", description: "below this => force review (default 0.5)" },
52
+ },
53
+ },
54
+ depth: { type: "string", enum: ["shallow", "deep"], description: "shallow=cheap/cached, deep=fresh (default shallow)" },
55
+ },
56
+ },
57
+ },
58
+ ];
59
+ function clientOrNull() {
60
+ if (!RAW_PK || RAW_PK.startsWith("0xYour"))
61
+ return null;
62
+ const pk = (RAW_PK.startsWith("0x") ? RAW_PK : `0x${RAW_PK}`);
63
+ return new GatewayClient({ chain: "base", privateKey: pk });
64
+ }
65
+ async function main() {
66
+ const server = new Server({ name: "402sentinel", version: "0.1.0" }, { capabilities: { tools: {} } });
67
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
68
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
69
+ const { name, arguments: args } = req.params;
70
+ if (name !== "assess_counterparty") {
71
+ return { content: [{ type: "text", text: `unknown tool: ${name}` }], isError: true };
72
+ }
73
+ const client = clientOrNull();
74
+ if (!client) {
75
+ return {
76
+ content: [{
77
+ type: "text",
78
+ text: JSON.stringify({
79
+ error: "CLIENT_PRIVATE_KEY not set. Provide a Base wallet (with USDC in its Circle Gateway balance) so this tool can pay $0.01 per assessment.",
80
+ }),
81
+ }],
82
+ isError: true,
83
+ };
84
+ }
85
+ try {
86
+ const { data } = await client.pay(`${BASE}/api/assess`, {
87
+ method: "POST",
88
+ body: args,
89
+ });
90
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
91
+ }
92
+ catch (e) {
93
+ return {
94
+ content: [{ type: "text", text: JSON.stringify({ error: `assessment failed: ${e.message}` }) }],
95
+ isError: true,
96
+ };
97
+ }
98
+ });
99
+ const transport = new StdioServerTransport();
100
+ await server.connect(transport);
101
+ }
102
+ main().catch((e) => {
103
+ console.error("402sentinel-mcp fatal:", e);
104
+ process.exit(1);
105
+ });
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@kaditang/402sentinel-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP tool to assess an x402 counterparty's risk BEFORE paying — allow/review/block, scored on-chain. Thin client for 402sentinel.com.",
5
+ "type": "module",
6
+ "bin": { "402sentinel-mcp": "./dist/index.js" },
7
+ "main": "dist/index.js",
8
+ "files": ["dist", "README.md"],
9
+ "scripts": {
10
+ "build": "node node_modules/typescript/bin/tsc",
11
+ "start": "node dist/index.js",
12
+ "dev": "node node_modules/tsx/dist/cli.mjs src/index.ts",
13
+ "prepublishOnly": "node node_modules/typescript/bin/tsc"
14
+ },
15
+ "keywords": ["x402", "mcp", "ai-agents", "risk", "counterparty", "base", "usdc"],
16
+ "author": "Biao Tang",
17
+ "license": "MIT",
18
+ "dependencies": {
19
+ "@modelcontextprotocol/sdk": "^1.0.4",
20
+ "@circle-fin/x402-batching": "^3.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "tsx": "^4.0.0",
24
+ "typescript": "^5.0.0"
25
+ },
26
+ "mcpName": "io.github.kaditang/402sentinel-mcp"
27
+ }