Skip to main content
Glama
setup.js10 kB
#!/usr/bin/env node /** * Agent Planner MCP - Automated Setup Wizard * * This script helps users configure the MCP server for Claude Desktop: * 1. Checks API server availability * 2. Guides token creation and validates it * 3. Creates .env file * 4. Detects and updates Claude Desktop config * 5. Tests the connection */ const fs = require('fs'); const path = require('path'); const readline = require('readline'); const { exec } = require('child_process'); const axios = require('axios'); // Colors for terminal output const colors = { reset: '\x1b[0m', bright: '\x1b[1m', green: '\x1b[32m', blue: '\x1b[34m', yellow: '\x1b[33m', red: '\x1b[31m', cyan: '\x1b[36m', }; function log(message, color = 'reset') { console.log(`${colors[color]}${message}${colors.reset}`); } function logStep(step, total, message) { log(`\nStep ${step}/${total}: ${message}`, 'bright'); } function logSuccess(message) { log(`✓ ${message}`, 'green'); } function logError(message) { log(`✗ ${message}`, 'red'); } function logInfo(message) { log(`ℹ ${message}`, 'cyan'); } // Create readline interface const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function question(query) { return new Promise(resolve => rl.question(query, resolve)); } // Detect Claude Desktop config location based on OS function getClaudeConfigPath() { const platform = process.platform; const homeDir = process.env.HOME || process.env.USERPROFILE; if (platform === 'darwin') { // macOS return path.join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'); } else if (platform === 'win32') { // Windows return path.join(homeDir, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json'); } else { // Linux return path.join(homeDir, '.config', 'Claude', 'claude_desktop_config.json'); } } // Check if API server is accessible async function checkApiHealth(apiUrl) { try { const response = await axios.get(`${apiUrl}/health`, { timeout: 5000 }); return response.status === 200; } catch (error) { return false; } } // Validate API token async function validateToken(apiUrl, token) { try { const response = await axios.get(`${apiUrl}/plans`, { headers: { 'Authorization': `ApiKey ${token}` }, timeout: 5000 }); return response.status === 200; } catch (error) { if (error.response && error.response.status === 401) { return false; } // If it's another error (like network), we can't validate throw new Error(`Cannot validate token: ${error.message}`); } } // Open URL in default browser function openBrowser(url) { const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'; exec(`${command} ${url}`, (error) => { if (error) { logInfo(`Could not open browser automatically. Please open: ${url}`); } }); } // Create .env file function createEnvFile(config) { const envContent = `# Agent Planner MCP Configuration # Generated on ${new Date().toISOString()} API_URL=${config.apiUrl} USER_API_TOKEN=${config.token} MCP_SERVER_NAME=planning-system MCP_SERVER_VERSION=0.2.0 NODE_ENV=production `; const envPath = path.join(__dirname, '..', '.env'); fs.writeFileSync(envPath, envContent); return envPath; } // Update Claude Desktop config function updateClaudeConfig(configPath, mcpServerPath, apiUrl, token) { let config = {}; // Read existing config if it exists if (fs.existsSync(configPath)) { try { const content = fs.readFileSync(configPath, 'utf8'); config = JSON.parse(content); } catch (error) { logInfo('Could not parse existing config, creating new one'); } } else { // Create directory if it doesn't exist const configDir = path.dirname(configPath); if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); } } // Ensure mcpServers exists if (!config.mcpServers) { config.mcpServers = {}; } // Add or update planning-system server config.mcpServers['planning-system'] = { command: 'node', args: [path.join(mcpServerPath, 'src', 'index.js')], env: { API_URL: apiUrl, USER_API_TOKEN: token } }; // Write config fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); return configPath; } // Main setup wizard async function runSetup() { log('\n🚀 Agent Planner MCP Setup Wizard\n', 'bright'); try { // Step 1: API Configuration logStep(1, 5, 'API Configuration'); log('\nWhere is your Agent Planner API running?'); log('1. Local development (localhost)'); log('2. Google Cloud Run'); log('3. Custom URL'); const deploymentType = await question('\nSelect option (1/2/3, default: 1): '); let apiUrl; let uiUrl; if (deploymentType === '2') { log('\nFor Cloud Run, you can find your URLs at:'); log('https://console.cloud.google.com/run?project=ta-agent-planner'); const apiUrlInput = await question('\nEnter API URL (e.g., https://agent-planner-api-xxx.run.app): '); apiUrl = apiUrlInput.trim(); // Derive UI URL from API URL or ask for it const suggestedUiUrl = apiUrl.replace('api-', 'ui-').replace('api.', 'ui.'); const uiUrlInput = await question(`Enter UI URL (default: ${suggestedUiUrl}): `); uiUrl = uiUrlInput.trim() || suggestedUiUrl; } else if (deploymentType === '3') { const apiUrlInput = await question('\nEnter API URL: '); apiUrl = apiUrlInput.trim(); const uiUrlInput = await question('Enter UI URL: '); uiUrl = uiUrlInput.trim(); } else { // Local development (default) apiUrl = 'http://localhost:3000'; uiUrl = 'http://localhost:3001'; } log('Checking API server...'); const apiAvailable = await checkApiHealth(apiUrl); if (!apiAvailable) { logError(`Cannot connect to API server at ${apiUrl}`); logInfo('Make sure the API server is running: cd agent-planner && npm start'); process.exit(1); } logSuccess(`Found API server at ${apiUrl}`); // Step 2: API Token Setup logStep(2, 5, 'API Token Setup'); log('\nPlease generate an API token:'); log('1. Open ' + uiUrl + '/app/settings in your browser'); log('2. Navigate to the "API Tokens" section'); log('3. Click "Create MCP Token" or "Create New Token"'); log('4. Enter a name (e.g., "MCP Server")'); log('5. Copy the generated token\n'); logInfo('Opening settings page in your browser...'); openBrowser(uiUrl + '/app/settings'); await new Promise(resolve => setTimeout(resolve, 2000)); const token = await question('\nEnter your API token: '); if (!token || token.trim().length < 10) { logError('Invalid token provided'); process.exit(1); } log('Validating token...'); try { const isValid = await validateToken(apiUrl, token.trim()); if (!isValid) { logError('Token validation failed - please check the token and try again'); process.exit(1); } logSuccess('Token validated successfully'); } catch (error) { logError(`Token validation failed: ${error.message}`); process.exit(1); } // Step 3: Environment Configuration logStep(3, 5, 'Environment Configuration'); const envPath = createEnvFile({ apiUrl, token: token.trim() }); logSuccess(`Created .env file at: ${envPath}`); // Step 4: Claude Desktop Configuration logStep(4, 5, 'Claude Desktop Configuration'); const configPath = getClaudeConfigPath(); const mcpServerPath = path.join(__dirname, '..'); log(`Detected Claude Desktop config at: ${configPath}`); const shouldUpdateConfig = await question('Update Claude Desktop config? (y/n): '); if (shouldUpdateConfig.toLowerCase() === 'y' || shouldUpdateConfig.toLowerCase() === 'yes') { try { updateClaudeConfig(configPath, mcpServerPath, apiUrl, token.trim()); logSuccess('Added planning-system MCP server to Claude Desktop config'); } catch (error) { logError(`Failed to update config: ${error.message}`); logInfo('You can manually add the configuration later'); } } else { logInfo('Skipped Claude Desktop config update'); log('\nManual configuration:'); log(JSON.stringify({ "mcpServers": { "planning-system": { "command": "node", "args": [path.join(mcpServerPath, 'src', 'index.js')], "env": { "API_URL": apiUrl, "USER_API_TOKEN": token.trim().substring(0, 10) + '...' } } } }, null, 2)); } // Step 5: Testing Connection logStep(5, 5, 'Testing Connection'); log('Testing MCP server connection...'); // Simple test by loading the API client try { process.env.API_URL = apiUrl; process.env.USER_API_TOKEN = token.trim(); const apiClient = require('./api-client'); const plans = await apiClient.plans.getPlans(); logSuccess(`MCP server can connect to API`); logSuccess(`Successfully retrieved ${plans.length} plan(s)`); } catch (error) { logError(`Connection test failed: ${error.message}`); } // Success! log('\n🎉 Setup complete!\n', 'green'); log('Next steps:', 'bright'); log('1. Restart Claude Desktop to load the MCP server'); log('2. Look for the 🔨 icon in Claude Desktop - you should see planning tools'); log('3. Try asking: "List my plans" or "Create a new plan called \'Test Project\'"'); log(''); log('Configuration saved to:', 'bright'); log(` .env file: ${envPath}`); log(` Claude config: ${configPath}`); log(''); } catch (error) { logError(`\nSetup failed: ${error.message}`); process.exit(1); } finally { rl.close(); } } // Run the setup wizard runSetup();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TAgents/agent-planner-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server