twzrd-mcp-server 0.1.0 → 0.2.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 +114 -0
- package/dist/index.js +122 -226
- package/package.json +19 -31
- package/dist/index.d.ts +0 -14
- package/dist/index.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# twzrd-mcp-server - auto-pay MCP for the TWZRD Trust API
|
|
2
|
+
|
|
3
|
+
> Payment mechanism is mainnet-verified via the official x402 SDK (Python path,
|
|
4
|
+
> $0.001 moved 2026-06-26 - see Status). As of v0.2.0 the bundled TypeScript path
|
|
5
|
+
> uses the official x402 JS SDK (`@x402/core` + `@x402/svm` + `@x402/fetch`) and
|
|
6
|
+
> is construct-verified against the live mainnet challenge; one real on-chain
|
|
7
|
+
> settle remains before npm publish.
|
|
8
|
+
|
|
9
|
+
Auto-pay MCP server for TWZRD's Trust API, matching the competitor GTM shape
|
|
10
|
+
(anchor-x402, Br0ski777, BitBooth all ship one). An agent adds one `mcpServers`
|
|
11
|
+
entry; paid tool calls auto-handle the x402 challenge. Free tools never pay.
|
|
12
|
+
|
|
13
|
+
## Why this is a corrected rebuild
|
|
14
|
+
A first draft signed **EIP-3009 on Base (EVM/viem)**. TWZRD settles x402 on
|
|
15
|
+
**Solana** (`scheme:"exact"`, USDC, sponsored `feePayer`) — the EVM scheme never
|
|
16
|
+
matches the challenge, so that draft could not pay TWZRD at all (it would `tsc`-pass
|
|
17
|
+
yet fail every real call). This version is Solana-native and **refuses** any
|
|
18
|
+
non-Solana challenge instead of mis-signing.
|
|
19
|
+
|
|
20
|
+
## Safety guardrails (enforced before any signature)
|
|
21
|
+
- Per-call cap `TWZRD_MAX_USDC_PER_CALL` (default 0.05)
|
|
22
|
+
- Cumulative session cap `TWZRD_MAX_USDC_TOTAL` (default 1.00)
|
|
23
|
+
- Free discovery tools never enter the payment path
|
|
24
|
+
- No cross-chain fallback — a non-`exact`/non-`solana:` challenge is rejected
|
|
25
|
+
- Paid calls run the free preflight first; `decision=block` aborts the pay
|
|
26
|
+
|
|
27
|
+
## Status — payment path VERIFIED on mainnet 2026-06-26
|
|
28
|
+
|
|
29
|
+
Two authorized settles from dev wallet `2pHjZLqs…`:
|
|
30
|
+
|
|
31
|
+
1. **Hand-rolled `X-Payment` (this MCP's original approach): FAILED** — HTTP 402,
|
|
32
|
+
no USDC moved. The intel host validates via the official x402 lib's
|
|
33
|
+
`PaymentPayload`, so a hand-built header is rejected. (Green `tsc` ≠ settles —
|
|
34
|
+
fail-closed default was correct.)
|
|
35
|
+
2. **Official x402 SDK: SUCCEEDED** — `GET /v1/intel/quick/CqtQPaAuQ5UR…` →
|
|
36
|
+
**HTTP 200, `"paid":true,"charged_amount_usdc":0.001`**, tier Silver score 53.6.
|
|
37
|
+
USDC balance moved `0.057236 → 0.056236` (exactly $0.001). A second call against
|
|
38
|
+
a no-data pubkey returned `422 charged:false` — the server's no-charge-on-empty
|
|
39
|
+
guard works.
|
|
40
|
+
|
|
41
|
+
**Conclusion: auto-pay works ONLY via the official x402 SDK, not a hand-rolled
|
|
42
|
+
header.** Proven client wiring (Python):
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from x402.client import x402ClientSync
|
|
46
|
+
from x402.mechanisms.svm.signers import KeypairSigner
|
|
47
|
+
from x402.mechanisms.svm.exact import register_exact_svm_client
|
|
48
|
+
from x402.http.clients.requests import x402_requests
|
|
49
|
+
client = x402ClientSync()
|
|
50
|
+
register_exact_svm_client(client, KeypairSigner(keypair), rpc_url=RPC)
|
|
51
|
+
session = x402_requests(client)
|
|
52
|
+
session.get("https://intel.twzrd.xyz/v1/intel/quick/<wallet>") # auto-pays $0.001
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### TypeScript path — integrated (v0.2.0)
|
|
56
|
+
The hand-rolled `payAndRetry` is replaced with the official x402 JS SDK
|
|
57
|
+
(`@x402/core` client + `@x402/svm` ExactSvmScheme + `@x402/fetch`
|
|
58
|
+
`wrapFetchWithPayment`). `@x402/svm` reads the challenge `extra.feePayer` and builds
|
|
59
|
+
the partially-signed sponsored transfer (verified no-spend against the live mainnet
|
|
60
|
+
challenge: 496-byte tx, 2 signature slots), and the SDK encodes the `X-PAYMENT`
|
|
61
|
+
header the server validates. Spend caps + preflight gate + free/paid split are
|
|
62
|
+
preserved — caps are enforced in the payment selector before any signature.
|
|
63
|
+
**Remaining:** one real $0.001 on-chain settle to confirm end-to-end, then npm
|
|
64
|
+
publish + MCP-registry listing.
|
|
65
|
+
|
|
66
|
+
## Install & Config
|
|
67
|
+
|
|
68
|
+
### Python (recommended — the mainnet-proven path)
|
|
69
|
+
```bash
|
|
70
|
+
pip install twzrd-mcp
|
|
71
|
+
```
|
|
72
|
+
MCP client config (`mcpServers`):
|
|
73
|
+
```json
|
|
74
|
+
{ "mcpServers": { "twzrd": {
|
|
75
|
+
"command": "twzrd-mcp",
|
|
76
|
+
"env": {
|
|
77
|
+
"TWZRD_RPC_URL": "<your Solana RPC url>",
|
|
78
|
+
"TWZRD_WALLET_KEYPAIR": "/path/to/solana-keypair.json",
|
|
79
|
+
"TWZRD_MCP_PAYMENTS_ENABLED": "1",
|
|
80
|
+
"TWZRD_MAX_USDC_PER_CALL": "0.05",
|
|
81
|
+
"TWZRD_MAX_USDC_TOTAL": "1.00"
|
|
82
|
+
}
|
|
83
|
+
}}}
|
|
84
|
+
```
|
|
85
|
+
The **free** tools (`preflight`, `wallet_lookup`) need no wallet and no flags — leave
|
|
86
|
+
`TWZRD_MCP_PAYMENTS_ENABLED` unset and they work read-only. Only the paid tools need
|
|
87
|
+
the keypair + `TWZRD_MCP_PAYMENTS_ENABLED=1`.
|
|
88
|
+
|
|
89
|
+
### Node (`npx twzrd-mcp-server`) — v0.2.0, x402 JS SDK
|
|
90
|
+
```json
|
|
91
|
+
{ "mcpServers": { "twzrd": {
|
|
92
|
+
"command": "npx", "args": ["-y", "twzrd-mcp-server"],
|
|
93
|
+
"env": {
|
|
94
|
+
"TWZRD_WALLET_SECRET_KEY": "<base58 Solana secret>",
|
|
95
|
+
"TWZRD_RPC_URL": "<your Solana RPC url>",
|
|
96
|
+
"TWZRD_MAX_USDC_PER_CALL": "0.05",
|
|
97
|
+
"TWZRD_MAX_USDC_TOTAL": "1.00"
|
|
98
|
+
}
|
|
99
|
+
}}}
|
|
100
|
+
```
|
|
101
|
+
Auto-pay is enabled whenever `TWZRD_WALLET_SECRET_KEY` is present (set
|
|
102
|
+
`TWZRD_MCP_PAYMENTS_ENABLED=0` to force paid tools off). Free tools need no wallet.
|
|
103
|
+
Construct-verified against the live mainnet challenge; pending one real settle +
|
|
104
|
+
npm publish (until published, `npx twzrd-mcp-server` is not yet resolvable — see
|
|
105
|
+
the Python package above for a path that is live on PyPI today).
|
|
106
|
+
|
|
107
|
+
## Tools
|
|
108
|
+
- `preflight` (free) — allow/warn/block + trust_score before you pay a **seller** you're about to transact with
|
|
109
|
+
- `wallet_lookup` (free) — facilitators + counterparty breadth for a Solana wallet
|
|
110
|
+
- `verify_receipt` (free) — independently verify a wallet's cNFT Receipt offline (Ed25519 vs the genesis authority `2ELSDx`); no trust in any TWZRD server
|
|
111
|
+
- `quick_trust` ($0.001, auto-pay) — quick tier + score for any wallet
|
|
112
|
+
- `full_trust` ($0.05, auto-pay) — full trust intel + signed V6 receipt
|
|
113
|
+
|
|
114
|
+
> Note: `quick_trust`/`full_trust` pay TWZRD a fixed micro-fee for intel on **any** wallet — they do **not** refuse "risky" targets (you look those up on purpose). Use `preflight` to vet a counterparty you're about to *pay elsewhere*.
|
package/dist/index.js
CHANGED
|
@@ -1,257 +1,153 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TWZRD MCP Server — auto-pay x402 wrapper for TWZRD's Trust API.
|
|
2
|
+
* TWZRD MCP Server — auto-pay x402 wrapper for TWZRD's Trust API (SOLANA).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Agents install this MCP server; paid tool calls auto-handle the x402 challenge
|
|
5
|
+
* (detect 402 -> SDK builds + signs a Solana USDC payment -> retry). Free tools
|
|
6
|
+
* never pay.
|
|
7
|
+
*
|
|
8
|
+
* PAYMENT CORE: the official x402 SDK (@x402/core + @x402/svm + @x402/fetch).
|
|
9
|
+
* TWZRD settles x402 on **Solana** ("exact" scheme, USDC, sponsored feePayer):
|
|
10
|
+
* the buyer partial-signs a USDC transfer as the transfer authority, and TWZRD's
|
|
11
|
+
* wallet (the challenge `extra.feePayer`) co-signs + pays the SOL fee server-side.
|
|
12
|
+
* `@x402/svm`'s ExactSvmScheme reads `extra.feePayer` and builds exactly this
|
|
13
|
+
* partially-signed transaction; the SDK also encodes the X-PAYMENT header the
|
|
14
|
+
* server validates. (An earlier draft hand-rolled both and the server rejected
|
|
15
|
+
* it — the hand-rolled header never matched the official x402 PaymentPayload.)
|
|
16
|
+
*
|
|
17
|
+
* SAFETY GUARDRAILS (all enforced in the payment-requirements selector, BEFORE
|
|
18
|
+
* any signature):
|
|
19
|
+
* - Hard per-call cap (TWZRD_MAX_USDC_PER_CALL, default 0.05)
|
|
20
|
+
* - Cumulative session cap (TWZRD_MAX_USDC_TOTAL, default 1.00)
|
|
21
|
+
* - Free discovery tools are NEVER routed through the payment path
|
|
22
|
+
* - No cross-chain fallback: only a Solana "exact" requirement is selectable;
|
|
23
|
+
* anything else throws (refuse to pay) rather than mis-signing
|
|
24
|
+
* - Paid tools run the FREE preflight first; decision=block aborts the pay
|
|
25
|
+
*
|
|
26
|
+
* STATUS: payment mechanism is SDK-backed and the payload construction is
|
|
27
|
+
* verified against the live Solana "exact" challenge. The first real on-chain
|
|
28
|
+
* settle is the operator's go (needs a funded wallet). Set
|
|
29
|
+
* TWZRD_MCP_PAYMENTS_ENABLED=0 to force paid tools off (fail-closed) if desired.
|
|
7
30
|
*
|
|
8
31
|
* ENV:
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
32
|
+
* TWZRD_WALLET_SECRET_KEY base58 Solana secret key (64-byte). Required for paid calls.
|
|
33
|
+
* TWZRD_RPC_URL Solana RPC (default mainnet-beta public)
|
|
34
|
+
* TWZRD_API_URL default https://intel.twzrd.xyz
|
|
35
|
+
* TWZRD_MAX_USDC_PER_CALL default 0.05
|
|
36
|
+
* TWZRD_MAX_USDC_TOTAL default 1.00
|
|
37
|
+
* TWZRD_MCP_PAYMENTS_ENABLED "0" to force paid tools off (default: enabled when a key is present)
|
|
13
38
|
*/
|
|
14
39
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
15
40
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
16
|
-
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import
|
|
41
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
42
|
+
import { x402Client } from "@x402/core/client";
|
|
43
|
+
import { wrapFetchWithPayment } from "@x402/fetch";
|
|
44
|
+
import { ExactSvmScheme, SOLANA_MAINNET_CAIP2 } from "@x402/svm";
|
|
45
|
+
import { createKeyPairSignerFromBytes } from "@solana/kit";
|
|
46
|
+
import bs58 from "bs58";
|
|
21
47
|
// ── Config ─────────────────────────────────────────────────────────────────
|
|
22
48
|
const API_BASE = process.env.TWZRD_API_URL || "https://intel.twzrd.xyz";
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
const RPC_URL = process.env.TWZRD_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
50
|
+
const MAX_PER_CALL = Number(process.env.TWZRD_MAX_USDC_PER_CALL || "0.05");
|
|
51
|
+
const MAX_TOTAL = Number(process.env.TWZRD_MAX_USDC_TOTAL || "1.00");
|
|
52
|
+
const PAYMENTS_DISABLED = process.env.TWZRD_MCP_PAYMENTS_ENABLED === "0";
|
|
53
|
+
const SECRET = process.env.TWZRD_WALLET_SECRET_KEY || "";
|
|
54
|
+
let spentUsdc = 0; // cumulative session spend (USDC)
|
|
55
|
+
// ── Payment client (official x402 SDK, Solana exact scheme) ──────────────────
|
|
56
|
+
// The selector is the single chokepoint for every guardrail: it picks which
|
|
57
|
+
// `accepts[]` entry to pay and THROWS to refuse. Nothing is signed unless a
|
|
58
|
+
// requirement passes scheme + chain + per-call + session checks here first.
|
|
59
|
+
function selectSolanaExact(_x402Version, accepts) {
|
|
60
|
+
const req = (accepts || []).find((a) => a?.scheme === "exact" && String(a?.network || "").startsWith("solana:"));
|
|
61
|
+
if (!req) {
|
|
62
|
+
throw new Error(`Refusing to pay: no Solana "exact" payment option in challenge (${JSON.stringify((accepts || []).map((a) => ({ scheme: a?.scheme, network: a?.network })))})`);
|
|
37
63
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
64
|
+
const decimals = Number(req.extra?.decimals ?? 6);
|
|
65
|
+
const amountUsdc = Number(BigInt(req.amount)) / 10 ** decimals;
|
|
66
|
+
if (amountUsdc > MAX_PER_CALL) {
|
|
67
|
+
throw new Error(`Refusing: call price $${amountUsdc} exceeds per-call cap $${MAX_PER_CALL}`);
|
|
42
68
|
}
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
const agentKeypair = loadKeypair(KEYPAIR_SOURCE);
|
|
46
|
-
const agentPubkey = agentKeypair.publicKey.toBase58();
|
|
47
|
-
// ── Spend cap tracking (in-memory, per-process) ────────────────────────────
|
|
48
|
-
let dailySpentUsdc = 0;
|
|
49
|
-
let dailyResetAt = Date.now() + 24 * 60 * 60 * 1000;
|
|
50
|
-
function checkSpendCap(amountUsdc) {
|
|
51
|
-
const now = Date.now();
|
|
52
|
-
if (now > dailyResetAt) {
|
|
53
|
-
dailySpentUsdc = 0;
|
|
54
|
-
dailyResetAt = now + 24 * 60 * 60 * 1000;
|
|
69
|
+
if (spentUsdc + amountUsdc > MAX_TOTAL) {
|
|
70
|
+
throw new Error(`Refusing: would exceed session cap $${MAX_TOTAL} (spent $${spentUsdc})`);
|
|
55
71
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
72
|
+
// Conservative accounting: count the spend at selection time. A failed settle
|
|
73
|
+
// only makes the caps stricter (never looser), which is the safe direction.
|
|
74
|
+
spentUsdc += amountUsdc;
|
|
75
|
+
return req;
|
|
60
76
|
}
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// Find Solana scheme (scheme === "exact")
|
|
75
|
-
const accepts = challenge.accepts || [];
|
|
76
|
-
const scheme = accepts.find((a) => a.scheme === "exact" && a.network?.startsWith("solana:"));
|
|
77
|
-
if (!scheme) {
|
|
78
|
-
throw new Error(`No Solana payment scheme found (got: ${JSON.stringify(accepts.map((a) => a.scheme))})`);
|
|
77
|
+
// Build the payment-enabled fetch once, if a key is present and payments aren't
|
|
78
|
+
// force-disabled. Otherwise paid tools fail closed with a clear message.
|
|
79
|
+
let paidFetch = null;
|
|
80
|
+
let paymentInitError = "";
|
|
81
|
+
if (SECRET && !PAYMENTS_DISABLED) {
|
|
82
|
+
try {
|
|
83
|
+
const secretBytes = bs58.decode(SECRET);
|
|
84
|
+
const signer = await createKeyPairSignerFromBytes(secretBytes);
|
|
85
|
+
const scheme = new ExactSvmScheme(signer, { rpcUrl: RPC_URL });
|
|
86
|
+
const client = new x402Client(selectSolanaExact);
|
|
87
|
+
client.register(SOLANA_MAINNET_CAIP2, scheme);
|
|
88
|
+
paidFetch = wrapFetchWithPayment(fetch, client);
|
|
89
|
+
console.error(`TWZRD MCP: auto-pay armed (payer ${signer.address}) caps $${MAX_PER_CALL}/call $${MAX_TOTAL}/session`);
|
|
79
90
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const feePayer = scheme.extra?.feePayer;
|
|
84
|
-
const recentBlockhash = scheme.extra?.recentBlockhash;
|
|
85
|
-
const usdcMint = scheme.asset;
|
|
86
|
-
// ── Run free preflight before paying ──
|
|
87
|
-
const preflightResp = await fetch(`${API_BASE}/v1/intel/preflight`, {
|
|
88
|
-
method: "POST",
|
|
89
|
-
headers: { "Content-Type": "application/json" },
|
|
90
|
-
body: JSON.stringify({
|
|
91
|
-
seller_wallet: payTo,
|
|
92
|
-
resource_name: "MCP Tool Call",
|
|
93
|
-
price_usdc: amountUsdc,
|
|
94
|
-
agent_intent: "x402_mcp_auto_pay",
|
|
95
|
-
}),
|
|
96
|
-
});
|
|
97
|
-
const preflight = await preflightResp.json();
|
|
98
|
-
const card = preflight?.readiness_card || {};
|
|
99
|
-
if (card.decision === "block") {
|
|
100
|
-
throw new Error(`Preflight BLOCKED payment to ${payTo}: ${(card.caveats || []).join("; ")}`);
|
|
91
|
+
catch (e) {
|
|
92
|
+
paymentInitError = e instanceof Error ? e.message : String(e);
|
|
93
|
+
console.error(`TWZRD MCP: payment init failed — paid tools disabled: ${paymentInitError}`);
|
|
101
94
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
const transferIx = createTransferInstruction(agentAta.address, // source (agent's USDC ATA)
|
|
110
|
-
new PublicKey(payTo), // destination (merchant)
|
|
111
|
-
agentKeypair.publicKey, // owner
|
|
112
|
-
BigInt(amountMicro));
|
|
113
|
-
// Build transaction with sponsored feePayer
|
|
114
|
-
const feePayerPubkey = new PublicKey(feePayer);
|
|
115
|
-
const message = new TransactionMessage({
|
|
116
|
-
payerKey: feePayerPubkey,
|
|
117
|
-
recentBlockhash,
|
|
118
|
-
instructions: [transferIx],
|
|
119
|
-
}).compileToV0Message();
|
|
120
|
-
const tx = new VersionedTransaction(message);
|
|
121
|
-
tx.sign([agentKeypair]);
|
|
122
|
-
// Serialize and base64 encode for X-Payment header
|
|
123
|
-
const txBytes = tx.serialize();
|
|
124
|
-
const paymentHeader = Buffer.from(txBytes).toString("base64");
|
|
125
|
-
// ── Record spend ──
|
|
126
|
-
dailySpentUsdc += amountUsdc;
|
|
127
|
-
// ── Retry with payment header ──
|
|
128
|
-
const retryResp = await fetch(url, {
|
|
95
|
+
}
|
|
96
|
+
// ── HTTP: free path is plain fetch; paid path goes through the x402 SDK ───────
|
|
97
|
+
async function twzrdFetch(path, opts) {
|
|
98
|
+
const url = `${API_BASE}${path}`;
|
|
99
|
+
const method = opts?.method || "GET";
|
|
100
|
+
const body = opts?.body ? JSON.stringify(opts.body) : undefined;
|
|
101
|
+
const init = {
|
|
129
102
|
method,
|
|
130
|
-
headers: { "Content-Type": "application/json"
|
|
103
|
+
headers: { "Content-Type": "application/json" },
|
|
131
104
|
body,
|
|
132
|
-
}
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
105
|
+
};
|
|
106
|
+
if (opts?.paid) {
|
|
107
|
+
if (!paidFetch) {
|
|
108
|
+
throw new Error(SECRET
|
|
109
|
+
? `auto-pay unavailable: ${paymentInitError || "payments force-disabled (TWZRD_MCP_PAYMENTS_ENABLED=0)"}`
|
|
110
|
+
: "paid tool requires TWZRD_WALLET_SECRET_KEY (base58 Solana key)");
|
|
111
|
+
}
|
|
112
|
+
return paidFetch(url, init);
|
|
138
113
|
}
|
|
139
|
-
|
|
140
|
-
console.error(`[twzrd-mcp] paid ${amountUsdc} USDC → ${payTo.slice(0, 8)}.. for ${path} (daily: ${dailySpentUsdc.toFixed(3)}/${DAILY_CAP_USDC})`);
|
|
141
|
-
return retryResp;
|
|
114
|
+
return fetch(url, init);
|
|
142
115
|
}
|
|
143
|
-
// ──
|
|
144
|
-
const server = new Server({ name: "twzrd-mcp-server", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
116
|
+
// ── Tools (free vs paid clearly separated; paid tools pass { paid: true }) ───
|
|
145
117
|
const TOOLS = [
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
properties: {
|
|
152
|
-
wallet: { type: "string", description: "Solana wallet address (base58)" },
|
|
153
|
-
},
|
|
154
|
-
required: ["wallet"],
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
name: "full_trust",
|
|
159
|
-
description: "$0.05 full trust intelligence + signed V6 receipt. Auto-pays via x402. Runs free preflight first.",
|
|
160
|
-
inputSchema: {
|
|
161
|
-
type: "object",
|
|
162
|
-
properties: {
|
|
163
|
-
wallet: { type: "string", description: "Solana wallet address (base58)" },
|
|
164
|
-
},
|
|
165
|
-
required: ["wallet"],
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
name: "preflight",
|
|
170
|
-
description: "Free pre-payment check. No payment needed. Returns readiness_card with allow/warn/block decision.",
|
|
171
|
-
inputSchema: {
|
|
172
|
-
type: "object",
|
|
173
|
-
properties: {
|
|
174
|
-
seller_wallet: { type: "string", description: "Seller wallet to evaluate" },
|
|
175
|
-
},
|
|
176
|
-
required: ["seller_wallet"],
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
name: "verify_receipt",
|
|
181
|
-
description: "Free — verify a TWZRD V6 receipt offline.",
|
|
182
|
-
inputSchema: {
|
|
183
|
-
type: "object",
|
|
184
|
-
properties: {
|
|
185
|
-
leaf: { type: "string", description: "Hex keccak256 receipt leaf" },
|
|
186
|
-
signature: { type: "string", description: "Ed25519 signature" },
|
|
187
|
-
signing_pubkey: { type: "string", description: "Signer pubkey (base58)" },
|
|
188
|
-
},
|
|
189
|
-
required: ["leaf"],
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
name: "wallet_lookup",
|
|
194
|
-
description: "Free — discover which facilitators and counterparties a Solana wallet has.",
|
|
195
|
-
inputSchema: {
|
|
196
|
-
type: "object",
|
|
197
|
-
properties: {
|
|
198
|
-
wallet: { type: "string", description: "Solana wallet address (base58)" },
|
|
199
|
-
},
|
|
200
|
-
required: ["wallet"],
|
|
201
|
-
},
|
|
202
|
-
},
|
|
118
|
+
{ name: "preflight", description: "FREE pre-payment check. readiness_card with allow/warn/block + trust_score. No payment.", inputSchema: { type: "object", properties: { seller_wallet: { type: "string" }, resource_name: { type: "string" }, price_usdc: { type: "number" } }, required: ["seller_wallet"] } },
|
|
119
|
+
{ name: "wallet_lookup", description: "FREE: facilitators + counterparty breadth for a Solana wallet.", inputSchema: { type: "object", properties: { wallet: { type: "string" } }, required: ["wallet"] } },
|
|
120
|
+
{ name: "verify_receipt", description: "FREE: verify a TWZRD V6 receipt (leaf/signature/signing_pubkey).", inputSchema: { type: "object", properties: { leaf: { type: "string" }, signature: { type: "string" }, signing_pubkey: { type: "string" } }, required: ["leaf"] } },
|
|
121
|
+
{ name: "quick_trust", description: "PAID $0.001 (auto-pay, Solana x402): quick tier+score for a Solana wallet.", inputSchema: { type: "object", properties: { wallet: { type: "string" } }, required: ["wallet"] } },
|
|
122
|
+
{ name: "full_trust", description: "PAID $0.05 (auto-pay, Solana x402): full trust intel + signed V6 receipt.", inputSchema: { type: "object", properties: { wallet: { type: "string" }, seller_wallet: { type: "string" } }, required: ["wallet"] } },
|
|
203
123
|
];
|
|
124
|
+
const server = new Server({ name: "twzrd-mcp-server", version: "0.2.0" }, { capabilities: { tools: {} } });
|
|
204
125
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
205
126
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
206
127
|
const { name, arguments: args } = request.params;
|
|
128
|
+
const a = (args || {});
|
|
207
129
|
async function api(path, opts) {
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
if (!
|
|
211
|
-
throw new Error(`TWZRD API ${
|
|
212
|
-
return
|
|
130
|
+
const r = await twzrdFetch(path, opts);
|
|
131
|
+
const t = await r.text();
|
|
132
|
+
if (!r.ok)
|
|
133
|
+
throw new Error(`TWZRD API ${r.status}: ${t.slice(0, 200)}`);
|
|
134
|
+
return t;
|
|
213
135
|
}
|
|
136
|
+
// NOTE: quick_trust/full_trust BUY intel ON `wallet` — the caller looks a wallet
|
|
137
|
+
// up precisely because they want to know about it (including risky ones). We do
|
|
138
|
+
// NOT gate the purchase on that wallet's own trust score; that would be backwards
|
|
139
|
+
// (you'd be blocked from buying intel on exactly the wallets you most need it for).
|
|
140
|
+
// The `preflight` tool exists separately to vet a SELLER you are about to pay
|
|
141
|
+
// ELSEWHERE. Spend caps + the payment selector are the safety controls here.
|
|
214
142
|
switch (name) {
|
|
215
|
-
case "quick_trust": {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
case "full_trust": {
|
|
222
|
-
const wallet = String(args?.wallet || "");
|
|
223
|
-
if (!wallet)
|
|
224
|
-
throw new Error("wallet required");
|
|
225
|
-
return { content: [{ type: "text", text: await api(`/v1/intel/trust/${wallet}`) }] };
|
|
226
|
-
}
|
|
227
|
-
case "preflight": {
|
|
228
|
-
return {
|
|
229
|
-
content: [{
|
|
230
|
-
type: "text",
|
|
231
|
-
text: await api("/v1/intel/preflight", { method: "POST", body: { seller_wallet: args?.seller_wallet, resource_name: "MCP Tool Call", price_usdc: 0.05 } }),
|
|
232
|
-
}],
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
case "verify_receipt": {
|
|
236
|
-
return {
|
|
237
|
-
content: [{
|
|
238
|
-
type: "text",
|
|
239
|
-
text: await api("/v1/receipts/verify", { method: "POST", body: { leaf: args?.leaf, signature: args?.signature, signing_pubkey: args?.signing_pubkey } }),
|
|
240
|
-
}],
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
case "wallet_lookup": {
|
|
244
|
-
const wallet = String(args?.wallet || "");
|
|
245
|
-
if (!wallet)
|
|
246
|
-
throw new Error("wallet required");
|
|
247
|
-
return { content: [{ type: "text", text: await api(`/v1/intel/get_facilitator_footprint?wallet=${wallet}`) }] };
|
|
248
|
-
}
|
|
249
|
-
default:
|
|
250
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
143
|
+
case "quick_trust": return { content: [{ type: "text", text: await api(`/v1/intel/quick/${String(a.wallet)}`, { paid: true }) }] };
|
|
144
|
+
case "full_trust": return { content: [{ type: "text", text: await api(`/v1/intel/trust/${String(a.wallet)}${a.seller_wallet ? `?seller_wallet=${a.seller_wallet}` : ""}`, { paid: true }) }] };
|
|
145
|
+
case "preflight": return { content: [{ type: "text", text: await api("/v1/intel/preflight", { method: "POST", body: { seller_wallet: a.seller_wallet, resource_name: a.resource_name || "MCP", price_usdc: a.price_usdc ?? 0.05 } }) }] };
|
|
146
|
+
case "verify_receipt": return { content: [{ type: "text", text: await api("/v1/receipts/verify", { method: "POST", body: { leaf: a.leaf, signature: a.signature, signing_pubkey: a.signing_pubkey } }) }] };
|
|
147
|
+
case "wallet_lookup": return { content: [{ type: "text", text: await api(`/v1/intel/get_facilitator_footprint?wallet=${String(a.wallet)}`) }] };
|
|
148
|
+
default: throw new Error(`Unknown tool: ${name}`);
|
|
251
149
|
}
|
|
252
150
|
});
|
|
253
|
-
// ── Start ─────────────────────────────────────────────────────────────────
|
|
254
151
|
const transport = new StdioServerTransport();
|
|
255
152
|
await server.connect(transport);
|
|
256
|
-
console.error(`TWZRD MCP
|
|
257
|
-
//# sourceMappingURL=index.js.map
|
|
153
|
+
console.error(`TWZRD MCP (Solana x402) — paid=${paidFetch ? "enabled" : "disabled"} caps: $${MAX_PER_CALL}/call $${MAX_TOTAL}/session`);
|
package/package.json
CHANGED
|
@@ -1,43 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "twzrd-mcp-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "TWZRD Trust API MCP server with Solana x402 auto-pay (official @x402 SDK, spend-capped, preflight-gated).",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"bin": { "twzrd-mcp": "./dist/index.js" },
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"dist",
|
|
13
|
-
"README.md"
|
|
14
|
-
],
|
|
8
|
+
"files": ["dist", "README.md"],
|
|
9
|
+
"engines": { "node": ">=20" },
|
|
10
|
+
"repository": { "type": "git", "url": "https://github.com/twzrd-sol/wzrd-final.git", "directory": "packages/twzrd-mcp-server" },
|
|
11
|
+
"homepage": "https://intel.twzrd.xyz",
|
|
12
|
+
"keywords": ["mcp", "x402", "solana", "agent", "trust", "twzrd", "reputation"],
|
|
15
13
|
"scripts": {
|
|
16
14
|
"build": "tsc",
|
|
17
|
-
"prepublishOnly": "tsc",
|
|
18
15
|
"typecheck": "tsc --noEmit",
|
|
19
|
-
"
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
20
17
|
},
|
|
21
|
-
"keywords": [
|
|
22
|
-
"x402",
|
|
23
|
-
"twzrd",
|
|
24
|
-
"mcp",
|
|
25
|
-
"trust",
|
|
26
|
-
"reputation"
|
|
27
|
-
],
|
|
28
|
-
"author": "TWZRD",
|
|
29
|
-
"license": "MIT",
|
|
30
18
|
"dependencies": {
|
|
31
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
32
|
-
"@
|
|
33
|
-
"@
|
|
34
|
-
"@x402/
|
|
35
|
-
"@
|
|
36
|
-
"bs58": "^6.0.0"
|
|
37
|
-
"viem": "^2.53.1",
|
|
38
|
-
"zod": "^4.4.3"
|
|
19
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
20
|
+
"@x402/core": "^2.17.0",
|
|
21
|
+
"@x402/svm": "^2.17.0",
|
|
22
|
+
"@x402/fetch": "^2.17.0",
|
|
23
|
+
"@solana/kit": "^5.1.0",
|
|
24
|
+
"bs58": "^6.0.0"
|
|
39
25
|
},
|
|
40
26
|
"devDependencies": {
|
|
41
|
-
"typescript": "^5.
|
|
42
|
-
|
|
27
|
+
"typescript": "^5.5.0",
|
|
28
|
+
"@types/node": "^22.0.0"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT"
|
|
43
31
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TWZRD MCP Server — auto-pay x402 wrapper for TWZRD's Trust API.
|
|
3
|
-
*
|
|
4
|
-
* Solana x402: the 402 challenge includes a sponsored feePayer + recentBlockhash.
|
|
5
|
-
* The MCP builds a USDC transfer, signs with the agent's Solana keypair, retries.
|
|
6
|
-
* Always runs free preflight before auto-paying (spend cap enforced).
|
|
7
|
-
*
|
|
8
|
-
* ENV:
|
|
9
|
-
* TWZRD_SOLANA_KEYPAIR — Solana keypair JSON array (from solana config)
|
|
10
|
-
* TWZRD_API_URL — Base URL (default: https://intel.twzrd.xyz)
|
|
11
|
-
* TWZRD_SPEND_CAP_USDC — Max USDC per call (default: 0.05)
|
|
12
|
-
* TWZRD_DAILY_CAP_USDC — Max USDC per day (default: 1.00)
|
|
13
|
-
*/
|
|
14
|
-
export {};
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|