@stratabook/mcp 0.2.3 → 0.2.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/README.md CHANGED
@@ -45,6 +45,8 @@ The tools currently available are:
45
45
  - `strata_portfolio_history`
46
46
  - `strata_market_making_status`
47
47
  - `strata_market_making_reputation`
48
+ - `strata_market_making_prepare` — start or stop a Strand/Current from a market label, decimal base size, spread, and duration; no arrays or atom conversion
49
+ - `strata_market_making_submit_and_wait` — submit the externally signed preparation idempotently and wait for matching chain-derived state
48
50
  - `strata_market_making_strand_prepare`, `strata_market_making_strand_submit`
49
51
  - `strata_market_making_current_prepare`, `strata_market_making_current_submit`
50
52
  - `strata_vault_status`
@@ -82,6 +84,27 @@ so a disabled capability stops immediately even if a client cached an older
82
84
  tool list. Tool discovery from the connected server remains authoritative for
83
85
  self-hosted deployments or any future policy change.
84
86
 
87
+ For normal maker operation, use two calls:
88
+
89
+ 1. Call `strata_market_making_prepare` with `action: "start"`, a label such as
90
+ `SOL/USDC`, `product: "current"` or `"strand"`, `spreadBps`, a decimal size
91
+ such as `0.01 SOL`, and the maker wallet. Duration defaults to ten minutes
92
+ and levels default to three.
93
+ 2. Verify and sign only `prepared.transaction_base64` in the external wallet,
94
+ then pass it and `prepared.maker_control_id` to
95
+ `strata_market_making_submit_and_wait`.
96
+
97
+ The second call returns only after Strata's chain-derived maker status matches
98
+ the exact product settings. Use `action: "stop"` through the same pair. The
99
+ older product-specific tools remain available for strategies that deliberately
100
+ manage every low-level array and safety field.
101
+
102
+ For maker funding, initialize the market Vault if needed, activate the Strand
103
+ or Current, then deposit with `strata_vault_deposit`. The market keeps that
104
+ available collateral while a control is live and returns it after the final
105
+ control is disabled, exhausted, expired, or cancelled. Current follows Strata's
106
+ live mark and needs no separate publisher transaction.
107
+
85
108
  ## Hosted Streamable HTTP
86
109
 
87
110
  The managed public endpoint is:
@@ -21,6 +21,8 @@ const LEGACY_TOOL_CAPABILITIES = {
21
21
  strata_market_making_strand_submit: { ids: ["mm.strand.manage"] },
22
22
  strata_market_making_current_prepare: { ids: ["mm.current.manage"] },
23
23
  strata_market_making_current_submit: { ids: ["mm.current.manage"] },
24
+ strata_market_making_prepare: { ids: ["mm.strand.manage", "mm.current.manage"], match: "any" },
25
+ strata_market_making_submit_and_wait: { ids: ["mm.strand.manage", "mm.current.manage"], match: "any" },
24
26
  strata_execute_quote: { ids: ["trade.submit"] },
25
27
  strata_order_execute: { ids: ["orders.prepare", "orders.submit"] },
26
28
  };
@@ -61,6 +63,8 @@ const PLATFORM_TOOL_CAPABILITIES = {
61
63
  strata_market_making_strand_submit: { ids: ["mm.strand.manage"] },
62
64
  strata_market_making_current_prepare: { ids: ["mm.current.manage"] },
63
65
  strata_market_making_current_submit: { ids: ["mm.current.manage"] },
66
+ strata_market_making_prepare: { ids: ["mm.strand.manage", "mm.current.manage"], match: "any" },
67
+ strata_market_making_submit_and_wait: { ids: ["mm.strand.manage", "mm.current.manage"], match: "any" },
64
68
  strata_rewards: { ids: ["rewards.read"] },
65
69
  strata_referrals: { ids: ["referrals.read"] },
66
70
  strata_referral_link: { ids: ["referrals.link"] },
@@ -256,6 +260,7 @@ export async function createStrataMcpServer(options = {}) {
256
260
  instructions: STRATA_AGENT_HARNESS_INSTRUCTIONS,
257
261
  });
