Skip to main content
Glama
efremidze

swift-patterns-mcp

search_swift_content

Search across Swift and SwiftUI resources to find code examples and best practices from trusted iOS developers. Use natural language queries to access both free and premium content.

Instructions

Unified search across all enabled sources (free + premium). Use this for broad natural-language queries. When Patreon is enabled, includes premium creator posts and downloadable code.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesNatural-language search query
requireCodeNoPrioritize and return only results with code examples

Implementation Reference

  • The handler function `createSearchSwiftContentHandler` which implements the search logic, including lexical search, Patreon integration, semantic recall, and persistent memory (Memvid) recall.
    export function createSearchSwiftContentHandler(
      overrides: Partial<SearchSwiftContentDependencies> = {}
    ): ToolHandler {
      const deps = {
        ...createDefaultDependencies(),
        ...overrides,
      };
    
      async function trySemanticRecall(options: SemanticRecallOptions): Promise<BasePattern[]> {
        return withAbortTimeout<BasePattern[]>(
          signal => trySemanticRecallInner(options, signal),
          deps.semanticTimeoutMs,
          []
        );
      }
    
      async function trySemanticRecallInner(
        options: SemanticRecallOptions,
        signal?: AbortSignal
      ): Promise<BasePattern[]> {
        const { query, lexicalResults, config, sourceManager, requireCode } = options;
    
        try {
          throwIfAborted(signal);
    
          // Check if semantic recall should activate
          const maxScore = lexicalResults.length > 0
            ? Math.max(...lexicalResults.map(p => p.relevanceScore)) / 100
            : 0;
    
          const shouldActivate = lexicalResults.length === 0 || maxScore < config.minLexicalScore;
          if (!shouldActivate) return [];
    
          // Get/create index and fetch patterns from enabled sources
          const index = deps.createSemanticIndex(config);
          const enabledSourceIds = sourceManager.getEnabledSources().map(s => s.id as FreeSourceName);
          const allPatterns = await deps.fetchAllPatterns(enabledSourceIds, signal);
          throwIfAborted(signal);
    
          await index.index(allPatterns, signal);
          throwIfAborted(signal);
    
          // Search and filter
          const semanticResults = await index.search(query, 5, signal);
          throwIfAborted(signal);
          const existingIds = new Set(lexicalResults.map(p => p.id));
    
          return semanticResults.filter(p =>
            !existingIds.has(p.id) &&
            (!requireCode || p.hasCode) &&
            p.relevanceScore >= config.minRelevanceScore
          );
        } catch {
          // Semantic recall is best-effort; return empty on any failure
          return [];
        }
      }
    
      return async (args, context) => {
        const query = validateRequiredString(args, 'query', `Usage: search_swift_content({ query: "async await" })`);
        if (isValidationError(query)) return query;
    
        const requireCodeValidated = validateOptionalBoolean(args, 'requireCode');
        if (isValidationError(requireCodeValidated)) return requireCodeValidated;
        const requireCode = !!requireCodeValidated;
    
        const wantsCode = deps.detectCodeIntent(args, query);
    
        const enabledSourceIds = context.sourceManager.getEnabledSources().map(s => s.id);
        const patreonEnabled = enabledSourceIds.includes('patreon') && !!context.patreonSource;
    
        // Build intent key for caching
        const sourcesForCache = [
          ...deps.getSourceNames('all'),
          ...(patreonEnabled ? ['patreon'] : []),
        ].sort();
        const intentKey: IntentKey = {
          tool: 'search_swift_content',
          query,
          minQuality: 0,
          sources: sourcesForCache,
          requireCode,
        };
    
        const { results: finalResults } = await deps.cachedSearch({
          intentKey,
          sourceManager: context.sourceManager,
          fetcher: async () => {
            // Lexical search across free sources
            const results = await deps.searchMultipleSources(query);
            let filtered: BasePattern[] = requireCode
              ? results.filter(r => r.hasCode)
              : results;
    
            // Patreon unified search
            if (patreonEnabled && context.patreonSource) {
              try {
                const patreon = new context.patreonSource() as PatreonSourceInstance;
                const patreonResults = await withAbortTimeout<BasePattern[]>(
                  signal => patreon.searchPatterns(query, { mode: 'fast', signal }),
                  deps.patreonUnifiedTimeoutMs,
                  []
                );
                const patreonFiltered = requireCode
                  ? patreonResults.filter(r => r.hasCode)
                  : patreonResults;
    
                const dedupedPatreon = dedup(patreonFiltered, filtered);
                if (dedupedPatreon.length > 0) {
                  filtered = [...filtered, ...dedupedPatreon];
                }
              } catch (error) {
                deps.logger.warn({ err: error }, 'Patreon search failed in unified search');
              }
            }
    
            filtered.sort(byRelevanceDesc);
    
            // Semantic recall: supplement lexical results when enabled
            const semanticConfig = context.sourceManager.getSemanticRecallConfig();
            if (semanticConfig.enabled) {
              const semanticResults = await trySemanticRecall({
                query,
                lexicalResults: filtered,
                config: semanticConfig,
                sourceManager: context.sourceManager,
                requireCode,
              });
              if (semanticResults.length > 0) {
                filtered = [...filtered, ...semanticResults]
                  .sort(byRelevanceDesc);
              }
            }
    
            // Memvid recall: supplement with cross-session patterns
            const memvidConfig = context.sourceManager.getMemvidConfig();
            if (memvidConfig.enabled) {
              try {
                const memvidMemory = deps.getMemvidMemory();
                const memvidResults = await memvidMemory.search(query, {
                  k: 5,
                  mode: memvidConfig.useEmbeddings ? 'sem' : 'auto',
                });
    
                const newMemvidResults = dedup(
                  requireCode ? memvidResults.filter(p => p.hasCode) : memvidResults,
                  filtered,
                );
                if (newMemvidResults.length > 0) {
                  deps.logger.info({ count: newMemvidResults.length }, 'Added patterns from memvid persistent memory');
                  filtered = [...filtered, ...newMemvidResults]
                    .sort(byRelevanceDesc);
                }
              } catch (error) {
                deps.logger.warn({ err: error }, 'Memvid memory operation failed');
              }
            }
    
            return filtered;
          },
        });
    
        if (finalResults.length === 0) {
          return deps.createMarkdownResponse(
            `Search Results: "${query}"`,
            `No results found for "${query}"${requireCode ? ' with code examples' : ''}.`,
          );
        }
    
        // Format using shared utility
        const formatted = deps.formatSearchPatterns(finalResults, query, {
          ...COMMON_FORMAT_OPTIONS,
          includeCode: wantsCode,
        });
    
        return deps.createTextResponse(formatted);
      };
    }
  • Tool registration of `search_swift_content` using `searchSwiftContentHandler`.
    import { searchSwiftContentHandler } from './handlers/searchSwiftContent.js';
    import { listContentSourcesHandler } from './handlers/listContentSources.js';
    import { enableSourceHandler } from './handlers/enableSource.js';
    import { setupPatreonHandler } from './handlers/setupPatreon.js';
    import { getPatreonPatternsHandler } from './handlers/getPatreonPatterns.js';
    
    registerHandler('get_swift_pattern', getSwiftPatternHandler);
    registerHandler('search_swift_content', searchSwiftContentHandler);

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/efremidze/swift-mcp'

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