Skip to main content
Glama
efremidze

swift-patterns-mcp

get_swift_pattern

Retrieve curated Swift/SwiftUI patterns from trusted free sources like Swift by Sundell and SwiftLee. Get conceptual guidance and real-world code examples for topics such as SwiftUI, async-await, and testing.

Instructions

Get Swift/SwiftUI reference patterns from curated free sources (Sundell, van der Lee, Nil Coalescing, Point-Free). Best for conceptual guidance and free-source examples.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
topicYesTopic to search (e.g., 'swiftui', 'testing', 'async-await', 'performance')
sourceNoSpecific source to search (default: all free sources)
minQualityNoMinimum quality score 0-100 (default: 60)

Implementation Reference

  • Main handler function for 'get_swift_pattern' tool. Validates args (topic required, source/minQuality optional), performs a hybrid search combining strict (exact topic) and broad (query variants) searches, ranks results using overlap analysis, and formats output.
    export const getSwiftPatternHandler: ToolHandler = async (args, context) => {
      const topic = validateRequiredString(args, 'topic', `Usage: get_swift_pattern({ topic: "swiftui" })
    
    Example topics:
    - swiftui, concurrency, testing, networking
    - performance, architecture, protocols
    - async-await, combine, coredata`);
      if (isValidationError(topic)) return topic;
    
      const sourceValidated = validateOptionalString(args, 'source');
      if (isValidationError(sourceValidated)) return sourceValidated;
      const source = sourceValidated || "all";
    
      const minQualityValidated = validateOptionalNumber(args, 'minQuality');
      if (isValidationError(minQualityValidated)) return minQualityValidated;
      const minQuality = minQualityValidated || 65;
      const wantsCode = detectCodeIntent(args, topic);
    
      if (source !== 'all' && !FREE_SOURCE_NAMES.includes(source as FreeSourceName)) {
        const patreonCreator = CREATORS.find(c => c.id.toLowerCase() === source.toLowerCase());
    
        if (patreonCreator) {
          return createTextResponse(`"${patreonCreator.name}" is a Patreon creator, not a free source.
    
    Use get_patreon_patterns to search Patreon content:
    get_patreon_patterns({ topic: "${topic}" })`);
        }
    
        return createTextResponse(`"${source}" isn't a recognized source.
    
    Available free sources: ${FREE_SOURCE_NAMES.join(', ')}
    Patreon creators: ${CREATORS.map(c => c.id).join(', ')}
    
    For free sources, use:
    get_swift_pattern({ topic: "${topic}", source: "sundell" })
    
    For Patreon creators, use:
    get_patreon_patterns({ topic: "${topic}" })`);
      }
    
      // Build intent key for caching
      const intentKey: IntentKey = {
        tool: 'get_swift_pattern_hybrid_v3',
        query: topic,
        minQuality,
        sources: getSourceNames(source as FreeSourceName | 'all'),
      };
    
      const { results } = await cachedSearch({
        intentKey,
        sourceManager: context.sourceManager,
        fetcher: async () => {
          const searchSource = source as FreeSourceName | 'all';
          const profile = buildQueryProfile(topic);
          const [strictResults, broadResults] = await Promise.all([
            searchMultipleSources(topic, searchSource),
            runBroadSearch(topic, searchSource, profile),
          ]);
          return mergeAndRankPatterns(topic, minQuality, strictResults, broadResults);
        },
      });
    
      if (results.length === 0) {
        return createMarkdownResponse(
          `Swift Patterns: ${topic}`,
          `No patterns found for "${topic}" with quality ≥ ${minQuality}.`,
          `Try:
    - Broader search terms
    - Lower minQuality
    - Different topic
    - search_swift_content({ query: "${topic}" }) for broader discovery`,
          'Available sources: Swift by Sundell, Antoine van der Lee, Nil Coalescing, Point-Free',
          context.sourceManager.isSourceConfigured('patreon')
            ? `💡 For creator-specific/tutorial content, use get_patreon_patterns({ topic: "${topic}" }).`
            : undefined,
        );
      }
    
      // Format using shared utility
      const formatted = formatTopicPatterns(results, topic, {
        ...COMMON_FORMAT_OPTIONS,
        includeCode: wantsCode,
      });
    
      return createTextResponse(formatted);
    };
  • Schema definition for the 'get_swift_pattern' tool. Defines the input schema with required 'topic' string, optional 'source' enum (all/sundell/vanderlee/nilcoalescing/pointfree), and optional 'minQuality' number.
    {
      name: "get_swift_pattern",
      description: "Get Swift/SwiftUI reference patterns from curated free sources (Sundell, van der Lee, Nil Coalescing, Point-Free). Best for conceptual guidance and free-source examples.",
      inputSchema: {
        type: "object",
        properties: {
          topic: {
            type: "string",
            description: "Topic to search (e.g., 'swiftui', 'testing', 'async-await', 'performance')",
          },
          source: {
            type: "string",
            enum: ["all", "sundell", "vanderlee", "nilcoalescing", "pointfree"],
            description: "Specific source to search (default: all free sources)",
          },
          minQuality: {
            type: "number",
            description: "Minimum quality score 0-100 (default: 60)",
          },
        },
        required: ["topic"],
      },
    },
  • Registration of the 'get_swift_pattern' tool handler in the registry. Maps the tool name to getSwiftPatternHandler.
    registerHandler('get_swift_pattern', getSwiftPatternHandler);
  • Helper function that merges strict and broad search results, ranks patterns using query overlap analysis with bigram matching, exact query boost, code boost, and applies a strong overlap gate filter.
    function mergeAndRankPatterns(
      topic: string,
      minQuality: number,
      strictResults: BasePattern[],
      broadResults: BasePattern[],
    ): BasePattern[] {
      const profile = buildQueryProfile(topic);
      const rankedById = new Map<string, RankedPattern>();
      const normalizedTopic = topic.toLowerCase().trim().replace(/\s+/g, ' ');
      const topicParts = normalizedTopic.split(' ').filter(Boolean);
      const significantBigrams = topicParts
        .slice(0, -1)
        .map((part, index) => `${part} ${topicParts[index + 1]}`)
        .filter(phrase => phrase.length > 8);
      const applyStrongOverlapGate = profile.weightedTokens.length >= HYBRID_MIN_TOKENS_FOR_STRICT_GATE;
    
      const rankPattern = (pattern: BasePattern): RankedPattern | null => {
        const haystack = `${pattern.title} ${pattern.excerpt} ${pattern.content} ${pattern.topics.join(' ')}`.toLowerCase();
        const overlap = computeQueryOverlap(haystack, profile);
        const strongOverlap = isStrongQueryOverlap(overlap, profile);
        const hasBigramMatch = significantBigrams.length > 0
          ? significantBigrams.some(phrase => haystack.includes(phrase))
          : false;
    
        if (applyStrongOverlapGate && !strongOverlap) {
          return null;
        }
        if (
          applyStrongOverlapGate &&
          significantBigrams.length > 0 &&
          !hasBigramMatch &&
          overlap.matchedTokens < HYBRID_MIN_MATCHED_TOKENS_WITHOUT_PHRASE
        ) {
          return null;
        }
    
        const overlapBoost = Math.min(overlap.score, QUERY_OVERLAP_SCORE_CAP) * QUERY_OVERLAP_RELEVANCE_MULTIPLIER;
        const exactQueryBoost = normalizedTopic.length > 0 && haystack.includes(normalizedTopic)
          ? HYBRID_EXACT_QUERY_BOOST
          : 0;
        const codeBoost = pattern.hasCode ? HYBRID_CODE_BOOST : 0;
    
        return {
          pattern,
          overlap,
          rankScore: pattern.relevanceScore + overlapBoost + exactQueryBoost + codeBoost,
        };
      };
    
      for (const pattern of [...strictResults, ...broadResults]) {
        if (pattern.relevanceScore < minQuality) continue;
        const ranked = rankPattern(pattern);
        if (!ranked) continue;
    
        const existing = rankedById.get(pattern.id);
        if (!existing || ranked.rankScore > existing.rankScore) {
          rankedById.set(pattern.id, ranked);
        }
      }
    
      return Array.from(rankedById.values())
        .sort((a, b) => {
          const byRank = b.rankScore - a.rankScore;
          if (byRank !== 0) return byRank;
          return compareByOverlapThenScore(a, b);
        })
        .map(r => r.pattern);
    }
  • Helper function that performs broad search using query variants (up to HYBRID_VARIANT_LIMIT) from the query profile, deduplicating results by ID and keeping the highest relevance score.
    async function runBroadSearch(topic: string, source: FreeSourceName | 'all', profile: QueryProfile): Promise<BasePattern[]> {
      const variants = profile.compiledQueries.slice(0, HYBRID_VARIANT_LIMIT);
      if (variants.length === 0) return [];
    
      const all = await Promise.all(
        variants.map(query => searchMultipleSources(query, source))
      );
    
      const deduped = new Map<string, BasePattern>();
      for (const resultSet of all) {
        for (const pattern of resultSet) {
          const existing = deduped.get(pattern.id);
          if (!existing || pattern.relevanceScore > existing.relevanceScore) {
            deduped.set(pattern.id, pattern);
          }
        }
      }
    
      return Array.from(deduped.values());
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description only implies a read-only operation via 'Get,' but does not explicitly state safety, side effects, or dependencies like network access. For a simple retrieval tool, this is adequate but not thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the verb 'Get' and resource, efficiently conveying purpose and context without unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description could specify return format (e.g., code snippets, links), but the tool's simplicity and clear purpose make the current level adequate for selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the description adds context about 'curated free sources' but does not elaborate on individual parameters beyond what the schema provides, resulting in marginal added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves Swift/SwiftUI reference patterns from specific free sources (Sundell, van der Lee, etc.), making its purpose distinct from siblings like search_swift_content or list_content_sources.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description notes it is 'best for conceptual guidance and free-source examples,' implying appropriate use cases, but does not explicitly exclude scenarios like paid sources or advanced topics, nor mention sibling alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

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

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