Skip to main content
Glama
Seitrace

Seitrace Insights MCP Server

Official
by Seitrace
general.mcp.sdk.mjs17.9 kB
import { dbg } from './utils.mjs'; export const testGeneralResources = async (client) => { // Additional checks for the new general_faucet resource // Verify actions include request_faucet const genActions = await client.callTool({ name: 'list_resource_actions', arguments: { resource: 'general_faucet' }, }); const genActionsText = (genActions.content && genActions.content[0] && genActions.content[0].text) || ''; const genActionsParsed = JSON.parse(genActionsText); if ( !Array.isArray(genActionsParsed.actions) || !genActionsParsed.actions.find((a) => a.name === 'request_faucet') ) { throw new Error('general_faucet missing request_faucet action'); } // Verify schema for call_cosmos_lcd const lcdSchemaRes = await client.callTool({ name: 'get_resource_action_schema', arguments: { resource: 'general_rpc_lcd', action: 'call_cosmos_lcd' }, }); const lcdSchemaText = (lcdSchemaRes.content && lcdSchemaRes.content[0] && lcdSchemaRes.content[0].text) || ''; const lcdSchema = JSON.parse(lcdSchemaText); if ( !lcdSchema?.schema?.properties?.path || !lcdSchema?.schema?.properties?.chain_id || !lcdSchema?.schema?.properties?.endpoint || !Array.isArray(lcdSchema?.schema?.required) || !lcdSchema.schema.required.includes('path') ) { throw new Error('general_rpc_lcd.call_cosmos_lcd schema missing expected fields'); } // Verify faucet schema contains wallet_address and chain_id const faucetSchemaRes = await client.callTool({ name: 'get_resource_action_schema', arguments: { resource: 'general_faucet', action: 'request_faucet' }, }); const faucetSchemaText = (faucetSchemaRes.content && faucetSchemaRes.content[0] && faucetSchemaRes.content[0].text) || ''; const faucetSchema = JSON.parse(faucetSchemaText); if ( !faucetSchema?.schema?.properties?.wallet_address || !faucetSchema?.schema?.properties?.chain_id ) { throw new Error('general_faucet.request_faucet schema missing wallet_address or chain_id'); } // Additional checks for the new general_rpc_lcd resource // Verify actions include get_connection_details const rpcActionsRes = await client.callTool({ name: 'list_resource_actions', arguments: { resource: 'general_rpc_lcd' }, }); const rpcActionsText = (rpcActionsRes.content && rpcActionsRes.content[0] && rpcActionsRes.content[0].text) || ''; const rpcActionsParsed = JSON.parse(rpcActionsText); if ( !Array.isArray(rpcActionsParsed.actions) || !rpcActionsParsed.actions.find((a) => a.name === 'get_connection_details') || !rpcActionsParsed.actions.find((a) => a.name === 'call_evm_rpc') || !rpcActionsParsed.actions.find((a) => a.name === 'call_cosmos_rpc') ) { throw new Error('general_rpc_lcd missing required actions'); } // Verify rpc schema requires no inputs const rpcSchemaRes = await client.callTool({ name: 'get_resource_action_schema', arguments: { resource: 'general_rpc_lcd', action: 'get_connection_details' }, }); const rpcSchemaText = (rpcSchemaRes.content && rpcSchemaRes.content[0] && rpcSchemaRes.content[0].text) || ''; const rpcSchema = JSON.parse(rpcSchemaText); if (!rpcSchema?.schema || rpcSchema.schema.type !== 'object') { throw new Error('general_rpc_lcd.get_connection_details schema missing or not an object'); } if (Array.isArray(rpcSchema.schema.required) && rpcSchema.schema.required.length) { throw new Error('general_rpc_lcd.get_connection_details should not require any fields'); } // Verify schemas for call_evm_rpc and call_cosmos_rpc const evmSchemaRes = await client.callTool({ name: 'get_resource_action_schema', arguments: { resource: 'general_rpc_lcd', action: 'call_evm_rpc' }, }); const evmSchemaText = (evmSchemaRes.content && evmSchemaRes.content[0] && evmSchemaRes.content[0].text) || ''; const evmSchema = JSON.parse(evmSchemaText); if ( !evmSchema?.schema?.properties?.rpc_method || !evmSchema?.schema?.properties?.params || !evmSchema?.schema?.properties?.chain_id || !evmSchema?.schema?.properties?.endpoint || !Array.isArray(evmSchema?.schema?.required) || !evmSchema.schema.required.includes('rpc_method') ) { throw new Error('general_rpc_lcd.call_evm_rpc schema missing expected fields'); } const cosmosSchemaRes = await client.callTool({ name: 'get_resource_action_schema', arguments: { resource: 'general_rpc_lcd', action: 'call_cosmos_rpc' }, }); const cosmosSchemaText = (cosmosSchemaRes.content && cosmosSchemaRes.content[0] && cosmosSchemaRes.content[0].text) || ''; const cosmosSchema = JSON.parse(cosmosSchemaText); if ( !cosmosSchema?.schema?.properties?.rpc_method || !cosmosSchema?.schema?.properties?.params || !cosmosSchema?.schema?.properties?.chain_id || !cosmosSchema?.schema?.properties?.endpoint || !Array.isArray(cosmosSchema?.schema?.required) || !cosmosSchema.schema.required.includes('rpc_method') ) { throw new Error('general_rpc_lcd.call_cosmos_rpc schema missing expected fields'); } // Snippet generation for RPC actions (node + shell) const evmNodeSnippetRes = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_rpc_lcd', action: 'call_evm_rpc', language: 'node' }, }); const evmNodeSnippetText = (evmNodeSnippetRes.content && evmNodeSnippetRes.content[0] && evmNodeSnippetRes.content[0].text) || ''; let evmNodeSnippetParsed; try { evmNodeSnippetParsed = JSON.parse(evmNodeSnippetText); } catch { throw new Error('general_rpc_lcd.call_evm_rpc node snippet did not return JSON'); } if ( !evmNodeSnippetParsed?.snippet || !/eth_blockNumber|<rpc_method>/.test(evmNodeSnippetParsed.snippet) ) { throw new Error('general_rpc_lcd.call_evm_rpc node snippet missing method'); } const evmShellSnippetRes = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_rpc_lcd', action: 'call_evm_rpc', language: 'shell' }, }); const evmShellSnippetText = (evmShellSnippetRes.content && evmShellSnippetRes.content[0] && evmShellSnippetRes.content[0].text) || ''; // dbg('getResourceActionSnippet result:', evmShellSnippetText); const evmShellSnippetParsed = JSON.parse(evmShellSnippetText); if ( !evmShellSnippetParsed?.snippet || !/curl --request POST/.test(evmShellSnippetParsed.snippet) ) { throw new Error('general_rpc_lcd.call_evm_rpc shell snippet missing curl'); } const cosmosNodeSnippetRes = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_rpc_lcd', action: 'call_cosmos_rpc', language: 'node' }, }); const cosmosNodeSnippetText = (cosmosNodeSnippetRes.content && cosmosNodeSnippetRes.content[0] && cosmosNodeSnippetRes.content[0].text) || ''; const cosmosNodeSnippetParsed = JSON.parse(cosmosNodeSnippetText); if ( !cosmosNodeSnippetParsed?.snippet || !/status|<rpc_method>/.test(cosmosNodeSnippetParsed.snippet) ) { throw new Error('general_rpc_lcd.call_cosmos_rpc node snippet missing method'); } // Payload-driven snippet: method/params should appear in snippet const payloadSnippetRes = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_rpc_lcd', action: 'call_evm_rpc', language: 'node', payload: { rpc_method: 'eth_getBalance', params: ['0x0000000000000000000000000000000000000000', 'latest'], }, }, }); const payloadSnippetText = (payloadSnippetRes.content && payloadSnippetRes.content[0] && payloadSnippetRes.content[0].text) || ''; const payloadSnippetParsed = JSON.parse(payloadSnippetText); // dbg('Payload snippet:', payloadSnippetParsed); if ( !payloadSnippetParsed?.snippet || !/eth_getBalance/.test(payloadSnippetParsed.snippet) || !/\[\s*'0x0000000000000000000000000000000000000000',\s*'latest'\s*\]/.test( payloadSnippetParsed.snippet ) ) { throw new Error('RPC payload-driven node snippet missing method or params'); } // Unsupported language should error const badSnippet = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_rpc_lcd', action: 'call_evm_rpc', language: 'madeup' }, }); const badSnippetText = (badSnippet.content && badSnippet.content[0] && badSnippet.content[0].text) || ''; if (!/Unsupported or missing language/i.test(badSnippetText)) { throw new Error('Expected unsupported language error for RPC snippet'); } // Negative invoke: missing chain_id and endpoint should not hit network and should error clearly const evmInvokeMissingRes = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'general_rpc_lcd', action: 'call_evm_rpc', payload: { rpc_method: 'eth_blockNumber' }, }, }); const evmInvokeMissingText = (evmInvokeMissingRes.content && evmInvokeMissingRes.content[0] && evmInvokeMissingRes.content[0].text) || ''; if (!/Missing 'endpoint' or 'chain_id'/i.test(evmInvokeMissingText)) { throw new Error('Expected missing endpoint/chain_id error for call_evm_rpc'); } // LCD: missing both endpoint and chain_id should error const lcdInvokeMissingRes = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'general_rpc_lcd', action: 'call_cosmos_lcd', payload: { path: '/cosmos/gov/v1beta1/proposals' }, }, }); const lcdInvokeMissingText = (lcdInvokeMissingRes.content && lcdInvokeMissingRes.content[0] && lcdInvokeMissingRes.content[0].text) || ''; if (!/Missing 'endpoint' or 'chain_id'/i.test(lcdInvokeMissingText)) { throw new Error('Expected missing endpoint/chain_id error for call_cosmos_lcd'); } // Invoke rpc get_connection_details and assert structure const rpcInvokeRes = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'general_rpc_lcd', action: 'get_connection_details', payload: {}, }, }); const rpcInvokeText = (rpcInvokeRes.content && rpcInvokeRes.content[0] && rpcInvokeRes.content[0].text) || ''; let rpcDetails; try { rpcDetails = JSON.parse(rpcInvokeText); // dbg('RPC details:', JSON.stringify(rpcDetails, null, 2)); } catch (e) { throw new Error('general_rpc_lcd.get_connection_details did not return JSON'); } // New structure: keyed by chain_id ('pacific-1', 'atlantic-2') if (!rpcDetails['pacific-1'] || !rpcDetails['atlantic-2']) { throw new Error('general_rpc_lcd.get_connection_details missing expected chain keys'); } const pacific = rpcDetails['pacific-1']; const atlantic = rpcDetails['atlantic-2']; // Pacific checks if (!pacific?.cosmos?.rpc?.includes('https://rpc.sei-apis.com')) { throw new Error('pacific-1 cosmos.rpc missing expected endpoint'); } if (!pacific?.cosmos?.lcd?.includes('https://rest.sei-apis.com')) { throw new Error('pacific-1 cosmos.lcd missing expected endpoint'); } // Happy path: LCD proposals via pacific-1 const lcdInvokeOk = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'general_rpc_lcd', action: 'call_cosmos_lcd', payload: { chain_id: 'pacific-1', path: '/cosmos/gov/v1beta1/proposals', query: { 'pagination.limit': 1 }, }, }, }); const lcdInvokeOkText = (lcdInvokeOk.content && lcdInvokeOk.content[0] && lcdInvokeOk.content[0].text) || ''; dbg('call_cosmos_lcd response:', lcdInvokeOkText); let lcdJson; try { lcdJson = JSON.parse(lcdInvokeOkText); } catch { // tolerate non-JSON wrapper; ensure proposals keyword appears } if (lcdJson) { if (!Array.isArray(lcdJson.proposals)) { throw new Error('call_cosmos_lcd JSON missing proposals array'); } } else if (!/proposals/i.test(lcdInvokeOkText)) { throw new Error('call_cosmos_lcd response missing proposals'); } if ( !Array.isArray(pacific?.evm?.rpc) || !pacific.evm.rpc.includes('https://evm-rpc.sei-apis.com') ) { throw new Error('pacific-1 evm.rpc missing expected endpoint'); } if (pacific?.evm?.chainId !== 1329) { throw new Error('pacific-1 evm.chainId is not 1329'); } if ( (pacific?.evm?.multicall3 || '').toLowerCase() !== '0x0864515c3b40b6c4a32af7e6090d8ba30b391b1a' ) { throw new Error('pacific-1 evm.multicall3 address mismatch'); } if (pacific?.explorer?.url !== 'https://seitrace.com') { throw new Error('pacific-1 explorer.url mismatch'); } // Atlantic checks if (!atlantic?.cosmos?.rpc?.includes('https://rpc-testnet.sei-apis.com')) { throw new Error('atlantic-2 cosmos.rpc missing expected endpoint'); } if (!atlantic?.cosmos?.lcd?.includes('https://rest-testnet.sei-apis.com')) { throw new Error('atlantic-2 cosmos.lcd missing expected endpoint'); } if ( !Array.isArray(atlantic?.evm?.rpc) || !atlantic.evm.rpc.includes('https://evm-rpc-testnet.sei-apis.com') ) { throw new Error('atlantic-2 evm.rpc missing expected endpoint'); } if (atlantic?.evm?.chainId !== 1328) { throw new Error('atlantic-2 evm.chainId is not 1328'); } if ( (atlantic?.evm?.multicall3 || '').toLowerCase() !== '0xca11bde05977b3631167028862be2a173976ca11' ) { throw new Error('atlantic-2 evm.multicall3 address mismatch'); } if (atlantic?.explorer?.url !== 'https://seitrace.com') { throw new Error('atlantic-2 explorer.url mismatch'); } // Verify we can generate a shell snippet for faucet (fallback path) const faucetSnippetRes = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_faucet', action: 'request_faucet', language: 'shell' }, }); const faucetSnippetText = (faucetSnippetRes.content && faucetSnippetRes.content[0] && faucetSnippetRes.content[0].text) || ''; if (faucetSnippetText !== 'SNIPPET_GENERATION_NOT_SUPPORTED') { throw new Error('wrong'); } // Associations resource should exist and expose get_associations action const assocActions = await client.callTool({ name: 'list_resource_actions', arguments: { resource: 'general_associations' }, }); const assocActionsText = (assocActions.content && assocActions.content[0] && assocActions.content[0].text) || ''; const assocActionsParsed = JSON.parse(assocActionsText); if (!assocActionsParsed.actions?.find((a) => a.name === 'get_associations')) { throw new Error('general_associations missing get_associations action'); } // Snippet generation is supported for associations (shell) const assocSnippetRes = await client.callTool({ name: 'get_resource_action_snippet', arguments: { resource: 'general_associations', action: 'get_associations', language: 'node' }, }); const assocSnippetText = (assocSnippetRes.content && assocSnippetRes.content[0] && assocSnippetRes.content[0].text) || ''; let assocSnippetParsed; try { assocSnippetParsed = JSON.parse(assocSnippetText); dbg(`general_associations.get_associations snippet`, assocSnippetParsed); } catch { throw new Error('general_associations.get_associations snippet did not return JSON'); } if ( !assocSnippetParsed?.snippet || typeof assocSnippetParsed.snippet !== 'string' || !/\/api\/v1\/addresses\/associations/.test(assocSnippetParsed.snippet) || !/hashes=0x93F9989b63DCe31558EB6Eaf1005b5BA18E19b18/.test(assocSnippetParsed.snippet) ) { throw new Error('associations snippet missing expected path'); } // Schema requires hashes array; chain_id/endpoint optional const assocSchemaRes = await client.callTool({ name: 'get_resource_action_schema', arguments: { resource: 'general_associations', action: 'get_associations' }, }); const assocSchemaText = (assocSchemaRes.content && assocSchemaRes.content[0] && assocSchemaRes.content[0].text) || ''; const assocSchema = JSON.parse(assocSchemaText); if ( !Array.isArray(assocSchema?.schema?.required) || !assocSchema.schema.required.includes('hashes') || assocSchema.schema.properties.hashes?.type !== 'array' ) { throw new Error('general_associations.get_associations schema invalid (hashes)'); } // Invoke with pacific-1 sample hashes (public gateway); expect simplified fields const assocInvoke = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'general_associations', action: 'get_associations', payload: { chain_id: 'arctic-1', hashes: [ '0x93F9989b63DCe31558EB6Eaf1005b5BA18E19b18', '0x93F7989b63DCe31558EB6Eaf1005b5BA18E19b18', ], }, }, }); const assocInvokeText = (assocInvoke.content && assocInvoke.content[0] && assocInvoke.content[0].text) || ''; let assocData; try { assocData = JSON.parse(assocInvokeText); // dbg(`general_associations.get_associations response: ${JSON.stringify(assocData)}`); } catch (e) { throw new Error('general_associations.get_associations did not return JSON'); } if (!Array.isArray(assocData) || !assocData[0]?.hash || !Array.isArray(assocData[0]?.mappings)) { throw new Error('general_associations.get_associations unexpected shape'); } // If a mapping has a CREATE_*_POINTER type, it should include pointer and pointee const anyPointer = assocData .flatMap((e) => e.mappings || []) .find((m) => /CREATE_.*_POINTER/.test(m?.type || '')); if (anyPointer && (!anyPointer.pointer || !anyPointer.pointee)) { throw new Error('pointer mapping missing pointer/pointee fields'); } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Seitrace/seitrace-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server