helius-mcp 0.4.1 → 0.5.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.
@@ -35,15 +35,15 @@ export function registerConfigTools(server) {
35
35
  '"env": { "HELIUS_API_KEY": "your-api-key" }',
36
36
  '```',
37
37
  '',
38
- '**Get your free API key at: https://dev.helius.xyz**',
38
+ '**Get your free API key at: https://dashboard.helius.dev/api-keys**',
39
39
  '',
40
40
  'Note: Guide tools (getRateLimitInfo, getSenderInfo, etc.) work without an API key.',
41
41
  ].join('\n')
42
42
  }]
43
43
  };
44
44
  });
45
- server.tool('setHeliusApiKey', 'Set the Helius API key for the current session. Required before using data tools (getBalance, getAsset, etc.). Get your free API key at https://dev.helius.xyz', {
46
- apiKey: z.string().describe('Your Helius API key from https://dev.helius.xyz'),
45
+ server.tool('setHeliusApiKey', 'Set the Helius API key for the current session. Required before using data tools (getBalance, getAsset, etc.). Get your free API key at https://dashboard.helius.dev/api-keys', {
46
+ apiKey: z.string().describe('Your Helius API key from https://dashboard.helius.dev/api-keys'),
47
47
  network: z.enum(['mainnet-beta', 'devnet']).optional().default('mainnet-beta').describe('Network to use (default: mainnet-beta)')
48
48
  }, async ({ apiKey, network }) => {
49
49
  setApiKey(apiKey);
@@ -67,7 +67,7 @@ export function registerConfigTools(server) {
67
67
  '',
68
68
  'Please check your key and try again.',
69
69
  '',
70
- 'Get your free API key at: https://dev.helius.xyz',
70
+ 'Get your free API key at: https://dashboard.helius.dev/api-keys',
71
71
  ].join('\n')
72
72
  }],
73
73
  isError: true
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDocsTools(server: McpServer): void;
@@ -0,0 +1,215 @@
1
+ import { z } from 'zod';
2
+ import { fetchDoc, getDocsIndex } from '../utils/docs.js';
3
+ export function registerDocsTools(server) {
4
+ /**
5
+ * Lookup Helius documentation - fetches official docs for accurate information
6
+ */
7
+ server.tool('lookupHeliusDocs', 'Fetch official Helius documentation for accurate, up-to-date information. Use this when you need precise details about APIs, pricing, rate limits, or features. Returns the official llms.txt documentation which is optimized for AI consumption.', {
8
+ topic: z
9
+ .enum([
10
+ 'overview',
11
+ 'das',
12
+ 'rpc',
13
+ 'websocket',
14
+ 'enhanced-websockets',
15
+ 'webhooks',
16
+ 'enhanced-transactions',
17
+ 'sender',
18
+ 'priority-fee',
19
+ 'laserstream',
20
+ 'wallet-api',
21
+ 'zk-compression',
22
+ 'dedicated-nodes',
23
+ 'shred-delivery',
24
+ ])
25
+ .describe('Documentation topic to fetch'),
26
+ section: z
27
+ .string()
28
+ .optional()
29
+ .describe('Optional: specific section to extract (e.g., "credits", "rate limits", "parameters"). If provided, returns only matching sections.'),
30
+ }, async ({ topic, section }) => {
31
+ try {
32
+ const content = await fetchDoc(topic);
33
+ // If a section filter is provided, extract relevant parts
34
+ if (section) {
35
+ const sectionLower = section.toLowerCase();
36
+ const lines = content.split('\n');
37
+ const relevantLines = [];
38
+ let inRelevantSection = false;
39
+ let sectionDepth = 0;
40
+ for (const line of lines) {
41
+ // Check if this is a header
42
+ const headerMatch = line.match(/^(#{1,4})\s+(.+)/);
43
+ if (headerMatch) {
44
+ const depth = headerMatch[1].length;
45
+ const title = headerMatch[2].toLowerCase();
46
+ if (title.includes(sectionLower)) {
47
+ inRelevantSection = true;
48
+ sectionDepth = depth;
49
+ relevantLines.push(line);
50
+ }
51
+ else if (inRelevantSection && depth <= sectionDepth) {
52
+ // We've hit a new section at same or higher level
53
+ inRelevantSection = false;
54
+ }
55
+ else if (inRelevantSection) {
56
+ relevantLines.push(line);
57
+ }
58
+ }
59
+ else if (inRelevantSection) {
60
+ relevantLines.push(line);
61
+ }
62
+ else if (line.toLowerCase().includes(sectionLower)) {
63
+ // Include lines that mention the section keyword even outside headers
64
+ relevantLines.push(line);
65
+ }
66
+ }
67
+ if (relevantLines.length > 0) {
68
+ const result = [
69
+ `# Helius Docs: ${topic} (filtered by "${section}")`,
70
+ '',
71
+ ...relevantLines,
72
+ '',
73
+ '---',
74
+ `Source: https://www.helius.dev/docs (${topic})`,
75
+ ].join('\n');
76
+ return { content: [{ type: 'text', text: result }] };
77
+ }
78
+ else {
79
+ return {
80
+ content: [
81
+ {
82
+ type: 'text',
83
+ text: `No sections matching "${section}" found in ${topic} docs. Returning full documentation:\n\n${content}`,
84
+ },
85
+ ],
86
+ };
87
+ }
88
+ }
89
+ // Return full documentation
90
+ const result = [
91
+ `# Helius Docs: ${topic}`,
92
+ '',
93
+ content,
94
+ '',
95
+ '---',
96
+ `Source: https://www.helius.dev/docs`,
97
+ ].join('\n');
98
+ return { content: [{ type: 'text', text: result }] };
99
+ }
100
+ catch (error) {
101
+ const errorMsg = error instanceof Error ? error.message : String(error);
102
+ return {
103
+ content: [
104
+ {
105
+ type: 'text',
106
+ text: `Error fetching docs: ${errorMsg}\n\nTry again or check https://www.helius.dev/docs directly.`,
107
+ },
108
+ ],
109
+ isError: true,
110
+ };
111
+ }
112
+ });
113
+ /**
114
+ * List available documentation topics
115
+ */
116
+ server.tool('listHeliusDocTopics', 'List all available Helius documentation topics that can be fetched with lookupHeliusDocs.', {}, async () => {
117
+ const index = getDocsIndex();
118
+ const lines = [
119
+ '# Available Helius Documentation Topics',
120
+ '',
121
+ 'Use `lookupHeliusDocs` with any of these topics to fetch official documentation:',
122
+ '',
123
+ '| Topic | Description |',
124
+ '|-------|-------------|',
125
+ ...index.map((doc) => `| \`${doc.key}\` | ${doc.description} |`),
126
+ '',
127
+ '## Usage Examples',
128
+ '',
129
+ '```',
130
+ '// Get overview with plans, credits, rate limits',
131
+ 'lookupHeliusDocs({ topic: "overview" })',
132
+ '',
133
+ '// Get DAS API documentation',
134
+ 'lookupHeliusDocs({ topic: "das" })',
135
+ '',
136
+ '// Get specific section from docs',
137
+ 'lookupHeliusDocs({ topic: "overview", section: "credits" })',
138
+ 'lookupHeliusDocs({ topic: "das", section: "rate limits" })',
139
+ '```',
140
+ ];
141
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
142
+ });
143
+ /**
144
+ * Get credits information from official docs
145
+ */
146
+ server.tool('getHeliusCreditsInfo', 'Get official Helius credit costs from documentation. Fetches the latest pricing information directly from Helius docs.', {}, async () => {
147
+ try {
148
+ const content = await fetchDoc('overview');
149
+ // Extract credits section
150
+ const lines = content.split('\n');
151
+ const creditsLines = [];
152
+ let inCreditsSection = false;
153
+ for (let i = 0; i < lines.length; i++) {
154
+ const line = lines[i];
155
+ // Look for Credits section
156
+ if (line.includes('## Credits') || line.includes('| Credits |')) {
157
+ inCreditsSection = true;
158
+ }
159
+ if (inCreditsSection) {
160
+ creditsLines.push(line);
161
+ // Stop at next major section
162
+ if (creditsLines.length > 2 && line.startsWith('## ') && !line.includes('Credits')) {
163
+ creditsLines.pop(); // Remove the next section header
164
+ break;
165
+ }
166
+ }
167
+ }
168
+ // Also look for the credits table
169
+ const tableLines = [];
170
+ for (let i = 0; i < lines.length; i++) {
171
+ if (lines[i].includes('| Credits |') || lines[i].includes('| 0 |') || lines[i].includes('| 1 |') || lines[i].includes('| 3 |') || lines[i].includes('| 10 |') || lines[i].includes('| 100 |')) {
172
+ // Collect table lines
173
+ let j = i;
174
+ while (j < lines.length && (lines[j].includes('|') || lines[j].trim() === '')) {
175
+ if (lines[j].includes('|')) {
176
+ tableLines.push(lines[j]);
177
+ }
178
+ j++;
179
+ if (j - i > 20)
180
+ break; // Safety limit
181
+ }
182
+ break;
183
+ }
184
+ }
185
+ const result = [
186
+ '# Helius Credit Costs (Official)',
187
+ '',
188
+ 'Source: https://www.helius.dev/docs (fetched live)',
189
+ '',
190
+ ...tableLines,
191
+ '',
192
+ '## Key Points',
193
+ '- Credits are consumed per API call',
194
+ '- Monthly allocation resets each billing cycle',
195
+ '- Additional credits: $5 per million (paid plans)',
196
+ '',
197
+ '## Credit Tiers',
198
+ '| Plan | Monthly Credits |',
199
+ '|------|-----------------|',
200
+ '| Free | 1M |',
201
+ '| Developer ($49/mo) | 10M |',
202
+ '| Business ($499/mo) | 100M |',
203
+ '| Professional ($999/mo) | 200M |',
204
+ ].join('\n');
205
+ return { content: [{ type: 'text', text: result }] };
206
+ }
207
+ catch (error) {
208
+ const errorMsg = error instanceof Error ? error.message : String(error);
209
+ return {
210
+ content: [{ type: 'text', text: `Error fetching credits info: ${errorMsg}` }],
211
+ isError: true,
212
+ };
213
+ }
214
+ });
215
+ }
@@ -30,38 +30,68 @@ const RATE_LIMITS = {
30
30
  websocket: { connections: 250, enhanced: 100 },
31
31
  },
32
32
  };
33
- // Credit costs per method
33
+ // Credit costs per method - aligned with official Helius docs
34
+ // Source: https://www.helius.dev/docs/billing/credits
34
35
  const CREDIT_COSTS = {
35
- // Standard RPC (1 credit each)
36
+ // === 0 CREDITS ===
37
+ 'Helius Sender': { cost: 0, notes: 'Ultra-low latency transaction submission' },
38
+ // === 1 CREDIT (Standard RPC) ===
36
39
  getBalance: { cost: 1 },
37
40
  getAccountInfo: { cost: 1 },
38
- getMultipleAccounts: { cost: 1, notes: 'Per account in request' },
39
- getTransaction: { cost: 1 },
40
- getSignaturesForAddress: { cost: 1 },
41
- getBlock: { cost: 1 },
41
+ getMultipleAccounts: { cost: 1 },
42
42
  getBlockHeight: { cost: 1 },
43
43
  getSlot: { cost: 1 },
44
44
  getLatestBlockhash: { cost: 1 },
45
- sendTransaction: { cost: 1 },
45
+ sendTransaction: { cost: 1, notes: 'Via staked connections' },
46
46
  simulateTransaction: { cost: 1 },
47
47
  getTokenAccountsByOwner: { cost: 1 },
48
- getProgramAccounts: { cost: 1, notes: 'Can be expensive with large result sets' },
49
- // DAS API (10-100 credits)
48
+ getProgramAccountsV2: { cost: 1, notes: 'Paginated version' },
49
+ getTokenAccountsByOwnerV2: { cost: 1, notes: 'Paginated version' },
50
+ simulateBundle: { cost: 1, notes: 'Jito bundle simulation' },
51
+ 'Priority Fee API': { cost: 1 },
52
+ 'getSignatureStatuses (recent)': { cost: 1, notes: 'With searchTransactionHistory: false' },
53
+ // === 3 CREDITS (Data Streaming) ===
54
+ 'LaserStream gRPC': { cost: '3 per 0.1 MB', notes: 'Uncompressed data streamed' },
55
+ 'Enhanced WebSockets': { cost: '3 per 0.1 MB', notes: 'Uncompressed data streamed' },
56
+ // === 10 CREDITS (Historical Data & DAS API) ===
57
+ getProgramAccounts: { cost: 10, notes: 'Use getProgramAccountsV2 for 1 credit' },
58
+ getBlock: { cost: 10, notes: 'Historical/archival data' },
59
+ getBlocks: { cost: 10 },
60
+ getBlocksWithLimit: { cost: 10 },
61
+ getBlockTime: { cost: 10 },
62
+ getTransaction: { cost: 10, notes: 'Historical/archival data' },
63
+ getSignaturesForAddress: { cost: 10 },
64
+ getInflationReward: { cost: 10 },
65
+ 'getSignatureStatuses (historical)': { cost: 10, notes: 'With searchTransactionHistory: true' },
66
+ // DAS API (all 10 credits)
50
67
  getAsset: { cost: 10 },
51
- getAssetsByOwner: { cost: 10, notes: 'Per page of results' },
68
+ getAssetBatch: { cost: 10 },
69
+ getAssetsByOwner: { cost: 10 },
52
70
  getAssetsByGroup: { cost: 10 },
53
71
  getAssetsByCreator: { cost: 10 },
54
- searchAssets: { cost: 10, notes: 'Complex queries may cost more' },
72
+ getAssetsByAuthority: { cost: 10 },
73
+ searchAssets: { cost: 10 },
55
74
  getAssetProof: { cost: 10 },
56
- getAssetBatch: { cost: '10 per asset' },
57
- // Enhanced Transactions
58
- parseTransactions: { cost: '10-50', notes: 'Depends on transaction complexity' },
59
- getTransactionHistory: { cost: 10 },
75
+ getAssetProofBatch: { cost: 10 },
76
+ getNftEditions: { cost: 10 },
77
+ getSignaturesForAsset: { cost: 10 },
78
+ getTokenAccounts: { cost: 10 },
79
+ // ZK Compression (10 credits)
80
+ 'ZK Compression API': { cost: 10 },
81
+ // === 100 CREDITS (Enhanced APIs) ===
82
+ 'Enhanced Transactions API': { cost: 100, notes: 'parseTransactions, parsed history' },
83
+ getTransactionsForAddress: { cost: 100, notes: 'Developer+ plans only' },
84
+ getValidityProof: { cost: 100, notes: 'ZK Compression - computationally intensive' },
85
+ // Wallet API (all 100 credits)
86
+ 'Wallet Identity': { cost: 100 },
87
+ 'Batch Identity Lookup': { cost: 100, notes: 'Up to 100 addresses' },
88
+ 'Wallet Balances': { cost: 100 },
89
+ 'Wallet History': { cost: 100 },
90
+ 'Token Transfers': { cost: 100 },
91
+ 'Wallet Funding Source': { cost: 100 },
60
92
  // Webhooks
61
- webhookDelivery: { cost: 1, notes: 'Per webhook event delivered' },
62
- // Enhanced WebSockets
63
- wsConnection: { cost: 1, notes: 'Per new connection opened' },
64
- wsDataStreaming: { cost: '3 per 0.1 MB', notes: 'Enhanced WS only; Standard WS is free' },
93
+ 'Webhook Events': { cost: 1, notes: 'Per event delivered' },
94
+ 'Webhook Management': { cost: 100, notes: 'Create, edit, or delete' },
65
95
  };
66
96
  // Error codes and their meanings
67
97
  const ERROR_CODES = {
@@ -14,6 +14,7 @@ import { registerLaserstreamTools } from './laserstream.js';
14
14
  import { registerWalletTools } from './wallet.js';
15
15
  import { registerPlanTools } from './plans.js';
16
16
  import { registerGuideTools } from './guides.js';
17
+ import { registerDocsTools } from './docs.js';
17
18
  export function registerTools(server) {
18
19
  registerConfigTools(server);
19
20
  registerBalanceTools(server);
@@ -31,4 +32,5 @@ export function registerTools(server) {
31
32
  registerWalletTools(server);
32
33
  registerPlanTools(server);
33
34
  registerGuideTools(server);
35
+ registerDocsTools(server);
34
36
  }
@@ -189,11 +189,13 @@ export function registerPlanTools(server) {
189
189
  '- **Data add-ons:** Starting at $500/mo for Professional',
190
190
  '- **Features:** 24h historical replay, lowest latency',
191
191
  '',
192
- '### Credit Costs',
193
- '- Standard RPC calls: 1 credit',
194
- '- DAS API calls: 10-100 credits',
195
- '- Enhanced transactions: 10-50 credits',
196
- '- Additional credits: $5 per million (all paid plans)',
192
+ '### Credit Costs (from docs)',
193
+ '- **0 credits**: Helius Sender',
194
+ '- **1 credit**: Standard RPC, sendTransaction, Priority Fee API, webhook events',
195
+ '- **3 credits**: per 0.1 MB streamed (LaserStream, Enhanced WS)',
196
+ '- **10 credits**: getProgramAccounts, historical data (getBlock, getTransaction, etc.), DAS API',
197
+ '- **100 credits**: Enhanced Transactions, Wallet API, getValidityProof (ZK), webhook management',
198
+ '- **Additional credits**: $5 per million (all paid plans)',
197
199
  '',
198
200
  '**Docs:** https://www.helius.dev/pricing',
199
201
  ];
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Helius Documentation Fetcher
3
+ *
4
+ * Fetches official Helius documentation from GitHub for accurate, up-to-date information.
5
+ * Uses llms.txt files which are AI-optimized summaries of the documentation.
6
+ */
7
+ export declare const DOCS_INDEX: Record<string, {
8
+ path: string;
9
+ description: string;
10
+ }>;
11
+ /**
12
+ * Fetch a specific documentation file
13
+ */
14
+ export declare function fetchDoc(docKey: string): Promise<string>;
15
+ /**
16
+ * Fetch multiple documentation files
17
+ */
18
+ export declare function fetchDocs(docKeys: string[]): Promise<Map<string, string>>;
19
+ /**
20
+ * Get the list of available documentation topics
21
+ */
22
+ export declare function getAvailableDocTopics(): string[];
23
+ /**
24
+ * Get documentation index with descriptions
25
+ */
26
+ export declare function getDocsIndex(): Array<{
27
+ key: string;
28
+ description: string;
29
+ }>;
30
+ /**
31
+ * Search docs content for a specific term (searches cached docs only)
32
+ */
33
+ export declare function searchCachedDocs(searchTerm: string): Array<{
34
+ docKey: string;
35
+ matches: string[];
36
+ }>;
37
+ /**
38
+ * Clear the docs cache (useful for forcing fresh fetches)
39
+ */
40
+ export declare function clearDocsCache(): void;
41
+ /**
42
+ * Get cache stats
43
+ */
44
+ export declare function getDocsCacheStats(): {
45
+ cachedDocs: string[];
46
+ totalSize: number;
47
+ };
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Helius Documentation Fetcher
3
+ *
4
+ * Fetches official Helius documentation from GitHub for accurate, up-to-date information.
5
+ * Uses llms.txt files which are AI-optimized summaries of the documentation.
6
+ */
7
+ // GitHub raw URL base for Helius docs
8
+ const DOCS_BASE_URL = 'https://raw.githubusercontent.com/helius-labs/docs/main';
9
+ // Available llms.txt documentation files
10
+ export const DOCS_INDEX = {
11
+ overview: {
12
+ path: '/llms.txt',
13
+ description: 'Main Helius overview: plans, credits, rate limits, use cases, API index',
14
+ },
15
+ das: {
16
+ path: '/api-reference/das/llms.txt',
17
+ description: 'DAS API: getAsset, getAssetsByOwner, searchAssets, compressed NFTs',
18
+ },
19
+ rpc: {
20
+ path: '/api-reference/rpc/http/llms.txt',
21
+ description: 'Standard Solana RPC methods with Helius enhancements',
22
+ },
23
+ websocket: {
24
+ path: '/api-reference/rpc/websocket/llms.txt',
25
+ description: 'Standard Solana WebSocket subscriptions',
26
+ },
27
+ 'enhanced-websockets': {
28
+ path: '/enhanced-websockets/llms.txt',
29
+ description: 'Enhanced WebSockets: transactionSubscribe, accountSubscribe, filtering',
30
+ },
31
+ webhooks: {
32
+ path: '/api-reference/webhooks/llms.txt',
33
+ description: 'Webhooks: setup, transaction types, delivery, troubleshooting',
34
+ },
35
+ 'enhanced-transactions': {
36
+ path: '/api-reference/enhanced-transactions/llms.txt',
37
+ description: 'Enhanced Transactions API: parseTransactions, transaction history',
38
+ },
39
+ sender: {
40
+ path: '/api-reference/sender/llms.txt',
41
+ description: 'Helius Sender: transaction submission, SWQoS, tips, latency',
42
+ },
43
+ 'priority-fee': {
44
+ path: '/api-reference/priority-fee/llms.txt',
45
+ description: 'Priority Fee API: fee estimation, compute units',
46
+ },
47
+ laserstream: {
48
+ path: '/api-reference/laserstream/grpc/llms.txt',
49
+ description: 'LaserStream gRPC: real-time streaming, subscriptions, replay',
50
+ },
51
+ 'wallet-api': {
52
+ path: '/api-reference/wallet-api/llms.txt',
53
+ description: 'Wallet API: balances, history, transfers, identity, funding source',
54
+ },
55
+ 'zk-compression': {
56
+ path: '/api-reference/zk-compression/llms.txt',
57
+ description: 'ZK Compression API: compressed accounts, validity proofs',
58
+ },
59
+ 'dedicated-nodes': {
60
+ path: '/dedicated-nodes/llms.txt',
61
+ description: 'Dedicated Nodes: private infrastructure, Yellowstone gRPC',
62
+ },
63
+ 'shred-delivery': {
64
+ path: '/shred-delivery/llms.txt',
65
+ description: 'Shred Delivery: lowest latency, UDP shreds',
66
+ },
67
+ };
68
+ // In-memory cache for fetched docs (per session)
69
+ const docsCache = new Map();
70
+ const CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
71
+ /**
72
+ * Fetch a specific documentation file
73
+ */
74
+ export async function fetchDoc(docKey) {
75
+ const docInfo = DOCS_INDEX[docKey];
76
+ if (!docInfo) {
77
+ const availableKeys = Object.keys(DOCS_INDEX).join(', ');
78
+ throw new Error(`Unknown doc key: "${docKey}". Available: ${availableKeys}`);
79
+ }
80
+ // Check cache
81
+ const cached = docsCache.get(docKey);
82
+ if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
83
+ return cached.content;
84
+ }
85
+ // Fetch from GitHub
86
+ const url = `${DOCS_BASE_URL}${docInfo.path}`;
87
+ try {
88
+ const response = await fetch(url);
89
+ if (!response.ok) {
90
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
91
+ }
92
+ const content = await response.text();
93
+ // Cache the result
94
+ docsCache.set(docKey, { content, fetchedAt: Date.now() });
95
+ return content;
96
+ }
97
+ catch (error) {
98
+ const errorMsg = error instanceof Error ? error.message : String(error);
99
+ throw new Error(`Failed to fetch docs from ${url}: ${errorMsg}`);
100
+ }
101
+ }
102
+ /**
103
+ * Fetch multiple documentation files
104
+ */
105
+ export async function fetchDocs(docKeys) {
106
+ const results = new Map();
107
+ const errors = [];
108
+ await Promise.all(docKeys.map(async (key) => {
109
+ try {
110
+ const content = await fetchDoc(key);
111
+ results.set(key, content);
112
+ }
113
+ catch (error) {
114
+ errors.push(`${key}: ${error instanceof Error ? error.message : String(error)}`);
115
+ }
116
+ }));
117
+ if (errors.length > 0 && results.size === 0) {
118
+ throw new Error(`Failed to fetch any docs:\n${errors.join('\n')}`);
119
+ }
120
+ return results;
121
+ }
122
+ /**
123
+ * Get the list of available documentation topics
124
+ */
125
+ export function getAvailableDocTopics() {
126
+ return Object.keys(DOCS_INDEX);
127
+ }
128
+ /**
129
+ * Get documentation index with descriptions
130
+ */
131
+ export function getDocsIndex() {
132
+ return Object.entries(DOCS_INDEX).map(([key, info]) => ({
133
+ key,
134
+ description: info.description,
135
+ }));
136
+ }
137
+ /**
138
+ * Search docs content for a specific term (searches cached docs only)
139
+ */
140
+ export function searchCachedDocs(searchTerm) {
141
+ const results = [];
142
+ const searchLower = searchTerm.toLowerCase();
143
+ for (const [docKey, cached] of docsCache.entries()) {
144
+ const lines = cached.content.split('\n');
145
+ const matches = lines.filter((line) => line.toLowerCase().includes(searchLower));
146
+ if (matches.length > 0) {
147
+ results.push({ docKey, matches: matches.slice(0, 5) }); // Limit to 5 matches per doc
148
+ }
149
+ }
150
+ return results;
151
+ }
152
+ /**
153
+ * Clear the docs cache (useful for forcing fresh fetches)
154
+ */
155
+ export function clearDocsCache() {
156
+ docsCache.clear();
157
+ }
158
+ /**
159
+ * Get cache stats
160
+ */
161
+ export function getDocsCacheStats() {
162
+ const cachedDocs = Array.from(docsCache.keys());
163
+ let totalSize = 0;
164
+ for (const cached of docsCache.values()) {
165
+ totalSize += cached.content.length;
166
+ }
167
+ return { cachedDocs, totalSize };
168
+ }
@@ -12,7 +12,7 @@ export function getApiKey() {
12
12
  throw new Error('API key not set. Please use the setHeliusApiKey tool first:\n\n' +
13
13
  ' Tool: setHeliusApiKey\n' +
14
14
  ' Arguments: { "apiKey": "your-helius-api-key" }\n\n' +
15
- 'Get your free API key at: https://dev.helius.xyz');
15
+ 'Get your free API key at: https://dashboard.helius.dev/api-keys');
16
16
  }
17
17
  return apiKey;
18
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helius-mcp",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Official Helius MCP Server - Complete Solana blockchain data access for Claude",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",