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);
});