Skip to main content
Glama
ebowwa

Xcode MCP Server

by ebowwa

xcode_show_build_settings

Display build settings for Xcode projects and schemes to configure compilation parameters and project configurations.

Instructions

Show build settings for a project/scheme

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath to .xcodeproj file
schemeYesScheme name

Implementation Reference

  • MCP CallToolRequestSchema handler that dispatches 'xcode_*' tool calls to CommandExecutor.executeCommand after stripping the 'xcode_' prefix. This is the entry point for executing the tool.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;
    
      try {
        // Handle web monitor tools
        if (name === 'start_web_monitor') {
          const result = await this.webMonitorManager.start();
          return {
            content: [
              {
                type: 'text',
                text: `${result.message}\n\nWeb interface available at: ${result.url}`
              }
            ]
          };
        }
        
        if (name === 'stop_web_monitor') {
          const result = this.webMonitorManager.stop();
          return {
            content: [
              {
                type: 'text',
                text: result.message
              }
            ]
          };
        }
        
        if (name === 'web_monitor_status') {
          const status = this.webMonitorManager.getStatus();
          let text = status.running 
            ? `Web monitor is running at ${status.url} (port ${status.port})`
            : 'Web monitor is not running';
          return {
            content: [
              {
                type: 'text',
                text: text
              }
            ]
          };
        }
        
        // Handle Xcode commands
        // Remove 'xcode_' prefix if present
        const commandName = name.startsWith('xcode_') ? name.slice(6) : name;
        const result = await this.commandExecutor.executeCommand(commandName, args);
        
        let responseText = result.output;
        if (result.error) {
          responseText += `\n\nWarnings/Errors:\n${result.error}`;
        }
        if (!result.success) {
          responseText = `Command failed: ${result.error}\n\nCommand executed: ${result.command}`;
        }
        
        return {
          content: [
            {
              type: 'text',
              text: responseText,
            },
          ],
        };
      } catch (error) {
        if (error instanceof McpError) {
          throw error;
        }
        
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${errorMessage}`,
            },
          ],
        };
      }
    });
  • Core execution logic for commands (including 'show_build_settings'). Validates parameters, builds shell command template, executes via child_process.execAsync, and returns output/error. This implements the tool logic generically.
    async executeCommand(name: string, args: Record<string, any> = {}): Promise<{
      success: boolean;
      output: string;
      error?: string;
      command: string;
    }> {
      const command = this.getCommand(name);
      if (!command) {
        throw new Error(`Command '${name}' not found`);
      }
    
      this.validateParameters(command, args);
    
      // Handle internal commands
      if (command.command.startsWith('internal:')) {
        return await this.executeInternalCommand(command, args);
      }
    
      // Handle external commands
      const builtCommand = this.buildCommand(command, args);
    
      try {
        const { stdout, stderr } = await execAsync(builtCommand);
        
        return {
          success: true,
          output: stdout,
          error: stderr || undefined,
          command: builtCommand
        };
      } catch (error) {
        return {
          success: false,
          output: '',
          error: error instanceof Error ? error.message : String(error),
          command: builtCommand
        };
      }
    }
  • Generates the input schema and metadata for MCP tools like 'xcode_show_build_settings' from loaded command definitions.
    // Generate MCP tool definitions from commands
    generateMCPToolDefinitions(): Array<{
      name: string;
      description: string;
      inputSchema: any;
    }> {
      return Object.entries(this.commands).map(([name, command]) => ({
        name: `xcode_${name}`,
        description: command.description,
        inputSchema: {
          type: 'object',
          properties: command.parameters ? Object.fromEntries(
            Object.entries(command.parameters).map(([paramName, paramDef]) => [
              paramName,
              {
                type: paramDef.type,
                description: paramDef.description,
                ...(paramDef.default !== undefined && { default: paramDef.default })
              }
            ])
          ) : {},
          required: command.parameters ? Object.entries(command.parameters)
            .filter(([_, paramDef]) => paramDef.required)
            .map(([paramName]) => paramName) : []
        }
      }));
    }
  • src/index.ts:87-89 (registration)
    Registers the list of available tools (including all generated xcode_* tools) for MCP ListToolsRequestSchema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [...tools, ...webMonitorTools],
    }));
  • Helper function that constructs the actual shell command string from the command template and parameters, used in tool execution.
    buildCommand(command: XcodeCommand, args: Record<string, any>): string {
      let builtCommand = command.command;
    
      // Replace required parameters
      if (command.parameters) {
        for (const [paramName, paramDef] of Object.entries(command.parameters)) {
          const value = args[paramName] !== undefined ? args[paramName] : paramDef.default;
          
          if (paramDef.type === 'boolean') {
            // Handle boolean parameters
            if (value === true) {
              // Replace placeholder with the template if true
              builtCommand = builtCommand.replace(`{${paramName}}`, paramDef.template || '');
            } else {
              // Remove placeholder if false
              builtCommand = builtCommand.replace(`{${paramName}}`, '');
            }
          } else if (value !== undefined && value !== null && value !== '') {
            if (paramDef.template) {
              // Use custom template for parameter
              const paramValue = paramDef.template.replace(`{${paramName}}`, value);
              builtCommand = builtCommand.replace(`{${paramName}}`, paramValue);
            } else {
              // Direct replacement
              builtCommand = builtCommand.replace(`{${paramName}}`, value);
            }
          } else {
            // Remove optional parameter placeholders
            builtCommand = builtCommand.replace(new RegExp(`\\s*\\{${paramName}\\}`, 'g'), '');
          }
        }
      }
    
      // Clean up any remaining placeholder patterns
      builtCommand = builtCommand.replace(/\s+/g, ' ').trim();
      
      return builtCommand;
    }

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/ebowwa/xcode-mcp'

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