Skip to main content
Glama

search_symbols

Search for Apple framework symbols using flexible queries with wildcards, filter by type, platform, or framework, and control results with maxResults.

Instructions

Search for symbols across Apple frameworks (supports wildcards like "RPBroadcast*")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
frameworkNoOptional: Search within specific framework only
maxResultsNoOptional: Maximum number of results (default: 20)
platformNoOptional: Filter by platform (iOS, macOS, etc.)
queryYesSearch query (supports wildcards: * and ?)
symbolTypeNoOptional: Filter by symbol type (class, protocol, struct, etc.)

Implementation Reference

  • Core implementation of the search_symbols tool. The buildSearchSymbolsHandler returns an async function that handles the tool call: checks active technology, searches local symbol index or falls back to framework search, applies filters, and formats results in markdown.
    export const buildSearchSymbolsHandler = (context: ServerContext) => { const {client, state} = context; const noTechnology = buildNoTechnologyMessage(context); return async (args: {maxResults?: number; platform?: string; query: string; symbolType?: string}): Promise<ToolResponse> => { const activeTechnology = state.getActiveTechnology(); if (!activeTechnology) { return noTechnology(); } const {query, maxResults = 20, platform, symbolType} = args; // Get or create technology-specific local index from state const techLocalIndex = state.getLocalSymbolIndex(client); // Build local index from cached files if not already built if (techLocalIndex.getSymbolCount() === 0) { try { console.error('📚 Building symbol index from cache...'); await techLocalIndex.buildIndexFromCache(); console.error(`✅ Index built with ${techLocalIndex.getSymbolCount()} symbols`); } catch (error) { console.warn('Failed to build local symbol index:', error instanceof Error ? error.message : String(error)); } } // Comprehensive download disabled - it was broken and blocking // If local index is empty/small, use direct framework search as fallback let symbolResults = techLocalIndex.search(query, maxResults * 2); if (symbolResults.length === 0 && techLocalIndex.getSymbolCount() < 50) { // Fallback: search framework.references directly (fast, no download needed) console.error('📋 Using framework references for search...'); const frameworkResults = await client.searchFramework(activeTechnology.title, query, {maxResults: maxResults * 2, platform, symbolType}); symbolResults = frameworkResults.map(r => ({ id: r.path ?? r.title, title: r.title, path: r.path ?? '', kind: r.symbolKind ?? 'symbol', abstract: r.description, platforms: r.platforms ? r.platforms.split(', ') : [], tokens: [], filePath: '', })); } // Apply filters let filteredResults = symbolResults; if (platform) { const platformLower = platform.toLowerCase(); filteredResults = filteredResults.filter(result => result.platforms.some(p => p.toLowerCase().includes(platformLower))); } if (symbolType) { const typeLower = symbolType.toLowerCase(); filteredResults = filteredResults.filter(result => result.kind.toLowerCase().includes(typeLower)); } filteredResults = filteredResults.slice(0, maxResults); // Validate result relevance const technologyIdentifier = activeTechnology.identifier.replace('doc://com.apple.documentation/', '').replace(/^documentation\//, ''); const isRelevantResult = (result: LocalSymbolIndexEntry) => { const resultPath = result.path.toLowerCase(); const technologyPath = technologyIdentifier.toLowerCase(); return resultPath.includes(technologyPath); }; const relevantResults = filteredResults.filter(result => isRelevantResult(result)); const hasIrrelevantResults = relevantResults.length < filteredResults.length; const lines = [ header(1, `🔍 Search Results for "${query}"`), '', bold('Technology', activeTechnology.title), bold('Matches', filteredResults.length.toString()), bold('Total Symbols Indexed', techLocalIndex.getSymbolCount().toString()), '', ]; // Add status information if (techLocalIndex.getSymbolCount() < 50) { lines.push( '⚠️ **Limited Results:** Only basic symbols are indexed.', 'For comprehensive results, additional symbols are being downloaded in the background.', '', ); } else { lines.push( '✅ **Comprehensive Index:** Full symbol database is available.', '', ); } lines.push(header(2, 'Symbols'), ''); // Show warning if results seem irrelevant if (hasIrrelevantResults && filteredResults.length > 0) { lines.push( '⚠️ **Note:** Some results may not be from the selected technology.', 'For specific symbol names, try using `get_documentation` instead.', '', ); } if (filteredResults.length > 0) { for (const result of filteredResults) { const platforms = result.platforms.length > 0 ? result.platforms.join(', ') : 'All platforms'; lines.push( `### ${result.title}`, ` • **Kind:** ${result.kind}`, ` • **Path:** ${result.path}`, ` • **Platforms:** ${platforms}`, ` ${result.abstract}`, '', ); } } else { // Check if this looks like a specific symbol name that should use direct documentation lookup const isSpecificSymbol = /^[A-Z][a-zA-Z\d]*$/.test(query) || /^[A-Z][a-zA-Z\d]*\.[A-Z][a-zA-Z\d]*$/.test(query); lines.push( 'No symbols matched those terms within this technology.', '', '**Search Tips:**', '• Try wildcards: `Grid*` or `*Item`', '• Use broader keywords: "grid" instead of "griditem"', '• Check spelling and try synonyms', '', ); if (isSpecificSymbol) { lines.push( '**💡 Suggestion:** This looks like a specific symbol name.', 'Try using `get_documentation` instead for direct access:', '', '```', `get_documentation { "path": "${query}" }`, '```', '', ); } lines.push( '**Note:** If this is your first search, symbols are being downloaded in the background.', 'Try searching again in a few moments for more comprehensive results.', '', ); } return { content: [{text: lines.join('\n'), type: 'text'}], }; }; };
  • Tool registration object defining name, description, input JSON schema, and the handler instance for search_symbols.
    { name: 'search_symbols', description: 'Search and discover symbols within the currently selected technology. ' + 'Use this for exploration and finding symbols by keywords. Supports wildcards (* and ?). ' + 'For specific known symbols, use get_documentation instead.', inputSchema: { type: 'object', required: ['query'], properties: { maxResults: { type: 'number', description: 'Optional maximum number of results (default 20)', }, platform: { type: 'string', description: 'Optional platform filter (iOS, macOS, etc.)', }, query: { type: 'string', description: 'Search keywords with wildcard support (* for any characters, ? for single character)', }, symbolType: { type: 'string', description: 'Optional symbol kind filter (class, protocol, etc.)', }, }, }, handler: buildSearchSymbolsHandler(context), },
  • JSON Schema for input validation of the search_symbols tool parameters.
    inputSchema: { type: 'object', required: ['query'], properties: { maxResults: { type: 'number', description: 'Optional maximum number of results (default 20)', }, platform: { type: 'string', description: 'Optional platform filter (iOS, macOS, etc.)', }, query: { type: 'string', description: 'Search keywords with wildcard support (* for any characters, ? for single character)', }, symbolType: { type: 'string', description: 'Optional symbol kind filter (class, protocol, etc.)', }, },

Other Tools

Related Tools

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/MightyDillah/apple-doc-mcp'

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