Skip to main content
Glama

search_unified

Search Apple's Human Interface Guidelines and technical API documentation simultaneously to find design principles and implementation details across iOS, macOS, watchOS, tvOS, and visionOS platforms.

Instructions

Unified search across both HIG design guidelines and technical documentation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query (keywords, component names, design concepts)
platformNoOptional: Filter by Apple platform

Implementation Reference

  • Main execution logic for the 'search_unified' tool. Performs unified search by calling HIG and technical search methods, generates cross-references, combines and ranks results.
    async searchUnified(args: {
      query: string;
      platform?: ApplePlatform;
    }): Promise<{
      results: UnifiedSearchResult[];
      designResults: SearchResult[];
      technicalResults: TechnicalSearchResult[];
      total: number;
      query: string;
      sources: string[];
      crossReferences: Array<{
        designSection: string;
        technicalSymbol: string;
        relevance: number;
      }>;
    }> {
      const { query, platform } = args;
      
      // Use sensible defaults internally
      const includeDesign = true;
      const includeTechnical = true;
      const maxResults = 20;
    
      // Input validation
      if (!query || typeof query !== 'string' || query.trim().length === 0) {
        throw new Error('Invalid query: must be a non-empty string');
      }
    
      if (query.length > 100) {
        throw new Error('Query too long: maximum 100 characters allowed');
      }
    
      const sources: string[] = [];
      let designResults: SearchResult[] = [];
      let technicalResults: TechnicalSearchResult[] = [];
    
      try {
        // Search design guidelines if requested
        if (includeDesign) {
          sources.push('design-guidelines');
          try {
            const designSearch = await this.searchHumanInterfaceGuidelines({
              query,
              platform
            });
            designResults = designSearch.results;
          } catch {
            // Fall through to fallback
          }
        }
    
        // Search technical documentation if requested
        if (includeTechnical) {
          sources.push('technical-documentation');
          try {
            const technicalSearch = await this.searchTechnicalDocumentation({
              query,
              platform
            });
            technicalResults = technicalSearch.results;
          } catch {
            // Fall through to fallback
          }
        }
    
        // Generate cross-references between design and technical content
        const crossReferences = this.generateCrossReferences(designResults, technicalResults, query);
    
        // Combine and rank results using unified scoring
        const unifiedResults = this.combineAndRankResults(
          designResults,
          technicalResults,
          crossReferences,
          maxResults
        );
    
        return {
          results: unifiedResults,
          designResults,
          technicalResults,
          total: unifiedResults.length,
          query: query.trim(),
          sources,
          crossReferences
        };
    
      } catch (error) {
        throw new Error(`Unified search failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
      }
    }
  • src/server.ts:202-220 (registration)
    Tool registration in ListToolsRequestHandler, defining name, description, and input schema.
      name: 'search_unified',
      title: 'Unified Search',
      description: 'Unified search across both HIG design guidelines and technical documentation',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Search query (keywords, component names, design concepts)',
          },
          platform: {
            type: 'string',
            enum: ['iOS', 'macOS', 'watchOS', 'tvOS', 'visionOS', 'universal'],
            description: 'Optional: Filter by Apple platform',
          },
        },
        required: ['query'],
      },
    },
  • Dispatch handler in CallToolRequestHandler that invokes the toolProvider's searchUnified method.
    case 'search_unified': {
      result = await this.toolProvider.searchUnified(args as any);
      break;
    }
  • TypeScript interface defining the arguments for searchUnified, imported and used for type safety.
    export interface SearchUnifiedArgs {
      query: string;
      searchType?: 'design' | 'technical' | 'both';
      platform?: ApplePlatform;
      category?: HIGCategory;
      framework?: string;
      symbolType?: string;
      includeImplementation?: boolean;
      limit?: number;
    }
  • Helper method that generates cross-references between design guidelines and technical symbols, used by the main handler.
    private generateCrossReferences(
      designResults: SearchResult[],
      technicalResults: TechnicalSearchResult[],
      query: string
    ): Array<{
      designSection: string;
      technicalSymbol: string;
      relevance: number;
    }> {
      const crossReferences: Array<{
        designSection: string;
        technicalSymbol: string;
        relevance: number;
      }> = [];
    
      // Common UI component mappings
      const componentMappings = new Map([
        // Buttons
        ['button', ['Button', 'UIButton', 'NSButton', 'SwiftUI.Button']],
        ['buttons', ['Button', 'UIButton', 'NSButton', 'SwiftUI.Button']],
        
        // Navigation
        ['navigation', ['NavigationView', 'UINavigationController', 'NSNavigationController', 'NavigationStack']],
        ['navigation bar', ['NavigationView', 'UINavigationBar', 'NSNavigationItem']],
        
        // Lists
        ['list', ['List', 'UITableView', 'NSTableView', 'UICollectionView']],
        ['table', ['UITableView', 'NSTableView', 'TableView']],
        
        // Text
        ['text', ['Text', 'UILabel', 'NSTextField', 'TextField']],
        ['label', ['Text', 'UILabel', 'NSTextField']],
        
        // Images
        ['image', ['Image', 'UIImageView', 'NSImageView']],
        ['icon', ['Image', 'UIImageView', 'NSImageView', 'SF Symbols']],
        
        // Controls
        ['picker', ['Picker', 'UIPickerView', 'NSPopUpButton']],
        ['slider', ['Slider', 'UISlider', 'NSSlider']],
        ['switch', ['Toggle', 'UISwitch', 'NSSwitch']],
        ['toggle', ['Toggle', 'UISwitch', 'NSSwitch']],
        
        // Layout
        ['stack', ['VStack', 'HStack', 'ZStack', 'UIStackView', 'NSStackView']],
        ['scroll', ['ScrollView', 'UIScrollView', 'NSScrollView']],
        
        // Sheets and Popups
        ['sheet', ['Sheet', 'UIModalPresentationStyle', 'NSModalSession']],
        ['alert', ['Alert', 'UIAlertController', 'NSAlert']],
        ['popup', ['Popover', 'UIPopoverController', 'NSPopover']]
      ]);
    
      // Extract key terms from query for mapping
      const queryTerms = query.toLowerCase().split(/\s+/).filter(term => term.length > 2);
      
      for (const designResult of designResults) {
        for (const technicalResult of technicalResults) {
          let relevance = 0;
    
          // Direct title matching
          const designTitle = designResult.title.toLowerCase();
          const technicalTitle = technicalResult.title.toLowerCase();
          
          // Check if design title contains technical symbol name or vice versa
          if (designTitle.includes(technicalTitle) || technicalTitle.includes(designTitle)) {
            relevance += 0.8;
          }
    
          // Component mapping-based relevance
          for (const [designTerm, technicalSymbols] of componentMappings) {
            if (designTitle.includes(designTerm)) {
              for (const symbol of technicalSymbols) {
                if (technicalTitle.includes(symbol.toLowerCase())) {
                  relevance += 0.6;
                  break;
                }
              }
            }
          }
    
          // Query term overlap between design and technical content
          for (const term of queryTerms) {
            if (designTitle.includes(term) && technicalTitle.includes(term)) {
              relevance += 0.3;
            }
          }
    
          // Platform consistency boost
          if (designResult.platform && technicalResult.platforms && typeof technicalResult.platforms === 'string') {
            const designPlatform = designResult.platform.toLowerCase();
            const technicalPlatforms = technicalResult.platforms.toLowerCase();
            if (technicalPlatforms.includes(designPlatform)) {
              relevance += 0.2;
            }
          }
    
          // Framework preference: slightly boost UIKit/AppKit over SwiftUI in cross-references for backward compatibility
          if (technicalResult.framework === 'UIKit' || technicalResult.framework === 'AppKit') {
            relevance += 0.1;
          }
    
          // Only include cross-references with meaningful relevance
          if (relevance >= 0.4) {
            const crossRefKey = `${designResult.title}:${technicalResult.title}`;
            // Avoid duplicate cross-references
            if (!crossReferences.some(ref => `${ref.designSection}:${ref.technicalSymbol}` === crossRefKey)) {
              crossReferences.push({
                designSection: designResult.title,
                technicalSymbol: technicalResult.title,
                relevance: Math.round(relevance * 100) / 100
              });
            }
          }
        }
      }
    
      // Sort by relevance and limit to top cross-references
      return crossReferences
        .sort((a, b) => b.relevance - a.relevance)
        .slice(0, 10);
    }

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/tmaasen/apple-dev-mcp'

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