@aibtc/mcp-server 1.70.1 → 1.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +45 -8
  2. package/dist/bridge/index.js +4 -4
  3. package/dist/config/contracts.d.ts +4 -4
  4. package/dist/config/contracts.js +2 -2
  5. package/dist/config/networks.js +4 -1
  6. package/dist/endpoints/registry.d.ts +8 -26
  7. package/dist/endpoints/registry.js +7 -932
  8. package/dist/index.js +118 -42
  9. package/dist/services/stacking.service.d.ts +144 -45
  10. package/dist/services/stacking.service.js +416 -123
  11. package/dist/services/x402-discovery.service.d.ts +81 -0
  12. package/dist/services/x402-discovery.service.js +170 -0
  13. package/dist/tools/arxiv-research.tools.d.ts +1 -1
  14. package/dist/tools/arxiv-research.tools.js +6 -6
  15. package/dist/tools/at-stake-legion.tools.d.ts +1 -1
  16. package/dist/tools/at-stake-legion.tools.js +14 -14
  17. package/dist/tools/at-stake.tools.d.ts +1 -1
  18. package/dist/tools/at-stake.tools.js +17 -17
  19. package/dist/tools/bitcoin.tools.d.ts +1 -1
  20. package/dist/tools/bitcoin.tools.js +12 -12
  21. package/dist/tools/bitflow.tools.d.ts +1 -1
  22. package/dist/tools/bitflow.tools.js +21 -21
  23. package/dist/tools/bns.tools.d.ts +1 -1
  24. package/dist/tools/bns.tools.js +18 -18
  25. package/dist/tools/bounty-hint.d.ts +1 -1
  26. package/dist/tools/bounty-scanner.tools.d.ts +1 -1
  27. package/dist/tools/bounty-scanner.tools.js +20 -20
  28. package/dist/tools/child-inscription.tools.d.ts +1 -1
  29. package/dist/tools/child-inscription.tools.js +6 -6
  30. package/dist/tools/competition.tools.d.ts +1 -1
  31. package/dist/tools/competition.tools.js +4 -4
  32. package/dist/tools/contract.tools.d.ts +1 -1
  33. package/dist/tools/contract.tools.js +8 -8
  34. package/dist/tools/credentials.tools.d.ts +1 -1
  35. package/dist/tools/credentials.tools.js +8 -8
  36. package/dist/tools/defi.tools.d.ts +1 -1
  37. package/dist/tools/defi.tools.js +21 -21
  38. package/dist/tools/dual-stacking.tools.d.ts +1 -1
  39. package/dist/tools/dual-stacking.tools.js +7 -7
  40. package/dist/tools/earning.tools.d.ts +1 -1
  41. package/dist/tools/earning.tools.js +5 -5
  42. package/dist/tools/endpoint.tools.d.ts +1 -1
  43. package/dist/tools/endpoint.tools.js +92 -49
  44. package/dist/tools/identity.tools.d.ts +1 -1
  45. package/dist/tools/identity.tools.js +19 -19
  46. package/dist/tools/inbox-x402.tools.d.ts +1 -1
  47. package/dist/tools/inbox-x402.tools.js +2 -2
  48. package/dist/tools/inbox.tools.d.ts +1 -1
  49. package/dist/tools/inbox.tools.js +2 -2
  50. package/dist/tools/index.d.ts +6 -3
  51. package/dist/tools/index.js +69 -58
  52. package/dist/tools/inference-marketplace.tools.d.ts +1 -1
  53. package/dist/tools/inference-marketplace.tools.js +10 -10
  54. package/dist/tools/jingswap.tools.d.ts +1 -1
  55. package/dist/tools/jingswap.tools.js +30 -30
  56. package/dist/tools/legion.tools.d.ts +1 -1
  57. package/dist/tools/legion.tools.js +20 -20
  58. package/dist/tools/lightning.tools.d.ts +1 -1
  59. package/dist/tools/lightning.tools.js +14 -14
  60. package/dist/tools/mempool.tools.d.ts +1 -1
  61. package/dist/tools/mempool.tools.js +5 -5
  62. package/dist/tools/news.tools.d.ts +1 -1
  63. package/dist/tools/news.tools.js +2 -1
  64. package/dist/tools/nft.tools.d.ts +1 -1
  65. package/dist/tools/nft.tools.js +12 -12
  66. package/dist/tools/nonce.tools.d.ts +1 -1
  67. package/dist/tools/nonce.tools.js +8 -8
  68. package/dist/tools/nostr.tools.d.ts +1 -1
  69. package/dist/tools/nostr.tools.js +12 -12
  70. package/dist/tools/openrouter.tools.d.ts +1 -1
  71. package/dist/tools/openrouter.tools.js +4 -4
  72. package/dist/tools/ordinals-marketplace.tools.d.ts +1 -1
  73. package/dist/tools/ordinals-marketplace.tools.js +10 -10
  74. package/dist/tools/ordinals-p2p.tools.d.ts +1 -1
  75. package/dist/tools/ordinals-p2p.tools.js +18 -18
  76. package/dist/tools/ordinals.tools.d.ts +1 -1
  77. package/dist/tools/ordinals.tools.js +8 -8
  78. package/dist/tools/pillar-direct.tools.d.ts +1 -1
  79. package/dist/tools/pillar-direct.tools.js +59 -38
  80. package/dist/tools/pillar.tools.d.ts +1 -1
  81. package/dist/tools/pillar.tools.js +28 -26
  82. package/dist/tools/profiles.d.ts +51 -0
  83. package/dist/tools/profiles.js +111 -0
  84. package/dist/tools/psbt.tools.d.ts +1 -1
  85. package/dist/tools/psbt.tools.js +8 -8
  86. package/dist/tools/query.tools.d.ts +1 -1
  87. package/dist/tools/query.tools.js +12 -12
  88. package/dist/tools/relay-diagnostic.tools.d.ts +1 -1
  89. package/dist/tools/relay-diagnostic.tools.js +3 -3
  90. package/dist/tools/reputation.tools.d.ts +1 -1
  91. package/dist/tools/reputation.tools.js +22 -22
  92. package/dist/tools/runes.tools.d.ts +1 -1
  93. package/dist/tools/runes.tools.js +18 -18
  94. package/dist/tools/sbtc.tools.d.ts +1 -1
  95. package/dist/tools/sbtc.tools.js +14 -33
  96. package/dist/tools/scaffold.tools.d.ts +1 -1
  97. package/dist/tools/scaffold.tools.js +4 -4
  98. package/dist/tools/settings.tools.d.ts +1 -1
  99. package/dist/tools/settings.tools.js +9 -9
  100. package/dist/tools/signing.tools.d.ts +1 -1
  101. package/dist/tools/signing.tools.js +20 -20
  102. package/dist/tools/skill-mappings.js +4 -0
  103. package/dist/tools/souldinals.tools.d.ts +1 -1
  104. package/dist/tools/souldinals.tools.js +10 -10
  105. package/dist/tools/stacking-lottery.tools.d.ts +1 -1
  106. package/dist/tools/stacking-lottery.tools.js +11 -11
  107. package/dist/tools/stacking.tools.d.ts +1 -1
  108. package/dist/tools/stacking.tools.js +358 -50
  109. package/dist/tools/stacks-market.tools.d.ts +1 -1
  110. package/dist/tools/stacks-market.tools.js +22 -22
  111. package/dist/tools/styx.tools.d.ts +1 -1
  112. package/dist/tools/styx.tools.js +11 -11
  113. package/dist/tools/taproot-multisig.tools.d.ts +1 -1
  114. package/dist/tools/taproot-multisig.tools.js +5 -5
  115. package/dist/tools/tenero.tools.d.ts +1 -1
  116. package/dist/tools/tenero.tools.js +22 -22
  117. package/dist/tools/tokens.tools.d.ts +1 -1
  118. package/dist/tools/tokens.tools.js +10 -10
  119. package/dist/tools/transfer.tools.d.ts +1 -1
  120. package/dist/tools/transfer.tools.js +4 -4
  121. package/dist/tools/wallet-management.tools.d.ts +1 -1
  122. package/dist/tools/wallet-management.tools.js +16 -16
  123. package/dist/tools/wallet.tools.d.ts +1 -1
  124. package/dist/tools/wallet.tools.js +2 -2
  125. package/dist/tools/yield-dashboard.tools.d.ts +1 -1
  126. package/dist/tools/yield-dashboard.tools.js +18 -27
  127. package/dist/tools/yield-hunter.tools.d.ts +1 -1
  128. package/dist/tools/yield-hunter.tools.js +6 -6
  129. package/dist/utils/bitcoin.d.ts +8 -0
  130. package/dist/utils/bitcoin.js +24 -0
  131. package/dist/utils/fee.js +1 -1
  132. package/package.json +8 -7
  133. package/skill/SKILL.md +1 -1
  134. package/skill/references/stacks-defi.md +1 -1
