@agenttrust-sdk/mcp 0.2.1 → 0.2.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.
- package/dist/embedded-data/devnet-attestor-trace.json +32 -0
- package/dist/embedded-data/devnet-chained-validation.json +52 -0
- package/dist/embedded-data/devnet-counterparties.json +53 -0
- package/dist/embedded-data/devnet-demo-policies.json +46 -0
- package/dist/embedded-data/devnet-namespaces.json +107 -0
- package/dist/embedded-data/devnet-smoke.json +24 -0
- package/dist/embedded-docs/getting-started/architecture-overview.mdx +85 -0
- package/dist/embedded-docs/getting-started/quickstart.mdx +100 -0
- package/dist/embedded-docs/index.mdx +64 -0
- package/dist/embedded-docs/integration-guides/capability-namespaces.mdx +15 -0
- package/dist/embedded-docs/integration-guides/custom-attestor.mdx +15 -0
- package/dist/embedded-docs/integration-guides/facilitator-adapters.mdx +85 -0
- package/dist/embedded-docs/integration-guides/pay-sh-adapter.mdx +110 -0
- package/dist/embedded-docs/integration-guides/x402-facilitator.mdx +79 -0
- package/dist/embedded-docs/programs/policy-vault/counterparty-tier-policy.mdx +15 -0
- package/dist/embedded-docs/programs/policy-vault/index.mdx +68 -0
- package/dist/embedded-docs/programs/policy-vault/kill-switch-policy.mdx +15 -0
- package/dist/embedded-docs/programs/policy-vault/require-validation-policy.mdx +15 -0
- package/dist/embedded-docs/programs/policy-vault/spending-policy.mdx +15 -0
- package/dist/embedded-docs/programs/policy-vault/velocity-policy.mdx +15 -0
- package/dist/embedded-docs/programs/trustgate.mdx +53 -0
- package/dist/embedded-docs/programs/validation-registry.mdx +49 -0
- package/dist/embedded-docs/reference/byte-offset-reference.mdx +20 -0
- package/dist/embedded-docs/reference/changelog.mdx +19 -0
- package/dist/embedded-docs/reference/devnet-program-ids.mdx +24 -0
- package/dist/embedded-docs/reference/discriminator-constants.mdx +16 -0
- package/dist/embedded-docs/reference/formal-verification.mdx +19 -0
- package/dist/embedded-docs/reference/mainnet-program-ids.mdx +16 -0
- package/dist/embedded-docs/reference/quantu-agent-registry.mdx +15 -0
- package/dist/embedded-docs/sdk/atomic-tx-invariant.mdx +37 -0
- package/dist/embedded-docs/sdk/gate-payment.mdx +22 -0
- package/dist/embedded-docs/sdk/index.mdx +73 -0
- package/dist/embedded-docs/sdk/mount-trustgate.mdx +15 -0
- package/dist/embedded-examples/attestor-demo/README.md +100 -0
- package/dist/embedded-examples/pay-sh-demo/README.md +136 -0
- package/dist/embedded-examples/pay-sh-demo/src/deps-real.ts +150 -0
- package/dist/embedded-examples/pay-sh-demo/src/deps.ts +150 -0
- package/dist/embedded-examples/pay-sh-demo/src/index.ts +471 -0
- package/dist/embedded-examples/pay-sh-demo/src/middleware.ts +198 -0
- package/dist/embedded-examples/pay-sh-demo/src/policy.ts +247 -0
- package/dist/embedded-examples/pay-sh-demo/src/x402.ts +140 -0
- package/dist/index.js +73 -18
- package/dist/index.js.map +1 -1
- package/dist/resources/docs.js +68 -46
- package/dist/resources/docs.js.map +1 -1
- package/dist/server.js +6 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/discovery/docs.js +6 -0
- package/dist/tools/discovery/docs.js.map +1 -1
- package/dist/tools/discovery/facilitator-walkthrough.js +43 -18
- package/dist/tools/discovery/facilitator-walkthrough.js.map +1 -1
- package/dist/tools/read/demo-state.js +7 -4
- package/dist/tools/read/demo-state.js.map +1 -1
- package/dist/trustgate/server/src/facilitators/README.md +241 -0
- package/package.json +2 -2
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Adding a new facilitator adapter
|
|
2
|
+
|
|
3
|
+
This directory holds AgentTrust's facilitator-abstraction layer. Pay.sh is the
|
|
4
|
+
first concrete implementation; future facilitators (Dexter, atxp_ai, MCPay,
|
|
5
|
+
Latinum, Corbits, plus ones that don't exist yet) drop in here as one new
|
|
6
|
+
file each. **Routes, policy logic, and the registry stay untouched.**
|
|
7
|
+
|
|
8
|
+
If you can follow this doc end-to-end in under two hours and end up with a
|
|
9
|
+
new adapter that passes its unit tests, the architecture is doing its job.
|
|
10
|
+
If you can't, file a bug — that's the architecture failing.
|
|
11
|
+
|
|
12
|
+
## Mental model
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
HTTP request x402 facilitator API
|
|
16
|
+
│ POST /verify
|
|
17
|
+
▼ POST /settle
|
|
18
|
+
┌────────────────────────┐ │
|
|
19
|
+
│ routes/{verify, │ getActiveAdapter(req) │
|
|
20
|
+
│ settle}.ts ├─────────────────────────────► FacilitatorRegistry
|
|
21
|
+
└──────┬─────────────────┘ X-Facilitator header │
|
|
22
|
+
│ env TRUSTGATE_DEFAULT_FACILITATOR │
|
|
23
|
+
│ programmatic default │
|
|
24
|
+
▼ │
|
|
25
|
+
adapter.parseRequest(req) ◄───────────────────── one of:
|
|
26
|
+
│ │
|
|
27
|
+
▼ PaySh
|
|
28
|
+
simulateGatePayment / decide(ctx) Dexter (stub)
|
|
29
|
+
│ Atxp (stub)
|
|
30
|
+
▼ McPay (stub)
|
|
31
|
+
adapter.formatChallenge(decision, ctx) <new>
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
adapter.validatePaymentProof(proof, ctx) (settle only)
|
|
35
|
+
│
|
|
36
|
+
▼
|
|
37
|
+
adapter.emitFeedback(ctx, settlement) (settle only)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The interface contract (5 methods) lives in [`types.ts`](./types.ts). Every
|
|
41
|
+
adapter implements those 5 methods — nothing else. If you find yourself
|
|
42
|
+
adding a 6th method, propose an interface change via PR rather than
|
|
43
|
+
side-stepping in your adapter.
|
|
44
|
+
|
|
45
|
+
## Step-by-step
|
|
46
|
+
|
|
47
|
+
### 1. Read the wire format you're adapting to
|
|
48
|
+
|
|
49
|
+
Don't guess. Pay.sh's adapter is built from a careful read of
|
|
50
|
+
`/tmp/pay/rust/crates/core/src/server/payment.rs` and
|
|
51
|
+
`/tmp/pay/rust/crates/core/src/client/x402.rs`. Identify:
|
|
52
|
+
|
|
53
|
+
- Which HTTP headers carry the 402 challenge?
|
|
54
|
+
- Which header carries the proof on retry?
|
|
55
|
+
- What's the JSON body shape on /verify and /settle?
|
|
56
|
+
- How is the recipient encoded? Wallet pubkey or ATA?
|
|
57
|
+
- Is there a payment_id (32-byte) hint anywhere?
|
|
58
|
+
- What does the facilitator expect back on Allow vs Deny?
|
|
59
|
+
|
|
60
|
+
Document the answers in your adapter file's JSDoc header.
|
|
61
|
+
|
|
62
|
+
### 2. Define your adapter's request body Zod schema
|
|
63
|
+
|
|
64
|
+
Strict mode at the root, strict on AgentTrust-specific fields, passthrough
|
|
65
|
+
on framework-specific fields you don't need. The schema is the contract;
|
|
66
|
+
unknown fields fail loud rather than ride through silently.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// dexter/schemas.ts
|
|
70
|
+
import { z } from "zod";
|
|
71
|
+
import { PubkeyString, AmountString, AgentTrustExtraSchema } from "../pay-sh";
|
|
72
|
+
|
|
73
|
+
export const DexterBodySchema = z.object({
|
|
74
|
+
// Dexter-specific fields here
|
|
75
|
+
...
|
|
76
|
+
}).strict();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Reuse Pay.sh's `PubkeyString` / `AmountString` / `AgentTrustExtraSchema` —
|
|
80
|
+
they encode AgentTrust-wide invariants (u32 policyId, u64 amount).
|
|
81
|
+
|
|
82
|
+
### 3. Implement the 5-method `FacilitatorAdapter` class
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// dexter/index.ts
|
|
86
|
+
export class Dexter implements FacilitatorAdapter {
|
|
87
|
+
readonly name = "dexter";
|
|
88
|
+
readonly description = "Cascade Dexter — x402 facilitator";
|
|
89
|
+
readonly protocols = ["x402"] as const;
|
|
90
|
+
|
|
91
|
+
constructor(private readonly deps: DexterDeps) {}
|
|
92
|
+
|
|
93
|
+
async parseRequest(req: ExpressRequest): Promise<VerifyContext | null> {
|
|
94
|
+
const parsed = DexterBodySchema.safeParse(req.body);
|
|
95
|
+
if (!parsed.success) return null;
|
|
96
|
+
// translate parsed.data → VerifyContext
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
formatChallenge(decision: GateDecision, ctx: VerifyContext): ChallengeResponse {
|
|
100
|
+
// translate decision + ctx → wire-level challenge
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
formatSettlement(ctx: VerifyContext): SettlementResponse {
|
|
104
|
+
// produce the unsigned tx skeleton + facilitator metadata
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async validatePaymentProof(proof: unknown, ctx: VerifyContext): Promise<PaymentProofValidation> {
|
|
108
|
+
// verify proof shape (Zod), confirm on chain, cross-check vs ctx
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async emitFeedback(ctx: VerifyContext, settlement: ConfirmedSettlement): Promise<FeedbackEmissionResult> {
|
|
112
|
+
// delegate to deps.emitFeedbackCpi
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Constructor takes a `DexterDeps` interface — chain calls live there so the
|
|
118
|
+
adapter is testable without an Anchor provider. Mirror Pay.sh's
|
|
119
|
+
[`PayShDeps`](./pay-sh/index.ts) shape.
|
|
120
|
+
|
|
121
|
+
### 4. Register in `index.ts`
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
// facilitators/index.ts (existing barrel)
|
|
125
|
+
export { Dexter, type DexterDeps } from "./dexter";
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
That's the only change to existing code. Routes already dispatch via
|
|
129
|
+
`registry.getActiveAdapter(req)` — they pick up the new adapter
|
|
130
|
+
automatically as soon as something registers it.
|
|
131
|
+
|
|
132
|
+
### 5. Wire the production deps factory
|
|
133
|
+
|
|
134
|
+
In your application's boot code (e.g., the demo's `createDemoApp`, or a
|
|
135
|
+
production `startServer` configuration):
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { Dexter, FacilitatorRegistry } from "@agenttrust/trustgate-server";
|
|
139
|
+
|
|
140
|
+
const registry = new FacilitatorRegistry();
|
|
141
|
+
registry.register(new Dexter(makeDexterDeps({ rpcUrl, facilitatorKeypair, ... })));
|
|
142
|
+
registry.setDefault("dexter");
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The deps factory builds `validateOnChainTx`, `emitFeedbackCpi`, and any
|
|
146
|
+
other I/O the adapter needs. For Pay.sh's reference deps factory shape,
|
|
147
|
+
see [`pay-sh/index.ts`'s `PayShDeps`](./pay-sh/index.ts).
|
|
148
|
+
|
|
149
|
+
### 6. Add unit tests
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// test/dexter.test.ts
|
|
153
|
+
describe("Dexter.parseRequest", () => {
|
|
154
|
+
it("parses valid Dexter body", async () => { ... });
|
|
155
|
+
it("returns null on malformed proof", async () => { ... });
|
|
156
|
+
// ... mirror pay-sh.test.ts's coverage
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The existing [`pay-sh.test.ts`](../../test/pay-sh.test.ts) is the
|
|
161
|
+
template. 32 cases for Pay.sh; aim for similar coverage on each adapter.
|
|
162
|
+
|
|
163
|
+
### 7. (Optional) Add an integration demo
|
|
164
|
+
|
|
165
|
+
Drop a new `examples/<name>-demo/` next to `examples/pay-sh-demo/`,
|
|
166
|
+
mirroring its structure. The integration test spins the demo via
|
|
167
|
+
supertest — no real CLI required for CI.
|
|
168
|
+
|
|
169
|
+
### 8. (Optional) Stub adapters before full integration
|
|
170
|
+
|
|
171
|
+
Pay.sh, Dexter, atxp, and MCPay are all live full adapters today
|
|
172
|
+
(Phase D promotion). New facilitators that ship in stages can register
|
|
173
|
+
a placeholder first via the [`stubs/`](./stubs/) pattern:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
// stubs/your-facilitator.ts
|
|
177
|
+
import { NotImplementedAdapter } from "./_base";
|
|
178
|
+
export class YourFacilitator extends NotImplementedAdapter {
|
|
179
|
+
readonly name = "your-facilitator";
|
|
180
|
+
readonly description = "<short pitch — x402 facilitator stub>";
|
|
181
|
+
readonly protocols = ["x402"] as const;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Stub methods throw `NotImplementedError`; routes catch this and surface
|
|
186
|
+
501 with the adapter name. Callers know the integration is on the
|
|
187
|
+
roadmap, not absent by accident. The `agenttrust_list_facilitators`
|
|
188
|
+
MCP tool reports each adapter's status — full vs stub — so a consumer
|
|
189
|
+
can choose accordingly.
|
|
190
|
+
|
|
191
|
+
## Things to NOT do
|
|
192
|
+
|
|
193
|
+
- **Don't fork an existing facilitator's source code.** AgentTrust composes
|
|
194
|
+
by implementing the wire spec, not by depending on a vendor's internal
|
|
195
|
+
types. This keeps you decoupled from their version churn and lets a
|
|
196
|
+
single adapter speak multiple flavors.
|
|
197
|
+
|
|
198
|
+
- **Don't add facilitator-specific behavior to `routes/verify.ts` or
|
|
199
|
+
`routes/settle.ts`.** All quirks live in the adapter. If a route needs
|
|
200
|
+
a new generic capability, propose an interface change in `types.ts`.
|
|
201
|
+
|
|
202
|
+
- **Don't change the `FacilitatorAdapter` interface to fit one
|
|
203
|
+
adapter's quirks.** The interface is the contract every adapter signs.
|
|
204
|
+
Quirks live in the adapter's `parseRequest` / `formatChallenge`
|
|
205
|
+
implementation and in adapter-private helpers.
|
|
206
|
+
|
|
207
|
+
- **Don't import directly from a facilitator's npm package.** Read their
|
|
208
|
+
spec / source for context, then implement from spec. The adapter's
|
|
209
|
+
Zod schemas are the canonical source of truth for what's on the wire.
|
|
210
|
+
|
|
211
|
+
- **Don't skip the security pass** on `validatePaymentProof` and
|
|
212
|
+
`emitFeedback`. Those are the proof-of-payment surfaces — every adapter
|
|
213
|
+
needs:
|
|
214
|
+
- replay defense (sig ↔ paymentIdHash binding via `ReplayCache`)
|
|
215
|
+
- self-pay defense (transfer authority ≠ facilitator fee payer)
|
|
216
|
+
- amount + mint + recipient cross-check vs ctx
|
|
217
|
+
- idempotent feedback emission (catch "account already in use")
|
|
218
|
+
|
|
219
|
+
Pay.sh's [`pay-sh/proof-validator.ts`](./pay-sh/proof-validator.ts) and
|
|
220
|
+
[`pay-sh/feedback.ts`](./pay-sh/feedback.ts) are the template. Cargo-cult
|
|
221
|
+
these patterns; don't reinvent them.
|
|
222
|
+
|
|
223
|
+
## Reference implementations
|
|
224
|
+
|
|
225
|
+
| File | What it shows |
|
|
226
|
+
|--|--|
|
|
227
|
+
| [`pay-sh/index.ts`](./pay-sh/index.ts) | The 5-method class + deps DI |
|
|
228
|
+
| [`pay-sh/schemas.ts`](./pay-sh/schemas.ts) | Strict Zod schemas |
|
|
229
|
+
| [`pay-sh/proof-validator.ts`](./pay-sh/proof-validator.ts) | ReplayCache + crossCheck |
|
|
230
|
+
| [`pay-sh/feedback.ts`](./pay-sh/feedback.ts) | Idempotent emit_feedback retry |
|
|
231
|
+
| [`pay-sh/request-meta.ts`](./pay-sh/request-meta.ts) | Typed view of `rawRequestMeta` |
|
|
232
|
+
| [`mock.ts`](./mock.ts) | Pure in-memory adapter — LSP substitution check |
|
|
233
|
+
| [`stubs/_base.ts`](./stubs/_base.ts) | NotImplementedAdapter base class |
|
|
234
|
+
|
|
235
|
+
## Spec / playbook references
|
|
236
|
+
|
|
237
|
+
- `docs/plan/research/05-trustgate-x402-class.md` §A — locked x402 wire format
|
|
238
|
+
- `coinbase/x402/specs/transports-v2/http.md` — canonical x402 v2
|
|
239
|
+
- `coinbase/x402/specs/schemes/exact/scheme_exact_svm.md` — Solana exact scheme
|
|
240
|
+
- `programs/trustgate/src/instructions/emit_feedback.rs` — the on-chain CPI
|
|
241
|
+
signature your adapter ultimately calls
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agenttrust-sdk/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "MCP server for AgentTrust — query and call deployed Solana programs from Claude Desktop / Cursor / any MCP client",
|
|
5
5
|
"author": "AgentTrust Labs (https://agenttrust.tech)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"typescript": "^5.6.0"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
|
-
"build": "tsc && node -
|
|
63
|
+
"build": "tsc && node scripts/copy-embedded-assets.js",
|
|
64
64
|
"lint": "tsc --noEmit",
|
|
65
65
|
"start": "node dist/index.js",
|
|
66
66
|
"dev": "ts-node src/index.ts",
|