helius-mcp 0.5.3 → 1.2.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 (67) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +1 -1
  3. package/README.md +97 -21
  4. package/dist/http.d.ts +1 -0
  5. package/dist/http.js +2 -0
  6. package/dist/index.js +93 -2
  7. package/dist/scripts/validate-catalog.d.ts +13 -0
  8. package/dist/scripts/validate-catalog.js +76 -0
  9. package/dist/tools/accounts.js +114 -204
  10. package/dist/tools/assets.js +109 -123
  11. package/dist/tools/auth.d.ts +2 -0
  12. package/dist/tools/auth.js +459 -0
  13. package/dist/tools/balance.js +28 -32
  14. package/dist/tools/blocks.js +68 -87
  15. package/dist/tools/config.js +18 -79
  16. package/dist/tools/das-extras.js +56 -41
  17. package/dist/tools/docs.js +12 -54
  18. package/dist/tools/enhanced-websockets.js +104 -74
  19. package/dist/tools/fees.js +42 -61
  20. package/dist/tools/guides.js +126 -515
  21. package/dist/tools/index.js +50 -2
  22. package/dist/tools/laserstream.js +107 -53
  23. package/dist/tools/network.js +47 -69
  24. package/dist/tools/plans.d.ts +21 -0
  25. package/dist/tools/plans.js +105 -246
  26. package/dist/tools/product-catalog.d.ts +10 -0
  27. package/dist/tools/product-catalog.js +123 -0
  28. package/dist/tools/recommend.d.ts +4 -0
  29. package/dist/tools/recommend.js +233 -0
  30. package/dist/tools/shared.js +8 -3
  31. package/dist/tools/solana-knowledge.d.ts +2 -0
  32. package/dist/tools/solana-knowledge.js +544 -0
  33. package/dist/tools/tokens.js +17 -18
  34. package/dist/tools/transactions.js +232 -302
  35. package/dist/tools/transfers.d.ts +2 -0
  36. package/dist/tools/transfers.js +270 -0
  37. package/dist/tools/wallet.js +175 -177
  38. package/dist/tools/webhooks.js +80 -82
  39. package/dist/types/transaction-types.d.ts +1 -1
  40. package/dist/types/transaction-types.js +2 -1
  41. package/dist/utils/config.d.ts +27 -0
  42. package/dist/utils/config.js +76 -0
  43. package/dist/utils/docs.d.ts +24 -0
  44. package/dist/utils/docs.js +72 -0
  45. package/dist/utils/errors.d.ts +32 -0
  46. package/dist/utils/errors.js +157 -0
  47. package/dist/utils/feedback.d.ts +16 -0
  48. package/dist/utils/feedback.js +87 -0
  49. package/dist/utils/formatters.d.ts +0 -1
  50. package/dist/utils/formatters.js +0 -3
  51. package/dist/utils/helius.d.ts +15 -5
  52. package/dist/utils/helius.js +52 -45
  53. package/dist/version.d.ts +1 -0
  54. package/dist/version.js +1 -0
  55. package/package.json +17 -7
  56. package/system-prompts/helius/claude.system.md +170 -0
  57. package/system-prompts/helius/full.md +2868 -0
  58. package/system-prompts/helius/openai.developer.md +170 -0
  59. package/system-prompts/helius-dflow/claude.system.md +290 -0
  60. package/system-prompts/helius-dflow/full.md +3647 -0
  61. package/system-prompts/helius-dflow/openai.developer.md +290 -0
  62. package/system-prompts/helius-phantom/claude.system.md +348 -0
  63. package/system-prompts/helius-phantom/full.md +5472 -0
  64. package/system-prompts/helius-phantom/openai.developer.md +348 -0
  65. package/system-prompts/svm/claude.system.md +174 -0
  66. package/system-prompts/svm/full.md +699 -0
  67. package/system-prompts/svm/openai.developer.md +174 -0
