#!/usr/bin/env node
import { spawn, exec } from 'child_process';
import { promisify } from 'util';
import fs from 'fs';
const execAsync = promisify(exec);
console.log('π Setting up Custom MCP Server...\n');
// Check if .env.local exists and create it if not
const envFile = '.env.local';
if (!fs.existsSync(envFile)) {
console.log('π Creating .env.local file...');
fs.writeFileSync(envFile, `# Local environment variables
# Add your Redis URL here if using local Redis
# REDIS_URL=redis://localhost:6379
# For Upstash Redis (production)
# UPSTASH_REDIS_REST_URL=
# UPSTASH_REDIS_REST_TOKEN=
`);
console.log('β Created .env.local file');
}
// Check if Redis is available
async function checkRedis() {
try {
// Check if Docker is available
await execAsync('docker --version');
console.log('π³ Docker is available');
// Check if Redis container exists
try {
const { stdout } = await execAsync('docker ps -a --filter name=redis-mcp --format "{{.Names}}"');
if (stdout.trim() === 'redis-mcp') {
console.log('π Redis container already exists');
// Check if it's running
const { stdout: statusOut } = await execAsync('docker ps --filter name=redis-mcp --format "{{.Names}}"');
if (statusOut.trim() === 'redis-mcp') {
console.log('β Redis container is already running');
} else {
console.log('π Starting Redis container...');
await execAsync('docker start redis-mcp');
console.log('β Redis container started');
}
} else {
console.log('π Creating new Redis container...');
await execAsync('docker run -d --name redis-mcp -p 6379:6379 redis:alpine');
console.log('β Redis container created and started');
}
// Update .env.local with Redis URL
let envContent = fs.readFileSync(envFile, 'utf8');
if (!envContent.includes('REDIS_URL=redis://localhost:6379')) {
envContent = envContent.replace('# REDIS_URL=redis://localhost:6379', 'REDIS_URL=redis://localhost:6379');
fs.writeFileSync(envFile, envContent);
console.log('β Updated .env.local with Redis URL');
}
} catch (error) {
console.log('β Error setting up Redis:', error.message);
console.log('βΉοΈ You can run the server without Redis (HTTP transport only)');
}
} catch (error) {
console.log('βΉοΈ Docker not available - Redis setup skipped');
console.log('βΉοΈ You can run the server without Redis (HTTP transport only)');
}
}
// Start the development server
function startDevServer() {
console.log('\nπ― Starting development server...');
const devProcess = spawn('npm', ['run', 'dev'], {
stdio: 'inherit',
shell: process.platform === 'win32'
});
devProcess.on('error', (error) => {
console.error('Failed to start development server:', error);
});
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log('\nπ Shutting down...');
devProcess.kill('SIGINT');
process.exit(0);
});
}
// Main setup flow
async function main() {
try {
await checkRedis();
console.log('\nβ
Setup complete!');
console.log('\nπ Next steps:');
console.log(' β’ Development server will start automatically');
console.log(' β’ Test HTTP transport: npm run test:http');
console.log(' β’ Test SSE transport: npm run test:sse');
console.log(' β’ Test with Claude Desktop: npm run test:stdio');
// Auto-start dev server
setTimeout(startDevServer, 2000);
} catch (error) {
console.error('β Setup failed:', error);
process.exit(1);
}
}
main();