Skip to main content
Glama
index.ts10.2 kB
#!/usr/bin/env node /** * MCP Server for MIST.cash SDK * Exposes private payment functionality on Starknet via Model Context Protocol */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; // Import tools import { generarSecretoTransaccion } from './tools/generar-secreto.js'; import { obtenerAssetsTransaccion } from './tools/obtener-assets.js'; import { verificarExistenciaTransaccion } from './tools/verificar-existencia.js'; import { calcularHashTransaccion } from './tools/calcular-hash.js'; import { obtenerConfiguracionChamber } from './tools/obtener-configuracion.js'; // Import resources import { getChamberContractInfo, getTransactionDetails, listResources } from './resources/index.js'; // Create MCP server instance const server = new Server( { name: 'mcp-mistcash', version: '1.0.0', }, { capabilities: { tools: {}, resources: {}, }, } ); // List available tools server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'generar_secreto_transaccion', description: 'Generate a transaction secret for private payments. Creates a cryptographic secret using a claiming key and recipient address.', inputSchema: { type: 'object', properties: { claiming_key: { type: 'string', description: 'Claiming key for the transaction', }, recipient_address: { type: 'string', description: 'Starknet address of the recipient (must start with 0x)', }, }, required: ['claiming_key', 'recipient_address'], }, }, { name: 'obtener_assets_transaccion', description: 'Fetch assets from a transaction. WARNING: This shows assets even if already spent. Use verificar_existencia_transaccion for accurate verification.', inputSchema: { type: 'object', properties: { transaction_key: { type: 'string', description: 'Transaction key to query', }, recipient_address: { type: 'string', description: 'Starknet address of the recipient', }, provider_rpc_url: { type: 'string', description: 'Optional custom Starknet RPC URL', }, }, required: ['transaction_key', 'recipient_address'], }, }, { name: 'verificar_existencia_transaccion', description: 'Verify if a transaction exists with specific assets. For fully private transactions where assets are not publicly visible.', inputSchema: { type: 'object', properties: { claiming_key: { type: 'string', description: 'Claiming key for the transaction', }, recipient: { type: 'string', description: 'Starknet address of the recipient', }, token_address: { type: 'string', description: 'Token contract address (e.g., ETH, USDC)', }, amount: { type: 'string', description: 'Amount in base units (wei)', }, provider_rpc_url: { type: 'string', description: 'Optional custom Starknet RPC URL', }, }, required: ['claiming_key', 'recipient', 'token_address', 'amount'], }, }, { name: 'calcular_hash_transaccion', description: 'Calculate the unique hash of a transaction using transaction parameters.', inputSchema: { type: 'object', properties: { transaction_key: { type: 'string', description: 'Transaction key', }, recipient_address: { type: 'string', description: 'Starknet address of the recipient', }, token_address: { type: 'string', description: 'Token contract address', }, amount: { type: 'string', description: 'Amount in base units (wei)', }, }, required: ['transaction_key', 'recipient_address', 'token_address', 'amount'], }, }, { name: 'obtener_configuracion_chamber', description: 'Get Chamber contract configuration including contract address, network, and supported tokens.', inputSchema: { type: 'object', properties: { network: { type: 'string', enum: ['mainnet', 'sepolia'], description: 'Starknet network', default: 'mainnet', }, }, }, }, ], }; }); // Handle tool calls server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const { name, arguments: args } = request.params; switch (name) { case 'generar_secreto_transaccion': return { content: [ { type: 'text', text: JSON.stringify(await generarSecretoTransaccion(args), null, 2), }, ], }; case 'obtener_assets_transaccion': return { content: [ { type: 'text', text: JSON.stringify(await obtenerAssetsTransaccion(args), null, 2), }, ], }; case 'verificar_existencia_transaccion': return { content: [ { type: 'text', text: JSON.stringify(await verificarExistenciaTransaccion(args), null, 2), }, ], }; case 'calcular_hash_transaccion': return { content: [ { type: 'text', text: JSON.stringify(await calcularHashTransaccion(args), null, 2), }, ], }; case 'obtener_configuracion_chamber': return { content: [ { type: 'text', text: JSON.stringify(await obtenerConfiguracionChamber(args || {}), null, 2), }, ], }; default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: errorMessage }, null, 2), }, ], isError: true, }; } }); // List available resources server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: listResources(), }; }); // Read resource content server.setRequestHandler(ReadResourceRequestSchema, async (request) => { const { uri } = request.params; if (uri === 'chamber://contract-info') { const network = (process.env.STARKNET_NETWORK || 'mainnet') as 'mainnet' | 'sepolia'; return getChamberContractInfo(network); } if (uri.startsWith('chamber://tx/')) { const txHash = uri.replace('chamber://tx/', ''); return getTransactionDetails(txHash); } throw new Error(`Unknown resource: ${uri}`); }); // Start server async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('MCP MIST.cash Server running on stdio'); console.error(`Network: ${process.env.STARKNET_NETWORK || 'mainnet'}`); console.error(`RPC URL: ${process.env.STARKNET_RPC_URL || 'default'}`); } main().catch((error) => { console.error('Fatal error:', error); process.exit(1); });

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/joadataarg/Mcp-mistcash'

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