helius-mcp 0.2.2 → 0.2.4

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.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { registerTools } from './tools/index.js';
5
5
  import { setApiKey } from './utils/helius.js';
6
6
  const server = new McpServer({
7
7
  name: 'helius-claude-plugin',
8
- version: '0.3.0'
8
+ version: '0.2.4'
9
9
  });
10
10
  // Register all tools
11
11
  registerTools(server);
@@ -21,7 +21,7 @@ async function main() {
21
21
  }
22
22
  const transport = new StdioServerTransport();
23
23
  await server.connect(transport);
24
- console.error('🚀 Helius MCP Server v0.3.0 running (20 tools)');
24
+ console.error('🚀 Helius MCP Server v0.2.4 running (29 tools)');
25
25
  }
26
26
  main().catch((error) => {
27
27
  console.error('Failed to start server:', error);
package/dist/tools/das.js CHANGED
@@ -238,11 +238,12 @@ export function registerDasTools(server) {
238
238
  });
239
239
  // searchAssets - Advanced asset search
240
240
  server.tool('searchAssets', 'Advanced search for digital assets with complex filters. Search by name, royalties, burned status, frozen status, and more. Much more powerful than other DAS methods.', {
241
- query: z.string().optional().describe('Search query string'),
241
+ name: z.string().optional().describe('Search by asset name'),
242
242
  ownerAddress: z.string().optional().describe('Filter by owner'),
243
243
  creatorAddress: z.string().optional().describe('Filter by creator'),
244
244
  burnt: z.boolean().optional().describe('Filter burnt assets'),
245
245
  frozen: z.boolean().optional().describe('Filter frozen assets'),
246
+ compressed: z.boolean().optional().describe('Filter compressed NFTs'),
246
247
  page: z.number().optional().default(1).describe('Page number'),
247
248
  limit: z.number().optional().default(20).describe('Results per page (max 1000)')
248
249
  }, async (params) => {
@@ -302,11 +303,13 @@ export function registerDasTools(server) {
302
303
  isError: true
303
304
  };
304
305
  }
305
- const proofs = await dasRequest('getAssetProofBatch', { ids });
306
+ const result = await dasRequest('getAssetProofBatch', { ids });
307
+ // Handle both array and object responses
308
+ const proofsArray = Array.isArray(result) ? result : Object.values(result);
306
309
  return {
307
310
  content: [{
308
311
  type: 'text',
309
- text: `**Batch Merkle Proofs** (${proofs.length} proofs)\n\n${proofs.map((p, i) => `${i + 1}. ${formatAddress(ids[i])}\n Root: ${formatAddress(p.root)}`).join('\n\n')}`
312
+ text: `**Batch Merkle Proofs** (${proofsArray.length} proofs)\n\n${proofsArray.map((p, i) => `${i + 1}. ${formatAddress(ids[i])}\n Root: ${formatAddress(p.root)}`).join('\n\n')}`
310
313
  }]
311
314
  };
312
315
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { restRequest } from '../utils/helius.js';
2
+ import { rpcRequest } from '../utils/helius.js';
3
3
  export function registerPriorityFeeTools(server) {
4
4
  server.tool('getPriorityFeeEstimate', 'Get optimal priority fee estimates for Solana transactions. Returns recommended fees in microlamports for different priority levels (min, low, medium, high, very high). Essential for ensuring transaction confirmation during network congestion.', {
5
5
  accountKeys: z.array(z.string()).optional().describe('Account addresses involved in transaction for more accurate estimates'),
@@ -9,15 +9,12 @@ export function registerPriorityFeeTools(server) {
9
9
  }).optional().describe('Priority fee options')
10
10
  }, async ({ accountKeys, options }) => {
11
11
  try {
12
- const body = {};
12
+ const params = {};
13
13
  if (accountKeys)
14
- body.accountKeys = accountKeys;
14
+ params.accountKeys = accountKeys;
15
15
  if (options)
16
- body.options = options;
17
- const result = await restRequest('/v0/priority-fee', {
18
- method: 'POST',
19
- body: JSON.stringify(body)
20
- });
16
+ params.options = options;
17
+ const result = await rpcRequest('getPriorityFeeEstimate', [params]);
21
18
  const lines = ['**Priority Fee Estimate**', ''];
22
19
  if (result.priorityFeeLevels) {
23
20
  lines.push('**Fee Levels (microlamports):**');
package/dist/tools/rpc.js CHANGED
@@ -11,7 +11,7 @@ export function registerRpcTools(server) {
11
11
  return {
12
12
  content: [{
13
13
  type: 'text',
14
- text: `**SOL Balance**\n\nAddress: ${formatAddress(address)}\nBalance: ${formatSol(lamports)} SOL\n(${lamports.toLocaleString()} lamports)`
14
+ text: `**SOL Balance**\n\nAddress: ${formatAddress(address)}\nBalance: ${formatSol(lamports)}\n(${lamports.toLocaleString()} lamports)`
15
15
  }]
16
16
  };
17
17
  }
@@ -28,7 +28,8 @@ export function registerRpcTools(server) {
28
28
  encoding: z.enum(['base58', 'base64', 'jsonParsed']).optional().default('base64').describe('Data encoding format')
29
29
  }, async ({ address, encoding }) => {
30
30
  try {
31
- const accountInfo = await rpcRequest('getAccountInfo', [address, { encoding }]);
31
+ const result = await rpcRequest('getAccountInfo', [address, { encoding }]);
32
+ const accountInfo = result.value;
32
33
  if (!accountInfo) {
33
34
  return {
34
35
  content: [{ type: 'text', text: `Account ${formatAddress(address)} does not exist.` }]
@@ -37,7 +38,7 @@ export function registerRpcTools(server) {
37
38
  return {
38
39
  content: [{
39
40
  type: 'text',
40
- text: `**Account Info**\n\nAddress: ${formatAddress(address)}\nOwner: ${formatAddress(accountInfo.owner)}\nBalance: ${formatSol(accountInfo.lamports)} SOL\nData Size: ${accountInfo.data?.length || 0} bytes\nExecutable: ${accountInfo.executable ? 'Yes' : 'No'}`
41
+ text: `**Account Info**\n\nAddress: ${formatAddress(address)}\nOwner: ${formatAddress(accountInfo.owner)}\nBalance: ${formatSol(accountInfo.lamports)}\nData Size: ${accountInfo.data?.length || 0} bytes\nExecutable: ${accountInfo.executable ? 'Yes' : 'No'}`
41
42
  }]
42
43
  };
43
44
  }
@@ -66,7 +67,7 @@ export function registerRpcTools(server) {
66
67
  lines.push(`${i + 1}. ${formatAddress(addresses[i])}`);
67
68
  if (acc) {
68
69
  lines.push(` Owner: ${formatAddress(acc.owner)}`);
69
- lines.push(` Balance: ${formatSol(acc.lamports)} SOL`);
70
+ lines.push(` Balance: ${formatSol(acc.lamports)}`);
70
71
  }
71
72
  else {
72
73
  lines.push(` Status: Does not exist`);
@@ -117,12 +117,12 @@ export async function dasRequest(method, params = {}) {
117
117
  */
118
118
  export async function restRequest(endpoint, options = {}) {
119
119
  const apiKey = getApiKey();
120
- const url = `https://api.helius.xyz${endpoint}`;
120
+ const separator = endpoint.includes('?') ? '&' : '?';
121
+ const url = `https://api.helius.xyz${endpoint}${separator}api-key=${apiKey}`;
121
122
  const response = await fetch(url, {
122
123
  ...options,
123
124
  headers: {
124
125
  'Content-Type': 'application/json',
125
- 'Authorization': `Bearer ${apiKey}`,
126
126
  ...options.headers,
127
127
  },
128
128
  });
@@ -130,5 +130,10 @@ export async function restRequest(endpoint, options = {}) {
130
130
  const text = await response.text();
131
131
  throw new Error(`HTTP ${response.status}: ${text}`);
132
132
  }
133
- return response.json();
133
+ // Handle empty responses (like DELETE operations)
134
+ const text = await response.text();
135
+ if (!text || text === 'null') {
136
+ return null;
137
+ }
138
+ return JSON.parse(text);
134
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helius-mcp",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Official Helius MCP Server - Complete Solana blockchain data access for Claude",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",