Skip to main content
Glama

xcresult_list_attachments

List test attachments from Xcode result files to identify available files for export by name, type, and index.

Instructions

List all attachments for a specific test - shows attachment names, types, and indices for export

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
xcresult_pathYesAbsolute path to the .xcresult file
test_idYesTest ID or index number to list attachments for

Implementation Reference

  • Core handler function that validates inputs, parses the XCResult file using XCResultParser, finds the test node, retrieves attachments, formats the output with indices/types/sizes, and returns formatted text response.
    public static async xcresultListAttachments(
      xcresultPath: string,
      testId: string
    ): Promise<McpResult> {
      // Validate xcresult path
      if (!existsSync(xcresultPath)) {
        throw new McpError(
          ErrorCode.InvalidParams,
          `XCResult file not found: ${xcresultPath}`
        );
      }
    
      if (!xcresultPath.endsWith('.xcresult')) {
        throw new McpError(
          ErrorCode.InvalidParams,
          `Path must be an .xcresult file: ${xcresultPath}`
        );
      }
    
      // Check if xcresult is readable
      if (!XCResultParser.isXCResultReadable(xcresultPath)) {
        throw new McpError(
          ErrorCode.InternalError,
          `XCResult file is not readable or incomplete: ${xcresultPath}`
        );
      }
    
      if (!testId || testId.trim() === '') {
        throw new McpError(
          ErrorCode.InvalidParams,
          'Test ID or index is required'
        );
      }
    
      try {
        const parser = new XCResultParser(xcresultPath);
        
        // First find the test node to get the actual test identifier
        const testNode = await parser.findTestNode(testId);
        if (!testNode) {
          throw new McpError(
            ErrorCode.InvalidParams,
            `Test '${testId}' not found. Run xcresult_browse "${xcresultPath}" to see all available tests`
          );
        }
    
        if (!testNode.nodeIdentifier) {
          throw new McpError(
            ErrorCode.InvalidParams,
            `Test '${testId}' does not have a valid identifier for attachment retrieval`
          );
        }
    
        // Get test attachments
        const attachments = await parser.getTestAttachments(testNode.nodeIdentifier);
        
        let output = `📎 Attachments for test: ${testNode.name}\n`;
        output += `Found ${attachments.length} attachments\n`;
        output += '='.repeat(80) + '\n\n';
        
        if (attachments.length === 0) {
          output += 'No attachments found for this test.\n';
        } else {
          attachments.forEach((att, index) => {
            const filename = att.name || att.filename || 'unnamed';
            output += `[${index + 1}] ${filename}\n`;
            
            // Determine type from identifier or filename
            let type = att.uniform_type_identifier || att.uniformTypeIdentifier || '';
            if (!type || type === 'unknown') {
              // Infer type from filename extension or special patterns
              const ext = filename.toLowerCase().split('.').pop();
              if (ext === 'jpeg' || ext === 'jpg') type = 'public.jpeg';
              else if (ext === 'png') type = 'public.png';
              else if (ext === 'mp4') type = 'public.mpeg-4';
              else if (ext === 'mov') type = 'com.apple.quicktime-movie';
              else if (ext === 'txt') type = 'public.plain-text';
              else if (filename.toLowerCase().includes('app ui hierarchy')) type = 'ui-hierarchy';
              else if (filename.toLowerCase().includes('ui snapshot')) type = 'ui-snapshot';
              else if (filename.toLowerCase().includes('synthesized event')) type = 'synthesized-event';
              else type = 'unknown';
            }
            
            output += `    Type: ${type}\n`;
            if (att.payloadSize || att.payload_size) {
              output += `    Size: ${att.payloadSize || att.payload_size} bytes\n`;
            }
            output += '\n';
          });
          
          output += '\n💡 To export a specific attachment, use xcresult_export_attachment with the attachment index.\n';
        }
        
        return { content: [{ type: 'text', text: output }] };
    
      } catch (error) {
        if (error instanceof McpError) {
          throw error;
        }
    
        const errorMessage = error instanceof Error ? error.message : String(error);
        
        if (errorMessage.includes('xcresulttool')) {
          throw new McpError(
            ErrorCode.InternalError,
            `XCResult parsing failed. Make sure Xcode Command Line Tools are installed: ${errorMessage}`
          );
        }
        
        throw new McpError(
          ErrorCode.InternalError,
          `Failed to list attachments: ${errorMessage}`
        );
      }
    }
  • JSON Schema definition for the tool including input parameters: xcresult_path (required string) and test_id (required string). Used by both CLI and MCP server.
      name: 'xcresult_list_attachments',
      description: 'List all attachments for a specific test - shows attachment names, types, and indices for export',
      inputSchema: {
        type: 'object',
        properties: {
          xcresult_path: {
            type: 'string',
            description: 'Absolute path to the .xcresult file',
          },
          test_id: {
            type: 'string',
            description: 'Test ID or index number to list attachments for',
          },
        },
        required: ['xcresult_path', 'test_id'],
      },
    },
  • MCP server registration: switch case in CallToolRequestSchema handler that validates parameters and delegates to XCResultTools.xcresultListAttachments.
    case 'xcresult_list_attachments':
      if (!args.xcresult_path) {
        throw new McpError(ErrorCode.InvalidParams, `Missing required parameter: xcresult_path`);
      }
      if (!args.test_id) {
        throw new McpError(ErrorCode.InvalidParams, `Missing required parameter: test_id`);
      }
      return await XCResultTools.xcresultListAttachments(
        args.xcresult_path as string,
        args.test_id as string
      );

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/lapfelix/XcodeMCP'

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