258
262
  const { registerTool, handles: registeredTools } = trackedToolRegistrar(server);
263
+ const makerQuickstartPreparations = new Map();
259
264
  server.registerResource("strata_agent_harness", STRATA_AGENT_HARNESS_URI, {
260
265
  title: "Strata Agent Harness",
261
266
  description: "Canonical capability-gated first-run workflow for Strata agents.",
@@ -1509,6 +1514,109 @@ export async function createStrataMcpServer(options = {}) {
1509
1514
  const response = await platformClient.orders.status(marketId, { orderControlId, idempotencyKey });
1510
1515
  return toolResult(response, `Order control ${response.order_control_id} is ${response.status}.`);
1511
1516
  }));
1517
+ const makerPrepare = registerTool("strata_market_making_prepare", {
1518
+ title: "Prepare simple Strata market making",
1519
+ description: "Prepare a pro-level Strand or Current from a market label, decimal base size, spread, and duration. Strata resolves IDs, decimals, live mark, tick grid, expiry, safety bounds, and fixed on-chain arrays. Sign only the returned transaction externally, then call submit_and_wait.",
1520
+ inputSchema: {
1521
+ action: z.enum(["start", "stop"]),
1522
+ market: z.string().min(1).max(128),
1523
+ product: z.enum(["strand", "current"]),
1524
+ makerWallet: z.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/),
1525
+ spreadBps: z.number().int().min(1).max(5_000).optional(),
1526
+ size: z.string().min(1).max(64).optional(),
1527
+ duration: z.union([
1528
+ z.number().int().min(1).max(604_800),
1529
+ z.string().regex(/^[1-9][0-9]*(?:s|m|h|d)$/i),
1530
+ ]).optional(),
1531
+ levels: z.number().int().min(1).max(16).optional(),
1532
+ levelStepBps: z.number().int().min(1).max(5_000).optional(),
1533
+ side: z.enum(["both", "buy", "sell"]).optional(),
1534
+ asyncOnly: z.boolean().optional(),
1535
+ },
1536
+ annotations: {
1537
+ readOnlyHint: false,
1538
+ destructiveHint: true,
1539
+ idempotentHint: false,
1540
+ openWorldHint: true,
1541
+ },
1542
+ }, async (args) => guardedTool(client, `mm.${args.product}.manage`, async () => {
1543
+ const prepared = args.action === "stop"
1544
+ ? await platformClient.marketMaking.prepareStop({
1545
+ market: args.market,
1546
+ product: args.product,
1547
+ makerWallet: args.makerWallet,
1548
+ })
1549
+ : (() => {
1550
+ if (args.spreadBps === undefined || args.size === undefined) {
1551
+ return undefined;
1552
+ }
1553
+ return platformClient.marketMaking.prepareStart({
1554
+ market: args.market,
1555
+ product: args.product,
1556
+ makerWallet: args.makerWallet,
1557
+ spreadBps: args.spreadBps,
1558
+ size: args.size,
1559
+ ...(args.duration === undefined ? {} : { duration: args.duration }),
1560
+ ...(args.levels === undefined ? {} : { levels: args.levels }),
1561
+ ...(args.levelStepBps === undefined ? {} : { levelStepBps: args.levelStepBps }),
1562
+ ...(args.side === undefined ? {} : { side: args.side }),
1563
+ ...(args.asyncOnly === undefined ? {} : { asyncOnly: args.asyncOnly }),
1564
+ });
1565
+ })();
1566
+ if (prepared === undefined) {
1567
+ return toolError("invalid_request", "Starting market making requires spreadBps and size.", false);
1568
+ }
1569
+ const resolved = await prepared;
1570
+ makerQuickstartPreparations.set(resolved.prepared.maker_control_id, resolved);
1571
+ while (makerQuickstartPreparations.size > 128) {
1572
+ const oldest = makerQuickstartPreparations.keys().next().value;
1573
+ if (oldest === undefined)
1574
+ break;
1575
+ makerQuickstartPreparations.delete(oldest);
1576
+ }
1577
+ const response = {
1578
+ action: args.action,
1579
+ market: resolved.market,
1580
+ product: resolved.product,
1581
+ ...("base_asset" in resolved ? { base_asset: resolved.base_asset } : {}),
1582
+ operation: resolved.operation,
1583
+ prepared: resolved.prepared,
1584
+ };
1585
+ return toolResult(response, `Prepared ${args.action} for ${resolved.market.label} as ${resolved.prepared.maker_control_id}. Verify and sign only prepared.transaction_base64, then submit it within 30 seconds.`);
1586
+ }));
1587
+ const makerSubmitAndWait = registerTool("strata_market_making_submit_and_wait", {
1588
+ title: "Submit and confirm Strata market making",
1589
+ description: "Submit the exact externally signed quickstart transaction and wait until Strata's chain-derived maker state confirms the product started or stopped. The control ID is its default idempotency key.",
1590
+ inputSchema: {
1591
+ makerControlId: z.string().regex(/^mc_[0-9a-f]{32}$/),
1592
+ signedTransactionBase64: z.string().min(4).max(4_096).regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/),
1593
+ idempotencyKey: z.string().min(1).max(64).regex(/^[A-Za-z0-9._-]+$/).optional(),
1594
+ confirmationTimeoutMs: z.number().int().min(1_000).max(120_000).optional(),
1595
+ },
1596
+ annotations: {
1597
+ readOnlyHint: false,
1598
+ destructiveHint: true,
1599
+ idempotentHint: true,
1600
+ openWorldHint: true,
1601
+ },
1602
+ }, async (args) => {
1603
+ const prepared = makerQuickstartPreparations.get(args.makerControlId);
1604
+ if (!prepared) {
1605
+ return toolError("session_expired", "This quickstart preparation is not in the current MCP session. Prepare it again; maker transactions expire after 30 seconds.", false);
1606
+ }
1607
+ return guardedTool(client, `mm.${prepared.product}.manage`, async () => {
1608
+ const response = await platformClient.marketMaking.submitPrepared({
1609
+ prepared,
1610
+ signedTransactionBase64: args.signedTransactionBase64,
1611
+ ...(args.idempotencyKey === undefined ? {} : { idempotencyKey: args.idempotencyKey }),
1612
+ ...(args.confirmationTimeoutMs === undefined
1613
+ ? {}
1614
+ : { confirmationTimeoutMs: args.confirmationTimeoutMs }),
1615
+ });
1616
+ makerQuickstartPreparations.delete(args.makerControlId);
1617
+ return toolResult(response, `${response.product} is confirmed ${response.operation.action === "cancel" ? "stopped" : "live"} on ${response.market.label}.`);
1618
+ });
1619
+ });
1512
1620
  const makerStrandPrepare = registerTool("strata_market_making_strand_prepare", {
1513
1621
  title: "Prepare Strata Strand control",
1514
1622
  description: "Build one exact unsigned maker-owned Strand transaction. Every exposure and level size is expressed in base-asset atoms, never lots or whole tokens. Verify and sign it externally with the maker wallet, then submit it with the Strand submit tool.",
@@ -1700,6 +1808,8 @@ export async function createStrataMcpServer(options = {}) {
1700
1808
  orderPrepare,
1701
1809
  orderSubmit,
1702
1810
  orderStatus,
1811
+ makerPrepare,
1812
+ makerSubmitAndWait,
1703
1813
  makerStrandPrepare,
1704
1814
  makerStrandSubmit,
1705
1815
  makerCurrentPrepare,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stratabook/mcp",
3
- "version": "0.2.3",
3
+ "version": "0.2.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.2.3",
47
+ "@stratabook/sdk": "0.2.5",
48
48
  "zod": "^3.25.76"
49
49
  },
50
50
  "devDependencies": {