Skip to main content
Glama

SpiderFoot MCP Server

mcp-client-enhanced.js6.04 kB
// Enhanced MCP Client with proper session handling import axios from 'axios'; class MCPClient { constructor(baseUrl = 'http://localhost:5002') { this.baseUrl = baseUrl; this.sessionId = null; this.requestId = 1; // Configure axios instance this.axios = axios.create({ baseURL: baseUrl, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' }, // Don't throw on non-2xx status codes validateStatus: () => true, // Get raw response to access headers transformResponse: (res) => res }); } /** * Send a JSON-RPC request to the MCP server */ /** * Parse Server-Sent Events (SSE) response */ _parseSSEResponse(data) { const lines = data.split('\n').filter(line => line.trim() !== ''); const result = { event: null, data: null, id: null, retry: null }; for (const line of lines) { const colonIndex = line.indexOf(':'); if (colonIndex === -1) continue; const field = line.slice(0, colonIndex).trim(); let value = line.slice(colonIndex + 1).trim(); // Remove leading space if present if (value.startsWith(' ')) { value = value.slice(1); } if (field === 'data') { try { result.data = JSON.parse(value); } catch (e) { result.data = value; } } else if (field === 'event') { result.event = value; } else if (field === 'id') { result.id = value; } else if (field === 'retry') { result.retry = parseInt(value, 10); } } return result; } async _sendRequest(method, params = {}) { const requestId = this.requestId++; const requestData = { jsonrpc: '2.0', method, params, id: requestId }; // Add session ID to headers if available const headers = {}; if (this.sessionId) { headers['mcp-session-id'] = this.sessionId; } try { console.log(`\n=== Sending ${method} request ===`); console.log('Request:', JSON.stringify(requestData, null, 2)); const response = await this.axios.post('/mcp', requestData, { headers, responseType: 'text' // Get raw response text }); console.log('\n=== Response ==='); console.log('Status:', response.status, response.statusText); console.log('Headers:', JSON.stringify(response.headers, null, 2)); // Parse SSE response const sseResponse = this._parseSSEResponse(response.data); console.log('SSE Response:', JSON.stringify(sseResponse, null, 2)); // Extract JSON-RPC response from SSE data let responseData = sseResponse.data; // If data is still a string, try to parse it as JSON if (typeof responseData === 'string') { try { responseData = JSON.parse(responseData); } catch (e) { throw new Error('Failed to parse SSE data as JSON'); } } // Update session ID if provided in headers if (response.headers['mcp-session-id']) { this.sessionId = response.headers['mcp-session-id']; console.log('Session ID updated:', this.sessionId); } // Handle JSON-RPC errors if (responseData.error) { throw new Error(`JSON-RPC Error (${responseData.error.code}): ${responseData.error.message}`); } return responseData.result; } catch (error) { console.error('\n❌ Request failed:'); if (error.response) { console.error('Status:', error.response.status); console.error('Headers:', error.response.headers); console.error('Data:', error.response.data); } else if (error.request) { console.error('No response received'); } else { console.error('Error:', error.message); } throw error; } } /** * Initialize a new MCP session */ async initialize() { const result = await this._sendRequest('initialize', { protocolVersion: '1.0', clientInfo: { name: 'spiderfoot-mcp-client', version: '1.0.0' }, capabilities: {} }); console.log('\n✅ MCP Session initialized'); console.log('Server version:', result.serverInfo.version); console.log('Protocol version:', result.protocolVersion); return result; } /** * List available tools */ async listTools() { return this._sendRequest('mcp.list_tools'); } /** * Call a specific tool */ async callTool(toolName, params = {}) { return this._sendRequest(`mcp.${toolName}`, params); } /** * Get tool schema */ async getToolSchema(toolName) { return this._sendRequest('mcp.get_tool_schema', { tool: toolName }); } } // Example usage async function main() { const client = new MCPClient(); try { // 1. Initialize session console.log('Initializing MCP session...'); await client.initialize(); if (!client.sessionId) { throw new Error('Failed to establish MCP session'); } // 2. List available tools console.log('\nListing available tools...'); const tools = await client.listTools(); console.log('Available tools:', JSON.stringify(tools, null, 2)); // 3. Call spiderfoot_ping console.log('\nCalling spiderfoot_ping...'); const pingResult = await client.callTool('spiderfoot_ping'); console.log('Ping result:', JSON.stringify(pingResult, null, 2)); // 4. List scans console.log('\nListing scans...'); const scans = await client.callTool('spiderfoot_scans'); console.log('Scans:', JSON.stringify(scans, null, 2)); } catch (error) { console.error('\n❌ Error:', error.message); process.exit(1); } } // Run the example if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { main(); } export default MCPClient;

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/CorbettCajun/Spiderfoot-MCP-Server'

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