Skip to main content
Glama
smithery-client.ts5.96 kB
#!/usr/bin/env tsx /** * Example: Connect to Smithery-hosted MCP server * * This demonstrates how to connect to an MCP server hosted on Smithery * using the Streamable HTTP transport with configuration support. * * Note: Replace <your-package> with your actual Smithery package name * * Usage: * export SMITHERY_API_KEY="your-api-key" # If auth required * tsx examples/smithery-client.ts */ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/transport/streamable-http.js'; // Configuration for Smithery deployment const SMITHERY_CONFIG = { // Base configuration maxRetries: 3, timeout: 30000, // Tool-specific settings defaultWorkspace: process.cwd(), allowedAgents: ['claude', 'copilot', 'gemini'], }; async function main() { // Get package name from environment or use placeholder const packageName = process.env.SMITHERY_PACKAGE || 'mcp-dincoder'; const apiKey = process.env.SMITHERY_API_KEY; console.log(`🔗 Connecting to Smithery MCP server: ${packageName}\n`); // Encode configuration as base64 const configBase64 = Buffer.from(JSON.stringify(SMITHERY_CONFIG)).toString('base64'); // Create transport for Smithery server const transport = new StreamableHTTPClientTransport({ url: new URL(`https://server.smithery.ai/${packageName}/mcp?config=${configBase64}`), fetch: fetch, headers: apiKey ? { 'Authorization': `Bearer ${apiKey}`, } : undefined, }); // Create client const client = new Client({ name: 'smithery-example-client', version: '1.0.0', }); try { // Connect to server await client.connect(transport); console.log('✅ Connected to Smithery successfully!\n'); // Get server info const serverInfo = await client.getServerInfo(); console.log('📋 Server Information:'); console.log(` - Name: ${serverInfo.name}`); console.log(` - Version: ${serverInfo.version}`); console.log(` - Protocol: ${serverInfo.protocolVersion}`); console.log(); // List available tools const tools = await client.listTools(); console.log(`📦 Available tools (${tools.tools.length} total):`); // Group tools by category const toolCategories: Record<string, typeof tools.tools> = {}; tools.tools.forEach(tool => { const category = tool.name.split('.')[0]; if (!toolCategories[category]) { toolCategories[category] = []; } toolCategories[category].push(tool); }); // Display tools by category Object.entries(toolCategories).forEach(([category, categoryTools]) => { console.log(`\n ${category}:`); categoryTools.forEach(tool => { const toolName = tool.name.split('.').slice(1).join('.'); console.log(` - ${toolName}: ${tool.description}`); }); }); console.log(); // Example workflow: Initialize a spec-driven project console.log('📝 Example Workflow: Spec-Driven Development\n'); // Step 1: Describe the project console.log('Step 1: Creating project specification...'); const specResult = await client.callTool('specify.describe', { description: 'A real-time collaborative markdown editor with WebSocket sync', workspacePath: SMITHERY_CONFIG.defaultWorkspace }); const specData = JSON.parse(specResult.content?.[0]?.text || '{}'); console.log(` ✓ Spec created: ${specData.details?.filename}`); // Step 2: Generate technical plan console.log('\nStep 2: Generating technical plan...'); const planResult = await client.callTool('plan.create', { constraintsText: 'TypeScript, React, Socket.io, PostgreSQL for persistence', specPath: specData.specPath, workspacePath: SMITHERY_CONFIG.defaultWorkspace }); const planData = JSON.parse(planResult.content?.[0]?.text || '{}'); console.log(` ✓ Plan created: ${planData.details?.planName}`); console.log(` ✓ Data model: ${planData.files?.dataModel ? 'Generated' : 'Not generated'}`); console.log(` ✓ Contracts: ${planData.files?.contracts ? 'Generated' : 'Not generated'}`); // Step 3: Generate tasks console.log('\nStep 3: Generating implementation tasks...'); const tasksResult = await client.callTool('tasks.generate', { scope: 'Real-time collaborative editor MVP', planPath: planData.files?.plan, workspacePath: SMITHERY_CONFIG.defaultWorkspace }); const tasksData = JSON.parse(tasksResult.content?.[0]?.text || '{}'); console.log(` ✓ Tasks generated: ${tasksData.details?.totalTasks || 0} tasks`); console.log(` ✓ Story points: ${tasksData.details?.totalStoryPoints || 0} points`); // Step 4: Read all artifacts console.log('\nStep 4: Reading all artifacts...'); const artifactsResult = await client.callTool('artifacts.read', { artifactType: 'all', workspacePath: SMITHERY_CONFIG.defaultWorkspace }); const artifactsData = JSON.parse(artifactsResult.content?.[0]?.text || '{}'); console.log(` ✓ Artifacts retrieved: ${Object.keys(artifactsData.artifacts || {}).join(', ')}`); console.log('\n✨ Spec-driven workflow completed successfully!'); } catch (error) { console.error('❌ Error:', error); // Provide helpful error messages if (error instanceof Error) { if (error.message.includes('ECONNREFUSED')) { console.log('\n💡 Tip: Make sure the server is deployed to Smithery'); console.log(' Run: npm run deploy:smithery'); } else if (error.message.includes('401') || error.message.includes('403')) { console.log('\n💡 Tip: Check your SMITHERY_API_KEY environment variable'); } } } finally { // Close connection await client.close(); console.log('\n👋 Connection closed'); } } // Run the example main().catch(console.error);

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/flight505/MCP_DinCoder'

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