@agenttrust-sdk/mcp 0.3.1 → 0.3.2

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 (51) hide show
  1. package/README.md +25 -3
  2. package/dist/chain.js +4 -2
  3. package/dist/chain.js.map +1 -1
  4. package/dist/config.d.ts +22 -2
  5. package/dist/config.js +165 -15
  6. package/dist/config.js.map +1 -1
  7. package/dist/embedded-docs/mcp/hosted-endpoint.mdx +1 -1
  8. package/dist/embedded-docs/mcp/install.mdx +12 -3
  9. package/dist/embedded-docs/mcp/tools.mdx +2 -2
  10. package/dist/embedded-docs/quickstart.mdx +83 -0
  11. package/dist/errors.d.ts +79 -0
  12. package/dist/errors.js +277 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/index.js +13 -6
  15. package/dist/index.js.map +1 -1
  16. package/dist/server.js +19 -16
  17. package/dist/server.js.map +1 -1
  18. package/dist/tools/discovery/docs.d.ts +6 -0
  19. package/dist/tools/discovery/docs.js +13 -1
  20. package/dist/tools/discovery/docs.js.map +1 -1
  21. package/dist/tools/discovery/facilitator-walkthrough.d.ts +5 -0
  22. package/dist/tools/discovery/facilitator-walkthrough.js +13 -2
  23. package/dist/tools/discovery/facilitator-walkthrough.js.map +1 -1
  24. package/dist/tools/index.js +2 -0
  25. package/dist/tools/index.js.map +1 -1
  26. package/dist/tools/read/get-quantu-reputation.d.ts +23 -3
  27. package/dist/tools/read/get-quantu-reputation.js +32 -7
  28. package/dist/tools/read/get-quantu-reputation.js.map +1 -1
  29. package/dist/tools/read/simulate-payment.js +13 -13
  30. package/dist/tools/read/simulate-payment.js.map +1 -1
  31. package/dist/tools/write/emit-feedback.d.ts +4 -4
  32. package/dist/tools/write/emit-feedback.js +55 -12
  33. package/dist/tools/write/emit-feedback.js.map +1 -1
  34. package/dist/tools/write/init-authority.d.ts +43 -0
  35. package/dist/tools/write/init-authority.js +92 -0
  36. package/dist/tools/write/init-authority.js.map +1 -0
  37. package/dist/tools/write/init-policy.d.ts +23 -3
  38. package/dist/tools/write/init-policy.js +92 -15
  39. package/dist/tools/write/init-policy.js.map +1 -1
  40. package/dist/tools/write/request-validation.js +6 -2
  41. package/dist/tools/write/request-validation.js.map +1 -1
  42. package/dist/tools/write/respond-to-validation.d.ts +3 -2
  43. package/dist/tools/write/respond-to-validation.js +10 -7
  44. package/dist/tools/write/respond-to-validation.js.map +1 -1
  45. package/dist/tools/write/set-killswitch.d.ts +10 -0
  46. package/dist/tools/write/set-killswitch.js +63 -14
  47. package/dist/tools/write/set-killswitch.js.map +1 -1
  48. package/package.json +2 -2
  49. package/dist/embedded-docs/getting-started/architecture-overview.mdx +0 -85
  50. package/dist/embedded-docs/reference/formal-verification.mdx +0 -19
  51. package/dist/embedded-docs/sdk/atomic-tx-invariant.mdx +0 -37
package/README.md CHANGED
@@ -24,7 +24,7 @@ deployed AgentTrust programs through natural language.
24
24
  | `agenttrust_list_facilitators` | Active facilitator adapters (Pay.sh / Dexter / atxp / MCPay) + ship status. |
25
25
  | `agenttrust_demo_state` | Three pre-warmed devnet counterparties used by `examples/pay-sh-demo`. |
26
26
 
27
- ### Write (require `KEYPAIR_B58` env)
27
+ ### Write (require a signer: `KEYPAIR_B58` / `KEYPAIR_PATH` / Solana CLI default)
28
28
 
29
29
  | Tool | Effect |
30
30
  |--|--|
@@ -105,7 +105,17 @@ The script edits the Claude Desktop config in place. It backs up the
105
105
  prior config to `claude_desktop_config.json.bak.<timestamp>` so you can
106
106
  revert if needed.
107
107
 
