mcp-client-v3.js•4.61 kB
// MCP Client v3 - Fixed session handling
import axios from 'axios';
const MCP_SERVER_URL = 'http://localhost:5002/mcp';
class MCPClientV3 {
constructor() {
this.sessionId = null;
this.requestId = 1;
this.axios = axios.create({
baseURL: 'http://localhost:5002',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream'
},
// Important: Disable automatic redirects
maxRedirects: 0,
// Don't throw on non-2xx status codes
validateStatus: () => true
});
}
async initialize() {
try {
console.log('Initializing MCP client...');
const response = await this.axios.post('/mcp', {
jsonrpc: '2.0',
method: 'initialize',
params: {
protocolVersion: '1.0',
clientInfo: {
name: 'mcp-client-v3',
version: '1.0.0'
},
capabilities: {}
},
id: this.requestId++
});
// Extract session ID from response headers (case-insensitive)
const sessionHeader = Object.entries(response.headers).find(
([key]) => key.toLowerCase() === 'mcp-session-id'
);
if (sessionHeader) {
this.sessionId = sessionHeader[1];
console.log('Session ID:', this.sessionId);
// Set the session ID in the default headers for future requests
this.axios.defaults.headers.common['mcp-session-id'] = this.sessionId;
} else {
console.warn('No session ID received in response headers');
console.log('Response headers:', response.headers);
}
console.log('Initialization response:', response.data);
return response.data;
} catch (error) {
console.error('Initialization failed:', error.message);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response headers:', error.response.headers);
console.error('Response data:', error.response.data);
}
throw error;
}
}
async listTools() {
return this.callMethod('mcp.list_tools', {});
}
async callMethod(method, params = {}) {
if (!this.sessionId) {
throw new Error('Not initialized. Call initialize() first.');
}
console.log(`\nCalling method: ${method}`);
console.log('Params:', JSON.stringify(params, null, 2));
try {
const response = await this.axios.post('/mcp', {
jsonrpc: '2.0',
method: method,
params: params,
id: this.requestId++
}, {
// Override headers to ensure session ID is included
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream',
'mcp-session-id': this.sessionId
}
});
console.log('Response status:', response.status);
console.log('Response headers:', response.headers);
console.log('Response data:', response.data);
return response.data;
} catch (error) {
console.error(`Method ${method} call failed:`, error.message);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response headers:', error.response.headers);
console.error('Response data:', error.response.data);
}
throw error;
}
}
}
// Test the MCP client
async function testMCPClient() {
const client = new MCPClientV3();
try {
// 1. Initialize the client
console.log('=== Starting MCP Client Test ===');
await client.initialize();
if (!client.sessionId) {
throw new Error('Failed to initialize MCP session - no session ID received');
}
// 2. List available tools
console.log('\n=== Listing Tools ===');
const tools = await client.listTools();
console.log('Available tools:', JSON.stringify(tools, null, 2));
// 3. Test a specific tool (e.g., spiderfoot_ping)
console.log('\n=== Testing SpiderFoot Ping ===');
const pingResult = await client.callMethod('spiderfoot_ping', {});
console.log('Ping result:', JSON.stringify(pingResult, null, 2));
// 4. List scans
console.log('\n=== Listing Scans ===');
const scans = await client.callMethod('spiderfoot_scans', {});
console.log('Scans:', JSON.stringify(scans, null, 2));
console.log('\n✅ MCP client test completed successfully!');
} catch (error) {
console.error('\n❌ MCP client test failed:', error.message);
process.exit(1);
}
}
// Run the test
testMCPClient();