@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
@@ -88,6 +88,21 @@ function formatSigAuthForApi(sigAuth) {
88
88
  : "0x" + sigAuth.pubkey,
89
89
  };
90
90
  }
91
+ /**
92
+ * The Pillar smart wallet's Fast Pool functions are hardcoded to pox-4
93
+ * (`pox-4.allow-contract-caller` + `pox4-fast-pool-v3.delegate-stx`, and
94
+ * `pox-4.revoke-delegate-stx`). Once PoX has moved past pox-4 those calls abort
95
+ * on chain, so refuse before signing instead of burning gas on a sure failure.
96
+ */
97
+ async function assertFastPoolPoxActive(action) {
98
+ const pox = await getHiroApi(NETWORK).getPoxInfo();
99
+ if (!pox.contract_id.endsWith(".pox-4")) {
100
+ throw new Error(`${action} is unavailable: the Pillar smart wallet's Fast Pool path calls pox-4, but the ` +
101
+ `active PoX contract is ${pox.contract_id}, so the transaction would abort on chain. ` +
102
+ `This needs a Pillar wallet contract update. For STX staking on PoX-5, use stack_stx ` +
103
+ `with a signer manager (see list_stacking_signers).`);
104
+ }
105
+ }
91
106
  // ============================================================================
92
107
  // Tool Registration
93
108
  // ============================================================================