108
- For write tools, add `KEYPAIR_B58` to the `env` block:
108
+ For write tools, supply a signer via any one of the four steps in the
109
+ resolution chain (first match wins):
110
+
111
+ 1. `KEYPAIR_B58` — base58-encoded 64-byte secret key
112
+ 2. `KEYPAIR_PATH` — absolute path to a JSON-array secret-key file (Solana CLI native format)
113
+ 3. `~/.config/solana/id.json` — Solana CLI's default keypair location, picked up automatically
114
+ 4. `SOLANA_KEYPAIR_PATH` — alt path env some tooling sets
115
+
116
+ If you already use `solana-keygen` locally, no env is needed — the
117
+ default `~/.config/solana/id.json` is detected automatically. To set an
118
+ explicit signer in the Claude Desktop config block:
109
119
 
110
120
  ```json
111
121
  "env": {
@@ -115,6 +125,16 @@ For write tools, add `KEYPAIR_B58` to the `env` block:
115
125
  }
116
126
  ```
117
127
 
128
+ Or point at a file instead of inlining the secret:
129
+
130
+ ```json
131
+ "env": {
132
+ "RPC_URL": "https://api.devnet.solana.com",
133
+ "NETWORK": "solana-devnet",
134
+ "KEYPAIR_PATH": "/Users/you/.config/solana/id.json"
135
+ }
136
+ ```
137
+
118
138
  ### Cursor
119
139
 
120
140
  Cursor's MCP config lives at `~/.cursor/mcp.json` (or per-workspace
@@ -176,7 +196,9 @@ The server listens on `http://0.0.0.0:8765`. Behind any reverse proxy
176
196
  |--|--|--|
177
197
  | `RPC_URL` | devnet RPC | Solana RPC endpoint. |
178
198
  | `NETWORK` | `solana-devnet` | `solana-devnet` or `solana-mainnet`. Drives Quantu program IDs. |
179
- | `KEYPAIR_B58` | unset | Base58-encoded 64-byte secret key. Required for write tools. |
199
+ | `KEYPAIR_B58` | unset | Base58-encoded 64-byte secret key. First step in the signer-resolution chain. |
200
+ | `KEYPAIR_PATH` | unset | Path to a JSON-array secret-key file (Solana CLI native format). Second step in the signer-resolution chain. |
201
+ | `SOLANA_KEYPAIR_PATH` | unset | Alt path env some tooling sets. Fourth step in the signer-resolution chain. |
180
202
  | `MCP_TRANSPORT` | `stdio` | `stdio` or `http`. |
181
203
  | `MCP_HTTP_PORT` | `8765` | Port for HTTP transport. |
182
204
  | `POLICY_VAULT_PROGRAM_ID` | devnet ID | Override the policy_vault program ID. |
package/dist/chain.js CHANGED
@@ -109,8 +109,10 @@ class ChainClient {
109
109
  }
110
110
  requireSigner() {
111
111
  if (!this.cfg.signer) {
112
- throw new Error("This tool requires KEYPAIR_B58 in the environment. " +
113
- "Set it to a base58-encoded 64-byte secret key, then restart the MCP server.");
112
+ throw new Error("This tool requires a signer. Set one of: KEYPAIR_B58 (base58 of a " +
113
+ "64-byte secret key), KEYPAIR_PATH (absolute path to a Solana CLI " +
114
+ "keypair JSON), or run `solana-keygen new` so ~/.config/solana/id.json " +
115
+ "exists. Then restart the MCP server.");
114
116
  }
115
117
  return this.cfg.signer;
116
118
  }
package/dist/chain.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  /**
2
2
  * Env parsing for the AgentTrust MCP server.
3
3
  *
4
- * Read tools work without any env. Write tools require `KEYPAIR_B58`.
4
+ * Read tools work without any env. Write tools require a signer
5
+ * keypair, resolved through a four-step fallback chain (see `readSigner`):
6
+ * 1. `KEYPAIR_B58` — base58 of the 64-byte secret key
7
+ * 2. `KEYPAIR_PATH` — JSON-array secret-key file (Solana CLI native)
8
+ * 3. `~/.config/solana/id.json` — Solana CLI's default keypair location
9
+ * 4. `SOLANA_KEYPAIR_PATH` — alt name some tooling sets
10
+ *
5
11
  * The HTTP transport requires `MCP_HTTP_PORT` (else stdio is the default).
6
12
  *
7
13
  * Defaults are biased toward the local-developer / Claude Desktop case:
@@ -19,15 +25,29 @@ export interface AgentTrustConfig {
19
25
  * shape rather than a sibling field on AgentTrustConfig. */
