Scrapbox MCP Server

#!/usr/bin/env node /** * Test script for Scrapbox MCP Server * * This script tests the Scrapbox MCP Server by simulating MCP tool calls * and verifying the responses. */ import { spawn } from 'child_process'; import { createInterface } from 'readline'; import path from 'path'; import { fileURLToPath } from 'url'; // Get the directory name of the current module const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Path to the MCP server executable const serverPath = path.join(__dirname, 'build', 'index.js'); // Test cases const testCases = [ { name: 'Valid URL Test', input: { jsonrpc: '2.0', id: '1', method: 'callTool', params: { name: 'get_page_content', arguments: { url: 'https://scrapbox.io/razokulover-tech-memo/%E3%82%B3%E3%83%AB%E3%83%96%E3%81%AE%E7%B5%8C%E9%A8%93%E5%AD%A6%E7%BF%92%E3%83%A2%E3%83%87%E3%83%AB' } } }, expectedStatus: 'success' }, { name: 'Invalid URL Test', input: { jsonrpc: '2.0', id: '2', method: 'callTool', params: { name: 'get_page_content', arguments: { url: 'https://example.com/not-scrapbox' } } }, expectedStatus: 'error' }, { name: 'Missing URL Test', input: { jsonrpc: '2.0', id: '3', method: 'callTool', params: { name: 'get_page_content', arguments: {} } }, expectedStatus: 'error' }, { name: 'Non-existent Page Test', input: { jsonrpc: '2.0', id: '4', method: 'callTool', params: { name: 'get_page_content', arguments: { url: 'https://scrapbox.io/razokulover-tech-memo/this-page-does-not-exist-12345' } } }, expectedStatus: 'error' } ]; // Start the MCP server process console.log('Starting Scrapbox MCP Server...'); const serverProcess = spawn('node', [serverPath], { stdio: ['pipe', 'pipe', process.stderr] }); // Create readline interface for reading server output const rl = createInterface({ input: serverProcess.stdout, crlfDelay: Infinity }); // Set up event handlers serverProcess.on('error', (error) => { console.error('Failed to start server:', error); process.exit(1); }); // Buffer to store server responses let responseBuffer = ''; // Process server output rl.on('line', (line) => { try { // Try to parse the line as JSON const response = JSON.parse(line); // Find the corresponding test case const testCase = testCases.find(tc => tc.input.id === response.id); if (testCase) { console.log(`\n===== ${testCase.name} =====`); // Check if the response matches the expected status const isSuccess = !response.error; const statusMatches = (testCase.expectedStatus === 'success' && isSuccess) || (testCase.expectedStatus === 'error' && !isSuccess); console.log(`Status: ${isSuccess ? 'SUCCESS' : 'ERROR'}`); if (isSuccess) { // For successful responses, show the content const content = response.result.content[0].text; console.log('Content preview:'); console.log(content.substring(0, 200) + (content.length > 200 ? '...' : '')); } else { // For error responses, show the error message console.log('Error:', response.error.message); } console.log(`Test ${statusMatches ? 'PASSED' : 'FAILED'}`); } } catch (error) { // Not a JSON line or other error, ignore } }); // Function to run tests sequentially async function runTests() { console.log('Running tests...\n'); // Wait for server to initialize await new Promise(resolve => setTimeout(resolve, 1000)); // Run each test case with a delay between them for (const testCase of testCases) { // Send the test input to the server serverProcess.stdin.write(JSON.stringify(testCase.input) + '\n'); // Wait for the response to be processed await new Promise(resolve => setTimeout(resolve, 2000)); } // Clean up and exit console.log('\nAll tests completed.'); serverProcess.kill(); process.exit(0); } // Start running tests runTests().catch(error => { console.error('Test error:', error); serverProcess.kill(); process.exit(1); });