We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/andychoi/mcp-strapi'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
#!/usr/bin/env node
/**
* MCP-Strapi Integration Test Runner
*
* Runs all test suites sequentially and aggregates results.
*
* Usage:
* node tests/run-all.js # Run all tests
* node tests/run-all.js 01 03 # Run specific tests by number
* node tests/run-all.js --list # List available tests
*
* Environment:
* STRAPI_URL Strapi base URL (default: http://localhost:1337)
* STRAPI_ADMIN_EMAIL Super admin email
* STRAPI_ADMIN_PASSWORD Super admin password
*/
import { execSync } from 'child_process';
import { readdirSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
// Discover test files
const testFiles = readdirSync(__dirname)
.filter((f) => /^\d{2}-.+\.js$/.test(f))
.sort();
const args = process.argv.slice(2);
// --list flag
if (args.includes('--list')) {
console.log('Available test suites:\n');
for (const file of testFiles) {
const num = file.split('-')[0];
const name = file.replace(/^\d+-/, '').replace('.js', '').replace(/-/g, ' ');
console.log(` ${num} ${name}`);
}
console.log(`\nUsage: node tests/run-all.js [test-numbers...]`);
console.log(`Example: node tests/run-all.js 01 03 05`);
process.exit(0);
}
// Filter by requested test numbers
let selectedFiles = testFiles;
if (args.length > 0 && !args[0].startsWith('-')) {
selectedFiles = testFiles.filter((f) => args.some((num) => f.startsWith(num)));
if (selectedFiles.length === 0) {
console.error(`No test files match: ${args.join(', ')}`);
console.error('Use --list to see available tests.');
process.exit(1);
}
}
// ─── Run tests ───────────────────────────────────────────────────────────────
console.log('\x1b[1m╔══════════════════════════════════════════════╗\x1b[0m');
console.log('\x1b[1m║ MCP-Strapi Integration Test Suite ║\x1b[0m');
console.log('\x1b[1m╚══════════════════════════════════════════════╝\x1b[0m');
console.log();
console.log(` Strapi URL: ${process.env.STRAPI_URL || 'http://localhost:1337'}`);
console.log(` Test suites: ${selectedFiles.length}`);
console.log();
const results = [];
const startTime = Date.now();
for (const file of selectedFiles) {
const num = file.split('-')[0];
const name = file.replace(/^\d+-/, '').replace('.js', '').replace(/-/g, ' ');
const filePath = join(__dirname, file);
console.log(`\x1b[1m┌─ Suite ${num}: ${name} ─┐\x1b[0m`);
try {
execSync(`node "${filePath}"`, {
stdio: 'inherit',
env: { ...process.env },
timeout: 120_000, // 2 minutes per suite
});
results.push({ num, name, status: 'passed' });
} catch (err) {
if (err.status) {
results.push({ num, name, status: 'failed', exitCode: err.status });
} else {
results.push({ num, name, status: 'error', error: err.message });
}
}
console.log();
}
// ─── Aggregate results ──────────────────────────────────────────────────────
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
const passedSuites = results.filter((r) => r.status === 'passed').length;
const failedSuites = results.filter((r) => r.status !== 'passed').length;
console.log('\x1b[1m╔══════════════════════════════════════════════╗\x1b[0m');
console.log('\x1b[1m║ Overall Results ║\x1b[0m');
console.log('\x1b[1m╠══════════════════════════════════════════════╣\x1b[0m');
for (const r of results) {
const icon = r.status === 'passed' ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
console.log(` ${icon} ${r.num}: ${r.name}`);
}
console.log('\x1b[1m╠══════════════════════════════════════════════╣\x1b[0m');
console.log(` Suites: \x1b[32m${passedSuites} passed\x1b[0m, \x1b[31m${failedSuites} failed\x1b[0m (${elapsed}s)`);
console.log('\x1b[1m╚══════════════════════════════════════════════╝\x1b[0m');
process.exit(failedSuites > 0 ? 1 : 0);