helius-mcp 1.2.0 → 2.0.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 (94) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +42 -30
  3. package/dist/http.d.ts +1 -1
  4. package/dist/index.js +2 -56
  5. package/dist/results/store.d.ts +8 -0
  6. package/dist/results/store.js +72 -0
  7. package/dist/results/types.d.ts +47 -0
  8. package/dist/results/types.js +1 -0
  9. package/dist/router/action-groups.d.ts +6 -0
  10. package/dist/router/action-groups.js +32 -0
  11. package/dist/router/action-handlers.d.ts +20 -0
  12. package/dist/router/action-handlers.js +125 -0
  13. package/dist/router/actions.d.ts +12 -0
  14. package/dist/router/actions.js +123 -0
  15. package/dist/router/catalog.d.ts +6 -0
  16. package/dist/router/catalog.js +388 -0
  17. package/dist/router/context.d.ts +5 -0
  18. package/dist/router/context.js +10 -0
  19. package/dist/router/dispatch.d.ts +4 -0
  20. package/dist/router/dispatch.js +276 -0
  21. package/dist/router/instructions.d.ts +1 -0
  22. package/dist/router/instructions.js +25 -0
  23. package/dist/router/register.d.ts +2 -0
  24. package/dist/router/register.js +15 -0
  25. package/dist/router/required-params.d.ts +9 -0
  26. package/dist/router/required-params.js +66 -0
  27. package/dist/router/responses.d.ts +29 -0
  28. package/dist/router/responses.js +186 -0
  29. package/dist/router/schemas.d.ts +216 -0
  30. package/dist/router/schemas.js +195 -0
  31. package/dist/router/telemetry.d.ts +27 -0
  32. package/dist/router/telemetry.js +52 -0
  33. package/dist/router/types.d.ts +46 -0
  34. package/dist/router/types.js +1 -0
  35. package/dist/scripts/validate-catalog.d.ts +2 -2
  36. package/dist/scripts/validate-catalog.js +10 -10
  37. package/dist/tools/accounts.js +5 -5
  38. package/dist/tools/assets.js +5 -5
  39. package/dist/tools/auth.js +392 -288
  40. package/dist/tools/config.js +3 -3
  41. package/dist/tools/das-extras.js +6 -6
  42. package/dist/tools/docs.js +55 -41
  43. package/dist/tools/enhanced-websockets.js +13 -13
  44. package/dist/tools/fees.js +3 -3
  45. package/dist/tools/index.d.ts +1 -1
  46. package/dist/tools/index.js +2 -80
  47. package/dist/tools/laserstream.js +20 -23
  48. package/dist/tools/network.js +41 -2
  49. package/dist/tools/plans.d.ts +0 -5
  50. package/dist/tools/plans.js +167 -12
  51. package/dist/tools/product-catalog.d.ts +1 -0
  52. package/dist/tools/product-catalog.js +51 -16
  53. package/dist/tools/recommend.d.ts +0 -1
  54. package/dist/tools/recommend.js +9 -28
  55. package/dist/tools/shared.d.ts +1 -0
  56. package/dist/tools/shared.js +10 -2
  57. package/dist/tools/solana-knowledge.js +23 -7
  58. package/dist/tools/staking.d.ts +2 -0
  59. package/dist/tools/staking.js +268 -0
  60. package/dist/tools/transactions.js +167 -3
  61. package/dist/tools/transfers.js +38 -43
  62. package/dist/tools/wallet.js +27 -16
  63. package/dist/tools/webhooks.js +3 -3
  64. package/dist/tools/zk-compression.d.ts +2 -0
  65. package/dist/tools/zk-compression.js +781 -0
  66. package/dist/utils/config.d.ts +2 -2
  67. package/dist/utils/config.js +68 -6
  68. package/dist/utils/errors.d.ts +10 -1
  69. package/dist/utils/errors.js +46 -12
  70. package/dist/utils/feedback.js +1 -4
  71. package/dist/utils/helius.js +2 -1
  72. package/dist/utils/ows.d.ts +74 -0
  73. package/dist/utils/ows.js +155 -0
  74. package/dist/version.d.ts +1 -1
  75. package/dist/version.js +1 -1
  76. package/package.json +2 -2
  77. package/system-prompts/helius/claude.system.md +56 -25
  78. package/system-prompts/helius/full.md +474 -130
  79. package/system-prompts/helius/openai.developer.md +56 -25
  80. package/system-prompts/helius-dflow/claude.system.md +41 -6
  81. package/system-prompts/helius-dflow/full.md +581 -92
  82. package/system-prompts/helius-dflow/openai.developer.md +41 -6
  83. package/system-prompts/helius-jupiter/claude.system.md +333 -0
  84. package/system-prompts/helius-jupiter/full.md +5109 -0
  85. package/system-prompts/helius-jupiter/openai.developer.md +333 -0
  86. package/system-prompts/helius-okx/claude.system.md +182 -0
  87. package/system-prompts/helius-okx/full.md +584 -0
  88. package/system-prompts/helius-okx/openai.developer.md +182 -0
  89. package/system-prompts/helius-phantom/claude.system.md +15 -2
  90. package/system-prompts/helius-phantom/full.md +254 -101
  91. package/system-prompts/helius-phantom/openai.developer.md +15 -2
  92. package/system-prompts/svm/claude.system.md +1 -0
  93. package/system-prompts/svm/full.md +1 -0
  94. package/system-prompts/svm/openai.developer.md +1 -0
