mcp-content-extractor.test.ts•4.44 kB
import { describe, it, expect } from 'vitest';
import { spawn } from 'child_process';
describe('MCP Content Extractor Integration', () => {
it('should provide extract_content tool in MCP tools/list response', async () => {
const result = await new Promise<any>((resolve, reject) => {
const server = spawn('node', ['dist/bin/llmresearcher.js', '--mcp'], {
stdio: ['pipe', 'pipe', 'pipe']
});
let responseData = '';
let timeoutId: NodeJS.Timeout;
const cleanup = () => {
clearTimeout(timeoutId);
server.kill();
};
server.stdout.on('data', (data) => {
responseData += data.toString();
try {
const response = JSON.parse(responseData.trim());
cleanup();
resolve(response);
} catch (e) {
// Not complete JSON yet, continue waiting
}
});
server.stderr.on('data', (data) => {
const errorMsg = data.toString();
if (errorMsg.includes('MCP Research Server running')) {
const listToolsRequest = {
jsonrpc: "2.0",
id: 1,
method: "tools/list"
};
server.stdin.write(JSON.stringify(listToolsRequest) + '\n');
}
});
server.on('error', (err) => {
cleanup();
reject(err);
});
timeoutId = setTimeout(() => {
cleanup();
reject(new Error('Timeout waiting for server response'));
}, 10000);
});
// Verify response structure
expect(result.result).toBeDefined();
expect(result.result.tools).toBeDefined();
expect(result.result.tools).toHaveLength(3);
// Find extract_content tool
const extractorTool = result.result.tools.find((tool: any) => tool.name === 'extract_content');
expect(extractorTool).toBeDefined();
// Check tool properties
expect(extractorTool.description).toContain('Extract detailed content from a URL');
expect(extractorTool.description).toContain('IMPORTANT: This tool must ONLY be used with URLs obtained from the search results');
expect(extractorTool.description).toContain('github_code_search or duckduckgo_web_search');
// Check input schema
const properties = extractorTool.inputSchema.properties;
expect(properties.url).toBeDefined();
expect(properties.url.type).toBe('string');
expect(properties.url.description).toContain('Must be a URL from previous search results');
// Check required parameters
expect(extractorTool.inputSchema.required).toEqual(['url']);
}, 15000);
it('should have correct parameter structure for extract_content tool', async () => {
const result = await new Promise<any>((resolve, reject) => {
const server = spawn('node', ['dist/bin/llmresearcher.js', '--mcp'], {
stdio: ['pipe', 'pipe', 'pipe']
});
let responseData = '';
let timeoutId: NodeJS.Timeout;
const cleanup = () => {
clearTimeout(timeoutId);
server.kill();
};
server.stdout.on('data', (data) => {
responseData += data.toString();
try {
const response = JSON.parse(responseData.trim());
cleanup();
resolve(response);
} catch (e) {
// Not complete JSON yet
}
});
server.stderr.on('data', (data) => {
const errorMsg = data.toString();
if (errorMsg.includes('MCP Research Server running')) {
const listToolsRequest = {
jsonrpc: "2.0",
id: 1,
method: "tools/list"
};
server.stdin.write(JSON.stringify(listToolsRequest) + '\n');
}
});
server.on('error', (err) => {
cleanup();
reject(err);
});
timeoutId = setTimeout(() => {
cleanup();
reject(new Error('Timeout'));
}, 10000);
});
const extractorTool = result.result.tools.find((tool: any) => tool.name === 'extract_content');
const properties = extractorTool.inputSchema.properties;
// Check all expected properties exist
expect(Object.keys(properties)).toEqual(['url']);
// Check required parameters
expect(extractorTool.inputSchema.required).toEqual(['url']);
// Verify url parameter details
expect(properties.url.description).toContain('this MCP server');
expect(properties.url.description).toContain('search tools');
}, 15000);
});