@@ -0,0 +1,233 @@
1
+ import { z } from 'zod';
2
+ import { mcpText } from '../utils/errors.js';
3
+ import { hasApiKey } from '../utils/helius.js';
4
+ import { getPreferences, savePreferences } from '../utils/config.js';
5
+ import { HELIUS_PLANS, detectCurrentPlan } from './plans.js';
6
+ import { PRODUCT_CATALOG } from './product-catalog.js';
7
+ // fetchDoc/extractSections no longer needed — live billing fetch removed
8
+ // ─── Known MCP Tools (for validation script) ───
9
+ export const KNOWN_TOOLS = new Set([
10
+ 'getStarted', 'setHeliusApiKey', 'generateKeypair', 'checkSignupBalance',
11
+ 'agenticSignup', 'getAccountStatus', 'previewUpgrade', 'upgradePlan', 'payRenewal',
12
+ 'getBalance', 'getTokenBalances', 'getWalletBalances',
13
+ 'parseTransactions', 'getTransactionHistory', 'getWalletHistory', 'getWalletTransfers',
14
+ 'getAsset', 'getAssetsByOwner', 'searchAssets', 'getAssetsByGroup',
15
+ 'getAssetProof', 'getAssetProofBatch', 'getSignaturesForAsset', 'getNftEditions',
16
+ 'getAccountInfo', 'getTokenAccounts', 'getProgramAccounts', 'getTokenHolders',
17
+ 'getBlock', 'getNetworkStatus',
18
+ 'getPriorityFeeEstimate',
19
+ 'createWebhook', 'getAllWebhooks', 'getWebhookByID', 'updateWebhook', 'deleteWebhook',
20
+ 'transactionSubscribe', 'accountSubscribe', 'getEnhancedWebSocketInfo',
21
+ 'laserstreamSubscribe', 'getLaserstreamInfo',
22
+ 'getWalletIdentity', 'batchWalletIdentity', 'getWalletFundedBy',
23
+ 'getHeliusPlanInfo', 'compareHeliusPlans',
24
+ 'lookupHeliusDocs', 'listHeliusDocTopics', 'getHeliusCreditsInfo', 'getRateLimitInfo',
25
+ 'troubleshootError', 'getSenderInfo', 'getWebhookGuide', 'getLatencyComparison', 'getPumpFunGuide',
26
+ 'recommendStack',
27
+ 'transferSol', 'transferToken',
28
+ ]);
29
+ // ─── Plan Ranking ───
30
+ export const PLAN_RANK = { free: 0, developer: 1, business: 2, professional: 3 };
31
+ function planAtOrBelow(plan, maxPlan) {
32
+ return (PLAN_RANK[plan] ?? 99) <= (PLAN_RANK[maxPlan] ?? 99);
33
+ }
34
+ // ─── Plan Limitations ───
35
+ function derivePlanLimitations(minimumPlan) {
36
+ const plan = HELIUS_PLANS[minimumPlan];
37
+ if (!plan)
38
+ return [];
39
+ const limitations = [];
40
+ limitations.push(`${plan.name} plan — see \`getHeliusPlanInfo\` for credits and rate limits`);
41
+ const gates = [];
42
+ if (!plan.features.enhancedWebSockets)
43
+ gates.push('Enhanced WebSockets');
44
+ if (!plan.features.laserstream) {
45
+ gates.push('Laserstream');
46
+ }
47
+ else if (typeof plan.features.laserstream === 'string' && plan.features.laserstream.toLowerCase().includes('devnet only')) {
48
+ limitations.push('Laserstream limited to devnet');
49
+ }
50
+ if (gates.length > 0)
51
+ limitations.push(`No ${gates.join(' or ')}`);
52
+ return limitations;
53
+ }
54
+ const TIER_MAP = {
55
+ free: 'budget',
56
+ developer: 'standard',
57
+ business: 'production',
58
+ professional: 'production',
59
+ };
60
+ const TIER_DISPLAY = { budget: 'Free', standard: 'Developer', production: 'Business / Professional' };
61
+ const TIER_PLANS = { budget: 'free', standard: 'developer', production: 'business' };
62
+ function groupCatalogByTier() {
63
+ const groups = { budget: [], standard: [], production: [] };
64
+ for (const product of Object.values(PRODUCT_CATALOG)) {
65
+ const tier = TIER_MAP[product.minimumPlan] ?? 'production';
66
+ groups[tier].push(product);
67
+ }
68
+ const tiers = [];
69
+ if (groups.budget.length > 0)
70
+ tiers.push({ tier: 'budget', tierPlan: 'free', products: groups.budget });
71
+ if (groups.standard.length > 0)
72
+ tiers.push({ tier: 'standard', tierPlan: 'developer', products: groups.standard });
73
+ if (groups.production.length > 0)
74
+ tiers.push({ tier: 'production', tierPlan: 'business', products: groups.production });
75
+ return tiers;
76
+ }
77
+ // ─── Formatting ───
78
+ function formatProduct(product) {
79
+ const docs = product.referenceFile ? ` | Docs: \`${product.referenceFile}\`` : '';
80
+ return `- **${product.name}** \u2014 ${product.description} (${product.creditCostPerCall})${docs}\n Tools: ${product.mcpTools.map(t => '`' + t + '`').join(', ')}`;
81
+ }
82
+ function formatTier(tier, detectedPlan) {
83
+ const tierLabel = TIER_DISPLAY[tier.tier];
84
+ let heading = `## ${tierLabel} Tier`;
85
+ if (detectedPlan) {
86
+ if (planAtOrBelow(tier.tierPlan, detectedPlan)) {
87
+ heading += ` \u2014 Available on your plan`;
88
+ }
89
+ else {
90
+ heading += ` \u2014 Requires upgrade`;
91
+ }
92
+ }
93
+ const lines = [heading, ''];
94
+ for (const product of tier.products) {
95
+ lines.push(formatProduct(product), '');
96
+ }
97
+ const limitations = derivePlanLimitations(tier.tierPlan);
98
+ if (limitations.length > 0) {
99
+ lines.push(`### ${tierLabel} Tier Limits`);
100
+ for (const lim of limitations) {
101
+ lines.push(`- ${lim}`);
102
+ }
103
+ }
104
+ return lines.join('\n');
105
+ }
106
+ function formatUpgradeTier(tier) {
107
+ const planInfo = HELIUS_PLANS[tier.tierPlan];
108
+ const planName = planInfo ? planInfo.name : tier.tierPlan;
109
+ const tierLabel = TIER_DISPLAY[tier.tier];
110
+ const productNames = tier.products.map(p => p.name);
111
+ const firstDesc = tier.products[0].description.split('.')[0];
112
+ const addsLine = `Adds: ${productNames.join(', ')} \u2014 ${firstDesc}`;
113
+ const refs = tier.products
114
+ .filter(p => p.referenceFile)
115
+ .map(p => `\`${p.referenceFile}\``);
116
+ const refsLine = refs.length > 0 ? `Read: ${refs.join(', ')}` : '';
117
+ const lines = [
118
+ `### ${tierLabel} Tier \u2014 Requires ${planName} plan`,
119
+ addsLine,
120
+ ];
121
+ if (refsLine)
122
+ lines.push(refsLine);
123
+ return lines.join('\n');
124
+ }
125
+ function formatCatalog(availableTiers, upgradeTiers, description, complexity, detectedPlan) {
126
+ const lines = ['# Helius Product Catalog', ''];
127
+ lines.push(`> "${description}"`, '');
128
+ if (detectedPlan) {
129
+ const planInfo = HELIUS_PLANS[detectedPlan];
130
+ if (planInfo) {
131
+ lines.push(`**Your plan:** ${planInfo.name}`, '');
132
+ }
133
+ }
134
+ lines.push('---', '');
135
+ if (complexity) {
136
+ const label = { low: 'free tier only', medium: 'free + developer tiers', high: 'all tiers' };
137
+ lines.push(`_Showing ${label[complexity]}_`, '', '---', '');
138
+ }
139
+ for (let i = 0; i < availableTiers.length; i++) {
140
+ lines.push(formatTier(availableTiers[i], detectedPlan));
141
+ if (i < availableTiers.length - 1) {
142
+ lines.push('', '---', '');
143
+ }
144
+ }
145
+ if (upgradeTiers.length > 0) {
146
+ lines.push('', '---', '', '## Upgrade Paths', '');
147
+ for (let i = 0; i < upgradeTiers.length; i++) {
148
+ lines.push(formatUpgradeTier(upgradeTiers[i]));
149
+ if (i < upgradeTiers.length - 1) {
150
+ lines.push('');
151
+ }
152
+ }
153
+ }
154
+ lines.push('', '---', '', '_Use `getHeliusPlanInfo` for pricing and `lookupHeliusDocs` for API details._', '', '*Token tip: Use batch endpoints and `section` filters on `lookupHeliusDocs` to minimize per-call context usage.*');
155
+ return lines.join('\n');
156
+ }
157
+ // ─── Filtering ───
158
+ const COMPLEXITY_MAX_TIER = {
159
+ low: ['budget'],
160
+ medium: ['budget', 'standard'],
161
+ high: ['budget', 'standard', 'production'],
162
+ };
163
+ const SCALE_TIERS = {
164
+ budget: ['budget'],
165
+ standard: ['standard'],
166
+ production: ['production'],
167
+ all: ['budget', 'standard', 'production'],
168
+ };
169
+ // ─── Tool Registration ───
170
+ export function registerRecommendTools(server) {
171
+ server.tool('recommendStack', 'BEST FOR: project architecture when user describes a Solana app to build. PREFER getHeliusPlanInfo for pricing-only, lookupHeliusDocs for API docs. Get tiered architecture recommendations. Returns Helius products, MCP tools, credit costs, minimum plan, and reference files.', {
172
+ description: z.string().describe('What the user wants to build, in their own words'),
173
+ budget: z.enum(['free', 'developer', 'business', 'professional']).optional(),
174
+ complexity: z.enum(['low', 'medium', 'high']).optional(),
175
+ scale: z.enum(['budget', 'standard', 'production', 'all']).optional().default('all'),
176
+ remember: z.boolean().optional().describe('Save budget/complexity preferences for future sessions'),
177
+ }, async ({ description, budget, complexity, scale, remember }) => {
178
+ // 1. Load saved preferences, merge with provided params
179
+ const savedPrefs = getPreferences();
180
+ const effectiveBudget = budget ?? savedPrefs.budget;
181
+ const effectiveComplexity = complexity ?? savedPrefs.complexity;
182
+ // 2. Save preferences if requested
183
+ if (remember) {
184
+ savePreferences({
185
+ budget: effectiveBudget,
186
+ complexity: effectiveComplexity,
187
+ });
188
+ }
189
+ // 3. Detect current plan from JWT
190
+ const detectedPlan = await detectCurrentPlan();
191
+ // 4. Group catalog into tiers
192
+ let tiers = groupCatalogByTier();
193
+ // 5. Apply filters (AND logic)
194
+ if (scale !== 'all') {
195
+ const allowed = SCALE_TIERS[scale] ?? [];
196
+ tiers = tiers.filter(t => allowed.includes(t.tier));
197
+ }
198
+ if (effectiveComplexity) {
199
+ const allowed = COMPLEXITY_MAX_TIER[effectiveComplexity] ?? [];
200
+ tiers = tiers.filter(t => allowed.includes(t.tier));
201
+ }
202
+ if (effectiveBudget) {
203
+ tiers = tiers.filter(t => planAtOrBelow(t.tierPlan, effectiveBudget));
204
+ }
205
+ if (tiers.length === 0) {
206
+ return mcpText(`# Helius Product Catalog\n\n` +
207
+ `> "${description}"\n\n` +
208
+ 'No tiers match your current filters. Try:\n' +
209
+ '- Increasing your `budget` (e.g., `developer`, `business`)\n' +
210
+ '- Setting `scale` to `all` to see all tiers\n' +
211
+ '- Removing filters to see the full recommendation');
212
+ }
213
+ // 6. Partition tiers when plan is detected and no explicit budget filter
214
+ const shouldSplit = detectedPlan && !budget && !savedPrefs.budget;
215
+ let availableTiers = tiers;
216
+ let upgradeTiers = [];
217
+ if (shouldSplit) {
218
+ const available = tiers.filter(t => planAtOrBelow(t.tierPlan, detectedPlan));
219
+ const upgrades = tiers.filter(t => !planAtOrBelow(t.tierPlan, detectedPlan));
220
+ if (available.length > 0) {
221
+ availableTiers = available;
222
+ upgradeTiers = upgrades;
223
+ }
224
+ }
225
+ // 7. Format output
226
+ let output = formatCatalog(availableTiers, upgradeTiers, description, effectiveComplexity, detectedPlan);
227
+ // 9. Soft hint: if no API key, append setup note
228
+ if (!hasApiKey()) {
229
+ output += '\n\n---\n\n> **Setup needed:** You\'ll need a Helius API key to use these tools. Call `getStarted` for setup instructions.';
230
+ }
231
+ return mcpText(output);
232
+ });
233
+ }
@@ -2,10 +2,15 @@ const NO_API_KEY_MESSAGE = `**Helius API Key Required**
2
2
 
3
3
  I need a Helius API key to query the Solana blockchain.
4
4
 
5
- **Get your key:**
5
+ **Option 1 — Sign up here (recommended):**
6
+ 1. Call \`generateKeypair\` to create a signup wallet
7
+ 2. Fund the wallet with ~0.001 SOL + 1 USDC
8
+ 3. Call \`agenticSignup\` to create your account — the API key will be configured automatically
9
+
10
+ **Option 2 — Use an existing key:**
6
11
  1. Go to https://dashboard.helius.dev/api-keys
7
- 2. Sign in or sign up
8
- 3. Send your API key here in chat`;
12
+ 2. Copy your API key
13
+ 3. Call \`setHeliusApiKey\` with your key`;
9
14
  export function noApiKeyResponse() {
10
15
  return {
11
16
  content: [{ type: 'text', text: NO_API_KEY_MESSAGE }]
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerSolanaKnowledgeTools(server: McpServer): void;