20
26
  readonly programs: ProgramIds;
21
27
  readonly quantu: QuantuProgramIds;
22
- /** Optional signer keypair. Loaded from KEYPAIR_B58. Write tools require this. */
28
+ /** Optional signer keypair. Resolved via the layered fallback chain
29
+ * documented on `readSigner`. Write tools require this. */
23
30
  readonly signer?: Keypair;
24
31
  /** Transport selection. */
25
32
  readonly transport: "stdio" | "http";
26
33
  /** HTTP transport port (only used when transport === "http"). */
27
34
  readonly httpPort: number;
35
+ /** HTTP transport bind host (only used when transport === "http").
36
+ * Defaults to 127.0.0.1 so a laptop developer doesn't expose the
37
+ * server on the LAN. Production-style deploys (Fly, Vercel) set
38
+ * `MCP_HTTP_HOST=0.0.0.0` explicitly. */
39
+ readonly httpHost: string;
28
40
  /** Optional default facilitator name to surface in tool replies. */
29
41
  readonly defaultFacilitator?: string;
30
42
  }
43
+ /**
44
+ * Decode a JSON-array secret-key file (Solana CLI's native format) into
45
+ * a Keypair. Exported for direct testing.
46
+ *
47
+ * Throws with a clear, source-named error when the file is unreadable,
48
+ * not valid JSON, not an array of numbers, or the wrong byte length.
49
+ */
50
+ export declare function readKeypairFile(filePath: string): Keypair;
31
51
  export declare function loadConfig(): AgentTrustConfig;
32
52
  /**
33
53
  * Build a Solana Explorer URL for a tx signature or account, scoped to
package/dist/config.js CHANGED
@@ -2,18 +2,61 @@
2
2
  /**
3
3
  * Env parsing for the AgentTrust MCP server.
4
4
  *
5
- * Read tools work without any env. Write tools require `KEYPAIR_B58`.
5
+ * Read tools work without any env. Write tools require a signer
6
+ * keypair, resolved through a four-step fallback chain (see `readSigner`):
7
+ * 1. `KEYPAIR_B58` — base58 of the 64-byte secret key
8
+ * 2. `KEYPAIR_PATH` — JSON-array secret-key file (Solana CLI native)
9
+ * 3. `~/.config/solana/id.json` — Solana CLI's default keypair location
10
+ * 4. `SOLANA_KEYPAIR_PATH` — alt name some tooling sets
11
+ *
6
12
  * The HTTP transport requires `MCP_HTTP_PORT` (else stdio is the default).
7
13
  *
8
14
  * Defaults are biased toward the local-developer / Claude Desktop case:
9
15
  * devnet RPC, devnet program IDs, no signer required.
10
16
  */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
11
50
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
51
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
52
  };
14
53
  Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.readKeypairFile = readKeypairFile;
15
55
  exports.loadConfig = loadConfig;
16
56
  exports.explorerUrl = explorerUrl;
57
+ const fs = __importStar(require("fs"));
58
+ const os = __importStar(require("os"));
59
+ const path = __importStar(require("path"));
17
60
  const web3_js_1 = require("@solana/web3.js");
18
61
  const bs58_1 = __importDefault(require("bs58"));
19
62
  const trustgate_1 = require("@agenttrust-sdk/trustgate");
@@ -26,34 +69,140 @@ function readNetwork() {
26
69
  }
27
70
  return "solana-devnet";
28
71
  }