@@ -99,13 +114,13 @@ export function registerPillarDirectTools(server) {
99
114
  description: "Generate a new secp256k1 signing keypair for Pillar smart wallet direct operations. " +
100
115
  "Returns the compressed public key (33 bytes hex). " +
101
116
  "After generation, propose this pubkey on your smart wallet contract (admin must do this).",
102
- inputSchema: {
117
+ inputSchema: z.object({
103
118
  smartWallet: z
104
119
  .string()
105
120
  .default("pending")
106
121
  .describe("Smart wallet contract ID this key is for (e.g. SPV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RCJDC22.my-wallet). " +
107
122
  "Use 'pending' if creating a new wallet — pillar_direct_create_wallet will update it automatically."),
108
- },
123
+ }),
109
124
  }, async ({ smartWallet }) => {
110
125
  try {
111
126
  const keyService = getSigningKeyService();
@@ -126,12 +141,12 @@ export function registerPillarDirectTools(server) {
126
141
  server.registerTool("pillar_key_unlock", {
127
142
  description: "Unlock a signing key for Pillar direct operations. " +
128
143
  "Uses auto-derived password. Usually not needed — tools auto-unlock on first use.",
129
- inputSchema: {
144
+ inputSchema: z.object({
130
145
  keyId: z
131
146
  .string()
132
147
  .optional()
133
148
  .describe("The signing key ID to unlock. If omitted, unlocks the first stored key."),
134
- },
149
+ }),
135
150
  }, async ({ keyId }) => {
136
151
  try {
137
152
  const keyService = getSigningKeyService();
@@ -160,7 +175,7 @@ export function registerPillarDirectTools(server) {
160
175
  });
161
176
  server.registerTool("pillar_key_lock", {
162
177
  description: "Lock the signing key, clearing sensitive data from memory.",
163
- inputSchema: {},
178
+ inputSchema: z.object({}),
164
179
  }, async () => {
165
180
  try {
166
181
  const keyService = getSigningKeyService();
@@ -176,7 +191,7 @@ export function registerPillarDirectTools(server) {
176
191
  });
177
192
  server.registerTool("pillar_key_info", {
178
193
  description: "Show signing key info: pubkey, smart wallet, lock status, and all stored keys.",
179
- inputSchema: {},
194
+ inputSchema: z.object({}),
180
195
  }, async () => {
181
196
  try {
182
197
  const keyService = getSigningKeyService();
@@ -215,7 +230,7 @@ export function registerPillarDirectTools(server) {
215
230
  "Agent-signed, no browser needed. Your sBTC is supplied to Zest, borrowed against, " +
216
231
  "and re-supplied for amplified Bitcoin exposure. Backend sponsors gas. " +
217
232
  "For simple yield without leverage, use pillar_direct_supply instead.",
218
- inputSchema: {
233
+ inputSchema: z.object({
219
234
  sbtcAmount: z
220
235
  .number()
221
236
  .positive()
@@ -228,7 +243,7 @@ export function registerPillarDirectTools(server) {
228
243
  .number()
229
244
  .positive()
230
245
  .describe("Min sBTC from swap in sats (slippage protection)"),
231
- },
246
+ }),
232
247
  }, async ({ sbtcAmount, aeUsdcToBorrow, minSbtcFromSwap }) => {
233
248
  try {
234
249
  const { keyService, session } = await requireActiveKey();
@@ -265,7 +280,7 @@ export function registerPillarDirectTools(server) {
265
280
  server.registerTool("pillar_direct_unwind", {
266
281
  description: "Close or reduce your leveraged sBTC position. Agent-signed, no browser needed. " +
267
282
  "Swaps sBTC to aeUSDC to repay debt, then withdraws remaining sBTC collateral. Backend sponsors gas.",
268
- inputSchema: {
283
+ inputSchema: z.object({
269
284
  sbtcToSwap: z
270
285
  .number()
271
286
  .positive()
@@ -278,7 +293,7 @@ export function registerPillarDirectTools(server) {
278
293
  .number()
279
294
  .positive()
280
295
  .describe("Min aeUSDC from swap (slippage protection, 6 decimals)"),
281
- },
296
+ }),
282
297
  }, async ({ sbtcToSwap, sbtcToWithdraw, minAeUsdcFromSwap }) => {
283
298
  try {
284
299
  const { keyService, session } = await requireActiveKey();
@@ -317,12 +332,12 @@ export function registerPillarDirectTools(server) {
317
332
  description: "Earn yield on your Bitcoin. Supply sBTC from your Pillar smart wallet to Zest Protocol. " +
318
333
  "No leverage, no liquidation risk. Agent-signed, no browser needed. Backend sponsors gas. " +
319
334
  "For leveraged exposure (1.5x), use pillar_direct_boost instead.",
320
- inputSchema: {
335
+ inputSchema: z.object({
321
336
  sbtcAmount: z
322
337
  .number()
323
338
  .positive()
324
339
  .describe("sBTC amount in sats to supply"),
325
- },
340
+ }),
326
341
  }, async ({ sbtcAmount }) => {
327
342
  try {
328
343
  const { keyService, session } = await requireActiveKey();
@@ -357,7 +372,7 @@ export function registerPillarDirectTools(server) {
357
372
  description: "Send sBTC from your Pillar smart wallet to a recipient. " +
358
373
  "Agent-signed, no browser needed. Supports BNS names, wallet names, or Stacks addresses. " +
359
374
  "Backend sponsors gas.",
360
- inputSchema: {
375
+ inputSchema: z.object({
361
376
  to: z
362
377
  .string()
363
378
  .describe("Recipient: BNS name (muneeb.btc), Pillar wallet name, or Stacks address (SP...)"),
@@ -369,7 +384,7 @@ export function registerPillarDirectTools(server) {
369
384
  .enum(["bns", "wallet", "address"])
370
385
  .default("bns")
371
386
  .describe("Type of recipient: 'bns' (default), 'wallet', or 'address'"),
372
- },
387
+ }),
373
388
  }, async ({ to, amount, recipientType }) => {
374
389
  try {
375
390
  const { keyService, session } = await requireActiveKey();
@@ -435,7 +450,7 @@ export function registerPillarDirectTools(server) {
435
450
  description: "Configure auto-compound for your Pillar wallet. " +
436
451
  "When enabled, a keeper automatically boosts when sBTC accumulates above the trigger. " +
437
452
  "Agent-signed, no browser needed. Backend sponsors gas.",
438
- inputSchema: {
453
+ inputSchema: z.object({
439
454
  enabled: z.boolean().describe("Enable or disable auto-compound"),
440
455
  minSbtc: z
441
456
  .number()
@@ -445,7 +460,7 @@ export function registerPillarDirectTools(server) {
445
460
  .number()
446
461
  .positive()
447
462
  .describe("sBTC amount above minimum that triggers auto-compound (in sats)"),
448
- },
463
+ }),
449
464
  }, async ({ enabled, minSbtc, trigger }) => {
450
465
  try {
451
466
  const { keyService, session } = await requireActiveKey();
@@ -483,7 +498,7 @@ export function registerPillarDirectTools(server) {
483
498
  server.registerTool("pillar_direct_position", {
484
499
  description: "View your Pillar smart wallet balances (STX, sBTC, aeUSDC) and Zest position. " +
485
500
  "No signing needed — reads on-chain data.",
486
- inputSchema: {},
501
+ inputSchema: z.object({}),
487
502
  }, async () => {
488
503
  try {
489
504
  const { session } = await requireActiveKey();
@@ -584,12 +599,12 @@ export function registerPillarDirectTools(server) {
584
599
  server.registerTool("pillar_direct_withdraw_collateral", {
585
600
  description: "Withdraw sBTC collateral from Zest on the Pillar smart wallet. " +
586
601
  "Agent-signed, no browser needed. Backend sponsors gas.",
587
- inputSchema: {
602
+ inputSchema: z.object({
588
603
  sbtcAmount: z
589
604
  .number()
590
605
  .positive()
591
606
  .describe("sBTC amount in sats to withdraw"),
592
- },
607
+ }),
593
608
  }, async ({ sbtcAmount }) => {
594
609
  try {
595
610
  const { keyService, session } = await requireActiveKey();
@@ -623,11 +638,11 @@ export function registerPillarDirectTools(server) {
623
638
  description: "Add a backup admin address to your Pillar smart wallet for recovery purposes. " +
624
639
  "Agent-signed, no browser needed. The admin can help recover funds if you lose access to your passkey. " +
625
640
  "Backend sponsors gas.",
626
- inputSchema: {
641
+ inputSchema: z.object({
627
642
  newAdmin: z
628
643
  .string()
629
644
  .describe("Stacks address (SP...) to add as backup admin"),
630
- },
645
+ }),
631
646
  }, async ({ newAdmin }) => {
632
647
  try {
633
648
  const { keyService, session } = await requireActiveKey();
@@ -666,7 +681,7 @@ export function registerPillarDirectTools(server) {
666
681
  "and deploys a new smart wallet with the pubkey registered. " +
667
682
  "Backend deploys the contract and calls onboard() in background. " +
668
683
  "After ~20-30 seconds the wallet is ready for pillar_direct_* operations.",
669
- inputSchema: {
684
+ inputSchema: z.object({
670
685
  walletName: z
671
686
  .string()
672
687
  .min(3)
@@ -678,7 +693,7 @@ export function registerPillarDirectTools(server) {
678
693
  .default("SPV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RCJDC22.beta-v2-wallet")
679
694
  .describe("Contract address of the referring wallet. " +
680
695
  "Defaults to the Pillar team wallet if not provided."),
681
- },
696
+ }),
682
697
  }, async ({ walletName, referredBy }) => {
683
698
  try {
684
699
  const api = getPillarApi();
@@ -744,11 +759,11 @@ export function registerPillarDirectTools(server) {
744
759
  server.registerTool("pillar_direct_dca_invite", {
745
760
  description: "Invite a DCA partner by email or wallet address. " +
746
761
  "DCA partners hold each other accountable — both must boost each week to keep the streak alive.",
747
- inputSchema: {
762
+ inputSchema: z.object({
748
763
  partner: z
749
764
  .string()
750
765
  .describe("Partner's email address or Stacks wallet address (SP...)"),
751
- },
766
+ }),
752
767
  }, async ({ partner }) => {
753
768
  try {
754
769
  const { session } = await requireActiveKey();
@@ -778,7 +793,7 @@ export function registerPillarDirectTools(server) {
778
793
  server.registerTool("pillar_direct_dca_partners", {
779
794
  description: "View your DCA partners and weekly status. " +
780
795
  "Shows active partnerships with streak, PnL, and weekly status badges, plus any pending invites.",
781
- inputSchema: {},
796
+ inputSchema: z.object({}),
782
797
  }, async () => {
783
798
  try {
784
799
  const { session } = await requireActiveKey();
@@ -816,7 +831,7 @@ export function registerPillarDirectTools(server) {
816
831
  // --- pillar_direct_dca_leaderboard (twin of pillar_dca_leaderboard) ---
817
832
  server.registerTool("pillar_direct_dca_leaderboard", {
818
833
  description: "View the DCA streak leaderboard. Shows top partnerships by streak length, and highlights your entry if you have one.",
819
- inputSchema: {},
834
+ inputSchema: z.object({}),
820
835
  }, async () => {
821
836
  try {
822
837
  const { session } = await requireActiveKey();
@@ -854,7 +869,7 @@ export function registerPillarDirectTools(server) {
854
869
  server.registerTool("pillar_direct_dca_status", {
855
870
  description: "Check your DCA schedule status. Shows all active DCA schedules (up to 10) with chunk progress " +
856
871
  "(completed, pending, failed) and next execution time.",
857
- inputSchema: {},
872
+ inputSchema: z.object({}),
858
873
  }, async () => {
859
874
  try {
860
875
  const { session } = await requireActiveKey();
@@ -945,12 +960,12 @@ export function registerPillarDirectTools(server) {
945
960
  server.registerTool("pillar_direct_quote", {
946
961
  description: "Get a boost quote showing projected leverage, LTV, and swap details. " +
947
962
  "No signing needed. Use this to determine aeUsdcToBorrow and minSbtcFromSwap before calling pillar_direct_boost.",
948
- inputSchema: {
963
+ inputSchema: z.object({
949
964
  sbtcAmount: z
950
965
  .number()
951
966
  .positive()
952
967
  .describe("sBTC amount in sats to boost"),
953
- },
968
+ }),
954
969
  }, async ({ sbtcAmount }) => {
955
970
  try {
956
971
  const api = getPillarApi();
@@ -970,7 +985,7 @@ export function registerPillarDirectTools(server) {
970
985
  description: "Resolve a recipient before sending. Resolves BNS names (.btc) via backend, " +
971
986
  "Pillar wallet names via backend, or validates a Stacks address. " +
972
987
  "Use this BEFORE pillar_direct_send to confirm the resolved address with the user.",
973
- inputSchema: {
988
+ inputSchema: z.object({
974
989
  to: z
975
990
  .string()
976
991
  .describe("Recipient: BNS name (muneeb.btc), Pillar wallet name, or Stacks address (SP...)"),
@@ -978,7 +993,7 @@ export function registerPillarDirectTools(server) {
978
993
  .enum(["bns", "wallet", "address"])
979
994
  .default("bns")
980
995
  .describe("Type of recipient: 'bns' (default), 'wallet', or 'address'"),
981
- },
996
+ }),
982
997
  }, async ({ to, recipientType }) => {
983
998
  try {
984
999
  const api = getPillarApi();
@@ -1041,10 +1056,11 @@ export function registerPillarDirectTools(server) {
1041
1056
  server.registerTool("pillar_direct_stack_stx", {
1042
1057
  description: "Stack STX from your Pillar smart wallet via Fast Pool or Stacking DAO. " +
1043
1058
  "Agent-signed, no browser needed. Backend sponsors gas. " +
1044
- "Fast Pool delegates STX to the pox4-fast-pool-v3 contract. " +
1059
+ "Fast Pool delegates STX to the pox4-fast-pool-v3 contract through pox-4, and is refused while " +
1060
+ "pox-4 is not the active PoX contract (PoX-5 is live; use stack_stx for PoX-5 staking). " +
1045
1061
  "Stacking DAO deposits STX into Stacking DAO core for stSTX yield. " +
1046
1062
  "Your wallet must be enrolled in dual stacking first (automatic for v2 wallets with sBTC).",
1047
- inputSchema: {
1063
+ inputSchema: z.object({
1048
1064
  stxAmount: z
1049
1065
  .number()
1050
1066
  .positive()
@@ -1053,9 +1069,12 @@ export function registerPillarDirectTools(server) {
1053
1069
  .enum(["fast-pool", "stacking-dao"])
1054
1070
  .describe("Stacking pool to use: 'fast-pool' (delegates to pox4-fast-pool-v3) " +
1055
1071
  "or 'stacking-dao' (deposits into Stacking DAO for stSTX)"),
1056
- },
1072
+ }),
1057
1073
  }, async ({ stxAmount, pool }) => {
1058
1074
  try {
1075
+ if (pool === "fast-pool") {
1076
+ await assertFastPoolPoxActive("Fast Pool stacking");
1077
+ }
1059
1078
  const { keyService, session } = await requireActiveKey();
1060
1079
  const authId = generateAuthId();
1061
1080
  // Build SIP-018 structured data matching the contract's hash builder.
@@ -1099,12 +1118,14 @@ export function registerPillarDirectTools(server) {
1099
1118
  });
1100
1119
  // --- pillar_direct_revoke_fast_pool ---
1101
1120
  server.registerTool("pillar_direct_revoke_fast_pool", {
1102
- description: "Revoke Fast Pool STX delegation from your Pillar smart wallet. " +
1121
+ description: "Revoke Fast Pool STX delegation from your Pillar smart wallet (pox-4 revoke-delegate-stx; " +
1122
+ "refused while pox-4 is not the active PoX contract). " +
1103
1123
  "Agent-signed, no browser needed. Backend sponsors gas. " +
1104
1124
  "After revoking, STX stays locked until the current PoX cycle ends, then returns to liquid.",
1105
- inputSchema: {},
1125
+ inputSchema: z.object({}),
1106
1126
  }, async () => {
1107
1127
  try {
1128
+ await assertFastPoolPoxActive("Revoking Fast Pool");
1108
1129
  const { keyService, session } = await requireActiveKey();
1109
1130
  const authId = generateAuthId();
1110
1131
  const structuredData = tupleCV({
@@ -1138,7 +1159,7 @@ export function registerPillarDirectTools(server) {
1138
1159
  "No signing needed — reads on-chain data. " +
1139
1160
  "Shows STX balance (locked vs liquid), current PoX cycle info, " +
1140
1161
  "and dual stacking enrollment status.",
1141
- inputSchema: {},
1162
+ inputSchema: z.object({}),
1142
1163
  }, async () => {
1143
1164
  try {
1144
1165
  const { session } = await requireActiveKey();
@@ -1,3 +1,3 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
2
  export declare function registerPillarTools(server: McpServer): void;
3
3
  //# sourceMappingURL=pillar.tools.d.ts.map
@@ -1,3 +1,5 @@
1
+ // Pillar MCP Tools - Handoff model
2
+ // MCP creates intent → Opens frontend → Frontend handles signing → MCP polls for result
1
3
  import { z } from "zod";
2
4
  import { getPillarApi } from "../services/pillar-api.service.js";
3
5
  import { createJsonResponse, createErrorResponse } from "../utils/index.js";
@@ -89,7 +91,7 @@ export function registerPillarTools(server) {
89
91
  server.registerTool("pillar_connect", {
90
92
  description: "Connect to your Pillar smart wallet. Opens the Pillar website - if you're logged in, " +
91
93
  "it will automatically connect and return your wallet address. Use this first before other Pillar actions.",
92
- inputSchema: {},
94
+ inputSchema: z.object({}),
93
95
  }, async () => {
94
96
  try {
95
97
  const api = getPillarApi();
@@ -143,7 +145,7 @@ export function registerPillarTools(server) {
143
145
  // Tool 2: Disconnect from Pillar
144
146
  server.registerTool("pillar_disconnect", {
145
147
  description: "Disconnect from Pillar. Clears locally stored wallet address.",
146
- inputSchema: {},
148
+ inputSchema: z.object({}),
147
149
  }, async () => {
148
150
  const session = await loadSession();
149
151
  await clearSession();
@@ -157,7 +159,7 @@ export function registerPillarTools(server) {
157
159
  // Tool 3: Get Pillar connection status
158
160
  server.registerTool("pillar_status", {
159
161
  description: "Check if you're connected to Pillar and get your wallet address.",
160
- inputSchema: {},
162
+ inputSchema: z.object({}),
161
163
  }, async () => {
162
164
  const session = await loadSession();
163
165
  if (session) {
@@ -178,11 +180,11 @@ export function registerPillarTools(server) {
178
180
  description: "Send sBTC from your Pillar smart wallet. Requires being connected first (use pillar_connect). " +
179
181
  "Opens the frontend for signing, then waits for confirmation. " +
180
182
  "Supports three recipient types: 'bns' for BNS names (muneeb.btc), 'wallet' for Pillar wallet names (iphone), 'address' for Stacks addresses (SP...).",
181
- inputSchema: {
183
+ inputSchema: z.object({
182
184
  to: z.string().describe("Recipient: BNS name (muneeb.btc), Pillar wallet name (iphone), or Stacks address (SP...)"),
183
185
  amount: z.number().positive().describe("Amount in satoshis"),
184
186
  recipientType: z.enum(["bns", "wallet", "address"]).optional().describe("Type of recipient: 'bns' (default), 'wallet' for Pillar smart wallets, or 'address' for raw Stacks addresses"),
185
- },
187
+ }),
186
188
  }, async ({ to, amount, recipientType }) => {
187
189
  try {
188
190
  // Get wallet address from session
@@ -249,10 +251,10 @@ export function registerPillarTools(server) {
249
251
  "- 'btc': Deposit BTC from your Leather/Xverse wallet - auto-converts to sBTC\n" +
250
252
  "- 'sbtc': Deposit sBTC directly from your Leather/Xverse wallet\n" +
251
253
  "Opens the frontend with the appropriate deposit flow.",
252
- inputSchema: {
254
+ inputSchema: z.object({
253
255
  method: z.enum(["exchange", "btc", "sbtc"]).describe("Funding method: 'exchange' (deposit from Coinbase/Binance), 'btc' (from Leather/Xverse BTC), 'sbtc' (from Leather/Xverse sBTC)"),
254
256
  amount: z.number().positive().optional().describe("Amount in satoshis to deposit (optional, can be set in UI)"),
255
- },
257
+ }),
256
258
  }, async ({ method, amount }) => {
257
259
  try {
258
260
  const session = await loadSession();
@@ -300,9 +302,9 @@ export function registerPillarTools(server) {
300
302
  server.registerTool("pillar_add_admin", {
301
303
  description: "Add a backup admin address to your Pillar smart wallet for recovery purposes. " +
302
304
  "The admin can help recover funds if you lose access to your passkey.",
303
- inputSchema: {
305
+ inputSchema: z.object({
304
306
  adminAddress: z.string().optional().describe("Stacks address (SP...) to add as backup admin (can be set in UI)"),
305
- },
307
+ }),
306
308
  }, async ({ adminAddress }) => {
307
309
  try {
308
310
  const session = await loadSession();
@@ -346,9 +348,9 @@ export function registerPillarTools(server) {
346
348
  description: "Earn yield on your Bitcoin. Supply sBTC from your Pillar smart wallet to Zest Protocol. " +
347
349
  "Your sBTC earns interest with no leverage and no liquidation risk. " +
348
350
  "This is the simplest way to earn on Pillar (Earn tab). For leveraged exposure, use pillar_boost instead.",
349
- inputSchema: {
351
+ inputSchema: z.object({
350
352
  amount: z.number().positive().optional().describe("Amount in satoshis to supply (optional, can be set in UI)"),
351
- },
353
+ }),
352
354
  }, async ({ amount }) => {
353
355
  try {
354
356
  const session = await loadSession();
@@ -391,10 +393,10 @@ export function registerPillarTools(server) {
391
393
  server.registerTool("pillar_auto_compound", {
392
394
  description: "Configure auto-compound for your Pillar wallet. " +
393
395
  "When enabled, a keeper will automatically boost your position when sBTC accumulates in your wallet.",
394
- inputSchema: {
396
+ inputSchema: z.object({
395
397
  minSbtc: z.number().nonnegative().optional().describe("Minimum sBTC to keep in wallet (in sats)"),
396
398
  trigger: z.number().positive().optional().describe("Amount above minimum that triggers auto-compound (in sats)"),
397
- },
399
+ }),
398
400
  }, async ({ minSbtc, trigger }) => {
399
401
  try {
400
402
  const session = await loadSession();
@@ -435,9 +437,9 @@ export function registerPillarTools(server) {
435
437
  server.registerTool("pillar_unwind", {
436
438
  description: "Close or reduce your leveraged sBTC position. " +
437
439
  "Opens a modal to repay borrowed sBTC and withdraw collateral back to your wallet.",
438
- inputSchema: {
440
+ inputSchema: z.object({
439
441
  percentage: z.number().min(1).max(100).optional().describe("Percentage of position to unwind (1-100, optional, can be set in UI)"),
440
- },
442
+ }),
441
443
  }, async ({ percentage }) => {
442
444
  try {
443
445
  const session = await loadSession();
@@ -484,9 +486,9 @@ export function registerPillarTools(server) {
484
486
  "For simple yield without leverage, use pillar_supply (Earn) instead. " +
485
487
  "Amounts over 100,000 sats automatically enter DCA mode -- split into daily 100k-sat chunks " +
486
488
  "(max 700k sats per schedule). The first chunk executes immediately, the rest follow daily.",
487
- inputSchema: {
489
+ inputSchema: z.object({
488
490
  amount: z.number().positive().optional().describe("Amount in satoshis to boost (optional, shown as suggestion)"),
489
- },
491
+ }),
490
492
  }, async ({ amount }) => {
491
493
  try {
492
494
  const session = await loadSession();
@@ -529,7 +531,7 @@ export function registerPillarTools(server) {
529
531
  server.registerTool("pillar_position", {
530
532
  description: "View your Pillar wallet balance and Zest position. " +
531
533
  "Opens the Position page in the browser AND returns the data (sBTC balance, collateral, borrowed, LTV, liquidation price).",
532
- inputSchema: {},
534
+ inputSchema: z.object({}),
533
535
  }, async () => {
534
536
  try {
535
537
  const session = await loadSession();
@@ -606,9 +608,9 @@ export function registerPillarTools(server) {
606
608
  description: "Create a new Pillar smart wallet. Opens the Pillar website to complete registration. " +
607
609
  "You'll need to enter your email to receive updates. " +
608
610
  "If the user doesn't have a referral link, tell them they can DM @pillar_btc on X (https://x.com/pillar_btc) to request one before signing up.",
609
- inputSchema: {
611
+ inputSchema: z.object({
610
612
  referral: z.string().optional().describe("Referral wallet address (optional, defaults to MCP referral)"),
611
- },
613
+ }),
612
614
  }, async ({ referral }) => {
613
615
  try {
614
616
  // Check if already connected
@@ -662,7 +664,7 @@ export function registerPillarTools(server) {
662
664
  // Tool 13: Get referral/invite link
663
665
  server.registerTool("pillar_invite", {
664
666
  description: "Get your Pillar referral link to invite friends. Share this link and earn rewards when friends sign up.",
665
- inputSchema: {},
667
+ inputSchema: z.object({}),
666
668
  }, async () => {
667
669
  try {
668
670
  const session = await loadSession();
@@ -688,9 +690,9 @@ export function registerPillarTools(server) {
688
690
  server.registerTool("pillar_dca_invite", {
689
691
  description: "Invite a DCA partner by email or wallet address. " +
690
692
  "DCA partners hold each other accountable — both must boost each week to keep the streak alive.",
691
- inputSchema: {
693
+ inputSchema: z.object({
692
694
  partner: z.string().describe("Partner's email address or Stacks wallet address (SP...)"),
693
- },
695
+ }),
694
696
  }, async ({ partner }) => {
695
697
  try {
696
698
  const session = await loadSession();
@@ -724,7 +726,7 @@ export function registerPillarTools(server) {
724
726
  server.registerTool("pillar_dca_partners", {
725
727
  description: "View your DCA partners and weekly status. " +
726
728
  "Shows active partnerships with streak, PnL, and weekly status badges, plus any pending invites.",
727
- inputSchema: {},
729
+ inputSchema: z.object({}),
728
730
  }, async () => {
729
731
  try {
730
732
  const session = await loadSession();
@@ -766,7 +768,7 @@ export function registerPillarTools(server) {
766
768
  // Tool 16: DCA streak leaderboard (direct API)
767
769
  server.registerTool("pillar_dca_leaderboard", {
768
770
  description: "View the DCA streak leaderboard. Shows top partnerships by streak length, and highlights your entry if you have one.",
769
- inputSchema: {},
771
+ inputSchema: z.object({}),
770
772
  }, async () => {
771
773
  try {
772
774
  const session = await loadSession();
@@ -806,7 +808,7 @@ export function registerPillarTools(server) {
806
808
  server.registerTool("pillar_dca_status", {
807
809
  description: "Check your DCA schedule status. Shows all active DCA schedules (up to 10) with chunk progress " +
808
810
  "(completed, pending, failed) and next execution time.",
809
- inputSchema: {},
811
+ inputSchema: z.object({}),
810
812
  }, async () => {
811
813
  try {
812
814
  const session = await loadSession();
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tool profiles: which tools the server exposes.
3
+ *
4
+ * Every tool definition is sent to the client's model on each session, so
5
+ * `--install` writes `AIBTC_TOOLS=core`: a lean set covering wallet, balances,
6
+ * transfers, x402 and earning. Other groups are added with
7
+ * `AIBTC_TOOLS=core,defi,ordinals` (the core set is always included).
8
+ *
9
+ * An unset AIBTC_TOOLS loads every tool: configs written before profiles
10
+ * existed have no AIBTC_TOOLS, and their users keep the tools they had.
11
+ */
12
+ /** Tools exposed by default, whatever groups are enabled. */
13
+ export declare const CORE_TOOLS: ReadonlySet<string>;
14
+ export declare const TOOL_GROUPS: {
15
+ readonly wallet: "Wallet management extras, encrypted credential store";
16
+ readonly stacks: "Stacks transactions, contracts, tokens, NFTs, chain queries, nonce tools";
17
+ readonly sbtc: "sBTC deposit/withdraw, Styx BTC→sBTC";
18
+ readonly bitcoin: "Bitcoin L1 UTXOs, mempool watch";
19
+ readonly lightning: "Lightning (Spark) wallet and L402 payments";
20
+ readonly stacking: "PoX stacking, dual stacking, StackSpot";
21
+ readonly defi: "ALEX, Zest, Bitflow, Jingswap, yield hunter/dashboard, Tenero analytics";
22
+ readonly pillar: "Pillar smart wallet";
23
+ readonly ordinals: "Inscriptions, runes, PSBT, ordinals marketplace/P2P, taproot multisig";
24
+ readonly bns: "BNS names";
25
+ readonly identity: "ERC-8004 identity and reputation, message signing";
26
+ readonly social: "Nostr, AIBTC inbox";
27
+ readonly earn: "Bounty board (create, accept, pay, my views)";
28
+ readonly legion: "AIBTC News Legion";
29
+ readonly markets: "Stacks prediction market, At Stake";
30
+ readonly dev: "Scaffolding, OpenRouter, settings, inference marketplace, arXiv";
31
+ };
32
+ export type ToolGroup = keyof typeof TOOL_GROUPS;
33
+ /** Which tools to expose: every tool, or the core set plus the named groups. */
34
+ export type ToolSelection = {
35
+ all: true;
36
+ } | {
37
+ all: false;
38
+ groups: ReadonlySet<ToolGroup>;
39
+ };
40
+ export declare const ALL_TOOLS: ToolSelection;
41
+ export declare function isToolGroup(name: string): name is ToolGroup;
42
+ export declare function isToolSelected(selection: ToolSelection, name: string, group: ToolGroup): boolean;
43
+ /**
44
+ * Resolve the selection from `--profile <lean|full>` and `AIBTC_TOOLS`
45
+ * (`all`, or `core` and/or comma-separated group names; unset means `all`).
46
+ * Unknown values throw so a typo doesn't silently hide tools.
47
+ */
48
+ export declare function resolveToolSelection(argv?: readonly string[], env?: NodeJS.ProcessEnv): ToolSelection;
49
+ /** Server-instructions paragraph telling the agent what is off and how to turn it on. */
50
+ export declare function describeSelection(selection: ToolSelection): string;
51
+ //# sourceMappingURL=profiles.d.ts.map