chore: remove checked-in sqlitedb (#16)
* chore: remove unused sqlite db * ignore sqlite db
This commit is contained in:
committed by
GitHub
parent
e54d7dfcc7
commit
59fd0cfa1b
374
scripts/mcp_test.js
Normal file
374
scripts/mcp_test.js
Normal file
@@ -0,0 +1,374 @@
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
console.error('🔄 Starting MCP server for comprehensive endpoint testing...');
|
||||
|
||||
// Test configuration
|
||||
let currentStepIndex = 0;
|
||||
let messageId = 1;
|
||||
let testData = {
|
||||
projectId: null,
|
||||
taskId: null,
|
||||
createdProjectId: null,
|
||||
taskTitle: "Test Task from MCP Script",
|
||||
updatedTaskTitle: "Updated Test Task Title",
|
||||
secondTaskTitle: "Second Test Task",
|
||||
renamedTaskTitle: "Renamed Second Task",
|
||||
};
|
||||
|
||||
const testSequence = [
|
||||
'initialize',
|
||||
'initialized_notification',
|
||||
'list_tools',
|
||||
'list_projects',
|
||||
'create_project',
|
||||
'list_tasks', // empty
|
||||
'create_task',
|
||||
'get_task',
|
||||
'list_tasks', // with task
|
||||
'set_task_status',
|
||||
'list_tasks', // filtered
|
||||
'complete_task',
|
||||
'list_tasks', // completed
|
||||
'create_task', // second task
|
||||
'update_task', // legacy
|
||||
'update_task_title',
|
||||
'update_task_description',
|
||||
'list_tasks', // after updates
|
||||
'delete_task_by_title',
|
||||
'list_tasks', // final
|
||||
'summary'
|
||||
];
|
||||
|
||||
const stepHandlers = {
|
||||
initialize: {
|
||||
description: 'Initialize MCP connection',
|
||||
action: () => {
|
||||
console.log('📤 Sending initialize request...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0.0"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
initialized_notification: {
|
||||
description: 'Send initialized notification',
|
||||
action: () => {
|
||||
console.log('📤 Sending initialized notification...');
|
||||
mcpProcess.stdin.write('{"jsonrpc": "2.0", "method": "notifications/initialized"}\n');
|
||||
// Notifications don't have responses, auto-advance
|
||||
setTimeout(() => executeNextStep(), 200);
|
||||
},
|
||||
responseHandler: null
|
||||
},
|
||||
|
||||
list_tools: {
|
||||
description: 'List available MCP tools',
|
||||
action: () => {
|
||||
console.log('📤 Sending tools/list...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/list", "params": {}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
list_projects: {
|
||||
description: 'List all projects',
|
||||
action: () => {
|
||||
console.log('📤 Sending list_projects...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "list_projects", "arguments": {}}}\n`);
|
||||
},
|
||||
responseHandler: (response) => {
|
||||
try {
|
||||
const parsedResponse = JSON.parse(response);
|
||||
if (parsedResponse.result?.content) {
|
||||
const projectsResponse = JSON.parse(parsedResponse.result.content[0].text);
|
||||
if (projectsResponse.success && projectsResponse.projects.length > 0) {
|
||||
testData.projectId = projectsResponse.projects[0].id;
|
||||
console.log(`💾 Found existing project: ${testData.projectId}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('⚠️ Could not parse projects response');
|
||||
}
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
create_project: {
|
||||
description: 'Create a new test project',
|
||||
action: () => {
|
||||
console.log('📤 Sending create_project...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "create_project", "arguments": {"name": "Test Project from MCP", "git_repo_path": "/tmp/test-project", "use_existing_repo": false, "setup_script": "echo \\"Setup complete\\"", "dev_script": "echo \\"Dev server started\\""}}}\n`);
|
||||
},
|
||||
responseHandler: (response) => {
|
||||
try {
|
||||
const parsedResponse = JSON.parse(response);
|
||||
if (parsedResponse.result?.content) {
|
||||
const createProjectResponse = JSON.parse(parsedResponse.result.content[0].text);
|
||||
if (createProjectResponse.success && createProjectResponse.project_id) {
|
||||
testData.createdProjectId = createProjectResponse.project_id;
|
||||
console.log(`💾 Created project: ${testData.createdProjectId}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('⚠️ Could not parse create project response');
|
||||
}
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
list_tasks: {
|
||||
description: 'List tasks in project',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
const context = getListTasksContext();
|
||||
|
||||
console.log(`📤 Sending list_tasks (${context})...`);
|
||||
|
||||
let args = { project_id: projectToUse };
|
||||
|
||||
// Add context-specific filters
|
||||
if (context === 'filtered') {
|
||||
args.status = 'in-progress';
|
||||
} else if (context === 'completed') {
|
||||
args.status = 'done';
|
||||
} else if (context === 'empty') {
|
||||
args.include_execution_status = true;
|
||||
}
|
||||
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "list_tasks", "arguments": ${JSON.stringify(args)}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
create_task: {
|
||||
description: 'Create a new task',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
const isSecondTask = getCreateTaskContext() === 'second';
|
||||
const title = isSecondTask ? testData.secondTaskTitle : testData.taskTitle;
|
||||
const description = isSecondTask ?
|
||||
"This is a second task for testing updates" :
|
||||
"This task was created during endpoint testing";
|
||||
|
||||
console.log(`📤 Sending create_task (${isSecondTask ? 'second task' : 'first task'})...`);
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "create_task", "arguments": {"project_id": "${projectToUse}", "title": "${title}", "description": "${description}"}}}\n`);
|
||||
},
|
||||
responseHandler: (response) => {
|
||||
try {
|
||||
const parsedResponse = JSON.parse(response);
|
||||
if (parsedResponse.result?.content) {
|
||||
const createTaskResponse = JSON.parse(parsedResponse.result.content[0].text);
|
||||
if (createTaskResponse.success && createTaskResponse.task_id) {
|
||||
testData.taskId = createTaskResponse.task_id;
|
||||
console.log(`💾 Created task: ${testData.taskId}`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('⚠️ Could not parse create task response');
|
||||
}
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
get_task: {
|
||||
description: 'Get task details by ID',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending get_task...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "get_task", "arguments": {"project_id": "${projectToUse}", "task_id": "${testData.taskId}"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
set_task_status: {
|
||||
description: 'Set task status (agent-friendly)',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending set_task_status (agent-friendly)...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "set_task_status", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.taskTitle}", "status": "in-progress"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
complete_task: {
|
||||
description: 'Complete task (agent-friendly)',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending complete_task (agent-friendly)...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "complete_task", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.taskTitle}"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
update_task: {
|
||||
description: 'Update task (legacy UUID method)',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending update_task (legacy method)...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "update_task", "arguments": {"project_id": "${projectToUse}", "task_id": "${testData.taskId}", "title": "${testData.updatedTaskTitle}", "description": "Updated description via legacy method", "status": "in-review"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
update_task_title: {
|
||||
description: 'Update task title (agent-friendly)',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending update_task_title (agent-friendly)...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "update_task_title", "arguments": {"project_id": "${projectToUse}", "current_title": "${testData.secondTaskTitle}", "new_title": "${testData.renamedTaskTitle}"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
update_task_description: {
|
||||
description: 'Update task description (agent-friendly)',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending update_task_description (agent-friendly)...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "update_task_description", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.renamedTaskTitle}", "description": "This description was updated using the agent-friendly endpoint"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
delete_task_by_title: {
|
||||
description: 'Delete task by title (agent-friendly)',
|
||||
action: () => {
|
||||
const projectToUse = testData.createdProjectId || testData.projectId;
|
||||
console.log('📤 Sending delete_task_by_title (agent-friendly)...');
|
||||
mcpProcess.stdin.write(`{"jsonrpc": "2.0", "id": ${messageId++}, "method": "tools/call", "params": {"name": "delete_task_by_title", "arguments": {"project_id": "${projectToUse}", "task_title": "${testData.renamedTaskTitle}"}}}\n`);
|
||||
},
|
||||
responseHandler: () => {
|
||||
executeNextStep();
|
||||
}
|
||||
},
|
||||
|
||||
summary: {
|
||||
description: 'Test completion summary',
|
||||
action: () => {
|
||||
console.log('✅ All endpoint tests completed successfully!');
|
||||
console.log('');
|
||||
console.log('📊 Test Summary:');
|
||||
console.log(` - Project ID used: ${testData.projectId || 'N/A'}`);
|
||||
console.log(` - Created project: ${testData.createdProjectId || 'N/A'}`);
|
||||
console.log(` - Task ID tested: ${testData.taskId || 'N/A'}`);
|
||||
console.log(` - Task title: ${testData.taskTitle}`);
|
||||
console.log('');
|
||||
console.log('🎯 Agent-Friendly Endpoints Tested:');
|
||||
console.log(' ✅ set_task_status - Change task status by title');
|
||||
console.log(' ✅ complete_task - Mark task done by title');
|
||||
console.log(' ✅ update_task_title - Change task title');
|
||||
console.log(' ✅ update_task_description - Update task description');
|
||||
console.log(' ✅ delete_task_by_title - Delete task by title');
|
||||
console.log('');
|
||||
console.log('🔧 Legacy Endpoints Tested:');
|
||||
console.log(' ✅ update_task - Update task by ID (more complex)');
|
||||
console.log(' ✅ get_task - Get task details by ID');
|
||||
console.log('');
|
||||
console.log('🎉 All MCP endpoints are working correctly!');
|
||||
console.log('💡 Agents should prefer the title-based endpoints for easier usage');
|
||||
setTimeout(() => mcpProcess.kill(), 500);
|
||||
},
|
||||
responseHandler: null
|
||||
}
|
||||
};
|
||||
|
||||
// Helper functions to determine context
|
||||
function getListTasksContext() {
|
||||
const prevSteps = testSequence.slice(0, currentStepIndex);
|
||||
if (prevSteps[prevSteps.length - 1] === 'create_project') return 'empty';
|
||||
if (prevSteps[prevSteps.length - 1] === 'set_task_status') return 'filtered';
|
||||
if (prevSteps[prevSteps.length - 1] === 'complete_task') return 'completed';
|
||||
if (prevSteps[prevSteps.length - 1] === 'update_task_description') return 'after updates';
|
||||
if (prevSteps[prevSteps.length - 1] === 'delete_task_by_title') return 'final';
|
||||
return 'with task';
|
||||
}
|
||||
|
||||
function getCreateTaskContext() {
|
||||
const prevSteps = testSequence.slice(0, currentStepIndex);
|
||||
const createTaskCount = prevSteps.filter(step => step === 'create_task').length;
|
||||
return createTaskCount > 0 ? 'second' : 'first';
|
||||
}
|
||||
|
||||
// Execute current step
|
||||
function executeCurrentStep() {
|
||||
if (currentStepIndex >= testSequence.length) {
|
||||
console.log('⚠️ All steps completed');
|
||||
return;
|
||||
}
|
||||
|
||||
const stepName = testSequence[currentStepIndex];
|
||||
const stepHandler = stepHandlers[stepName];
|
||||
|
||||
if (!stepHandler) {
|
||||
console.error(`❌ Unknown step: ${stepName}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`🔄 Step ${currentStepIndex + 1}/${testSequence.length}: ${stepHandler.description}`);
|
||||
|
||||
setTimeout(() => {
|
||||
stepHandler.action();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Move to next step
|
||||
function executeNextStep() {
|
||||
currentStepIndex++;
|
||||
executeCurrentStep();
|
||||
}
|
||||
|
||||
// Start MCP process
|
||||
const mcpProcess = spawn('vibe-kanban', ["--mcp"], {
|
||||
stdio: ['pipe', 'pipe', 'inherit'],
|
||||
});
|
||||
|
||||
mcpProcess.stdout.on('data', (data) => {
|
||||
const response = data.toString().trim();
|
||||
const currentStepName = testSequence[currentStepIndex];
|
||||
const stepHandler = stepHandlers[currentStepName];
|
||||
|
||||
console.log(`📥 MCP Response (${currentStepName}):`);
|
||||
console.log(response);
|
||||
|
||||
if (stepHandler?.responseHandler) {
|
||||
stepHandler.responseHandler(response);
|
||||
}
|
||||
});
|
||||
|
||||
mcpProcess.on('exit', (code) => {
|
||||
console.error(`🔴 MCP server exited with code: ${code}`);
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
mcpProcess.on('error', (error) => {
|
||||
console.error('❌ MCP server error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Start the sequence
|
||||
setTimeout(() => {
|
||||
executeCurrentStep();
|
||||
}, 500);
|
||||
|
||||
// Safety timeout
|
||||
setTimeout(() => {
|
||||
console.error('⏰ Test timeout - killing process');
|
||||
mcpProcess.kill();
|
||||
}, 45000);
|
||||
Reference in New Issue
Block a user