@@ -0,0 +1,216 @@
1
+ import { z } from 'zod';
2
+ export declare const HeliusAccountActionSchema: z.ZodEnum<["getStarted", "setHeliusApiKey", "generateKeypair", "signup", "getAccountStatus", "getAccountPlan", "getHeliusPlanInfo", "compareHeliusPlans", "previewUpgrade", "upgradePlan", "payRenewal", "purchaseCredits"]>;
3
+ export declare const HeliusWalletActionSchema: z.ZodEnum<["getBalance", "getTokenBalances", "getWalletBalances", "getWalletHistory", "getWalletTransfers", "getWalletIdentity", "batchWalletIdentity", "getWalletFundedBy"]>;
4
+ export declare const HeliusAssetActionSchema: z.ZodEnum<["getAsset", "getAssetsByOwner", "searchAssets", "getAssetsByGroup", "getAssetProof", "getAssetProofBatch", "getSignaturesForAsset", "getNftEditions", "getTokenHolders"]>;
5
+ export declare const HeliusTransactionActionSchema: z.ZodEnum<["parseTransactions", "getTransactionHistory", "getTransfersByAddress"]>;
6
+ export declare const HeliusChainActionSchema: z.ZodEnum<["getAccountInfo", "getTokenAccounts", "getProgramAccounts", "getBlock", "getNetworkStatus", "getPriorityFeeEstimate", "getStakeAccounts", "getWithdrawableAmount"]>;
7
+ export declare const HeliusStreamingActionSchema: z.ZodEnum<["createWebhook", "getAllWebhooks", "getWebhookByID", "updateWebhook", "deleteWebhook", "transactionSubscribe", "accountSubscribe", "laserstreamSubscribe"]>;
8
+ export declare const HeliusKnowledgeActionSchema: z.ZodEnum<["lookupHeliusDocs", "listHeliusDocTopics", "getHeliusCreditsInfo", "getRateLimitInfo", "troubleshootError", "recommendStack", "getSIMD", "listSIMDs", "searchSolanaDocs", "readSolanaSourceFile", "fetchHeliusBlog", "getPumpFunGuide", "getSenderInfo", "getWebhookGuide", "getLatencyComparison", "getEnhancedWebSocketInfo", "getLaserstreamInfo"]>;
9
+ export declare const HeliusWriteActionSchema: z.ZodEnum<["transferSol", "transferToken", "stakeSOL", "unstakeSOL", "withdrawStake"]>;
10
+ export declare const HeliusCompressionActionSchema: z.ZodEnum<["getCompressedAccount", "getCompressedAccountsByOwner", "getMultipleCompressedAccounts", "getCompressedBalance", "getCompressedBalanceByOwner", "getCompressedMintTokenHolders", "getCompressedTokenAccountBalance", "getCompressedTokenAccountsByOwner", "getCompressedTokenAccountsByDelegate", "getCompressedTokenBalancesByOwnerV2", "getCompressedAccountProof", "getMultipleCompressedAccountProofs", "getMultipleNewAddressProofs", "getCompressionSignaturesForAccount", "getCompressionSignaturesForAddress", "getCompressionSignaturesForOwner", "getCompressionSignaturesForTokenOwner", "getLatestCompressionSignatures", "getLatestNonVotingSignatures", "getTransactionWithCompressionInfo", "getValidityProof", "getIndexerHealth", "getIndexerSlot"]>;
11
+ export declare const HELIUS_ACCOUNT_SCHEMA: {
12
+ action: z.ZodEnum<["getStarted", "setHeliusApiKey", "generateKeypair", "signup", "getAccountStatus", "getAccountPlan", "getHeliusPlanInfo", "compareHeliusPlans", "previewUpgrade", "upgradePlan", "payRenewal", "purchaseCredits"]>;
13
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
14
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
15
+ apiKey: z.ZodOptional<z.ZodString>;
16
+ network: z.ZodOptional<z.ZodString>;
17
+ paymentIntentId: z.ZodOptional<z.ZodString>;
18
+ plan: z.ZodOptional<z.ZodString>;
19
+ period: z.ZodOptional<z.ZodString>;
20
+ couponCode: z.ZodOptional<z.ZodString>;
21
+ email: z.ZodOptional<z.ZodString>;
22
+ firstName: z.ZodOptional<z.ZodString>;
23
+ lastName: z.ZodOptional<z.ZodString>;
24
+ discoveryPath: z.ZodOptional<z.ZodString>;
25
+ frictionPoints: z.ZodOptional<z.ZodString>;
26
+ } & {
27
+ readonly _feedback: z.ZodString;
28
+ readonly _feedbackTool: z.ZodString;
29
+ readonly _model: z.ZodString;
30
+ };
31
+ export declare const HELIUS_WALLET_SCHEMA: {
32
+ action: z.ZodEnum<["getBalance", "getTokenBalances", "getWalletBalances", "getWalletHistory", "getWalletTransfers", "getWalletIdentity", "batchWalletIdentity", "getWalletFundedBy"]>;
33
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
34
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
35
+ address: z.ZodOptional<z.ZodString>;
36
+ addresses: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
37
+ limit: z.ZodOptional<z.ZodNumber>;
38
+ page: z.ZodOptional<z.ZodNumber>;
39
+ cursor: z.ZodOptional<z.ZodString>;
40
+ before: z.ZodOptional<z.ZodString>;
41
+ after: z.ZodOptional<z.ZodString>;
42
+ showNfts: z.ZodOptional<z.ZodBoolean>;
43
+ showZeroBalance: z.ZodOptional<z.ZodBoolean>;
44
+ showNative: z.ZodOptional<z.ZodBoolean>;
45
+ } & {
46
+ readonly _feedback: z.ZodString;
47
+ readonly _feedbackTool: z.ZodString;
48
+ readonly _model: z.ZodString;
49
+ };
50
+ export declare const HELIUS_ASSET_SCHEMA: {
51
+ action: z.ZodEnum<["getAsset", "getAssetsByOwner", "searchAssets", "getAssetsByGroup", "getAssetProof", "getAssetProofBatch", "getSignaturesForAsset", "getNftEditions", "getTokenHolders"]>;
52
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
53
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
54
+ id: z.ZodOptional<z.ZodString>;
55
+ ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
56
+ address: z.ZodOptional<z.ZodString>;
57
+ ownerAddress: z.ZodOptional<z.ZodString>;
58
+ creatorAddress: z.ZodOptional<z.ZodString>;
59
+ authorityAddress: z.ZodOptional<z.ZodString>;
60
+ groupKey: z.ZodOptional<z.ZodString>;
61
+ groupValue: z.ZodOptional<z.ZodString>;
62
+ mint: z.ZodOptional<z.ZodString>;
63
+ limit: z.ZodOptional<z.ZodNumber>;
64
+ page: z.ZodOptional<z.ZodNumber>;
65
+ name: z.ZodOptional<z.ZodString>;
66
+ compressed: z.ZodOptional<z.ZodBoolean>;
67
+ burnt: z.ZodOptional<z.ZodBoolean>;
68
+ frozen: z.ZodOptional<z.ZodBoolean>;
69
+ onlyVerified: z.ZodOptional<z.ZodBoolean>;
70
+ } & {
71
+ readonly _feedback: z.ZodString;
72
+ readonly _feedbackTool: z.ZodString;
73
+ readonly _model: z.ZodString;
74
+ };
75
+ export declare const HELIUS_TRANSACTION_SCHEMA: {
76
+ action: z.ZodEnum<["parseTransactions", "getTransactionHistory", "getTransfersByAddress"]>;
77
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
78
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
79
+ address: z.ZodOptional<z.ZodString>;
80
+ signature: z.ZodOptional<z.ZodString>;
81
+ signatures: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
82
+ limit: z.ZodOptional<z.ZodNumber>;
83
+ before: z.ZodOptional<z.ZodString>;
84
+ until: z.ZodOptional<z.ZodString>;
85
+ paginationToken: z.ZodOptional<z.ZodString>;
86
+ sortOrder: z.ZodOptional<z.ZodString>;
87
+ status: z.ZodOptional<z.ZodString>;
88
+ mode: z.ZodOptional<z.ZodString>;
89
+ transactionDetails: z.ZodOptional<z.ZodString>;
90
+ tokenAccounts: z.ZodOptional<z.ZodString>;
91
+ } & {
92
+ readonly _feedback: z.ZodString;
93
+ readonly _feedbackTool: z.ZodString;
94
+ readonly _model: z.ZodString;
95
+ };
96
+ export declare const HELIUS_CHAIN_SCHEMA: {
97
+ action: z.ZodEnum<["getAccountInfo", "getTokenAccounts", "getProgramAccounts", "getBlock", "getNetworkStatus", "getPriorityFeeEstimate", "getStakeAccounts", "getWithdrawableAmount"]>;
98
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
99
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
100
+ address: z.ZodOptional<z.ZodString>;
101
+ addresses: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
102
+ programId: z.ZodOptional<z.ZodString>;
103
+ slot: z.ZodOptional<z.ZodNumber>;
104
+ limit: z.ZodOptional<z.ZodNumber>;
105
+ page: z.ZodOptional<z.ZodNumber>;
106
+ stakeAccount: z.ZodOptional<z.ZodString>;
107
+ accountKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
108
+ priorityLevel: z.ZodOptional<z.ZodString>;
109
+ includeAllLevels: z.ZodOptional<z.ZodBoolean>;
110
+ encoding: z.ZodOptional<z.ZodString>;
111
+ dataSize: z.ZodOptional<z.ZodNumber>;
112
+ owner: z.ZodOptional<z.ZodString>;
113
+ mint: z.ZodOptional<z.ZodString>;
114
+ } & {
115
+ readonly _feedback: z.ZodString;
116
+ readonly _feedbackTool: z.ZodString;
117
+ readonly _model: z.ZodString;
118
+ };
119
+ export declare const HELIUS_STREAMING_SCHEMA: {
120
+ action: z.ZodEnum<["createWebhook", "getAllWebhooks", "getWebhookByID", "updateWebhook", "deleteWebhook", "transactionSubscribe", "accountSubscribe", "laserstreamSubscribe"]>;
121
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
122
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
123
+ account: z.ZodOptional<z.ZodString>;
124
+ accountAddresses: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ webhookID: z.ZodOptional<z.ZodString>;
126
+ webhookURL: z.ZodOptional<z.ZodString>;
127
+ transactionTypes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
128
+ signature: z.ZodOptional<z.ZodString>;
129
+ encoding: z.ZodOptional<z.ZodString>;
130
+ commitment: z.ZodOptional<z.ZodString>;
131
+ region: z.ZodOptional<z.ZodString>;
132
+ webhookType: z.ZodOptional<z.ZodString>;
133
+ accountInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
134
+ accountExclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
135
+ accountRequired: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
136
+ subscribeAccounts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
137
+ accountOwners: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
138
+ transactionAccountInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
139
+ transactionAccountExclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
140
+ transactionAccountRequired: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
141
+ } & {
142
+ readonly _feedback: z.ZodString;
143
+ readonly _feedbackTool: z.ZodString;
144
+ readonly _model: z.ZodString;
145
+ };
146
+ export declare const HELIUS_KNOWLEDGE_SCHEMA: {
147
+ action: z.ZodEnum<["lookupHeliusDocs", "listHeliusDocTopics", "getHeliusCreditsInfo", "getRateLimitInfo", "troubleshootError", "recommendStack", "getSIMD", "listSIMDs", "searchSolanaDocs", "readSolanaSourceFile", "fetchHeliusBlog", "getPumpFunGuide", "getSenderInfo", "getWebhookGuide", "getLatencyComparison", "getEnhancedWebSocketInfo", "getLaserstreamInfo"]>;
148
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
149
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
150
+ topic: z.ZodOptional<z.ZodString>;
151
+ section: z.ZodOptional<z.ZodString>;
152
+ query: z.ZodOptional<z.ZodString>;
153
+ slug: z.ZodOptional<z.ZodString>;
154
+ number: z.ZodOptional<z.ZodString>;
155
+ path: z.ZodOptional<z.ZodString>;
156
+ category: z.ZodOptional<z.ZodString>;
157
+ repo: z.ZodOptional<z.ZodString>;
158
+ branch: z.ZodOptional<z.ZodString>;
159
+ description: z.ZodOptional<z.ZodString>;
160
+ budget: z.ZodOptional<z.ZodString>;
161
+ complexity: z.ZodOptional<z.ZodString>;
162
+ scale: z.ZodOptional<z.ZodString>;
163
+ remember: z.ZodOptional<z.ZodBoolean>;
164
+ errorCode: z.ZodOptional<z.ZodString>;
165
+ } & {
166
+ readonly _feedback: z.ZodString;
167
+ readonly _feedbackTool: z.ZodString;
168
+ readonly _model: z.ZodString;
169
+ };
170
+ export declare const HELIUS_WRITE_SCHEMA: {
171
+ action: z.ZodEnum<["transferSol", "transferToken", "stakeSOL", "unstakeSOL", "withdrawStake"]>;
172
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
173
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
174
+ recipientAddress: z.ZodOptional<z.ZodString>;
175
+ mintAddress: z.ZodOptional<z.ZodString>;
176
+ amount: z.ZodOptional<z.ZodNumber>;
177
+ sendMax: z.ZodOptional<z.ZodBoolean>;
178
+ stakeAccount: z.ZodOptional<z.ZodString>;
179
+ destination: z.ZodOptional<z.ZodString>;
180
+ owsWallet: z.ZodOptional<z.ZodString>;
181
+ } & {
182
+ readonly _feedback: z.ZodString;
183
+ readonly _feedbackTool: z.ZodString;
184
+ readonly _model: z.ZodString;
185
+ };
186
+ export declare const HELIUS_COMPRESSION_SCHEMA: {
187
+ action: z.ZodEnum<["getCompressedAccount", "getCompressedAccountsByOwner", "getMultipleCompressedAccounts", "getCompressedBalance", "getCompressedBalanceByOwner", "getCompressedMintTokenHolders", "getCompressedTokenAccountBalance", "getCompressedTokenAccountsByOwner", "getCompressedTokenAccountsByDelegate", "getCompressedTokenBalancesByOwnerV2", "getCompressedAccountProof", "getMultipleCompressedAccountProofs", "getMultipleNewAddressProofs", "getCompressionSignaturesForAccount", "getCompressionSignaturesForAddress", "getCompressionSignaturesForOwner", "getCompressionSignaturesForTokenOwner", "getLatestCompressionSignatures", "getLatestNonVotingSignatures", "getTransactionWithCompressionInfo", "getValidityProof", "getIndexerHealth", "getIndexerSlot"]>;
188
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
189
+ args: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>]>>;
190
+ address: z.ZodOptional<z.ZodString>;
191
+ addresses: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
192
+ hash: z.ZodOptional<z.ZodString>;
193
+ hashes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
194
+ owner: z.ZodOptional<z.ZodString>;
195
+ delegate: z.ZodOptional<z.ZodString>;
196
+ mint: z.ZodOptional<z.ZodString>;
197
+ limit: z.ZodOptional<z.ZodNumber>;
198
+ cursor: z.ZodOptional<z.ZodString>;
199
+ } & {
200
+ readonly _feedback: z.ZodString;
201
+ readonly _feedbackTool: z.ZodString;
202
+ readonly _model: z.ZodString;
203
+ };
204
+ export declare const EXPAND_RESULT_SCHEMA: {
205
+ resultId: z.ZodString;
206
+ section: z.ZodOptional<z.ZodString>;
207
+ item: z.ZodOptional<z.ZodNumber>;
208
+ page: z.ZodOptional<z.ZodNumber>;
209
+ range: z.ZodOptional<z.ZodString>;
210
+ continuation: z.ZodOptional<z.ZodString>;
211
+ detail: z.ZodOptional<z.ZodEnum<["summary", "standard", "full"]>>;
212
+ } & {
213
+ readonly _feedback: z.ZodString;
214
+ readonly _feedbackTool: z.ZodString;
215
+ readonly _model: z.ZodString;
216
+ };
@@ -0,0 +1,195 @@
1
+ import { z } from 'zod';
2
+ import { HELIUS_ACCOUNT_ACTIONS, HELIUS_ASSET_ACTIONS, HELIUS_CHAIN_ACTIONS, HELIUS_COMPRESSION_ACTIONS, HELIUS_KNOWLEDGE_ACTIONS, HELIUS_STREAMING_ACTIONS, HELIUS_TRANSACTION_ACTIONS, HELIUS_WALLET_ACTIONS, HELIUS_WRITE_ACTIONS, } from './actions.js';
3
+ import { withTelemetry } from './telemetry.js';
4
+ const detailField = z.enum(['summary', 'standard', 'full']).optional();
5
+ const argsField = z.union([
6
+ z.object({}).passthrough(),
7
+ z.string().transform((s, ctx) => {
8
+ try {
9
+ return JSON.parse(s);
10
+ }
11
+ catch {
12
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'args must be a JSON object string' });
13
+ return z.NEVER;
14
+ }
15
+ }).pipe(z.object({}).passthrough()),
16
+ ]).optional();
17
+ const stringArray = () => z.array(z.string()).optional();
18
+ const optionalString = () => z.string().optional();
19
+ const optionalNumber = () => z.coerce.number().optional();
20
+ const optionalBoolean = () => z.boolean().optional();
21
+ export const HeliusAccountActionSchema = z.enum(HELIUS_ACCOUNT_ACTIONS);
22
+ export const HeliusWalletActionSchema = z.enum(HELIUS_WALLET_ACTIONS);
23
+ export const HeliusAssetActionSchema = z.enum(HELIUS_ASSET_ACTIONS);
24
+ export const HeliusTransactionActionSchema = z.enum(HELIUS_TRANSACTION_ACTIONS);
25
+ export const HeliusChainActionSchema = z.enum(HELIUS_CHAIN_ACTIONS);
26
+ export const HeliusStreamingActionSchema = z.enum(HELIUS_STREAMING_ACTIONS);
27
+ export const HeliusKnowledgeActionSchema = z.enum(HELIUS_KNOWLEDGE_ACTIONS);
28
+ export const HeliusWriteActionSchema = z.enum(HELIUS_WRITE_ACTIONS);
29
+ export const HeliusCompressionActionSchema = z.enum(HELIUS_COMPRESSION_ACTIONS);
30
+ export const HELIUS_ACCOUNT_SCHEMA = withTelemetry({
31
+ action: HeliusAccountActionSchema,
32
+ detail: detailField,
33
+ args: argsField,
34
+ apiKey: optionalString(),
35
+ network: optionalString(),
36
+ paymentIntentId: optionalString(),
37
+ plan: optionalString(),
38
+ period: optionalString(),
39
+ couponCode: optionalString(),
40
+ email: optionalString(),
41
+ firstName: optionalString(),
42
+ lastName: optionalString(),
43
+ discoveryPath: optionalString(),
44
+ frictionPoints: optionalString(),
45
+ });
46
+ export const HELIUS_WALLET_SCHEMA = withTelemetry({
47
+ action: HeliusWalletActionSchema,
48
+ detail: detailField,
49
+ args: argsField,
50
+ address: optionalString(),
51
+ addresses: stringArray(),
52
+ limit: optionalNumber(),
53
+ page: optionalNumber(),
54
+ cursor: optionalString(),
55
+ before: optionalString(),
56
+ after: optionalString(),
57
+ showNfts: optionalBoolean(),
58
+ showZeroBalance: optionalBoolean(),
59
+ showNative: optionalBoolean(),
60
+ });
61
+ export const HELIUS_ASSET_SCHEMA = withTelemetry({
62
+ action: HeliusAssetActionSchema,
63
+ detail: detailField,
64
+ args: argsField,
65
+ id: optionalString(),
66
+ ids: stringArray(),
67
+ address: optionalString(),
68
+ ownerAddress: optionalString(),
69
+ creatorAddress: optionalString(),
70
+ authorityAddress: optionalString(),
71
+ groupKey: optionalString(),
72
+ groupValue: optionalString(),
73
+ mint: optionalString(),
74
+ limit: optionalNumber(),
75
+ page: optionalNumber(),
76
+ name: optionalString(),
77
+ compressed: optionalBoolean(),
78
+ burnt: optionalBoolean(),
79
+ frozen: optionalBoolean(),
80
+ onlyVerified: optionalBoolean(),
81
+ });
82
+ export const HELIUS_TRANSACTION_SCHEMA = withTelemetry({
83
+ action: HeliusTransactionActionSchema,
84
+ detail: detailField,
85
+ args: argsField,
86
+ address: optionalString(),
87
+ signature: optionalString(),
88
+ signatures: stringArray(),
89
+ limit: optionalNumber(),
90
+ before: optionalString(),
91
+ until: optionalString(),
92
+ paginationToken: optionalString(),
93
+ sortOrder: optionalString(),
94
+ status: optionalString(),
95
+ mode: optionalString(),
96
+ transactionDetails: optionalString(),
97
+ tokenAccounts: optionalString(),
98
+ });
99
+ export const HELIUS_CHAIN_SCHEMA = withTelemetry({
100
+ action: HeliusChainActionSchema,
101
+ detail: detailField,
102
+ args: argsField,
103
+ address: optionalString(),
104
+ addresses: stringArray(),
105
+ programId: optionalString(),
106
+ slot: optionalNumber(),
107
+ limit: optionalNumber(),
108
+ page: optionalNumber(),
109
+ stakeAccount: optionalString(),
110
+ accountKeys: stringArray(),
111
+ priorityLevel: optionalString(),
112
+ includeAllLevels: optionalBoolean(),
113
+ encoding: optionalString(),
114
+ dataSize: optionalNumber(),
115
+ owner: optionalString(),
116
+ mint: optionalString(),
117
+ });
118
+ export const HELIUS_STREAMING_SCHEMA = withTelemetry({
119
+ action: HeliusStreamingActionSchema,
120
+ detail: detailField,
121
+ args: argsField,
122
+ account: optionalString(),
123
+ accountAddresses: stringArray(),
124
+ webhookID: optionalString(),
125
+ webhookURL: optionalString(),
126
+ transactionTypes: stringArray(),
127
+ signature: optionalString(),
128
+ encoding: optionalString(),
129
+ commitment: optionalString(),
130
+ region: optionalString(),
131
+ webhookType: optionalString(),
132
+ accountInclude: stringArray(),
133
+ accountExclude: stringArray(),
134
+ accountRequired: stringArray(),
135
+ subscribeAccounts: stringArray(),
136
+ accountOwners: stringArray(),
137
+ transactionAccountInclude: stringArray(),
138
+ transactionAccountExclude: stringArray(),
139
+ transactionAccountRequired: stringArray(),
140
+ });
141
+ export const HELIUS_KNOWLEDGE_SCHEMA = withTelemetry({
142
+ action: HeliusKnowledgeActionSchema,
143
+ detail: detailField,
144
+ args: argsField,
145
+ topic: optionalString(),
146
+ section: optionalString(),
147
+ query: optionalString(),
148
+ slug: optionalString(),
149
+ number: optionalString(),
150
+ path: optionalString(),
151
+ category: optionalString(),
152
+ repo: optionalString(),
153
+ branch: optionalString(),
154
+ description: optionalString(),
155
+ budget: optionalString(),
156
+ complexity: optionalString(),
157
+ scale: optionalString(),
158
+ remember: optionalBoolean(),
159
+ errorCode: optionalString(),
160
+ });
161
+ export const HELIUS_WRITE_SCHEMA = withTelemetry({
162
+ action: HeliusWriteActionSchema,
163
+ detail: detailField,
164
+ args: argsField,
165
+ recipientAddress: optionalString(),
166
+ mintAddress: optionalString(),
167
+ amount: optionalNumber(),
168
+ sendMax: optionalBoolean(),
169
+ stakeAccount: optionalString(),
170
+ destination: optionalString(),
171
+ owsWallet: optionalString(),
172
+ });
173
+ export const HELIUS_COMPRESSION_SCHEMA = withTelemetry({
174
+ action: HeliusCompressionActionSchema,
175
+ detail: detailField,
176
+ args: argsField,
177
+ address: optionalString(),
178
+ addresses: stringArray(),
179
+ hash: optionalString(),
180
+ hashes: stringArray(),
181
+ owner: optionalString(),
182
+ delegate: optionalString(),
183
+ mint: optionalString(),
184
+ limit: optionalNumber(),
185
+ cursor: optionalString(),
186
+ });
187
+ export const EXPAND_RESULT_SCHEMA = withTelemetry({
188
+ resultId: z.string(),
189
+ section: optionalString(),
190
+ item: optionalNumber(),
191
+ page: optionalNumber(),
192
+ range: optionalString(),
193
+ continuation: optionalString(),
194
+ detail: detailField,
195
+ });
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ export declare const TELEMETRY_FIELDS: {
3
+ readonly _feedback: z.ZodString;
4
+ readonly _feedbackTool: z.ZodString;
5
+ readonly _model: z.ZodString;
6
+ };
7
+ export type TelemetryPayload = {
8
+ _feedback: string;
9
+ _feedbackTool: string;
10
+ _model: string;
11
+ };
12
+ type PublicToolResponse = {
13
+ content: Array<{
14
+ type: 'text';
15
+ text: string;
16
+ }>;
17
+ isError?: boolean;
18
+ _meta?: Record<string, unknown>;
19
+ };
20
+ export declare function withTelemetry<T extends Record<string, z.ZodTypeAny>>(shape: T): T & typeof TELEMETRY_FIELDS;
21
+ export declare function splitTelemetry(params: Record<string, unknown>): {
22
+ telemetry: TelemetryPayload;
23
+ cleanParams: Record<string, unknown>;
24
+ };
25
+ export declare function normalizeTelemetry(toolName: string, params: Record<string, unknown>, telemetry: TelemetryPayload): TelemetryPayload;
26
+ export declare function withTelemetryHandler(toolName: string, handler: (params: Record<string, unknown>, extra: unknown, telemetry: TelemetryPayload) => Promise<PublicToolResponse> | PublicToolResponse): (params: Record<string, unknown>, extra: unknown) => Promise<PublicToolResponse>;
27
+ export {};
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import { sendFeedbackEvent } from '../utils/feedback.js';
3
+ const requiredTelemetryString = (description) => z.string().trim().min(1).describe(description);
4
+ export const TELEMETRY_FIELDS = {
5
+ _feedback: requiredTelemetryString('Short reason for this call or takeaway from the previous result, e.g. "initial balance check" or "balance looked healthy, checking history".'),
6
+ _feedbackTool: requiredTelemetryString('Current public tool and action in "tool.action" form, e.g. "heliusWallet.getBalance".'),
7
+ _model: requiredTelemetryString('LLM model identifier, for example claude-opus-4-6 or gpt-4o.'),
8
+ };
9
+ export function withTelemetry(shape) {
10
+ return {
11
+ ...shape,
12
+ ...TELEMETRY_FIELDS,
13
+ };
14
+ }
15
+ export function splitTelemetry(params) {
16
+ const { _feedback, _feedbackTool, _model, ...cleanParams } = params;
17
+ return {
18
+ telemetry: {
19
+ _feedback: String(_feedback ?? '').trim(),
20
+ _feedbackTool: String(_feedbackTool ?? '').trim(),
21
+ _model: String(_model ?? '').trim(),
22
+ },
23
+ cleanParams,
24
+ };
25
+ }
26
+ export function normalizeTelemetry(toolName, params, telemetry) {
27
+ const action = typeof params.action === 'string' ? params.action : undefined;
28
+ const currentTarget = action ? `${toolName}.${action}` : toolName;
29
+ const feedbackTool = telemetry._feedbackTool === 'none' ? currentTarget : telemetry._feedbackTool;
30
+ const feedback = telemetry._feedback === 'first_call'
31
+ ? `initial ${currentTarget}`
32
+ : telemetry._feedback;
33
+ return {
34
+ _feedback: feedback,
35
+ _feedbackTool: feedbackTool,
36
+ _model: telemetry._model,
37
+ };
38
+ }
39
+ export function withTelemetryHandler(toolName, handler) {
40
+ return async (params, extra) => {
41
+ const { telemetry, cleanParams } = splitTelemetry(params);
42
+ const normalizedTelemetry = normalizeTelemetry(toolName, cleanParams, telemetry);
43
+ sendFeedbackEvent({
44
+ type: 'tool_call',
45
+ toolName,
46
+ feedback: normalizedTelemetry._feedback,
47
+ feedbackTool: normalizedTelemetry._feedbackTool,
48
+ model: normalizedTelemetry._model,
49
+ });
50
+ return handler(cleanParams, extra, normalizedTelemetry);
51
+ };
52
+ }
@@ -0,0 +1,46 @@
1
+ import type { ActionName } from './actions.js';
2
+ import type { RoutedPublicToolName } from './action-groups.js';
3
+ export type DetailLevel = 'summary' | 'standard' | 'full';
4
+ export type ResponseFamily = 'scalar' | 'mutationReceipt' | 'record' | 'list' | 'history' | 'document' | 'streamingConfig' | 'catalog';
5
+ export type AuthRequirement = 'none' | 'apiKey' | 'jwt' | 'signer' | 'jwtAndSigner';
6
+ export type Mutability = 'read' | 'write';
7
+ export type ContinuationModel = 'none' | 'transactionHistory' | 'page';
8
+ export type GatePredicate = {
9
+ kind: 'always';
10
+ } | {
11
+ kind: 'network';
12
+ oneOf: Array<'devnet' | 'mainnet-beta'>;
13
+ } | {
14
+ kind: 'paramPresent';
15
+ field: string;
16
+ } | {
17
+ kind: 'paramEquals';
18
+ field: string;
19
+ value: string | number | boolean;
20
+ } | {
21
+ kind: 'and';
22
+ all: GatePredicate[];
23
+ };
24
+ export type CapabilityVariant = {
25
+ id: string;
26
+ minimumPlan: 'agent' | 'developer' | 'business' | 'professional';
27
+ predicate: GatePredicate;
28
+ label: string;
29
+ };
30
+ export type CapabilityGate = {
31
+ baseline: CapabilityVariant;
32
+ variants?: CapabilityVariant[];
33
+ };
34
+ export type ActionCatalogEntry = {
35
+ action: ActionName;
36
+ publicTool: RoutedPublicToolName;
37
+ aliases?: string[];
38
+ authRequirement: AuthRequirement;
39
+ capabilityGate: CapabilityGate;
40
+ mutability: Mutability;
41
+ responseFamily: ResponseFamily;
42
+ defaultDetail: DetailLevel;
43
+ handleEligibility: boolean;
44
+ normalizer: ResponseFamily;
45
+ continuationModel: ContinuationModel;
46
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -3,11 +3,11 @@
3
3
  * Validates the product catalog for correctness.
4
4
  *
5
5
  * Checks:
6
- * 1. Every mcpTools entry exists in KNOWN_TOOLS
6
+ * 1. Every mcpTools entry exists in the action registry
7
7
  * 2. Every referenceFile exists on disk
8
8
  * 3. Every docKey exists in DOCS_INDEX
9
9
  * 4. Every minimumPlan is a valid key in PLAN_RANK and HELIUS_PLANS
10
- * 5. Plan-feature compatibility (Laserstream mainnet → professional, Enhanced WebSockets → business+)
10
+ * 5. Plan-feature compatibility (Laserstream mainnet → business+, Enhanced WebSockets → developer+)
11
11
  * 6. No empty mcpTools arrays
12
12
  */
13
13
  export {};
@@ -3,17 +3,17 @@
3
3
  * Validates the product catalog for correctness.
4
4
  *
5
5
  * Checks:
6
- * 1. Every mcpTools entry exists in KNOWN_TOOLS
6
+ * 1. Every mcpTools entry exists in the action registry
7
7
  * 2. Every referenceFile exists on disk
8
8
  * 3. Every docKey exists in DOCS_INDEX
9
9
  * 4. Every minimumPlan is a valid key in PLAN_RANK and HELIUS_PLANS
10
- * 5. Plan-feature compatibility (Laserstream mainnet → professional, Enhanced WebSockets → business+)
10
+ * 5. Plan-feature compatibility (Laserstream mainnet → business+, Enhanced WebSockets → developer+)
11
11
  * 6. No empty mcpTools arrays
12
12
  */
13
13
  import fs from 'fs';
14
14
  import path from 'path';
15
- import { PRODUCT_CATALOG } from '../tools/product-catalog.js';
16
- import { KNOWN_TOOLS, PLAN_RANK } from '../tools/recommend.js';
15
+ import { PRODUCT_CATALOG, PLAN_RANK } from '../tools/product-catalog.js';
16
+ import { ACTION_NAME_SET } from '../router/actions.js';
17
17
  import { HELIUS_PLANS } from '../tools/plans.js';
18
18
  import { DOCS_INDEX } from '../utils/docs.js';
19
19
  // Resolve skill references relative to repo root
@@ -24,9 +24,9 @@ function error(productKey, msg) {
24
24
  errors.push(`[${productKey}] ${msg}`);
25
25
  }
26
26
  for (const [key, product] of Object.entries(PRODUCT_CATALOG)) {
27
- // 1. MCP tool names exist in KNOWN_TOOLS
27
+ // 1. MCP tool names exist in the canonical action registry
28
28
  for (const tool of product.mcpTools) {
29
- if (!KNOWN_TOOLS.has(tool)) {
29
+ if (!ACTION_NAME_SET.has(tool)) {
30
30
  error(key, `Unknown MCP tool "${tool}"`);
31
31
  }
32
32
  }
@@ -50,11 +50,11 @@ for (const [key, product] of Object.entries(PRODUCT_CATALOG)) {
50
50
  }
51
51
  // 5. Plan-feature compatibility
52
52
  const nameLower = product.name.toLowerCase();
53
- if (nameLower.includes('laserstream') && nameLower.includes('mainnet') && product.minimumPlan !== 'professional') {
54
- error(key, `Laserstream mainnet requires professional plan, but has "${product.minimumPlan}"`);
53
+ if (nameLower.includes('laserstream') && nameLower.includes('mainnet') && (PLAN_RANK[product.minimumPlan] ?? 0) < PLAN_RANK['business']) {
54
+ error(key, `Laserstream mainnet requires business+ plan, but has "${product.minimumPlan}"`);
55
55
  }
56
- if (nameLower.includes('enhanced websocket') && (PLAN_RANK[product.minimumPlan] ?? 0) < PLAN_RANK['business']) {
57
- error(key, `Enhanced WebSockets requires business+ plan, but has "${product.minimumPlan}"`);
56
+ if (nameLower.includes('enhanced websocket') && (PLAN_RANK[product.minimumPlan] ?? 0) < PLAN_RANK['developer']) {
57
+ error(key, `Enhanced WebSockets requires developer+ plan, but has "${product.minimumPlan}"`);
58
58
  }
59
59
  // 6. No empty mcpTools
60
60
  if (product.mcpTools.length === 0) {
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { getHeliusClient, hasApiKey } from '../utils/helius.js';
3
3
  import { formatAddress, formatSol } from '../utils/formatters.js';
4
4
  import { noApiKeyResponse } from './shared.js';
5
- import { mcpText, validateEnum, handleToolError, addressError, paginationError } from '../utils/errors.js';
5
+ import { mcpText, validateEnum, handleToolError, addressError, paginationError, missingParamError, exclusiveParamError, batchLimitError } from '../utils/errors.js';
6
6
  function formatParsedAccountData(account) {
7
7
  const lines = [];
8
8
  const parsedData = account.data;
@@ -34,17 +34,17 @@ export function registerAccountTools(server) {
34
34
  return err;
35
35
  // Validate: must provide exactly one of address or addresses
36
36
  if (!address && (!addresses || addresses.length === 0)) {
37
- return mcpText(`**Error:** Provide either \`address\` (single account) or \`addresses\` (batch of up to 100).`);
37
+ return missingParamError('getAccountInfo', 'Provide either `address` (single account) or `addresses` (batch of up to 100).');
38
38
  }
39
39
  if (address && addresses && addresses.length > 0) {
40
- return mcpText(`**Error:** Provide either \`address\` or \`addresses\`, not both.`);
40
+ return exclusiveParamError('getAccountInfo', 'address', 'addresses');
41
41
  }
42
42
  try {
43
43
  const helius = getHeliusClient();
44
44
  // --- Batch mode ---
45
45
  if (addresses && addresses.length > 0) {
46
46
  if (addresses.length > 100) {
47
- return mcpText(`**Error:** Maximum 100 accounts per request. You provided ${addresses.length}.`);
47
+ return batchLimitError('getAccountInfo', 100, addresses.length);
48
48
  }
49
49
  const result = await helius.getMultipleAccounts(addresses, { encoding });
50
50
  const accounts = result?.value || [];
@@ -110,7 +110,7 @@ export function registerAccountTools(server) {
110
110
  return noApiKeyResponse();
111
111
  const helius = getHeliusClient();
112
112
  if (!owner && !mint) {
113
- return mcpText(`**Error:** You must provide at least one of: owner or mint address.`);
113
+ return missingParamError('getTokenAccounts', 'Provide at least one of: `owner` or `mint` address.');
114
114
  }
115
115
  const params = { page, limit };
116
116
  if (owner)