@the_cfdude/productboard-mcp
Version:
Model Context Protocol server for Productboard REST API with dynamic tool loading
171 lines (138 loc) โข 7.2 kB
JavaScript
/**
* PRODUCTBOARD MCP SERVER - REAL API OPERATIONS TEST
*
* Creates real test entities in Productboard and performs actual API operations.
* This script validates that our MCP tools work with real API calls.
*
* Usage: npm run test-real-operations
*
* Strategy:
* 1. Create a "TEST Product" for all test entities
* 2. Create real components, features, notes, etc. under that product
* 3. Test update operations on those real entities
* 4. Clean up all test entities
*/
const testResults = [];
const createdItems = [];
// Import the MCP server to test tools directly
async function testRealApiOperations() {
console.log('๐งช REAL API OPERATIONS TEST - Creating Actual Test Entities');
console.log('================================================================================');
try {
// Step 1: Create a TEST Product first
console.log('\n๐ STEP 1: Creating TEST Product for all test entities');
console.log('--------------------------------------------------');
const { handleFeaturesTool } = await import('../build/tools/features.js');
// This will fail because we don't have create_product yet, but let's see the structure
console.log('๐งช Testing create_product (if available)...');
// Check if we have the products list first
const productsResult = await handleFeaturesTool('get_products', { limit: 1 });
console.log('โ
Successfully called get_products - API connection working');
// Step 2: Create real test entities under an existing product
console.log('\n๐ STEP 2: Creating real test entities');
console.log('--------------------------------------------------');
// Test create_note with real data
console.log('๐งช Testing create_note with real data...');
const { handleNotesTool } = await import('../build/tools/notes.js');
const noteResult = await handleNotesTool('create_note', {
title: 'TEST-CLEANUP: Real API Test Note',
content: 'This note was created by the real API operations test script to validate MCP tool functionality.',
ownerEmail: 'test@productboard.com',
sourceOrigin: 'api'
});
console.log('โ
Successfully created real note:', noteResult);
// Track for cleanup
if (noteResult && noteResult.content && noteResult.content[0]) {
const noteData = JSON.parse(noteResult.content[0].text);
if (noteData.note && noteData.note.id) {
createdItems.push({ type: 'note', id: noteData.note.id, handler: 'handleNotesTool' });
console.log(`๐ Tracked note ${noteData.note.id} for cleanup`);
}
}
// Test create_company with real data
console.log('๐งช Testing create_company with real data...');
const { handleCompaniesTool } = await import('../build/tools/companies.js');
const companyResult = await handleCompaniesTool('create_company', {
name: 'TEST-CLEANUP: Real API Test Company',
domain: 'test-cleanup-api.com',
description: 'Company created by real API operations test script'
});
console.log('โ
Successfully created real company:', companyResult);
// Track for cleanup
if (companyResult && companyResult.content && companyResult.content[0]) {
const companyData = JSON.parse(companyResult.content[0].text);
if (companyData.company && companyData.company.id) {
createdItems.push({ type: 'company', id: companyData.company.id, handler: 'handleCompaniesTool' });
console.log(`๐ Tracked company ${companyData.company.id} for cleanup`);
}
}
// Step 3: Test update operations on real entities
console.log('\n๐ STEP 3: Testing update operations on real entities');
console.log('--------------------------------------------------');
// Update the note we just created
if (createdItems.find(item => item.type === 'note')) {
const noteId = createdItems.find(item => item.type === 'note').id;
console.log(`๐งช Testing update_note on real note ID: ${noteId}...`);
const updateResult = await handleNotesTool('update_note', {
id: noteId,
title: 'TEST-CLEANUP: Updated Real API Test Note',
content: 'This note was updated by the real API operations test script.'
});
console.log('โ
Successfully updated real note:', updateResult);
}
// Update the company we just created
if (createdItems.find(item => item.type === 'company')) {
const companyId = createdItems.find(item => item.type === 'company').id;
console.log(`๐งช Testing update_company on real company ID: ${companyId}...`);
const updateResult = await handleCompaniesTool('update_company', {
id: companyId,
body: {
name: 'TEST-CLEANUP: Updated Real API Test Company',
description: 'Company updated by real API operations test script'
}
});
console.log('โ
Successfully updated real company:', updateResult);
}
// Step 4: Cleanup all created test entities
console.log('\n๐ STEP 4: Cleaning up test entities');
console.log('--------------------------------------------------');
for (const item of createdItems) {
try {
console.log(`๐งน Cleaning up ${item.type} ${item.id}...`);
const handler = await import(`../build/tools/${item.handler.replace('handle', '').replace('Tool', '').toLowerCase()}.js`);
const handlerFunction = handler[item.handler];
const deleteResult = await handlerFunction(`delete_${item.type}`, { id: item.id });
console.log(`โ
Successfully deleted ${item.type} ${item.id}`);
} catch (error) {
console.log(`โ ๏ธ Failed to cleanup ${item.type} ${item.id}:`, error.message);
}
}
console.log('\n๐ REAL API OPERATIONS TEST SUMMARY');
console.log('================================================================================');
console.log(`โ
Created ${createdItems.length} real test entities`);
console.log('โ
Performed real update operations');
console.log('โ
Cleaned up test entities');
console.log('๐ All API operations working correctly with real data!');
} catch (error) {
console.error('โ REAL API OPERATIONS TEST FAILED:', error);
console.error('Stack trace:', error.stack);
// Attempt cleanup even if test failed
if (createdItems.length > 0) {
console.log('\n๐งน Attempting cleanup after failure...');
for (const item of createdItems) {
try {
const handler = await import(`../build/tools/${item.handler.replace('handle', '').replace('Tool', '').toLowerCase()}.js`);
const handlerFunction = handler[item.handler];
await handlerFunction(`delete_${item.type}`, { id: item.id });
console.log(`โ
Cleaned up ${item.type} ${item.id}`);
} catch (cleanupError) {
console.log(`โ ๏ธ Failed to cleanup ${item.type} ${item.id}:`, cleanupError.message);
}
}
}
process.exit(1);
}
}
// Run the test
testRealApiOperations().catch(console.error);