| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /**
- * MCP SERVER DETECTION UTILITY
- * ============================
- *
- * Centralized utility for detecting MCP server configurations.
- * Used across TaskMaster integration and other MCP-dependent features.
- */
- import { promises as fsPromises } from 'fs';
- import path from 'path';
- import os from 'os';
- /**
- * Check if task-master-ai MCP server is configured
- * @returns {Promise<Object>} MCP detection result
- */
- export async function detectTaskMasterMCPServer() {
- try {
- const homeDir = os.homedir();
- const configPaths = [
- path.join(homeDir, '.pilotdeck.json'),
- path.join(homeDir, '.pilotdeck', 'settings.json')
- ];
-
- let configData = null;
- let configPath = null;
-
- // Try to read from either config file
- for (const filepath of configPaths) {
- try {
- const fileContent = await fsPromises.readFile(filepath, 'utf8');
- configData = JSON.parse(fileContent);
- configPath = filepath;
- break;
- } catch (error) {
- // File doesn't exist or is not valid JSON, try next
- continue;
- }
- }
-
- if (!configData) {
- return {
- hasMCPServer: false,
- reason: 'No pilotdeck configuration file found',
- hasConfig: false
- };
- }
- // Look for task-master-ai in user-scoped MCP servers
- let taskMasterServer = null;
- if (configData.mcpServers && typeof configData.mcpServers === 'object') {
- const serverEntry = Object.entries(configData.mcpServers).find(([name, config]) =>
- name === 'task-master-ai' ||
- name.includes('task-master') ||
- (config && config.command && config.command.includes('task-master'))
- );
-
- if (serverEntry) {
- const [name, config] = serverEntry;
- taskMasterServer = {
- name,
- scope: 'user',
- config,
- type: config.command ? 'stdio' : (config.url ? 'http' : 'unknown')
- };
- }
- }
- // Also check project-specific MCP servers if not found globally
- if (!taskMasterServer && configData.projects) {
- for (const [projectPath, projectConfig] of Object.entries(configData.projects)) {
- if (projectConfig.mcpServers && typeof projectConfig.mcpServers === 'object') {
- const serverEntry = Object.entries(projectConfig.mcpServers).find(([name, config]) =>
- name === 'task-master-ai' ||
- name.includes('task-master') ||
- (config && config.command && config.command.includes('task-master'))
- );
-
- if (serverEntry) {
- const [name, config] = serverEntry;
- taskMasterServer = {
- name,
- scope: 'local',
- projectPath,
- config,
- type: config.command ? 'stdio' : (config.url ? 'http' : 'unknown')
- };
- break;
- }
- }
- }
- }
- if (taskMasterServer) {
- const isValid = !!(taskMasterServer.config &&
- (taskMasterServer.config.command || taskMasterServer.config.url));
- const hasEnvVars = !!(taskMasterServer.config &&
- taskMasterServer.config.env &&
- Object.keys(taskMasterServer.config.env).length > 0);
- return {
- hasMCPServer: true,
- isConfigured: isValid,
- hasApiKeys: hasEnvVars,
- scope: taskMasterServer.scope,
- config: {
- command: taskMasterServer.config?.command,
- args: taskMasterServer.config?.args || [],
- url: taskMasterServer.config?.url,
- envVars: hasEnvVars ? Object.keys(taskMasterServer.config.env) : [],
- type: taskMasterServer.type
- }
- };
- } else {
- // Get list of available servers for debugging
- const availableServers = [];
- if (configData.mcpServers) {
- availableServers.push(...Object.keys(configData.mcpServers));
- }
- if (configData.projects) {
- for (const projectConfig of Object.values(configData.projects)) {
- if (projectConfig.mcpServers) {
- availableServers.push(...Object.keys(projectConfig.mcpServers).map(name => `local:${name}`));
- }
- }
- }
- return {
- hasMCPServer: false,
- reason: 'task-master-ai not found in configured MCP servers',
- hasConfig: true,
- configPath,
- availableServers
- };
- }
- } catch (error) {
- console.error('Error detecting MCP server config:', error);
- return {
- hasMCPServer: false,
- reason: `Error checking MCP config: ${error.message}`,
- hasConfig: false
- };
- }
- }
- /**
- * Get all configured MCP servers (not just TaskMaster)
- * @returns {Promise<Object>} All MCP servers configuration
- */
- export async function getAllMCPServers() {
- try {
- const homeDir = os.homedir();
- const configPaths = [
- path.join(homeDir, '.pilotdeck.json'),
- path.join(homeDir, '.pilotdeck', 'settings.json')
- ];
-
- let configData = null;
- let configPath = null;
-
- // Try to read from either config file
- for (const filepath of configPaths) {
- try {
- const fileContent = await fsPromises.readFile(filepath, 'utf8');
- configData = JSON.parse(fileContent);
- configPath = filepath;
- break;
- } catch (error) {
- continue;
- }
- }
-
- if (!configData) {
- return {
- hasConfig: false,
- servers: {},
- projectServers: {}
- };
- }
- return {
- hasConfig: true,
- configPath,
- servers: configData.mcpServers || {},
- projectServers: configData.projects || {}
- };
- } catch (error) {
- console.error('Error getting all MCP servers:', error);
- return {
- hasConfig: false,
- error: error.message,
- servers: {},
- projectServers: {}
- };
- }
- }
|