Skip to main content
Glama
0xteamhq

Grafana MCP Server

by 0xteamhq
interactive-test.js7.64 kB
#!/usr/bin/env node /** * Interactive MCP Test Client * Allows manual testing of MCP tools */ require('dotenv').config(); const { spawn } = require('child_process'); const readline = require('readline'); console.log('🎮 Interactive MCP Test Client'); console.log('==============================\n'); console.log('Starting MCP server with your Grafana instance...\n'); const server = spawn('node', ['dist/cli.js'], { env: process.env, stdio: ['pipe', 'pipe', 'inherit'] // Show server errors }); let requestId = 1; const responses = new Map(); // Parse server output server.stdout.on('data', (data) => { const lines = data.toString().split('\n'); lines.forEach(line => { if (line.trim() && line.startsWith('{')) { try { const json = JSON.parse(line); if (json.id) { responses.set(json.id, json); // Print response if (json.result) { console.log('\n✅ Response received:'); if (json.result.content) { try { const content = JSON.parse(json.result.content[0].text); console.log(JSON.stringify(content, null, 2)); } catch { console.log(json.result.content[0].text); } } else if (json.result.tools) { console.log(`Found ${json.result.tools.length} tools`); json.result.tools.slice(0, 10).forEach(tool => { console.log(` - ${tool.name}: ${tool.description.slice(0, 60)}...`); }); if (json.result.tools.length > 10) { console.log(` ... and ${json.result.tools.length - 10} more`); } } else { console.log(JSON.stringify(json.result, null, 2)); } } else if (json.error) { console.log('\n❌ Error:', json.error.message); } } } catch (e) { // Not JSON, ignore } } }); }); function sendRequest(method, params) { const request = { jsonrpc: '2.0', id: requestId++, method, params }; console.log(`\n→ Sending: ${method}`); server.stdin.write(JSON.stringify(request) + '\n'); } // Create readline interface for user input const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); // Initialize MCP setTimeout(() => { console.log('\n🔄 Initializing MCP protocol...'); sendRequest('initialize', { protocolVersion: '0.1.0', capabilities: {}, clientInfo: { name: 'interactive-test', version: '1.0.0' } }); setTimeout(() => { console.log('\n✨ MCP Server Ready!\n'); console.log('Available commands:'); console.log(' list - List all available tools'); console.log(' search <query> - Search dashboards'); console.log(' datasources - List all datasources'); console.log(' dashboards - List all dashboards'); console.log(' teams - List teams'); console.log(' users - List users'); console.log(' alerts - List alert rules'); console.log(' loki <datasourceUid> - Test Loki queries'); console.log(' prometheus <uid> - Test Prometheus queries'); console.log(' tool <name> <args> - Call any tool directly'); console.log(' help - Show this help'); console.log(' exit - Exit the client\n'); promptUser(); }, 1000); }, 500); function promptUser() { rl.question('mcp> ', (input) => { const [command, ...args] = input.trim().split(' '); switch (command) { case 'list': sendRequest('tools/list', {}); break; case 'search': sendRequest('tools/call', { name: 'search_dashboards', arguments: { query: args.join(' ') || '' } }); break; case 'datasources': sendRequest('tools/call', { name: 'list_datasources', arguments: {} }); break; case 'dashboards': sendRequest('tools/call', { name: 'search_dashboards', arguments: { query: '' } }); break; case 'teams': sendRequest('tools/call', { name: 'list_teams', arguments: {} }); break; case 'users': sendRequest('tools/call', { name: 'list_users_by_org', arguments: {} }); break; case 'alerts': sendRequest('tools/call', { name: 'list_alert_rules', arguments: { limit: 10 } }); break; case 'loki': if (args[0]) { sendRequest('tools/call', { name: 'list_loki_label_names', arguments: { datasourceUid: args[0] } }); } else { console.log('Usage: loki <datasourceUid>'); } break; case 'prometheus': if (args[0]) { sendRequest('tools/call', { name: 'query_prometheus', arguments: { datasourceUid: args[0], expr: 'up', queryType: 'instant', startTime: 'now' } }); } else { console.log('Usage: prometheus <datasourceUid>'); } break; case 'tool': if (args.length >= 1) { const toolName = args[0]; let toolArgs = {}; if (args.length > 1) { try { // Try to parse remaining args as JSON toolArgs = JSON.parse(args.slice(1).join(' ')); } catch { console.log('Error: Arguments must be valid JSON'); promptUser(); return; } } sendRequest('tools/call', { name: toolName, arguments: toolArgs }); } else { console.log('Usage: tool <name> <json-args>'); } break; case 'help': console.log('\nAvailable commands:'); console.log(' list - List all available tools'); console.log(' search <query> - Search dashboards'); console.log(' datasources - List all datasources'); console.log(' dashboards - List all dashboards'); console.log(' teams - List teams'); console.log(' users - List users'); console.log(' alerts - List alert rules'); console.log(' loki <datasourceUid> - Test Loki queries'); console.log(' prometheus <uid> - Test Prometheus queries'); console.log(' tool <name> <args> - Call any tool directly'); console.log(' help - Show this help'); console.log(' exit - Exit the client'); break; case 'exit': console.log('\nGoodbye! 👋'); server.kill('SIGTERM'); process.exit(0); break; default: if (command) { console.log(`Unknown command: ${command}. Type 'help' for available commands.`); } } // Continue prompting setTimeout(() => promptUser(), 100); }); } // Handle Ctrl+C process.on('SIGINT', () => { console.log('\n\nShutting down...'); server.kill('SIGTERM'); process.exit(0); });

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/0xteamhq/mcp-grafana'

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