UNPKG

@the_cfdude/productboard-mcp

Version:

Model Context Protocol server for Productboard REST API with dynamic tool loading

171 lines (138 loc) โ€ข 7.2 kB
#!/usr/bin/env node /** * 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);