@stratabook/mcp 0.1.3 → 0.1.5
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/src/cli.js +10 -2
- package/dist/src/generated-harness.d.ts +314 -10
- package/dist/src/generated-harness.js +391 -9
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/server.js +141 -5
- package/package.json +2 -2
package/dist/src/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
5
|
import { DEFAULT_API_BASE } from "@stratabook/sdk";
|
|
6
|
-
import { STRATA_AGENT_HARNESS } from "./generated-harness.js";
|
|
6
|
+
import { STRATA_ACTION_GRAPH, STRATA_AGENT_HARNESS, } from "./generated-harness.js";
|
|
7
7
|
import { createStrataMcpServer, probeStrataMcpReadiness } from "./server.js";
|
|
8
8
|
import { SERVER_VERSION } from "./version.js";
|
|
9
9
|
function parse(argv) {
|
|
@@ -60,7 +60,9 @@ Options:
|
|
|
60
60
|
--host HOST HTTP bind host (default: localhost)
|
|
61
61
|
--port N HTTP port (default: 8787)
|
|
62
62
|
|
|
63
|
-
This server
|
|
63
|
+
This server exposes capability-gated quote and execution operations. The external
|
|
64
|
+
agent owner controls permission and signing. Strata accepts public keys,
|
|
65
|
+
signatures, and signed transactions, never private keys or seed phrases.
|
|
64
66
|
`);
|
|
65
67
|
}
|
|
66
68
|
async function runStdio(options) {
|
|
@@ -100,6 +102,12 @@ async function runHttp(options) {
|
|
|
100
102
|
.set("Cache-Control", "public, max-age=300")
|
|
101
103
|
.json(STRATA_AGENT_HARNESS);
|
|
102
104
|
});
|
|
105
|
+
app.get("/.well-known/strata-action-graph.json", (_request, response) => {
|
|
106
|
+
response
|
|
107
|
+
.status(200)
|
|
108
|
+
.set("Cache-Control", "public, max-age=300")
|
|
109
|
+
.json(STRATA_ACTION_GRAPH);
|
|
110
|
+
});
|
|
103
111
|
app.post("/mcp", async (request, response) => {
|
|
104
112
|
let runtime;
|
|
105
113
|
let transport;
|
|
@@ -3,51 +3,355 @@ export declare const STRATA_AGENT_HARNESS: {
|
|
|
3
3
|
readonly harness_version: "1.0";
|
|
4
4
|
readonly contract_version: "1.1";
|
|
5
5
|
readonly name: "Strata Agent Harness";
|
|
6
|
-
readonly summary: "A capability-gated workflow for agents that
|
|
6
|
+
readonly summary: "A capability-gated workflow and executable action graph for agents that discover, read market and account state, quote, prepare, externally sign, and submit Strata operations.";
|
|
7
7
|
readonly entrypoints: {
|
|
8
8
|
readonly documentation: "https://stratabook.org/docs/agent-harness/";
|
|
9
9
|
readonly capabilities: "https://api.stratabook.app/sonar/capabilities";
|
|
10
10
|
readonly markets: "https://api.stratabook.app/sonar/markets";
|
|
11
|
+
readonly platform_capabilities: "https://api.stratabook.app/v2/capabilities";
|
|
12
|
+
readonly platform_markets: "https://api.stratabook.app/v2/markets";
|
|
13
|
+
readonly action_graph: "https://api.stratabook.app/sonar/action-graph";
|
|
11
14
|
readonly mcp: "https://api.stratabook.app/mcp";
|
|
12
15
|
readonly manifest: "https://api.stratabook.app/.well-known/strata-agent.json";
|
|
13
16
|
};
|
|
14
17
|
readonly interfaces: {
|
|
15
|
-
readonly mcp_tool_order: readonly ["strata_capabilities", "strata_markets", "strata_quote"];
|
|
16
|
-
readonly terminal: readonly ["npx -y @stratabook/sdk capabilities --json", "npx -y @stratabook/sdk markets --json", "npx -y @stratabook/sdk quote --market SOL/USDC --side sell --amount-atoms 10000000 --json"];
|
|
18
|
+
readonly mcp_tool_order: readonly ["strata_capabilities", "strata_action_graph", "strata_markets", "strata_quote", "strata_execution_challenge", "strata_execution_prepare", "strata_execution_submit"];
|
|
19
|
+
readonly terminal: readonly ["npx -y @stratabook/sdk capabilities --json", "npx -y @stratabook/sdk action-graph --json", "npx -y @stratabook/sdk markets --json", "npx -y @stratabook/sdk quote --market SOL/USDC --side sell --amount-atoms 10000000 --json"];
|
|
17
20
|
};
|
|
18
21
|
readonly workflow: readonly [{
|
|
19
22
|
readonly id: "discover_capabilities";
|
|
20
23
|
readonly instruction: "Read the live capability catalog before every objective. Never infer permission from documentation, package support, or an earlier session.";
|
|
21
24
|
}, {
|
|
22
25
|
readonly id: "establish_mode";
|
|
23
|
-
readonly instruction: "
|
|
26
|
+
readonly instruction: "Read the action graph and identify which prepare and submit nodes are live. The external agent owner configures its permissions and signer authority; static documentation never enables a Strata operation.";
|
|
24
27
|
}, {
|
|
25
28
|
readonly id: "understand_objective";
|
|
26
29
|
readonly instruction: "Resolve the user's market, side, amount, and tolerance. Ask before proceeding when any economically meaningful input is ambiguous.";
|
|
27
30
|
}, {
|
|
28
31
|
readonly id: "discover_market";
|
|
29
32
|
readonly instruction: "List markets, select one marked ready, and use its discovered base and quote decimals. Do not guess market identifiers or token decimals.";
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: "read_market_data";
|
|
35
|
+
readonly instruction: "When books.read is live, use the opaque market ID to read the Strata book, status, fees, and recent trades. Subscribe to the market stream for changes and recover from any sequence gap with a fresh snapshot.";
|
|
36
|
+
}, {
|
|
37
|
+
readonly id: "read_account";
|
|
38
|
+
readonly instruction: "When account.read is live, use the owner-configured signer to authorize the exact wallet, market, request time, and fill limit. Read or stream only the sanitized orders and fills returned by the official SDK, and recover stream gaps from a fresh signed snapshot.";
|
|
30
39
|
}, {
|
|
31
40
|
readonly id: "preserve_atoms";
|
|
32
41
|
readonly instruction: "Represent token amounts as unsigned base-10 atomic strings. Never pass settlement amounts through floating-point arithmetic.";
|
|
33
42
|
}, {
|
|
34
43
|
readonly id: "request_quote";
|
|
35
|
-
readonly instruction: "Request a fresh Sonar quote with an explicit side, exact input atoms, and
|
|
44
|
+
readonly instruction: "Request a fresh Sonar quote with an explicit side, exact input atoms, and execution tolerance supplied by the external agent.";
|
|
36
45
|
}, {
|
|
37
46
|
readonly id: "validate_quote";
|
|
38
47
|
readonly instruction: "Verify the quote binds to the selected market, side, and input. Check labelled fees, minimum output, price impact, server time, and expiry.";
|
|
39
48
|
}, {
|
|
40
49
|
readonly id: "report_result";
|
|
41
|
-
readonly instruction: "Report consumed input, expected output, minimum output, fees by asset side, price impact, and remaining validity
|
|
50
|
+
readonly instruction: "Report consumed input, expected output, minimum output, fees by asset side, price impact, and remaining validity.";
|
|
42
51
|
}, {
|
|
43
52
|
readonly id: "authorize_writes";
|
|
44
|
-
readonly instruction: "
|
|
53
|
+
readonly instruction: "When prepare and submit are exposed, keep signing external to Strata: request canonical authorization bytes, sign them with the owner-configured signer, verify the prepared transaction preserves the quote, then submit the externally signed transaction with idempotency.";
|
|
45
54
|
}, {
|
|
46
55
|
readonly id: "monitor_outcome";
|
|
47
56
|
readonly instruction: "After an authorized submission, report the durable receipt or explicit failure. Never claim completion from preparation, signing, or an unconfirmed request.";
|
|
48
57
|
}];
|
|
49
|
-
readonly stop_conditions: readonly ["The required live capability is disabled or absent.", "The market is paused, unavailable, or has no reviewed operation path.", "Market, side, amount, decimals, tolerance, or
|
|
50
|
-
readonly safety_rules: readonly ["Never request or accept wallet secrets, private keys, seed phrases, session keys, or production credentials in a prompt.", "Never call undocumented endpoints or reconstruct private Sonar behavior.", "Never silently widen slippage, refresh changed economics, substitute a market, or retry a non-retryable failure.", "Treat capability removal, revocation, expiry, and emergency disable as immediate stop signals.", "
|
|
58
|
+
readonly stop_conditions: readonly ["The required live capability is disabled or absent.", "The market is paused, unavailable, or has no reviewed operation path.", "Market, side, amount, decimals, tolerance, or signer authority is unavailable or ambiguous.", "The contract version is unsupported or a response contains unknown fields.", "A quote is expired or its market, side, amount, fee, minimum-output, or time binding is inconsistent.", "A requested operation exceeds the exposed tool, account, or policy scope.", "A user asks the agent to receive or expose wallet secrets, private keys, seed phrases, session keys, or production credentials."];
|
|
59
|
+
readonly safety_rules: readonly ["Never request or accept wallet secrets, private keys, seed phrases, session keys, or production credentials in a prompt.", "Never call undocumented endpoints or reconstruct private Sonar behavior.", "Never silently widen slippage, refresh changed economics, substitute a market, or retry a non-retryable failure.", "Treat capability removal, revocation, expiry, and emergency disable as immediate stop signals.", "Capability and action-graph availability are authoritative for Strata operations; permission and signer policy remain controlled by the external agent owner."];
|
|
51
60
|
};
|
|
52
61
|
export declare const STRATA_AGENT_HARNESS_URI = "strata://agent-harness/v1";
|
|
53
|
-
export declare const
|
|
62
|
+
export declare const STRATA_ACTION_GRAPH: {
|
|
63
|
+
readonly schema_version: 1;
|
|
64
|
+
readonly graph_version: "1.0";
|
|
65
|
+
readonly contract_version: "1.1";
|
|
66
|
+
readonly entry_node: "discover_capabilities";
|
|
67
|
+
readonly authority: {
|
|
68
|
+
readonly permission_source: "external_agent_owner";
|
|
69
|
+
readonly signing_location: "external";
|
|
70
|
+
readonly accepts_private_keys: false;
|
|
71
|
+
};
|
|
72
|
+
readonly nodes: readonly [{
|
|
73
|
+
readonly id: "discover_capabilities";
|
|
74
|
+
readonly kind: "discovery";
|
|
75
|
+
readonly summary: "Read the live capabilities that currently expose Strata operations.";
|
|
76
|
+
readonly required_capabilities: readonly [];
|
|
77
|
+
readonly available: true;
|
|
78
|
+
readonly operation: {
|
|
79
|
+
readonly method: "GET";
|
|
80
|
+
readonly path: "/sonar/capabilities";
|
|
81
|
+
readonly mcp_tool: "strata_capabilities";
|
|
82
|
+
};
|
|
83
|
+
}, {
|
|
84
|
+
readonly id: "discover_markets";
|
|
85
|
+
readonly kind: "discovery";
|
|
86
|
+
readonly summary: "Discover ready markets, token decimals, and public operation paths.";
|
|
87
|
+
readonly required_capabilities: readonly ["markets.read"];
|
|
88
|
+
readonly available: true;
|
|
89
|
+
readonly operation: {
|
|
90
|
+
readonly method: "GET";
|
|
91
|
+
readonly path: "/sonar/markets";
|
|
92
|
+
readonly mcp_tool: "strata_markets";
|
|
93
|
+
};
|
|
94
|
+
}, {
|
|
95
|
+
readonly id: "discover_action_graph";
|
|
96
|
+
readonly kind: "discovery";
|
|
97
|
+
readonly summary: "Read the executable topology, live node availability, external signing steps, and transition conditions.";
|
|
98
|
+
readonly required_capabilities: readonly [];
|
|
99
|
+
readonly available: true;
|
|
100
|
+
readonly operation: {
|
|
101
|
+
readonly method: "GET";
|
|
102
|
+
readonly path: "/sonar/action-graph";
|
|
103
|
+
readonly mcp_tool: "strata_action_graph";
|
|
104
|
+
};
|
|
105
|
+
}, {
|
|
106
|
+
readonly id: "discover_platform_capabilities";
|
|
107
|
+
readonly kind: "discovery";
|
|
108
|
+
readonly summary: "Read the versioned capabilities available through the official SDK.";
|
|
109
|
+
readonly required_capabilities: readonly [];
|
|
110
|
+
readonly available: true;
|
|
111
|
+
readonly operation: {
|
|
112
|
+
readonly method: "GET";
|
|
113
|
+
readonly path: "/v2/capabilities";
|
|
114
|
+
};
|
|
115
|
+
}, {
|
|
116
|
+
readonly id: "discover_platform_markets";
|
|
117
|
+
readonly kind: "discovery";
|
|
118
|
+
readonly summary: "Discover opaque market IDs and current market status.";
|
|
119
|
+
readonly required_capabilities: readonly ["markets.read"];
|
|
120
|
+
readonly available: true;
|
|
121
|
+
readonly operation: {
|
|
122
|
+
readonly method: "GET";
|
|
123
|
+
readonly path: "/v2/markets";
|
|
124
|
+
};
|
|
125
|
+
}, {
|
|
126
|
+
readonly id: "read_book";
|
|
127
|
+
readonly kind: "read";
|
|
128
|
+
readonly summary: "Read a sequenced Strata book snapshot.";
|
|
129
|
+
readonly required_capabilities: readonly ["books.read"];
|
|
130
|
+
readonly available: true;
|
|
131
|
+
readonly operation: {
|
|
132
|
+
readonly method: "GET";
|
|
133
|
+
readonly path: "/v2/markets/{market_id}/book";
|
|
134
|
+
};
|
|
135
|
+
}, {
|
|
136
|
+
readonly id: "read_market_status";
|
|
137
|
+
readonly kind: "read";
|
|
138
|
+
readonly summary: "Read tick size, minimum order size, and current market status.";
|
|
139
|
+
readonly required_capabilities: readonly ["books.read"];
|
|
140
|
+
readonly available: true;
|
|
141
|
+
readonly operation: {
|
|
142
|
+
readonly method: "GET";
|
|
143
|
+
readonly path: "/v2/markets/{market_id}/status";
|
|
144
|
+
};
|
|
145
|
+
}, {
|
|
146
|
+
readonly id: "read_best_bid_ask";
|
|
147
|
+
readonly kind: "read";
|
|
148
|
+
readonly summary: "Read the current best bid and ask.";
|
|
149
|
+
readonly required_capabilities: readonly ["books.read"];
|
|
150
|
+
readonly available: true;
|
|
151
|
+
readonly operation: {
|
|
152
|
+
readonly method: "GET";
|
|
153
|
+
readonly path: "/v2/markets/{market_id}/bbo";
|
|
154
|
+
};
|
|
155
|
+
}, {
|
|
156
|
+
readonly id: "read_fees";
|
|
157
|
+
readonly kind: "read";
|
|
158
|
+
readonly summary: "Read the market fee schedule.";
|
|
159
|
+
readonly required_capabilities: readonly ["books.read"];
|
|
160
|
+
readonly available: true;
|
|
161
|
+
readonly operation: {
|
|
162
|
+
readonly method: "GET";
|
|
163
|
+
readonly path: "/v2/markets/{market_id}/fees";
|
|
164
|
+
};
|
|
165
|
+
}, {
|
|
166
|
+
readonly id: "read_trades";
|
|
167
|
+
readonly kind: "read";
|
|
168
|
+
readonly summary: "Read recent anonymized trades.";
|
|
169
|
+
readonly required_capabilities: readonly ["books.read"];
|
|
170
|
+
readonly available: true;
|
|
171
|
+
readonly operation: {
|
|
172
|
+
readonly method: "GET";
|
|
173
|
+
readonly path: "/v2/markets/{market_id}/trades";
|
|
174
|
+
};
|
|
175
|
+
}, {
|
|
176
|
+
readonly id: "stream_market";
|
|
177
|
+
readonly kind: "read";
|
|
178
|
+
readonly summary: "Subscribe to book changes, trades, and heartbeats with automatic recovery.";
|
|
179
|
+
readonly required_capabilities: readonly ["books.read"];
|
|
180
|
+
readonly available: true;
|
|
181
|
+
readonly operation: {
|
|
182
|
+
readonly method: "WEBSOCKET";
|
|
183
|
+
readonly path: "/v2/markets/{market_id}/stream";
|
|
184
|
+
};
|
|
185
|
+
}, {
|
|
186
|
+
readonly id: "authorize_account_read";
|
|
187
|
+
readonly kind: "external_signature";
|
|
188
|
+
readonly summary: "The agent owner's configured signer authorizes the exact account request or stream challenge.";
|
|
189
|
+
readonly required_capabilities: readonly [];
|
|
190
|
+
readonly available: true;
|
|
191
|
+
}, {
|
|
192
|
+
readonly id: "read_account";
|
|
193
|
+
readonly kind: "read";
|
|
194
|
+
readonly summary: "Read the owner's sanitized open orders and fills for a Strata market.";
|
|
195
|
+
readonly required_capabilities: readonly ["account.read"];
|
|
196
|
+
readonly available: true;
|
|
197
|
+
readonly operation: {
|
|
198
|
+
readonly method: "GET";
|
|
199
|
+
readonly path: "/v2/markets/{market_id}/account/{wallet_address}";
|
|
200
|
+
};
|
|
201
|
+
}, {
|
|
202
|
+
readonly id: "stream_account";
|
|
203
|
+
readonly kind: "read";
|
|
204
|
+
readonly summary: "Subscribe to signed, sequenced order and fill state for the owner.";
|
|
205
|
+
readonly required_capabilities: readonly ["account.read"];
|
|
206
|
+
readonly available: true;
|
|
207
|
+
readonly operation: {
|
|
208
|
+
readonly method: "WEBSOCKET";
|
|
209
|
+
readonly path: "/v2/markets/{market_id}/account/{wallet_address}/stream";
|
|
210
|
+
};
|
|
211
|
+
}, {
|
|
212
|
+
readonly id: "request_quote";
|
|
213
|
+
readonly kind: "read";
|
|
214
|
+
readonly summary: "Request economics bound to a market, side, exact input atoms, and tolerance.";
|
|
215
|
+
readonly required_capabilities: readonly ["quotes.read"];
|
|
216
|
+
readonly available: true;
|
|
217
|
+
readonly operation: {
|
|
218
|
+
readonly method: "POST";
|
|
219
|
+
readonly path: "/sonar/markets/{market}/quote";
|
|
220
|
+
readonly mcp_tool: "strata_quote";
|
|
221
|
+
};
|
|
222
|
+
}, {
|
|
223
|
+
readonly id: "request_execution_challenge";
|
|
224
|
+
readonly kind: "prepare";
|
|
225
|
+
readonly summary: "Request canonical authorization bytes for an unexpired quote and external signer.";
|
|
226
|
+
readonly required_capabilities: readonly ["trade.prepare"];
|
|
227
|
+
readonly available: true;
|
|
228
|
+
readonly operation: {
|
|
229
|
+
readonly method: "POST";
|
|
230
|
+
readonly path: "/sonar/markets/{market}/execution/challenge";
|
|
231
|
+
readonly mcp_tool: "strata_execution_challenge";
|
|
232
|
+
};
|
|
233
|
+
}, {
|
|
234
|
+
readonly id: "sign_authorization";
|
|
235
|
+
readonly kind: "external_signature";
|
|
236
|
+
readonly summary: "The agent owner's configured signer signs the returned authorization bytes externally.";
|
|
237
|
+
readonly required_capabilities: readonly [];
|
|
238
|
+
readonly available: true;
|
|
239
|
+
}, {
|
|
240
|
+
readonly id: "prepare_execution";
|
|
241
|
+
readonly kind: "prepare";
|
|
242
|
+
readonly summary: "Exchange the authorization signature for a quote-bound partially signed transaction.";
|
|
243
|
+
readonly required_capabilities: readonly ["trade.prepare"];
|
|
244
|
+
readonly available: true;
|
|
245
|
+
readonly operation: {
|
|
246
|
+
readonly method: "POST";
|
|
247
|
+
readonly path: "/sonar/markets/{market}/execution/prepare";
|
|
248
|
+
readonly mcp_tool: "strata_execution_prepare";
|
|
249
|
+
};
|
|
250
|
+
}, {
|
|
251
|
+
readonly id: "sign_transaction";
|
|
252
|
+
readonly kind: "external_signature";
|
|
253
|
+
readonly summary: "The external signer verifies and fills its signature slot without sending key material to Strata.";
|
|
254
|
+
readonly required_capabilities: readonly [];
|
|
255
|
+
readonly available: true;
|
|
256
|
+
}, {
|
|
257
|
+
readonly id: "submit_execution";
|
|
258
|
+
readonly kind: "submit";
|
|
259
|
+
readonly summary: "Submit the signed transaction with an idempotency key.";
|
|
260
|
+
readonly required_capabilities: readonly ["trade.submit"];
|
|
261
|
+
readonly available: true;
|
|
262
|
+
readonly operation: {
|
|
263
|
+
readonly method: "POST";
|
|
264
|
+
readonly path: "/sonar/markets/{market}/execution/submit";
|
|
265
|
+
readonly mcp_tool: "strata_execution_submit";
|
|
266
|
+
};
|
|
267
|
+
}, {
|
|
268
|
+
readonly id: "receive_receipt";
|
|
269
|
+
readonly kind: "receipt";
|
|
270
|
+
readonly summary: "Receive the execution ID, Solana signature, and submitted status.";
|
|
271
|
+
readonly required_capabilities: readonly [];
|
|
272
|
+
readonly available: true;
|
|
273
|
+
}];
|
|
274
|
+
readonly edges: readonly [{
|
|
275
|
+
readonly from: "discover_capabilities";
|
|
276
|
+
readonly to: "discover_action_graph";
|
|
277
|
+
readonly condition: "the returned contract version is supported";
|
|
278
|
+
}, {
|
|
279
|
+
readonly from: "discover_action_graph";
|
|
280
|
+
readonly to: "discover_markets";
|
|
281
|
+
readonly condition: "markets.read is enabled";
|
|
282
|
+
}, {
|
|
283
|
+
readonly from: "discover_action_graph";
|
|
284
|
+
readonly to: "discover_platform_capabilities";
|
|
285
|
+
readonly condition: "the versioned SDK contract is supported";
|
|
286
|
+
}, {
|
|
287
|
+
readonly from: "discover_platform_capabilities";
|
|
288
|
+
readonly to: "discover_platform_markets";
|
|
289
|
+
readonly condition: "markets.read is enabled";
|
|
290
|
+
}, {
|
|
291
|
+
readonly from: "discover_platform_markets";
|
|
292
|
+
readonly to: "read_book";
|
|
293
|
+
readonly condition: "books.read is enabled and the market is active";
|
|
294
|
+
}, {
|
|
295
|
+
readonly from: "discover_platform_markets";
|
|
296
|
+
readonly to: "read_market_status";
|
|
297
|
+
readonly condition: "books.read is enabled";
|
|
298
|
+
}, {
|
|
299
|
+
readonly from: "discover_platform_markets";
|
|
300
|
+
readonly to: "read_best_bid_ask";
|
|
301
|
+
readonly condition: "books.read is enabled";
|
|
302
|
+
}, {
|
|
303
|
+
readonly from: "discover_platform_markets";
|
|
304
|
+
readonly to: "read_fees";
|
|
305
|
+
readonly condition: "books.read is enabled";
|
|
306
|
+
}, {
|
|
307
|
+
readonly from: "discover_platform_markets";
|
|
308
|
+
readonly to: "read_trades";
|
|
309
|
+
readonly condition: "books.read is enabled";
|
|
310
|
+
}, {
|
|
311
|
+
readonly from: "read_book";
|
|
312
|
+
readonly to: "stream_market";
|
|
313
|
+
readonly condition: "books.read is enabled and the snapshot sequence is accepted";
|
|
314
|
+
}, {
|
|
315
|
+
readonly from: "discover_platform_markets";
|
|
316
|
+
readonly to: "authorize_account_read";
|
|
317
|
+
readonly condition: "account.read is enabled and the owner-configured signer is available";
|
|
318
|
+
}, {
|
|
319
|
+
readonly from: "authorize_account_read";
|
|
320
|
+
readonly to: "read_account";
|
|
321
|
+
readonly condition: "the signature binds the wallet, market, request time, and fill limit";
|
|
322
|
+
}, {
|
|
323
|
+
readonly from: "read_account";
|
|
324
|
+
readonly to: "stream_account";
|
|
325
|
+
readonly condition: "the stream challenge is signed by the same owner-configured signer";
|
|
326
|
+
}, {
|
|
327
|
+
readonly from: "discover_markets";
|
|
328
|
+
readonly to: "request_quote";
|
|
329
|
+
readonly condition: "quotes.read is enabled and the market is ready";
|
|
330
|
+
}, {
|
|
331
|
+
readonly from: "request_quote";
|
|
332
|
+
readonly to: "request_execution_challenge";
|
|
333
|
+
readonly condition: "trade.prepare is enabled and the quote is unexpired";
|
|
334
|
+
}, {
|
|
335
|
+
readonly from: "request_execution_challenge";
|
|
336
|
+
readonly to: "sign_authorization";
|
|
337
|
+
readonly condition: "the challenge bindings match the quote and signer";
|
|
338
|
+
}, {
|
|
339
|
+
readonly from: "sign_authorization";
|
|
340
|
+
readonly to: "prepare_execution";
|
|
341
|
+
readonly condition: "a valid external authorization signature is available";
|
|
342
|
+
}, {
|
|
343
|
+
readonly from: "prepare_execution";
|
|
344
|
+
readonly to: "sign_transaction";
|
|
345
|
+
readonly condition: "the prepared transaction preserves the signed bindings";
|
|
346
|
+
}, {
|
|
347
|
+
readonly from: "sign_transaction";
|
|
348
|
+
readonly to: "submit_execution";
|
|
349
|
+
readonly condition: "trade.submit is enabled and the signed transaction is unmodified";
|
|
350
|
+
}, {
|
|
351
|
+
readonly from: "submit_execution";
|
|
352
|
+
readonly to: "receive_receipt";
|
|
353
|
+
readonly condition: "the execution ID and idempotency key match";
|
|
354
|
+
}];
|
|
355
|
+
};
|
|
356
|
+
export declare const STRATA_ACTION_GRAPH_URI = "strata://action-graph/v1";
|
|
357
|
+
export declare const STRATA_AGENT_HARNESS_INSTRUCTIONS = "Strata Agent Harness 1.0. Start every objective with strata_capabilities, then strata_action_graph, then strata_markets. Read strata://agent-harness/v1 and strata://action-graph/v1. The external agent owner controls permission and signer authority. Strata accepts public keys, detached signatures, and signed transactions, never private keys or seed phrases. Resolve the market, side, exact input atoms, and tolerance before strata_quote. Treat amounts as unsigned base-10 token atoms; check quote bindings, labelled fees, minimum output, and expiry. To execute: request a challenge, sign its canonical authorization bytes externally, prepare, verify and sign the returned transaction externally, then submit with idempotency. Stop on ambiguity, unavailable capabilities, paused markets, unsupported contracts, inconsistent bindings, expiry, or missing signer authority.";
|
|
@@ -4,22 +4,30 @@ export const STRATA_AGENT_HARNESS = {
|
|
|
4
4
|
"harness_version": "1.0",
|
|
5
5
|
"contract_version": "1.1",
|
|
6
6
|
"name": "Strata Agent Harness",
|
|
7
|
-
"summary": "A capability-gated workflow for agents that
|
|
7
|
+
"summary": "A capability-gated workflow and executable action graph for agents that discover, read market and account state, quote, prepare, externally sign, and submit Strata operations.",
|
|
8
8
|
"entrypoints": {
|
|
9
9
|
"documentation": "https://stratabook.org/docs/agent-harness/",
|
|
10
10
|
"capabilities": "https://api.stratabook.app/sonar/capabilities",
|
|
11
11
|
"markets": "https://api.stratabook.app/sonar/markets",
|
|
12
|
+
"platform_capabilities": "https://api.stratabook.app/v2/capabilities",
|
|
13
|
+
"platform_markets": "https://api.stratabook.app/v2/markets",
|
|
14
|
+
"action_graph": "https://api.stratabook.app/sonar/action-graph",
|
|
12
15
|
"mcp": "https://api.stratabook.app/mcp",
|
|
13
16
|
"manifest": "https://api.stratabook.app/.well-known/strata-agent.json"
|
|
14
17
|
},
|
|
15
18
|
"interfaces": {
|
|
16
19
|
"mcp_tool_order": [
|
|
17
20
|
"strata_capabilities",
|
|
21
|
+
"strata_action_graph",
|
|
18
22
|
"strata_markets",
|
|
19
|
-
"strata_quote"
|
|
23
|
+
"strata_quote",
|
|
24
|
+
"strata_execution_challenge",
|
|
25
|
+
"strata_execution_prepare",
|
|
26
|
+
"strata_execution_submit"
|
|
20
27
|
],
|
|
21
28
|
"terminal": [
|
|
22
29
|
"npx -y @stratabook/sdk capabilities --json",
|
|
30
|
+
"npx -y @stratabook/sdk action-graph --json",
|
|
23
31
|
"npx -y @stratabook/sdk markets --json",
|
|
24
32
|
"npx -y @stratabook/sdk quote --market SOL/USDC --side sell --amount-atoms 10000000 --json"
|
|
25
33
|
]
|
|
@@ -31,7 +39,7 @@ export const STRATA_AGENT_HARNESS = {
|
|
|
31
39
|
},
|
|
32
40
|
{
|
|
33
41
|
"id": "establish_mode",
|
|
34
|
-
"instruction": "
|
|
42
|
+
"instruction": "Read the action graph and identify which prepare and submit nodes are live. The external agent owner configures its permissions and signer authority; static documentation never enables a Strata operation."
|
|
35
43
|
},
|
|
36
44
|
{
|
|
37
45
|
"id": "understand_objective",
|
|
@@ -41,13 +49,21 @@ export const STRATA_AGENT_HARNESS = {
|
|
|
41
49
|
"id": "discover_market",
|
|
42
50
|
"instruction": "List markets, select one marked ready, and use its discovered base and quote decimals. Do not guess market identifiers or token decimals."
|
|
43
51
|
},
|
|
52
|
+
{
|
|
53
|
+
"id": "read_market_data",
|
|
54
|
+
"instruction": "When books.read is live, use the opaque market ID to read the Strata book, status, fees, and recent trades. Subscribe to the market stream for changes and recover from any sequence gap with a fresh snapshot."
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "read_account",
|
|
58
|
+
"instruction": "When account.read is live, use the owner-configured signer to authorize the exact wallet, market, request time, and fill limit. Read or stream only the sanitized orders and fills returned by the official SDK, and recover stream gaps from a fresh signed snapshot."
|
|
59
|
+
},
|
|
44
60
|
{
|
|
45
61
|
"id": "preserve_atoms",
|
|
46
62
|
"instruction": "Represent token amounts as unsigned base-10 atomic strings. Never pass settlement amounts through floating-point arithmetic."
|
|
47
63
|
},
|
|
48
64
|
{
|
|
49
65
|
"id": "request_quote",
|
|
50
|
-
"instruction": "Request a fresh Sonar quote with an explicit side, exact input atoms, and
|
|
66
|
+
"instruction": "Request a fresh Sonar quote with an explicit side, exact input atoms, and execution tolerance supplied by the external agent."
|
|
51
67
|
},
|
|
52
68
|
{
|
|
53
69
|
"id": "validate_quote",
|
|
@@ -55,11 +71,11 @@ export const STRATA_AGENT_HARNESS = {
|
|
|
55
71
|
},
|
|
56
72
|
{
|
|
57
73
|
"id": "report_result",
|
|
58
|
-
"instruction": "Report consumed input, expected output, minimum output, fees by asset side, price impact, and remaining validity
|
|
74
|
+
"instruction": "Report consumed input, expected output, minimum output, fees by asset side, price impact, and remaining validity."
|
|
59
75
|
},
|
|
60
76
|
{
|
|
61
77
|
"id": "authorize_writes",
|
|
62
|
-
"instruction": "
|
|
78
|
+
"instruction": "When prepare and submit are exposed, keep signing external to Strata: request canonical authorization bytes, sign them with the owner-configured signer, verify the prepared transaction preserves the quote, then submit the externally signed transaction with idempotency."
|
|
63
79
|
},
|
|
64
80
|
{
|
|
65
81
|
"id": "monitor_outcome",
|
|
@@ -69,7 +85,7 @@ export const STRATA_AGENT_HARNESS = {
|
|
|
69
85
|
"stop_conditions": [
|
|
70
86
|
"The required live capability is disabled or absent.",
|
|
71
87
|
"The market is paused, unavailable, or has no reviewed operation path.",
|
|
72
|
-
"Market, side, amount, decimals, tolerance, or
|
|
88
|
+
"Market, side, amount, decimals, tolerance, or signer authority is unavailable or ambiguous.",
|
|
73
89
|
"The contract version is unsupported or a response contains unknown fields.",
|
|
74
90
|
"A quote is expired or its market, side, amount, fee, minimum-output, or time binding is inconsistent.",
|
|
75
91
|
"A requested operation exceeds the exposed tool, account, or policy scope.",
|
|
@@ -80,8 +96,374 @@ export const STRATA_AGENT_HARNESS = {
|
|
|
80
96
|
"Never call undocumented endpoints or reconstruct private Sonar behavior.",
|
|
81
97
|
"Never silently widen slippage, refresh changed economics, substitute a market, or retry a non-retryable failure.",
|
|
82
98
|
"Treat capability removal, revocation, expiry, and emergency disable as immediate stop signals.",
|
|
83
|
-
"
|
|
99
|
+
"Capability and action-graph availability are authoritative for Strata operations; permission and signer policy remain controlled by the external agent owner."
|
|
84
100
|
]
|
|
85
101
|
};
|
|
86
102
|
export const STRATA_AGENT_HARNESS_URI = "strata://agent-harness/v1";
|
|
87
|
-
export const
|
|
103
|
+
export const STRATA_ACTION_GRAPH = {
|
|
104
|
+
"schema_version": 1,
|
|
105
|
+
"graph_version": "1.0",
|
|
106
|
+
"contract_version": "1.1",
|
|
107
|
+
"entry_node": "discover_capabilities",
|
|
108
|
+
"authority": {
|
|
109
|
+
"permission_source": "external_agent_owner",
|
|
110
|
+
"signing_location": "external",
|
|
111
|
+
"accepts_private_keys": false
|
|
112
|
+
},
|
|
113
|
+
"nodes": [
|
|
114
|
+
{
|
|
115
|
+
"id": "discover_capabilities",
|
|
116
|
+
"kind": "discovery",
|
|
117
|
+
"summary": "Read the live capabilities that currently expose Strata operations.",
|
|
118
|
+
"required_capabilities": [],
|
|
119
|
+
"available": true,
|
|
120
|
+
"operation": {
|
|
121
|
+
"method": "GET",
|
|
122
|
+
"path": "/sonar/capabilities",
|
|
123
|
+
"mcp_tool": "strata_capabilities"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "discover_markets",
|
|
128
|
+
"kind": "discovery",
|
|
129
|
+
"summary": "Discover ready markets, token decimals, and public operation paths.",
|
|
130
|
+
"required_capabilities": [
|
|
131
|
+
"markets.read"
|
|
132
|
+
],
|
|
133
|
+
"available": true,
|
|
134
|
+
"operation": {
|
|
135
|
+
"method": "GET",
|
|
136
|
+
"path": "/sonar/markets",
|
|
137
|
+
"mcp_tool": "strata_markets"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "discover_action_graph",
|
|
142
|
+
"kind": "discovery",
|
|
143
|
+
"summary": "Read the executable topology, live node availability, external signing steps, and transition conditions.",
|
|
144
|
+
"required_capabilities": [],
|
|
145
|
+
"available": true,
|
|
146
|
+
"operation": {
|
|
147
|
+
"method": "GET",
|
|
148
|
+
"path": "/sonar/action-graph",
|
|
149
|
+
"mcp_tool": "strata_action_graph"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "discover_platform_capabilities",
|
|
154
|
+
"kind": "discovery",
|
|
155
|
+
"summary": "Read the versioned capabilities available through the official SDK.",
|
|
156
|
+
"required_capabilities": [],
|
|
157
|
+
"available": true,
|
|
158
|
+
"operation": {
|
|
159
|
+
"method": "GET",
|
|
160
|
+
"path": "/v2/capabilities"
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"id": "discover_platform_markets",
|
|
165
|
+
"kind": "discovery",
|
|
166
|
+
"summary": "Discover opaque market IDs and current market status.",
|
|
167
|
+
"required_capabilities": [
|
|
168
|
+
"markets.read"
|
|
169
|
+
],
|
|
170
|
+
"available": true,
|
|
171
|
+
"operation": {
|
|
172
|
+
"method": "GET",
|
|
173
|
+
"path": "/v2/markets"
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"id": "read_book",
|
|
178
|
+
"kind": "read",
|
|
179
|
+
"summary": "Read a sequenced Strata book snapshot.",
|
|
180
|
+
"required_capabilities": [
|
|
181
|
+
"books.read"
|
|
182
|
+
],
|
|
183
|
+
"available": true,
|
|
184
|
+
"operation": {
|
|
185
|
+
"method": "GET",
|
|
186
|
+
"path": "/v2/markets/{market_id}/book"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"id": "read_market_status",
|
|
191
|
+
"kind": "read",
|
|
192
|
+
"summary": "Read tick size, minimum order size, and current market status.",
|
|
193
|
+
"required_capabilities": [
|
|
194
|
+
"books.read"
|
|
195
|
+
],
|
|
196
|
+
"available": true,
|
|
197
|
+
"operation": {
|
|
198
|
+
"method": "GET",
|
|
199
|
+
"path": "/v2/markets/{market_id}/status"
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"id": "read_best_bid_ask",
|
|
204
|
+
"kind": "read",
|
|
205
|
+
"summary": "Read the current best bid and ask.",
|
|
206
|
+
"required_capabilities": [
|
|
207
|
+
"books.read"
|
|
208
|
+
],
|
|
209
|
+
"available": true,
|
|
210
|
+
"operation": {
|
|
211
|
+
"method": "GET",
|
|
212
|
+
"path": "/v2/markets/{market_id}/bbo"
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"id": "read_fees",
|
|
217
|
+
"kind": "read",
|
|
218
|
+
"summary": "Read the market fee schedule.",
|
|
219
|
+
"required_capabilities": [
|
|
220
|
+
"books.read"
|
|
221
|
+
],
|
|
222
|
+
"available": true,
|
|
223
|
+
"operation": {
|
|
224
|
+
"method": "GET",
|
|
225
|
+
"path": "/v2/markets/{market_id}/fees"
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"id": "read_trades",
|
|
230
|
+
"kind": "read",
|
|
231
|
+
"summary": "Read recent anonymized trades.",
|
|
232
|
+
"required_capabilities": [
|
|
233
|
+
"books.read"
|
|
234
|
+
],
|
|
235
|
+
"available": true,
|
|
236
|
+
"operation": {
|
|
237
|
+
"method": "GET",
|
|
238
|
+
"path": "/v2/markets/{market_id}/trades"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"id": "stream_market",
|
|
243
|
+
"kind": "read",
|
|
244
|
+
"summary": "Subscribe to book changes, trades, and heartbeats with automatic recovery.",
|
|
245
|
+
"required_capabilities": [
|
|
246
|
+
"books.read"
|
|
247
|
+
],
|
|
248
|
+
"available": true,
|
|
249
|
+
"operation": {
|
|
250
|
+
"method": "WEBSOCKET",
|
|
251
|
+
"path": "/v2/markets/{market_id}/stream"
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"id": "authorize_account_read",
|
|
256
|
+
"kind": "external_signature",
|
|
257
|
+
"summary": "The agent owner's configured signer authorizes the exact account request or stream challenge.",
|
|
258
|
+
"required_capabilities": [],
|
|
259
|
+
"available": true
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"id": "read_account",
|
|
263
|
+
"kind": "read",
|
|
264
|
+
"summary": "Read the owner's sanitized open orders and fills for a Strata market.",
|
|
265
|
+
"required_capabilities": [
|
|
266
|
+
"account.read"
|
|
267
|
+
],
|
|
268
|
+
"available": true,
|
|
269
|
+
"operation": {
|
|
270
|
+
"method": "GET",
|
|
271
|
+
"path": "/v2/markets/{market_id}/account/{wallet_address}"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "stream_account",
|
|
276
|
+
"kind": "read",
|
|
277
|
+
"summary": "Subscribe to signed, sequenced order and fill state for the owner.",
|
|
278
|
+
"required_capabilities": [
|
|
279
|
+
"account.read"
|
|
280
|
+
],
|
|
281
|
+
"available": true,
|
|
282
|
+
"operation": {
|
|
283
|
+
"method": "WEBSOCKET",
|
|
284
|
+
"path": "/v2/markets/{market_id}/account/{wallet_address}/stream"
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"id": "request_quote",
|
|
289
|
+
"kind": "read",
|
|
290
|
+
"summary": "Request economics bound to a market, side, exact input atoms, and tolerance.",
|
|
291
|
+
"required_capabilities": [
|
|
292
|
+
"quotes.read"
|
|
293
|
+
],
|
|
294
|
+
"available": true,
|
|
295
|
+
"operation": {
|
|
296
|
+
"method": "POST",
|
|
297
|
+
"path": "/sonar/markets/{market}/quote",
|
|
298
|
+
"mcp_tool": "strata_quote"
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"id": "request_execution_challenge",
|
|
303
|
+
"kind": "prepare",
|
|
304
|
+
"summary": "Request canonical authorization bytes for an unexpired quote and external signer.",
|
|
305
|
+
"required_capabilities": [
|
|
306
|
+
"trade.prepare"
|
|
307
|
+
],
|
|
308
|
+
"available": true,
|
|
309
|
+
"operation": {
|
|
310
|
+
"method": "POST",
|
|
311
|
+
"path": "/sonar/markets/{market}/execution/challenge",
|
|
312
|
+
"mcp_tool": "strata_execution_challenge"
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"id": "sign_authorization",
|
|
317
|
+
"kind": "external_signature",
|
|
318
|
+
"summary": "The agent owner's configured signer signs the returned authorization bytes externally.",
|
|
319
|
+
"required_capabilities": [],
|
|
320
|
+
"available": true
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"id": "prepare_execution",
|
|
324
|
+
"kind": "prepare",
|
|
325
|
+
"summary": "Exchange the authorization signature for a quote-bound partially signed transaction.",
|
|
326
|
+
"required_capabilities": [
|
|
327
|
+
"trade.prepare"
|
|
328
|
+
],
|
|
329
|
+
"available": true,
|
|
330
|
+
"operation": {
|
|
331
|
+
"method": "POST",
|
|
332
|
+
"path": "/sonar/markets/{market}/execution/prepare",
|
|
333
|
+
"mcp_tool": "strata_execution_prepare"
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"id": "sign_transaction",
|
|
338
|
+
"kind": "external_signature",
|
|
339
|
+
"summary": "The external signer verifies and fills its signature slot without sending key material to Strata.",
|
|
340
|
+
"required_capabilities": [],
|
|
341
|
+
"available": true
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"id": "submit_execution",
|
|
345
|
+
"kind": "submit",
|
|
346
|
+
"summary": "Submit the signed transaction with an idempotency key.",
|
|
347
|
+
"required_capabilities": [
|
|
348
|
+
"trade.submit"
|
|
349
|
+
],
|
|
350
|
+
"available": true,
|
|
351
|
+
"operation": {
|
|
352
|
+
"method": "POST",
|
|
353
|
+
"path": "/sonar/markets/{market}/execution/submit",
|
|
354
|
+
"mcp_tool": "strata_execution_submit"
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"id": "receive_receipt",
|
|
359
|
+
"kind": "receipt",
|
|
360
|
+
"summary": "Receive the execution ID, Solana signature, and submitted status.",
|
|
361
|
+
"required_capabilities": [],
|
|
362
|
+
"available": true
|
|
363
|
+
}
|
|
364
|
+
],
|
|
365
|
+
"edges": [
|
|
366
|
+
{
|
|
367
|
+
"from": "discover_capabilities",
|
|
368
|
+
"to": "discover_action_graph",
|
|
369
|
+
"condition": "the returned contract version is supported"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"from": "discover_action_graph",
|
|
373
|
+
"to": "discover_markets",
|
|
374
|
+
"condition": "markets.read is enabled"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"from": "discover_action_graph",
|
|
378
|
+
"to": "discover_platform_capabilities",
|
|
379
|
+
"condition": "the versioned SDK contract is supported"
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"from": "discover_platform_capabilities",
|
|
383
|
+
"to": "discover_platform_markets",
|
|
384
|
+
"condition": "markets.read is enabled"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"from": "discover_platform_markets",
|
|
388
|
+
"to": "read_book",
|
|
389
|
+
"condition": "books.read is enabled and the market is active"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
"from": "discover_platform_markets",
|
|
393
|
+
"to": "read_market_status",
|
|
394
|
+
"condition": "books.read is enabled"
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"from": "discover_platform_markets",
|
|
398
|
+
"to": "read_best_bid_ask",
|
|
399
|
+
"condition": "books.read is enabled"
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"from": "discover_platform_markets",
|
|
403
|
+
"to": "read_fees",
|
|
404
|
+
"condition": "books.read is enabled"
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
"from": "discover_platform_markets",
|
|
408
|
+
"to": "read_trades",
|
|
409
|
+
"condition": "books.read is enabled"
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
"from": "read_book",
|
|
413
|
+
"to": "stream_market",
|
|
414
|
+
"condition": "books.read is enabled and the snapshot sequence is accepted"
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"from": "discover_platform_markets",
|
|
418
|
+
"to": "authorize_account_read",
|
|
419
|
+
"condition": "account.read is enabled and the owner-configured signer is available"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"from": "authorize_account_read",
|
|
423
|
+
"to": "read_account",
|
|
424
|
+
"condition": "the signature binds the wallet, market, request time, and fill limit"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"from": "read_account",
|
|
428
|
+
"to": "stream_account",
|
|
429
|
+
"condition": "the stream challenge is signed by the same owner-configured signer"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"from": "discover_markets",
|
|
433
|
+
"to": "request_quote",
|
|
434
|
+
"condition": "quotes.read is enabled and the market is ready"
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"from": "request_quote",
|
|
438
|
+
"to": "request_execution_challenge",
|
|
439
|
+
"condition": "trade.prepare is enabled and the quote is unexpired"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"from": "request_execution_challenge",
|
|
443
|
+
"to": "sign_authorization",
|
|
444
|
+
"condition": "the challenge bindings match the quote and signer"
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"from": "sign_authorization",
|
|
448
|
+
"to": "prepare_execution",
|
|
449
|
+
"condition": "a valid external authorization signature is available"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"from": "prepare_execution",
|
|
453
|
+
"to": "sign_transaction",
|
|
454
|
+
"condition": "the prepared transaction preserves the signed bindings"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
"from": "sign_transaction",
|
|
458
|
+
"to": "submit_execution",
|
|
459
|
+
"condition": "trade.submit is enabled and the signed transaction is unmodified"
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"from": "submit_execution",
|
|
463
|
+
"to": "receive_receipt",
|
|
464
|
+
"condition": "the execution ID and idempotency key match"
|
|
465
|
+
}
|
|
466
|
+
]
|
|
467
|
+
};
|
|
468
|
+
export const STRATA_ACTION_GRAPH_URI = "strata://action-graph/v1";
|
|
469
|
+
export const STRATA_AGENT_HARNESS_INSTRUCTIONS = "Strata Agent Harness 1.0. Start every objective with strata_capabilities, then strata_action_graph, then strata_markets. Read strata://agent-harness/v1 and strata://action-graph/v1. The external agent owner controls permission and signer authority. Strata accepts public keys, detached signatures, and signed transactions, never private keys or seed phrases. Resolve the market, side, exact input atoms, and tolerance before strata_quote. Treat amounts as unsigned base-10 token atoms; check quote bindings, labelled fees, minimum output, and expiry. To execute: request a challenge, sign its canonical authorization bytes externally, prepare, verify and sign the returned transaction externally, then submit with idempotency. Stop on ambiguity, unavailable capabilities, paused markets, unsupported contracts, inconsistent bindings, expiry, or missing signer authority.";
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { capabilityAvailable, createStrataMcpServer, probeStrataMcpReadiness, type StrataMcpOptions, type StrataMcpReadiness, type StrataMcpRuntime, } from "./server.js";
|
|
2
|
-
export { STRATA_AGENT_HARNESS, STRATA_AGENT_HARNESS_INSTRUCTIONS, STRATA_AGENT_HARNESS_URI, } from "./generated-harness.js";
|
|
2
|
+
export { STRATA_AGENT_HARNESS, STRATA_AGENT_HARNESS_INSTRUCTIONS, STRATA_AGENT_HARNESS_URI, STRATA_ACTION_GRAPH, STRATA_ACTION_GRAPH_URI, } from "./generated-harness.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { capabilityAvailable, createStrataMcpServer, probeStrataMcpReadiness, } from "./server.js";
|
|
2
|
-
export { STRATA_AGENT_HARNESS, STRATA_AGENT_HARNESS_INSTRUCTIONS, STRATA_AGENT_HARNESS_URI, } from "./generated-harness.js";
|
|
2
|
+
export { STRATA_AGENT_HARNESS, STRATA_AGENT_HARNESS_INSTRUCTIONS, STRATA_AGENT_HARNESS_URI, STRATA_ACTION_GRAPH, STRATA_ACTION_GRAPH_URI, } from "./generated-harness.js";
|
package/dist/src/server.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { DEFAULT_SLIPPAGE_BPS, StrataApiError, StrataClient, } from "@stratabook/sdk";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
|
-
import { STRATA_AGENT_HARNESS, STRATA_AGENT_HARNESS_INSTRUCTIONS, STRATA_AGENT_HARNESS_URI, } from "./generated-harness.js";
|
|
4
|
+
import { STRATA_AGENT_HARNESS, STRATA_AGENT_HARNESS_INSTRUCTIONS, STRATA_AGENT_HARNESS_URI, STRATA_ACTION_GRAPH_URI, } from "./generated-harness.js";
|
|
5
5
|
import { SERVER_VERSION } from "./version.js";
|
|
6
6
|
const REFRESH_INTERVAL_MS = 5_000;
|
|
7
7
|
export function capabilityAvailable(catalog, id) {
|
|
8
8
|
return catalog.capabilities.some((capability) => capability.id === id
|
|
9
9
|
&& capability.default_enabled
|
|
10
10
|
&& capability.public_sdk
|
|
11
|
-
&& capability.
|
|
12
|
-
&& capability.
|
|
11
|
+
&& capability.mcp_exposure !== "none"
|
|
12
|
+
&& capability.risk === capability.mcp_exposure);
|
|
13
13
|
}
|
|
14
14
|
function strataClient(options) {
|
|
15
15
|
return options.client
|
|
@@ -56,9 +56,22 @@ export async function createStrataMcpServer(options = {}) {
|
|
|
56
56
|
},
|
|
57
57
|
],
|
|
58
58
|
}));
|
|
59
|
+
server.registerResource("strata_action_graph", STRATA_ACTION_GRAPH_URI, {
|
|
60
|
+
title: "Strata Action Graph",
|
|
61
|
+
description: "Live executable topology for discovery, quoting, external signing, and submission.",
|
|
62
|
+
mimeType: "application/json",
|
|
63
|
+
}, async () => ({
|
|
64
|
+
contents: [
|
|
65
|
+
{
|
|
66
|
+
uri: STRATA_ACTION_GRAPH_URI,
|
|
67
|
+
mimeType: "application/json",
|
|
68
|
+
text: JSON.stringify(await client.actionGraph()),
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
}));
|
|
59
72
|
server.registerPrompt("strata_start", {
|
|
60
73
|
title: "Start a Strata objective",
|
|
61
|
-
description: "Apply the Strata Agent Harness to a concrete
|
|
74
|
+
description: "Apply the Strata Agent Harness to a concrete objective.",
|
|
62
75
|
argsSchema: {
|
|
63
76
|
objective: z
|
|
64
77
|
.string()
|
|
@@ -88,6 +101,16 @@ export async function createStrataMcpServer(options = {}) {
|
|
|
88
101
|
openWorldHint: true,
|
|
89
102
|
},
|
|
90
103
|
}, async () => toolResult(await client.capabilities(), "Current Strata capabilities."));
|
|
104
|
+
server.registerTool("strata_action_graph", {
|
|
105
|
+
title: "Strata action graph",
|
|
106
|
+
description: "Discover live operations, required capabilities, transition conditions, and external signing boundaries.",
|
|
107
|
+
annotations: {
|
|
108
|
+
readOnlyHint: true,
|
|
109
|
+
destructiveHint: false,
|
|
110
|
+
idempotentHint: true,
|
|
111
|
+
openWorldHint: true,
|
|
112
|
+
},
|
|
113
|
+
}, async () => toolResult(await client.actionGraph(), "Current Strata action graph."));
|
|
91
114
|
const markets = server.registerTool("strata_markets", {
|
|
92
115
|
title: "Strata markets",
|
|
93
116
|
description: "List Strata markets and their current Sonar quote availability.",
|
|
@@ -158,7 +181,117 @@ export async function createStrataMcpServer(options = {}) {
|
|
|
158
181
|
+ `for ${response.amount_out_atoms} output atoms; minimum `
|
|
159
182
|
+ `${response.minimum_output_atoms}; expires at ${response.expires_at_ms}.`);
|
|
160
183
|
}));
|
|
161
|
-
const
|
|
184
|
+
const executionChallenge = server.registerTool("strata_execution_challenge", {
|
|
185
|
+
title: "Strata execution challenge",
|
|
186
|
+
description: "Request canonical quote-bound authorization bytes for the external signer configured by the agent owner.",
|
|
187
|
+
inputSchema: {
|
|
188
|
+
market: z.string().min(1).max(128).describe("Market label or public market ID."),
|
|
189
|
+
quoteId: z.string().regex(/^sq_[0-9a-f]{32}$/).describe("Unexpired Sonar quote ID."),
|
|
190
|
+
ownerWallet: z.string().min(32).max(44).describe("Base58 owner wallet public key."),
|
|
191
|
+
sessionPublicKey: z
|
|
192
|
+
.string()
|
|
193
|
+
.min(32)
|
|
194
|
+
.max(44)
|
|
195
|
+
.describe("Base58 public key for the externally configured signer."),
|
|
196
|
+
accountSequence: z
|
|
197
|
+
.string()
|
|
198
|
+
.regex(/^[0-9]+$/)
|
|
199
|
+
.max(20)
|
|
200
|
+
.describe("Current Vault account sequence as an unsigned decimal string."),
|
|
201
|
+
},
|
|
202
|
+
annotations: {
|
|
203
|
+
readOnlyHint: false,
|
|
204
|
+
destructiveHint: false,
|
|
205
|
+
idempotentHint: false,
|
|
206
|
+
openWorldHint: true,
|
|
207
|
+
},
|
|
208
|
+
}, async ({ market, quoteId, ownerWallet, sessionPublicKey, accountSequence }) => guardedTool(client, "trade.prepare", async () => {
|
|
209
|
+
const request = {
|
|
210
|
+
market,
|
|
211
|
+
quoteId,
|
|
212
|
+
ownerWallet,
|
|
213
|
+
sessionPublicKey,
|
|
214
|
+
accountSequence,
|
|
215
|
+
};
|
|
216
|
+
const response = await client.executionChallenge(request);
|
|
217
|
+
return toolResult(response, `Authorization challenge ${response.challenge_id}; expires at ${response.expires_at_ms}.`);
|
|
218
|
+
}));
|
|
219
|
+
const executionPrepare = server.registerTool("strata_execution_prepare", {
|
|
220
|
+
title: "Prepare Strata execution",
|
|
221
|
+
description: "Exchange an externally signed authorization challenge for a quote-bound partially signed transaction.",
|
|
222
|
+
inputSchema: {
|
|
223
|
+
market: z.string().min(1).max(128).describe("Market label or public market ID."),
|
|
224
|
+
challengeId: z
|
|
225
|
+
.string()
|
|
226
|
+
.regex(/^sc_[0-9a-f]{32}$/)
|
|
227
|
+
.describe("Execution challenge ID returned by Strata."),
|
|
228
|
+
authorizationSignature: z
|
|
229
|
+
.string()
|
|
230
|
+
.min(1)
|
|
231
|
+
.max(128)
|
|
232
|
+
.regex(/^[1-9A-HJ-NP-Za-km-z]+$/)
|
|
233
|
+
.describe("Base58 Ed25519 signature made externally over the challenge payload."),
|
|
234
|
+
},
|
|
235
|
+
annotations: {
|
|
236
|
+
readOnlyHint: false,
|
|
237
|
+
destructiveHint: false,
|
|
238
|
+
idempotentHint: false,
|
|
239
|
+
openWorldHint: true,
|
|
240
|
+
},
|
|
241
|
+
}, async ({ market, challengeId, authorizationSignature }) => guardedTool(client, "trade.prepare", async () => {
|
|
242
|
+
const request = {
|
|
243
|
+
market,
|
|
244
|
+
challengeId,
|
|
245
|
+
authorizationSignature,
|
|
246
|
+
};
|
|
247
|
+
const response = await client.executionPrepare(request);
|
|
248
|
+
return toolResult(response, `Prepared execution ${response.execution_id}; externally verify and sign before ${response.expires_at_ms}.`);
|
|
249
|
+
}));
|
|
250
|
+
const executionSubmit = server.registerTool("strata_execution_submit", {
|
|
251
|
+
title: "Submit Strata execution",
|
|
252
|
+
description: "Submit an externally signed prepared transaction with an idempotency key.",
|
|
253
|
+
inputSchema: {
|
|
254
|
+
market: z.string().min(1).max(128).describe("Market label or public market ID."),
|
|
255
|
+
executionId: z
|
|
256
|
+
.string()
|
|
257
|
+
.regex(/^se_[0-9a-f]{32}$/)
|
|
258
|
+
.describe("Prepared execution ID returned by Strata."),
|
|
259
|
+
signedTransactionBase64: z
|
|
260
|
+
.string()
|
|
261
|
+
.min(4)
|
|
262
|
+
.max(8_192)
|
|
263
|
+
.regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/)
|
|
264
|
+
.describe("The externally signed Solana transaction in canonical base64."),
|
|
265
|
+
idempotencyKey: z
|
|
266
|
+
.string()
|
|
267
|
+
.min(1)
|
|
268
|
+
.max(64)
|
|
269
|
+
.regex(/^[A-Za-z0-9._-]+$/)
|
|
270
|
+
.describe("Stable retry key for exactly this execution."),
|
|
271
|
+
},
|
|
272
|
+
annotations: {
|
|
273
|
+
readOnlyHint: false,
|
|
274
|
+
destructiveHint: true,
|
|
275
|
+
idempotentHint: true,
|
|
276
|
+
openWorldHint: true,
|
|
277
|
+
},
|
|
278
|
+
}, async ({ market, executionId, signedTransactionBase64, idempotencyKey }) => guardedTool(client, "trade.submit", async () => {
|
|
279
|
+
const request = {
|
|
280
|
+
market,
|
|
281
|
+
executionId,
|
|
282
|
+
signedTransactionBase64,
|
|
283
|
+
idempotencyKey,
|
|
284
|
+
};
|
|
285
|
+
const response = await client.executionSubmit(request);
|
|
286
|
+
return toolResult(response, `Submitted execution ${response.execution_id} as ${response.signature}.`);
|
|
287
|
+
}));
|
|
288
|
+
const handles = {
|
|
289
|
+
markets,
|
|
290
|
+
quote,
|
|
291
|
+
executionChallenge,
|
|
292
|
+
executionPrepare,
|
|
293
|
+
executionSubmit,
|
|
294
|
+
};
|
|
162
295
|
applyCapabilityCatalog(handles, initialCatalog);
|
|
163
296
|
let closed = false;
|
|
164
297
|
const refresh = async () => {
|
|
@@ -185,6 +318,9 @@ export async function createStrataMcpServer(options = {}) {
|
|
|
185
318
|
function applyCapabilityCatalog(handles, catalog) {
|
|
186
319
|
setToolEnabled(handles.markets, capabilityAvailable(catalog, "markets.read"));
|
|
187
320
|
setToolEnabled(handles.quote, capabilityAvailable(catalog, "quotes.read"));
|
|
321
|
+
setToolEnabled(handles.executionChallenge, capabilityAvailable(catalog, "trade.prepare"));
|
|
322
|
+
setToolEnabled(handles.executionPrepare, capabilityAvailable(catalog, "trade.prepare"));
|
|
323
|
+
setToolEnabled(handles.executionSubmit, capabilityAvailable(catalog, "trade.submit"));
|
|
188
324
|
}
|
|
189
325
|
function setToolEnabled(tool, enabled) {
|
|
190
326
|
if (enabled)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratabook/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Connect AI agents to Strata markets and Sonar quotes with MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT OR Apache-2.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
47
|
-
"@stratabook/sdk": "0.1.
|
|
47
|
+
"@stratabook/sdk": "0.1.4",
|
|
48
48
|
"zod": "^3.25.76"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|