29
- function readSigner() {
30
- const raw = process.env.KEYPAIR_B58?.trim();
31
- if (!raw)
32
- return undefined;
72
+ /**
73
+ * Decode a JSON-array secret-key file (Solana CLI's native format) into
74
+ * a Keypair. Exported for direct testing.
75
+ *
76
+ * Throws with a clear, source-named error when the file is unreadable,
77
+ * not valid JSON, not an array of numbers, or the wrong byte length.
78
+ */
79
+ function readKeypairFile(filePath) {
80
+ let raw;
81
+ try {
82
+ raw = fs.readFileSync(filePath, "utf8");
83
+ }
84
+ catch (err) {
85
+ throw new Error(`keypair file at ${filePath} is unreadable: ${err.message}`);
86
+ }
87
+ let parsed;
88
+ try {
89
+ parsed = JSON.parse(raw);
90
+ }
91
+ catch (err) {
92
+ throw new Error(`keypair file at ${filePath} is not valid JSON: ${err.message}`);
93
+ }
94
+ if (!Array.isArray(parsed) || !parsed.every((n) => typeof n === "number")) {
95
+ throw new Error(`keypair file at ${filePath} must be a JSON array of numbers (Solana CLI format)`);
96
+ }
97
+ const bytes = Uint8Array.from(parsed);
98
+ if (bytes.length !== 64) {
99
+ throw new Error(`keypair file at ${filePath}: expected 64-byte secret key, got ${bytes.length} bytes`);
100
+ }
33
101
  try {
34
- const bytes = bs58_1.default.decode(raw);
35
102
  return web3_js_1.Keypair.fromSecretKey(bytes);
36
103
  }
37
104
  catch (err) {
38
- throw new Error(`KEYPAIR_B58 is set but failed to decode: ${err.message}. ` +
39
- `Expected base58-encoded 64-byte secret key.`);
105
+ throw new Error(`keypair file at ${filePath} could not be loaded as a Solana keypair: ${err.message}`);
106
+ }
107
+ }
108
+ /**
109
+ * Layered signer detection. Tries, in order:
110
+ * 1. `KEYPAIR_B58` (base58 of 64-byte secret key)
111
+ * 2. `KEYPAIR_PATH` (JSON-array secret-key file)
112
+ * 3. `~/.config/solana/id.json` (Solana CLI's default keypair location)
113
+ * 4. `SOLANA_KEYPAIR_PATH` (alt name some tooling sets)
114
+ *
115
+ * Explicit env vars win over the well-known default. If an env var is
116
+ * SET but unparseable, we throw a clear error naming the source. If
117
+ * unset, we fall through silently. If none of the four is usable we
118
+ * return undefined — the read-only mode for no-auth read tools.
119
+ */
120
+ function readSigner() {
121
+ const b58 = process.env.KEYPAIR_B58?.trim();
122
+ if (b58) {
123
+ let bytes;
124
+ try {
125
+ bytes = bs58_1.default.decode(b58);
126
+ }
127
+ catch (err) {
128
+ throw new Error(`KEYPAIR_B58 is set but failed to decode as base58: ${err.message}. ` +
129
+ `Expected base58-encoded 64-byte secret key.`);
130
+ }
131
+ if (bytes.length !== 64) {
132
+ throw new Error(`KEYPAIR_B58 decoded to ${bytes.length} bytes; expected 64-byte secret key. ` +
133
+ `A 32-byte value is the public-key half only — Solana keypair files contain both halves.`);
134
+ }
135
+ try {
136
+ return web3_js_1.Keypair.fromSecretKey(bytes);
137
+ }
138
+ catch (err) {
139
+ throw new Error(`KEYPAIR_B58 decoded to 64 bytes but Solana rejected it: ${err.message}`);
140
+ }
40
141
  }
142
+ const explicitPath = process.env.KEYPAIR_PATH?.trim();
143
+ if (explicitPath) {
144
+ try {
145
+ return readKeypairFile(explicitPath);
146
+ }
147
+ catch (err) {
148
+ throw new Error(`KEYPAIR_PATH points at ${explicitPath} but the file is unreadable: ${err.message}`);
149
+ }
150
+ }
151
+ const altPath = process.env.SOLANA_KEYPAIR_PATH?.trim();
152
+ if (altPath) {
153
+ try {
154
+ return readKeypairFile(altPath);
155
+ }
156
+ catch (err) {
157
+ throw new Error(`SOLANA_KEYPAIR_PATH points at ${altPath} but the file is unreadable: ${err.message}`);
158
+ }
159
+ }
160
+ const defaultPath = path.join(os.homedir(), ".config", "solana", "id.json");
161
+ if (fs.existsSync(defaultPath)) {
162
+ try {
163
+ return readKeypairFile(defaultPath);
164
+ }
165
+ catch (err) {
166
+ throw new Error(`Solana CLI default keypair at ${defaultPath} is unusable: ${err.message}`);
167
+ }
168
+ }
169
+ return undefined;
41
170
  }
42
171
  function readTransport() {
43
172
  const raw = (process.env.MCP_TRANSPORT ?? "stdio").trim().toLowerCase();
44
173
  const port = Number.parseInt(process.env.MCP_HTTP_PORT ?? "8765", 10);
174
+ // Default bind 127.0.0.1 — a local-laptop user starting `MCP_TRANSPORT=http`
175
+ // should NOT expose the server on the LAN by accident. Hosted deploys
176
+ // (Fly, Vercel) explicitly set MCP_HTTP_HOST=0.0.0.0.
177
+ const host = (process.env.MCP_HTTP_HOST ?? "127.0.0.1").trim();
45
178
  if (raw === "http" || raw === "sse")
46
- return { transport: "http", httpPort: port };
47
- return { transport: "stdio", httpPort: port };
179
+ return { transport: "http", httpPort: port, httpHost: host };
180
+ return { transport: "stdio", httpPort: port, httpHost: host };
48
181
  }
49
182
  function loadConfig() {
50
183
  const network = readNetwork();
51
184
  const rpcUrl = (process.env.RPC_URL ?? (network === "solana-mainnet" ? MAINNET_RPC : DEVNET_RPC)).trim();
52
- const { transport, httpPort } = readTransport();
53
- // Devnet ships fully-deployed AgentTrust + Quantu. Mainnet ships
54
- // Quantu only (per CLAUDE.md). When mainnet is selected the AgentTrust
55
- // program IDs default to devnet placeholders — overridable via env once
56
- // mainnet deployment lands.
185
+ try {
186
+ // eslint-disable-next-line no-new
187
+ new URL(rpcUrl);
188
+ }
189
+ catch (err) {
190
+ throw new Error(`RPC_URL is not a valid URL: ${err.message}. Got: ${rpcUrl}`);
191
+ }
192
+ const { transport, httpPort, httpHost } = readTransport();
193
+ // AgentTrust programs ship on devnet. Quantu ships on both devnet and
194
+ // mainnet. When mainnet is selected the AgentTrust program IDs must be
195
+ // overridden via env — otherwise we'd silently point at devnet pubkeys
196
+ // on a mainnet RPC (every read returns `exists: false`, every write
197
+ // throws cryptic Anchor errors).
198
+ const policyVaultEnv = process.env.POLICY_VAULT_PROGRAM_ID?.trim();
199
+ const trustGateEnv = process.env.TRUSTGATE_PROGRAM_ID?.trim();
200
+ const validationRegistryEnv = process.env.VALIDATION_REGISTRY_PROGRAM_ID?.trim();
201
+ if (network === "solana-mainnet" && !policyVaultEnv && !trustGateEnv && !validationRegistryEnv) {
202
+ throw new Error("AgentTrust programs are not yet deployed on mainnet. " +
203
+ "Set explicit POLICY_VAULT_PROGRAM_ID, TRUSTGATE_PROGRAM_ID, and " +
204
+ "VALIDATION_REGISTRY_PROGRAM_ID env vars, or use NETWORK=solana-devnet (default).");
205
+ }
57
206
  const programs = {
58
207
  policyVault: parsePubkeyEnv("POLICY_VAULT_PROGRAM_ID", trustgate_1.DEFAULT_DEVNET_PROGRAM_IDS.policyVault),
59
208
  trustGate: parsePubkeyEnv("TRUSTGATE_PROGRAM_ID", trustgate_1.DEFAULT_DEVNET_PROGRAM_IDS.trustGate),
@@ -71,6 +220,7 @@ function loadConfig() {
71
220
  signer: readSigner(),
72
221
  transport,
73
222
  httpPort,
223
+ httpHost,
74
224
  defaultFacilitator: process.env.MCP_DEFAULT_FACILITATOR?.trim() || undefined,
75
225
  };
76
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -134,7 +134,7 @@ Phase M flagged this as Bug #4. Fixing it requires restructuring the transport i
134
134
 
135
135
  ## Auth
136
136
 
137
- The hosted endpoint has no authentication for read tools. Write tools require a `KEYPAIR_B58` environment variable on the *server*; the hosted instance doesn't have one set, so write tools surface the standard `signer required` error.
137
+ The hosted endpoint has no authentication for read tools. Write tools require a signer on the *server* (resolved via `KEYPAIR_B58` / `KEYPAIR_PATH` / Solana CLI default); the hosted instance has none of these set, so write tools surface the standard `signer required` error.
138
138
 
139
139
  For write-tool access from a hosted MCP context, run your own instance with your own keypair:
140
140
 
@@ -96,7 +96,14 @@ Behind any reverse proxy (Caddy, nginx, Vercel, Fly.io) this surfaces as a publi
96
96
 
97
97
  ## Write tools — adding a keypair
98
98
 
99
- The five write tools (`agenttrust_init_policy`, `agenttrust_set_killswitch`, `agenttrust_request_validation`, `agenttrust_respond_to_validation`, `agenttrust_emit_feedback`) require a signing keypair. Add `KEYPAIR_B58` to the `env` block:
99
+ The five write tools (`agenttrust_init_policy`, `agenttrust_set_killswitch`, `agenttrust_request_validation`, `agenttrust_respond_to_validation`, `agenttrust_emit_feedback`) require a signing keypair. The MCP server resolves a signer through a four-step chain (first match wins):
100
+
101
+ 1. `KEYPAIR_B58` — base58-encoded 64-byte secret key
102
+ 2. `KEYPAIR_PATH` — absolute path to a JSON-array secret-key file (Solana CLI native format)
103
+ 3. `~/.config/solana/id.json` — Solana CLI's default keypair location, picked up automatically
104
+ 4. `SOLANA_KEYPAIR_PATH` — alt path env some tooling sets
105
+
106
+ If you already use `solana-keygen` locally, no env is needed. To set an explicit signer in the Claude Desktop config, add `KEYPAIR_B58` to the `env` block:
100
107
 
101
108
  ```json
102
109
  {
@@ -114,7 +121,7 @@ The five write tools (`agenttrust_init_policy`, `agenttrust_set_killswitch`, `ag
114
121
  }
115
122
  ```
116
123
 
117
- Without `KEYPAIR_B58`, write tools surface a clear `signer required` error. Read and discovery tools never need it.
124
+ Without any usable signer, write tools surface a clear `signer required` error. Read and discovery tools never need one.
118
125
 
119
126
  Convert a Solana CLI keypair to base58:
120
127
 
@@ -135,7 +142,9 @@ cat ~/.config/solana/id.json | jq -r '.[0:64]' | npx bs58 encode
135
142
  |---|---|---|
136
143
  | `RPC_URL` | devnet RPC | Solana RPC endpoint |
137
144
  | `NETWORK` | `solana-devnet` | `solana-devnet` or `solana-mainnet`. Drives Quantu program IDs. |
138
- | `KEYPAIR_B58` | unset | Base58-encoded 64-byte secret key. Required for write tools. |
145
+ | `KEYPAIR_B58` | unset | Base58-encoded 64-byte secret key. First step in the signer-resolution chain. |
146
+ | `KEYPAIR_PATH` | unset | Path to a JSON-array secret-key file (Solana CLI native format). Second step in the signer-resolution chain. |
147
+ | `SOLANA_KEYPAIR_PATH` | unset | Alt path env some tooling sets. Fourth step in the signer-resolution chain. |
139
148
  | `MCP_TRANSPORT` | `stdio` | `stdio` or `http` |
140
149
  | `MCP_HTTP_PORT` | `8765` | Port for HTTP transport |
141
150
  | `POLICY_VAULT_PROGRAM_ID` | devnet ID | Override `policy_vault` program ID |
@@ -90,7 +90,7 @@ Returns the three pre-warmed devnet counterparties used by `examples/pay-sh-demo
90
90
 
91
91
  The demo state is bundled in the tarball as of 0.2.3 — the published package doesn't need a separate state file.
92
92
 
93
- ## Write (5 tools — require `KEYPAIR_B58`)
93
+ ## Write (5 tools — require a signer: `KEYPAIR_B58` / `KEYPAIR_PATH` / Solana CLI default)
94
94
 
95
95
  | Tool | Effect |
96
96
  |---|---|
@@ -114,7 +114,7 @@ Required args: `subject_asset`, `claim_uri_hash_hex`, `deadline_slot`. The capab
114
114
 
115
115
  ### `agenttrust_respond_to_validation`
116
116
 
117
- Required args: `subject_asset`, `claim_payload_hash_hex`, `claim_uri_hash_hex`, `expires_at_slot`. The signer (the keypair behind `KEYPAIR_B58`) is the attestor. v1 trust model: tx signature authenticates; v1.1+ adds Ed25519 sysvar verify.
117
+ Required args: `subject_asset`, `claim_payload_hash_hex`, `claim_uri_hash_hex`, `expires_at_slot`. The signer (resolved via the chain `KEYPAIR_B58` / `KEYPAIR_PATH` / Solana CLI default) is the attestor. v1 trust model: tx signature authenticates; v1.1+ adds Ed25519 sysvar verify.
118
118
 
119
119
  ### `agenttrust_emit_feedback`
120
120
 
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: Quickstart
3
+ description: AgentTrust in 60 seconds. Install the MCP server into Claude Desktop, create a policy, run a gate-decision simulation. No clone, no Anchor build.
4
+ ---
5
+
6
+ Sixty seconds, three steps, one MCP server. By the end you have a real `PolicyAccount` PDA on devnet and a decoded `gate_payment` decision in your chat client. No clone, no Anchor build, no local validator.
7
+
8
+ ## 1. Install the MCP server into Claude Desktop
9
+
10
+ Drop this block into `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, or `%APPDATA%\Claude\claude_desktop_config.json` on Windows:
11
+
12
+ ```json
13
+ {
14
+ "mcpServers": {
15
+ "agenttrust": {
16
+ "command": "npx",
17
+ "args": ["-y", "@agenttrust-sdk/mcp"],
18
+ "env": {
19
+ "RPC_URL": "https://api.devnet.solana.com",
20
+ "NETWORK": "solana-devnet"
21
+ }
22
+ }
23
+ }
24
+ }
25
+ ```
26
+
27
+ Restart Claude Desktop. Eighteen tools are now wired in. Ten read-only tools work immediately on devnet with zero credentials. The five write tools resolve a signer through the chain `KEYPAIR_B58` then `KEYPAIR_PATH` then `~/.config/solana/id.json` then `SOLANA_KEYPAIR_PATH` and use the first one that parses. If you already use `solana-keygen`, the default `id.json` is picked up automatically and no env var is needed.
28
+
29
+ ## 2. Create a policy
30
+
31
+ Ask Claude Desktop, in plain English:
32
+
33
+ > Use agenttrust_init_policy to create policy 1 for my agent. Enable Spending (bitmask 2) with a per-transaction max of 1 USDC.
34
+
35
+ The `agenttrust_init_policy` tool is self-healing. If your agent's `PolicyAuthority` PDA does not yet exist on devnet, the tool prepends an `init_authority` instruction (single member = your signer, threshold = 1) and submits both in one atomic transaction. You never see Anchor error 3012. Spending caps also default sanely: when at least one cap is set, unspecified peer caps default to the max of the specified caps rather than zero, so v1 policies (immutable post-init) cannot accidentally hard-deny every payment.
36
+
37
+ ```text
38
+ Output:
39
+ txSignature: 4n8…ZxR
40
+ explorerTxUrl: https://explorer.solana.com/tx/4n8…ZxR?cluster=devnet
41
+ policyPda: 9aF…tNm
42
+ effectiveSpending: { perTxMax: "1000000", dailyMax: "1000000", weeklyMax: "1000000" }
43
+ selfHealed: true
44
+ healedSteps: ["init_authority"]
45
+ ```
46
+
47
+ Open the `explorerTxUrl` to see the on-chain transaction. The `policyPda` is the `PolicyAccount` PDA the gate evaluates against on every payment.
48
+
49
+ ## 3. Run a gate-decision simulation
50
+
51
+ Now ask:
52
+
53
+ > Use agenttrust_simulate_payment to gate a 5-USDC payment from the tier-3 demo agent to the tier-0 demo agent against policy 1. What does the gate decide?
54
+
55
+ `agenttrust_simulate_payment` is read-only. It calls the on-chain `gate_payment` instruction in simulate mode and decodes the `GateDecision` return value — `Allow`, `Deny` with a stable reason code (1 through 15), or `RequireValidation` with the 32-byte capability hash. The same call path the Express service's `POST /verify` route uses for the real x402 v2 challenge.
56
+
57
+ ```text
58
+ Output:
59
+ kind: "Deny"
60
+ reasonCode: 5
61
+ reasonName: "SpendingPerTxExceeded"
62
+ ```
63
+
64
+ The gate denied the payment because 5 USDC exceeds the 1 USDC per-tx cap you set in step 2. Drop the amount to 0.5 USDC and ask again. The decision flips to `Allow`. You have just exercised the full PolicyVault decision path on devnet from a chat prompt.
65
+
66
+ ## Where to next
67
+
68
+ Sixty seconds is enough to feel the shape. The deeper paths:
69
+
70
+ <Cards>
71
+ <Card title="The three live paths" href="/getting-started/quickstart">
72
+ Hit the live x402 demo, mount the SDK middleware on Express, wire the MCP server, all against the hosted devnet build.
73
+ </Card>
74
+ <Card title="MCP server" href="/mcp">
75
+ Eighteen tools, four resources, three guided prompts. Full install reference at /mcp/install.
76
+ </Card>
77
+ <Card title="@agenttrust-sdk/trustgate" href="/sdk">
78
+ The TypeScript SDK every facilitator pulls in. Express middleware, client helpers, the atomicity guard, the full ValidationRegistry instruction builder set.
79
+ </Card>
80
+ <Card title="Architecture" href="/architecture">
81
+ How the three Anchor programs compose into one settlement path. The atomic-tx invariant. The FacilitatorAdapter pattern.
82
+ </Card>
83
+ </Cards>
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Structured error envelopes for MCP `tools/call` responses (F-013).
3
+ *
4
+ * Before this module, every thrown handler error was flattened to
5
+ * `{ isError: true, content: [{type:"text",text:"tool error: <msg>"}] }`
6
+ * — opaque to LLM agents and useless for automated recovery.
7
+ *
8
+ * Now `classifyError()` inspects the thrown value and produces a
9
+ * `ToolError` with:
10
+ * - `errorCode`: one of a fixed enum so callers can branch on it.
11
+ * - `message`: short human description (truncated original).
12
+ * - `hint`: single sentence of remediation guidance.
13
+ * - `cause`: truncated original message (<=500 chars) for debugging.
14
+ *
15
+ * `renderToolError()` serialises that envelope into the MCP
16
+ * `CallToolResult` shape. The envelope is JSON-encoded into
17
+ * `content[0].text` (so transports that only surface text still get a
18
+ * parseable payload), AND mirrored into `structuredContent` (the MCP
19
+ * spec field for machine-readable tool output, supported by the
20
+ * `@modelcontextprotocol/sdk` schema we already depend on).
21
+ *
22
+ * Tool handlers do NOT need to change. They still:
23
+ * - `throw new Error("...")` for ad-hoc failures
24
+ * - `throw new ZodError(...)` (implicitly, via `schema.parse()`)
25
+ * - throw `AnchorError` / `SendTransactionError` (via `.rpc()` calls)
26
+ * The classifier sniffs the thrown value (name, message prefix,
27
+ * `instanceof` where the constructor is in scope) and maps it.
28
+ *
29
+ * Note for future contributors: callers reading `content[0].text` as a
30
+ * string will see a JSON object now, not a plain sentence. This is
31
+ * intentional — `isError: true` is preserved so existing transports
32
+ * still treat it as a failure. If you add a new tool that throws a
33
+ * specific subclass, extend `classifyError()` here rather than
34
+ * pattern-matching in `server.ts`.
35
+ */
36
+ /** Stable enum of error categories surfaced to MCP clients. */
37
+ export type ToolErrorCode = "auth_required" | "input_invalid" | "rpc_failure" | "chain_error" | "not_found" | "internal";
38
+ export interface ToolError {
39
+ errorCode: ToolErrorCode;
40
+ message: string;
41
+ hint?: string;
42
+ cause?: string;
43
+ }
44
+ /**
45
+ * Classify an unknown thrown value into a structured `ToolError`.
46
+ *
47
+ * @param err The thrown value from a tool handler (or Zod parse).
48
+ * @param toolName Optional — the MCP tool that was being invoked. When
49
+ * supplied, surfaces in the `auth_required` hint so the
50
+ * LLM agent knows which call to retry.
51
+ */
52
+ export declare function classifyError(err: unknown, toolName?: string): ToolError;
53
+ /**
54
+ * Build the MCP `CallToolResult` envelope for a classified error.
55
+ *
56
+ * Returns the canonical shape:
57
+ * {
58
+ * isError: true,
59
+ * content: [{ type: "text", text: "<json string>" }],
60
+ * structuredContent: <ToolError as object>
61
+ * }
62
+ *
63
+ * The JSON-in-text duplication is intentional: MCP clients that only
64
+ * surface text content (current Claude Desktop fallback path) still get
65
+ * a parseable payload, while spec-compliant clients pick up the
66
+ * structured field directly.
67
+ *
68
+ * The return type is `unknown` so callers don't need to import the SDK's
69
+ * private `CallToolResult` zod type — the server handler returns
70
+ * `Promise<{ ... }>` and TS infers the shape at the call site.
71
+ */
72
+ export declare function renderToolError(toolError: ToolError): {
73
+ isError: true;
74
+ content: Array<{
75
+ type: "text";
76
+ text: string;
77
+ }>;
78
+ structuredContent: Record<string, unknown>;
79
+ };