@@ -1,4 +1,3 @@
1
- import * as btc from "@scure/btc-signer";
2
1
  import { z } from "zod";
3
2
  import { getAccount, getWalletAddress, NETWORK } from "../services/x402.service.js";
4
3
  import { getSbtcService } from "../services/sbtc.service.js";
@@ -8,26 +7,8 @@ import { getContracts, parseContractId } from "../config/contracts.js";
8
7
  import { createJsonResponse, createErrorResponse, resolveFee } from "../utils/index.js";
9
8
  import { getWalletManager } from "../services/wallet-manager.js";
10
9
  import { MempoolApi, getMempoolTxUrl } from "../services/mempool-api.js";
11
- import { getBtcNetwork } from "../transactions/bitcoin-builder.js";
12
10
  import { sponsoredSchema } from "./schemas.js";
13
- function parseBtcRecipientTuple(btcRecipientAddress) {
14
- const decoded = btc.Address(getBtcNetwork(NETWORK)).decode(btcRecipientAddress);
15
- if (decoded.type === "tr" && decoded.pubkey) {
16
- return { version: 0x06, hashbytesHex: Buffer.from(decoded.pubkey).toString("hex") };
17
- }
18
- switch (decoded.type) {
19
- case "pkh":
20
- return { version: 0x00, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
21
- case "sh":
22
- return { version: 0x01, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
23
- case "wpkh":
24
- return { version: 0x04, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
25
- case "wsh":
26
- return { version: 0x05, hashbytesHex: Buffer.from(decoded.hash).toString("hex") };
27
- default:
28
- throw new Error("Unsupported BTC recipient address type. Supported: P2PKH, P2SH, P2WPKH, P2WSH, P2TR.");
29
- }
30
- }
11
+ import { btcAddressToPoxAddr } from "../utils/bitcoin.js";
31
12
  function getReadonlySenderAddress() {
32
13
  const contracts = getContracts(NETWORK);
33
14
  return parseContractId(contracts.SBTC_REGISTRY).address;
@@ -36,12 +17,12 @@ export function registerSbtcTools(server) {
36
17
  // Get sBTC balance
37
18
  server.registerTool("sbtc_get_balance", {
38
19
  description: "Get the sBTC balance for a wallet address.",
39
- inputSchema: {
20
+ inputSchema: z.object({
40
21
  address: z
41
22
  .string()
42
23
  .optional()
43
24
  .describe("Wallet address to check. Uses configured wallet if not provided."),
44
- },
25
+ }),
45
26
  }, async ({ address }) => {
46
27
  try {
47
28
  const sbtcService = getSbtcService(NETWORK);
@@ -66,7 +47,7 @@ export function registerSbtcTools(server) {
66
47
 
67
48
  sBTC uses 8 decimals (same as Bitcoin).
68
49
  Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
69
- inputSchema: {
50
+ inputSchema: z.object({
70
51
  recipient: z.string().describe("The recipient's Stacks address"),
71
52
  amount: z.string().describe("Amount in satoshis (0.00000001 sBTC). Example: '100000' for 0.001 sBTC"),
72
53
  memo: z.string().optional().describe("Optional memo message"),
@@ -75,7 +56,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
75
56
  .optional()
76
57
  .describe("Optional fee: 'low' | 'medium' | 'high' preset or micro-STX amount. If omitted, auto-estimated."),
77
58
  sponsored: sponsoredSchema,
78
- },
59
+ }),
79
60
  }, async ({ recipient, amount, memo, fee, sponsored }) => {
80
61
  try {
81
62
  const sbtcService = getSbtcService(NETWORK);
@@ -107,7 +88,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
107
88
  const sbtcService = getSbtcService(NETWORK);
108
89
  const account = await getAccount();
109
90
  const resolvedFee = await resolveFee(fee, NETWORK, "contract_call");
110
- const recipientTuple = parseBtcRecipientTuple(btcRecipientAddress);
91
+ const recipientTuple = btcAddressToPoxAddr(btcRecipientAddress, NETWORK);
111
92
  const result = await sbtcService.initiateWithdrawal(account, BigInt(amount), BigInt(maxFee), recipientTuple, resolvedFee, sponsored);
112
93
  let requestId = null;
113
94
  try {
@@ -118,7 +99,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
118
99
  }
119
100
  return { result, recipientTuple, requestId };
120
101
  }
121
- const withdrawalInputSchema = {
102
+ const withdrawalInputSchema = z.object({
122
103
  amount: z
123
104
  .number()
124
105
  .int()
@@ -139,7 +120,7 @@ Example: To send 0.001 sBTC, use amount "100000" (satoshis).`,
139
120
  .optional()
140
121
  .describe("Optional fee: 'low' | 'medium' | 'high' preset or micro-STX amount."),
141
122
  sponsored: sponsoredSchema,
142
- };
123
+ });
143
124
  // Initiate sBTC withdrawal (peg-out to BTC L1)
144
125
  server.registerTool("sbtc_initiate_withdrawal", {
145
126
  description: `Initiate an sBTC peg-out to a Bitcoin L1 address.
@@ -242,7 +223,7 @@ Signers later process the request and send BTC on L1.`,
242
223
  ...(txid ? { explorerUrl: getExplorerTxUrl(txid, NETWORK) } : {}),
243
224
  });
244
225
  }
245
- const withdrawalStatusInputSchema = {
226
+ const withdrawalStatusInputSchema = z.object({
246
227
  requestId: z
247
228
  .number()
248
229
  .int()
@@ -253,7 +234,7 @@ Signers later process the request and send BTC on L1.`,
253
234
  .string()
254
235
  .optional()
255
236
  .describe("Initiate-withdrawal transaction ID (used to resolve requestId)"),
256
- };
237
+ });
257
238
  // Check withdrawal request status
258
239
  server.registerTool("sbtc_withdrawal_status", {
259
240
  description: "Check status of an sBTC withdrawal request by requestId or initiating txid.",
@@ -352,7 +333,7 @@ If the deposit fails, you can reclaim your BTC after the lock time expires.
352
333
 
353
334
  By default, only uses cardinal UTXOs (safe to spend - no inscriptions).
354
335
  Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`,
355
- inputSchema: {
336
+ inputSchema: z.object({
356
337
  amount: z
357
338
  .number()
358
339
  .int()
@@ -386,7 +367,7 @@ Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`
386
367
  .default(false)
387
368
  .describe("Include ordinal UTXOs (contains inscriptions). Default: false (cardinal only). " +
388
369
  "WARNING: Setting this to true may destroy valuable inscriptions!"),
389
- },
370
+ }),
390
371
  }, async ({ amount, feeRate, maxSignerFee, reclaimLockTime, includeOrdinals }) => {
391
372
  try {
392
373
  // Get wallet account (requires unlocked wallet)
@@ -459,7 +440,7 @@ Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`
459
440
  // Check sBTC deposit status
460
441
  server.registerTool("sbtc_deposit_status", {
461
442
  description: "Check the status of an sBTC deposit transaction from Emily API.",
462
- inputSchema: {
443
+ inputSchema: z.object({
463
444
  txid: z.string().describe("Bitcoin transaction ID of the deposit"),
464
445
  vout: z
465
446
  .number()
@@ -468,7 +449,7 @@ Set includeOrdinals=true to allow spending ordinal UTXOs (advanced users only).`
468
449
  .optional()
469
450
  .default(0)
470
451
  .describe("Output index of the deposit (default: 0)"),
471
- },
452
+ }),
472
453
  }, async ({ txid, vout }) => {
473
454
  try {
474
455
  const depositService = getSbtcDepositService(NETWORK);
@@ -1,3 +1,3 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
2
  export declare function registerScaffoldTools(server: McpServer): void;
3
3
  //# sourceMappingURL=scaffold.tools.d.ts.map
@@ -91,7 +91,7 @@ cd {projectName}
91
91
  npm install
92
92
  npm run dev
93
93
  \`\`\``,
94
- inputSchema: {
94
+ inputSchema: z.object({
95
95
  outputDir: z
96
96
  .string()
97
97
  .describe("Directory where the project folder will be created (e.g., '/Users/me/projects' or '.')"),
@@ -135,7 +135,7 @@ npm run dev
135
135
  .url()
136
136
  .optional()
137
137
  .describe("Custom relay URL (default: https://x402-relay.aibtc.com)"),
138
- },
138
+ }),
139
139
  }, async ({ outputDir, projectName, endpoints, recipientAddress, network, relayUrl }) => {
140
140
  try {
141
141
  const projectPath = path.join(outputDir, projectName);
@@ -210,7 +210,7 @@ npm install
210
210
  # Edit .dev.vars with RECIPIENT_ADDRESS and OPENROUTER_API_KEY
211
211
  npm run dev
212
212
  \`\`\``,
213
- inputSchema: {
213
+ inputSchema: z.object({
214
214
  outputDir: z
215
215
  .string()
216
216
  .describe("Directory where the project folder will be created (e.g., '/Users/me/projects' or '.')"),
@@ -264,7 +264,7 @@ npm run dev
264
264
  .optional()
265
265
  .default("anthropic/claude-3-haiku")
266
266
  .describe("Default OpenRouter model for all endpoints (default: anthropic/claude-3-haiku)"),
267
- },
267
+ }),
268
268
  }, async ({ outputDir, projectName, endpoints, recipientAddress, network, relayUrl, defaultModel, }) => {
269
269
  try {
270
270
  const projectPath = path.join(outputDir, projectName);
@@ -1,4 +1,4 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
2
  /**
3
3
  * Register settings tools for API key management
4
4
  */
@@ -16,12 +16,12 @@ export function registerSettingsTools(server) {
16
16
  description: `Save a Hiro API key to ~/.aibtc/config.json for authenticated Hiro API requests.
17
17
  Authenticated requests get higher rate limits than public (unauthenticated) requests.
18
18
  Get a free API key at https://platform.hiro.so/`,
19
- inputSchema: {
19
+ inputSchema: z.object({
20
20
  apiKey: z
21
21
  .string()
22
22
  .min(1)
23
23
  .describe("Your Hiro API key - WARNING: sensitive value"),
24
- },
24
+ }),
25
25
  }, async ({ apiKey }) => {
26
26
  try {
27
27
  await initializeStorage();
@@ -45,7 +45,7 @@ Get a free API key at https://platform.hiro.so/`,
45
45
  */
46
46
  server.registerTool("get_hiro_api_key", {
47
47
  description: "Check whether a Hiro API key is configured. Shows the key source (stored file or environment variable) and a masked preview.",
48
- inputSchema: {},
48
+ inputSchema: z.object({}),
49
49
  }, async () => {
50
50
  try {
51
51
  await initializeStorage();
@@ -81,7 +81,7 @@ Get a free API key at https://platform.hiro.so/`,
81
81
  */
82
82
  server.registerTool("delete_hiro_api_key", {
83
83
  description: "Remove the stored Hiro API key from ~/.aibtc/config.json. If HIRO_API_KEY is set in the environment, that will still be used as a fallback.",
84
- inputSchema: {},
84
+ inputSchema: z.object({}),
85
85
  }, async () => {
86
86
  try {
87
87
  await initializeStorage();
@@ -114,12 +114,12 @@ Get a free API key at https://platform.hiro.so/`,
114
114
  Use this if you run your own stacks-blockchain-api node (default port 3999) or use a third-party provider.
115
115
  The URL should serve the same /v2/ and /extended/v1/ endpoints as api.hiro.so.
116
116
  Example: http://localhost:3999`,
117
- inputSchema: {
117
+ inputSchema: z.object({
118
118
  url: z
119
119
  .string()
120
120
  .url()
121
121
  .describe("Base URL of your Stacks API node (e.g. http://localhost:3999)"),
122
- },
122
+ }),
123
123
  }, async ({ url }) => {
124
124
  try {
125
125
  await initializeStorage();
@@ -143,7 +143,7 @@ Example: http://localhost:3999`,
143
143
  */
144
144
  server.registerTool("get_stacks_api_url", {
145
145
  description: "Show the current Stacks API URL being used for blockchain queries. Indicates whether it's a custom node or the default Hiro API.",
146
- inputSchema: {},
146
+ inputSchema: z.object({}),
147
147
  }, async () => {
148
148
  try {
149
149
  await initializeStorage();
@@ -169,7 +169,7 @@ Example: http://localhost:3999`,
169
169
  */
170
170
  server.registerTool("delete_stacks_api_url", {
171
171
  description: "Remove the custom Stacks API URL and revert to the default Hiro API (api.mainnet.hiro.so or api.testnet.hiro.so).",
172
- inputSchema: {},
172
+ inputSchema: z.object({}),
173
173
  }, async () => {
174
174
  try {
175
175
  await initializeStorage();
@@ -199,7 +199,7 @@ Example: http://localhost:3999`,
199
199
  description: `Check the currently running MCP server version and compare with the latest published version on npm.
200
200
  Use this to detect if you're running a stale cached version (common with npx).
201
201
  If your version is outdated, clear the npx cache and restart your MCP client: npx clear-npx-cache (the client config already points at @latest, so the next launch pulls the newest version).`,
202
- inputSchema: {},
202
+ inputSchema: z.object({}),
203
203
  }, async () => {
204
204
  try {
205
205
  const currentVersion = packageJson.version;
@@ -24,6 +24,6 @@
24
24
  * Bitcoin signatures use BIP-137 format compatible with most Bitcoin wallets.
25
25
  * Nostr events are signed with BIP-340 Schnorr and can be published to Nostr relays.
26
26
  */
27
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
27
+ import { McpServer } from "@modelcontextprotocol/server";
28
28
  export declare function registerSigningTools(server: McpServer): void;
29
29
  //# sourceMappingURL=signing.tools.d.ts.map
@@ -534,7 +534,7 @@ export function registerSigningTools(server) {
534
534
  "Creates a signature that can be verified both off-chain and on-chain by smart contracts. " +
535
535
  "Use cases: meta-transactions, off-chain voting, permits, proving address control. " +
536
536
  "Requires an unlocked wallet.",
537
- inputSchema: {
537
+ inputSchema: z.object({
538
538
  message: z
539
539
  .record(z.string(), z.unknown())
540
540
  .describe("The structured data to sign as a JSON object. " +
@@ -547,7 +547,7 @@ export function registerSigningTools(server) {
547
547
  version: z.string().describe("Application version (e.g., '1.0.0')"),
548
548
  })
549
549
  .describe("Domain binding for the signature. Prevents cross-app and cross-version replay."),
550
- },
550
+ }),
551
551
  }, async ({ message, domain }) => {
552
552
  try {
553
553
  const account = requireUnlockedWallet();
@@ -604,7 +604,7 @@ export function registerSigningTools(server) {
604
604
  description: "Verify a SIP-018 signature and recover the signer's address. " +
605
605
  "Takes the verification hash (from sip018_sign or sip018_hash 'verification' field) and the signature, " +
606
606
  "then recovers the public key and derives the signer's Stacks address.",
607
- inputSchema: {
607
+ inputSchema: z.object({
608
608
  messageHash: z
609
609
  .string()
610
610
  .describe("The SIP-018 verification hash (from sip018_sign/sip018_hash 'verification' field). " +
@@ -617,7 +617,7 @@ export function registerSigningTools(server) {
617
617
  .optional()
618
618
  .describe("Optional: expected signer address to verify against. " +
619
619
  "If provided, returns whether the signature is valid for this signer."),
620
- },
620
+ }),
621
621
  }, async ({ messageHash, signature, expectedSigner }) => {
622
622
  try {
623
623
  // Recover public key from signature
@@ -657,7 +657,7 @@ export function registerSigningTools(server) {
657
657
  "Returns the full encoded hash, domain hash, and message hash. " +
658
658
  "Useful for preparing data for on-chain verification or multi-sig coordination. " +
659
659
  "Does not require an unlocked wallet.",
660
- inputSchema: {
660
+ inputSchema: z.object({
661
661
  message: z
662
662
  .record(z.string(), z.unknown())
663
663
  .describe("The structured data as a JSON object. " +
@@ -673,7 +673,7 @@ export function registerSigningTools(server) {
673
673
  .describe("Optional chain ID. Defaults to current network (1 for mainnet, 2147483648 for testnet)"),
674
674
  })
675
675
  .describe("Domain binding for the hash"),
676
- },
676
+ }),
677
677
  }, async ({ message, domain }) => {
678
678
  try {
679
679
  // Use provided chainId or default to current network
@@ -726,11 +726,11 @@ export function registerSigningTools(server) {
726
726
  "The message is prefixed with '\\x17Stacks Signed Message:\\n' before hashing (SIWS-compatible). " +
727
727
  "Use cases: proving address ownership, authentication, sign-in flows. " +
728
728
  "Requires an unlocked wallet.",
729
- inputSchema: {
729
+ inputSchema: z.object({
730
730
  message: z
731
731
  .string()
732
732
  .describe("The plain text message to sign. Will be prefixed with Stacks message prefix before signing."),
733
- },
733
+ }),
734
734
  }, async ({ message }) => {
735
735
  try {
736
736
  const account = requireUnlockedWallet();
@@ -768,7 +768,7 @@ export function registerSigningTools(server) {
768
768
  description: "Verify a Stacks message signature and recover the signer's address. " +
769
769
  "Takes the original message and signature, applies the Stacks prefix, and verifies. " +
770
770
  "Compatible with SIWS (Sign In With Stacks) authentication flows.",
771
- inputSchema: {
771
+ inputSchema: z.object({
772
772
  message: z
773
773
  .string()
774
774
  .describe("The original plain text message that was signed."),
@@ -781,7 +781,7 @@ export function registerSigningTools(server) {
781
781
  .optional()
782
782
  .describe("Optional: expected signer address to verify against. " +
783
783
  "If provided, returns whether the signature is valid for this signer."),
784
- },
784
+ }),
785
785
  }, async ({ message, signature, expectedSigner }) => {
786
786
  try {
787
787
  // Hash the message with the Stacks prefix
@@ -843,7 +843,7 @@ export function registerSigningTools(server) {
843
843
  "Use addressType 'p2tr' to force signing with the Taproot key. " +
844
844
  "Use cases: proving Bitcoin address ownership, authentication, off-chain verification. " +
845
845
  "Requires an unlocked wallet with Bitcoin keys.",
846
- inputSchema: {
846
+ inputSchema: z.object({
847
847
  message: z
848
848
  .string()
849
849
  .describe("The plain text message to sign."),
@@ -852,7 +852,7 @@ export function registerSigningTools(server) {
852
852
  .optional()
853
853
  .describe("Optional: address type to sign with. 'p2wpkh' uses native SegWit (bc1q, BIP-322), " +
854
854
  "'p2tr' uses Taproot (bc1p, BIP-322). If omitted, auto-detects from wallet address type."),
855
- },
855
+ }),
856
856
  }, async ({ message, addressType }) => {
857
857
  try {
858
858
  const account = requireUnlockedWallet();
@@ -993,7 +993,7 @@ export function registerSigningTools(server) {
993
993
  "BIP-137 works for legacy addresses; BIP-322 is required for bc1q and bc1p addresses. " +
994
994
  "Takes the original message and signature (hex or base64). " +
995
995
  "Compatible with signatures from most Bitcoin wallets.",
996
- inputSchema: {
996
+ inputSchema: z.object({
997
997
  message: z
998
998
  .string()
999
999
  .describe("The original plain text message that was signed."),
@@ -1012,7 +1012,7 @@ export function registerSigningTools(server) {
1012
1012
  .optional()
1013
1013
  .describe("Optional: alias for address (backward compatibility). " +
1014
1014
  "If address is not provided, this is used instead."),
1015
- },
1015
+ }),
1016
1016
  }, async ({ message, signature, address, expectedSigner }) => {
1017
1017
  try {
1018
1018
  // Use address param, fall back to expectedSigner for backward compat
@@ -1188,7 +1188,7 @@ export function registerSigningTools(server) {
1188
1188
  "you need a BIP-340 Schnorr signature over a pre-computed hash (e.g., BIP-341 sighash). " +
1189
1189
  "WARNING: This signs raw digests that cannot be human-verified — use confirmBlindSign=true after reviewing the digest. " +
1190
1190
  "Returns a 64-byte signature and the x-only public key. Requires an unlocked wallet.",
1191
- inputSchema: {
1191
+ inputSchema: z.object({
1192
1192
  digest: z
1193
1193
  .string()
1194
1194
  .length(64)
@@ -1205,7 +1205,7 @@ export function registerSigningTools(server) {
1205
1205
  .optional()
1206
1206
  .describe("Set to true to confirm you have reviewed the digest and accept the risk of signing a raw hash. " +
1207
1207
  "Default is false, which returns a warning with the digest for review before signing."),
1208
- },
1208
+ }),
1209
1209
  }, async ({ digest, auxRand, confirmBlindSign }) => {
1210
1210
  try {
1211
1211
  // Safety gate: require explicit confirmation before signing a raw digest.
@@ -1257,7 +1257,7 @@ export function registerSigningTools(server) {
1257
1257
  description: "Verify a BIP-340 Schnorr signature over a 32-byte digest. " +
1258
1258
  "Takes the digest, signature, and public key, returns whether the signature is valid. " +
1259
1259
  "Use for verifying Taproot signatures from other agents in multisig coordination.",
1260
- inputSchema: {
1260
+ inputSchema: z.object({
1261
1261
  digest: z
1262
1262
  .string()
1263
1263
  .length(64)
@@ -1273,7 +1273,7 @@ export function registerSigningTools(server) {
1273
1273
  .length(64)
1274
1274
  .regex(/^[0-9a-fA-F]+$/)
1275
1275
  .describe("32-byte hex-encoded x-only public key of the signer"),
1276
- },
1276
+ }),
1277
1277
  }, async ({ digest, signature, publicKey }) => {
1278
1278
  try {
1279
1279
  // Decode inputs (Zod schema enforces correct hex lengths:
@@ -1307,7 +1307,7 @@ export function registerSigningTools(server) {
1307
1307
  "Computes the NIP-01 event ID (SHA-256 of the canonical serialization) and signs it. " +
1308
1308
  "Returns the complete signed event ready to publish to Nostr relays. " +
1309
1309
  "Requires an unlocked wallet.",
1310
- inputSchema: {
1310
+ inputSchema: z.object({
1311
1311
  kind: z
1312
1312
  .number()
1313
1313
  .int()
@@ -1329,7 +1329,7 @@ export function registerSigningTools(server) {
1329
1329
  .describe("Key to sign with. 'nostr' (default): NIP-06 derived key (m/44'/1237'/0'/0/0). " +
1330
1330
  "'taproot': BIP-86 Taproot internal key. " +
1331
1331
  "'segwit': SegWit/P2WPKH key (x-only, 32 bytes)."),
1332
- },
1332
+ }),
1333
1333
  }, async ({ kind, content, tags, created_at, keySource }) => {
1334
1334
  try {
1335
1335
  const account = requireUnlockedWallet();
@@ -68,6 +68,10 @@ export const TOOL_SKILL_MAP = {
68
68
  get_stacking_status: "stacking",
69
69
  stack_stx: "stacking",
70
70
  extend_stacking: "stacking",
71
+ list_stacking_signers: "stacking",
72
+ unstake_stx: "stacking",
73
+ get_stacking_rewards: "stacking",
74
+ claim_stacking_rewards: "stacking",
71
75
  // dual-stacking skill — sBTC Dual Stacking yield protocol
72
76
  dual_stacking_status: "dual-stacking",
73
77
  dual_stacking_get_rewards: "dual-stacking",
@@ -13,6 +13,6 @@
13
13
  * Uses child inscription builders for on-chain provenance (parent-child relationship)
14
14
  * and Unisat Ordinals API for listing/loading inscriptions.
15
15
  */
16
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
+ import { McpServer } from "@modelcontextprotocol/server";
17
17
  export declare function registerSouldinalsTools(server: McpServer): void;
18
18
  //# sourceMappingURL=souldinals.tools.d.ts.map
@@ -200,7 +200,7 @@ export function registerSouldinalsTools(server) {
200
200
  "This broadcasts the commit tx and returns immediately. After it confirms " +
201
201
  "(typically 10-60 min), use `souldinals_reveal_soul` to complete.\n\n" +
202
202
  "Returns: commitTxid, revealAmount, contentBase64 (save all for souldinals_reveal_soul)",
203
- inputSchema: {
203
+ inputSchema: z.object({
204
204
  parentInscriptionId: z
205
205
  .string()
206
206
  .describe("Genesis parent inscription ID (format: {txid}i{index}). You must own this inscription."),
@@ -211,7 +211,7 @@ export function registerSouldinalsTools(server) {
211
211
  .union([z.enum(["fast", "medium", "slow"]), z.number().positive()])
212
212
  .optional()
213
213
  .describe("Fee rate: 'fast' (~10 min), 'medium' (~30 min), 'slow' (~1 hr), or number in sat/vB (default: medium)"),
214
- },
214
+ }),
215
215
  }, async ({ parentInscriptionId, soulContent, feeRate }) => {
216
216
  try {
217
217
  const walletManager = getWalletManager();
@@ -303,7 +303,7 @@ export function registerSouldinalsTools(server) {
303
303
  "The reveal tx spends both the commit output and the parent inscription UTXO, " +
304
304
  "returning the parent to your address and creating the child soul inscription.\n\n" +
305
305
  "Returns: inscriptionId ({revealTxid}i0) on success",
306
- inputSchema: {
306
+ inputSchema: z.object({
307
307
  commitTxid: z
308
308
  .string()
309
309
  .length(64)
@@ -322,7 +322,7 @@ export function registerSouldinalsTools(server) {
322
322
  .union([z.enum(["fast", "medium", "slow"]), z.number().positive()])
323
323
  .optional()
324
324
  .describe("Fee rate for reveal tx (default: medium)"),
325
- },
325
+ }),
326
326
  }, async ({ commitTxid, revealAmount, contentBase64, parentInscriptionId, feeRate, }) => {
327
327
  try {
328
328
  const walletManager = getWalletManager();
@@ -418,12 +418,12 @@ export function registerSouldinalsTools(server) {
418
418
  "Queries the Unisat Ordinals API for inscriptions with content type text/markdown.\n" +
419
419
  "If no address is provided, uses the current wallet's Taproot address.\n\n" +
420
420
  "Returns: array of soul inscriptions with id, number, content type, size, and timestamp.",
421
- inputSchema: {
421
+ inputSchema: z.object({
422
422
  address: z
423
423
  .string()
424
424
  .optional()
425
425
  .describe("Taproot (bc1p...) address to query. Omit to use the current wallet's Taproot address."),
426
- },
426
+ }),
427
427
  }, async ({ address }) => {
428
428
  try {
429
429
  let taprootAddress = address;
@@ -466,12 +466,12 @@ export function registerSouldinalsTools(server) {
466
466
  "Fetches the list of soul inscriptions (text/markdown) and returns the content of the " +
467
467
  "oldest one. If no address is provided, uses the current wallet's Taproot address.\n\n" +
468
468
  "Returns: inscription metadata and full Markdown content.",
469
- inputSchema: {
469
+ inputSchema: z.object({
470
470
  address: z
471
471
  .string()
472
472
  .optional()
473
473
  .describe("Taproot (bc1p...) address to query. Omit to use the current wallet's Taproot address."),
474
- },
474
+ }),
475
475
  }, async ({ address }) => {
476
476
  try {
477
477
  let taprootAddress = address;
@@ -520,11 +520,11 @@ export function registerSouldinalsTools(server) {
520
520
  "- focusAreas: list items under 'Focus' or 'Focus Areas' sections\n" +
521
521
  "- sections: all named H2/H3 sections\n\n" +
522
522
  "Also returns raw Markdown content.",
523
- inputSchema: {
523
+ inputSchema: z.object({
524
524
  inscriptionId: z
525
525
  .string()
526
526
  .describe("Inscription ID (format: {txid}i{index})"),
527
- },
527
+ }),
528
528
  }, async ({ inscriptionId }) => {
529
529
  try {
530
530
  // Fetch metadata and content in parallel
@@ -1,3 +1,3 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
2
  export declare function registerStackingLotteryTools(server: McpServer): void;
3
3
  //# sourceMappingURL=stacking-lottery.tools.d.ts.map
@@ -85,7 +85,7 @@ all participants recover their original STX contribution.
85
85
  Returns each pot's contract ID, configuration, current STX value, and lock status.
86
86
 
87
87
  Note: Stackspot is only available on mainnet.`,
88
- inputSchema: {},
88
+ inputSchema: z.object({}),
89
89
  }, async () => {
90
90
  try {
91
91
  if (NETWORK !== "mainnet") {
@@ -142,11 +142,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier
142
142
  (e.g., "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG").
143
143
 
144
144
  Note: Stackspot is only available on mainnet.`,
145
- inputSchema: {
145
+ inputSchema: z.object({
146
146
  contractName: z
147
147
  .string()
148
148
  .describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
149
- },
149
+ }),
150
150
  }, async ({ contractName }) => {
151
151
  try {
152
152
  if (NETWORK !== "mainnet") {
@@ -197,14 +197,14 @@ Amount must be in micro-STX (1 STX = 1,000,000 micro-STX).
197
197
  Requires an unlocked wallet with sufficient STX balance.
198
198
 
199
199
  Note: Stackspot is only available on mainnet.`,
200
- inputSchema: {
200
+ inputSchema: z.object({
201
201
  contractName: z
202
202
  .string()
203
203
  .describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
204
204
  amount: z
205
205
  .string()
206
206
  .describe("Amount to contribute in micro-STX (1 STX = 1,000,000 micro-STX)"),
207
- },
207
+ }),
208
208
  }, async ({ contractName, amount }) => {
209
209
  try {
210
210
  if (NETWORK !== "mainnet") {
@@ -278,11 +278,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier.
278
278
  Requires an unlocked wallet.
279
279
 
280
280
  Note: Stackspot is only available on mainnet.`,
281
- inputSchema: {
281
+ inputSchema: z.object({
282
282
  contractName: z
283
283
  .string()
284
284
  .describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
285
- },
285
+ }),
286
286
  }, async ({ contractName }) => {
287
287
  try {
288
288
  if (NETWORK !== "mainnet") {
@@ -331,11 +331,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier.
331
331
  Requires an unlocked wallet.
332
332
 
333
333
  Note: Stackspot is only available on mainnet.`,
334
- inputSchema: {
334
+ inputSchema: z.object({
335
335
  contractName: z
336
336
  .string()
337
337
  .describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
338
- },
338
+ }),
339
339
  }, async ({ contractName }) => {
340
340
  try {
341
341
  if (NETWORK !== "mainnet") {
@@ -385,11 +385,11 @@ Use a bare contract name (e.g., "STXLFG") or a fully-qualified identifier.
385
385
  Requires an unlocked wallet.
386
386
 
387
387
  Note: Stackspot is only available on mainnet.`,
388
- inputSchema: {
388
+ inputSchema: z.object({
389
389
  contractName: z
390
390
  .string()
391
391
  .describe('Pot contract name or full identifier (e.g., "STXLFG" or "SPT4SQP5RC1BFAJEQKBHZMXQ8NQ7G118F335BD85.STXLFG")'),
392
- },
392
+ }),
393
393
  }, async ({ contractName }) => {
394
394
  try {
395
395
  if (NETWORK !== "mainnet") {
@@ -1,3 +1,3 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
2
  export declare function registerStackingTools(server: McpServer): void;
3
3
  //# sourceMappingURL=stacking.tools.d.ts.map