Skip to main content
Glama

memory_contextual_search

Retrieve relevant information from memory using contextual search with intelligent ranking to find specific data based on queries and context.

Instructions

Perform contextual memory retrieval with intelligent ranking

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query
contextYes
optionsNo

Implementation Reference

  • The `retrieve` method of `ContextualMemoryRetrieval` class implements the core tool logic, taking exactly the parameters defined in the tool schema: query, context, and options. It performs contextual search, scoring, ranking, and returns RetrievalResult.
    async retrieve(
      query: string,
      context: RetrievalContext,
      options?: {
        maxResults?: number;
        minRelevance?: number;
        includeReasoning?: boolean;
      },
    ): Promise<RetrievalResult> {
      const startTime = Date.now();
      const maxResults = options?.maxResults || 10;
      const minRelevance = options?.minRelevance || 0.3;
    
      // Get candidate memories based on basic filtering
      const candidates = await this.getCandidateMemories(query, context);
    
      // Score and rank candidates
      const scoredMatches = await this.scoreAndRankCandidates(
        candidates,
        query,
        context,
      );
    
      // Filter by relevance threshold
      const relevantMatches = scoredMatches
        .filter((match) => match.relevanceScore >= minRelevance)
        .slice(0, maxResults);
    
      // Generate insights from matches
      const insights = await this.generateInsights(relevantMatches, context);
    
      const processingTime = Date.now() - startTime;
    
      return {
        matches: relevantMatches,
        metadata: {
          queryContext: context,
          totalCandidates: candidates.length,
          processingTime,
          fallbackUsed: relevantMatches.length === 0 && candidates.length > 0,
        },
        insights,
      };
    }
  • Type definitions for RetrievalContext, ContextualMatch, and RetrievalResult match the tool's inputSchema structure and expected output.
    export interface RetrievalContext {
      currentProject?: {
        path: string;
        language: string;
        framework?: string;
        domain?: string;
        size?: "small" | "medium" | "large";
      };
      userIntent?: {
        action: "analyze" | "recommend" | "deploy" | "troubleshoot" | "learn";
        urgency: "low" | "medium" | "high";
        experience: "novice" | "intermediate" | "expert";
      };
      sessionContext?: {
        recentActions: string[];
        focusAreas: string[];
        timeConstraints?: number; // minutes
      };
      temporalContext?: {
        timeRange?: { start: string; end: string };
        recency: "recent" | "all" | "historical";
        seasonality?: boolean;
      };
    }
  • Tool definition including name, description, and inputSchema in the exported memoryTools array, which registers it for MCP usage.
    {
      name: "memory_contextual_search",
      description: "Perform contextual memory retrieval with intelligent ranking",
      inputSchema: {
        type: "object",
        properties: {
          query: {
            type: "string",
            description: "Search query",
          },
          context: {
            type: "object",
            properties: {
              currentProject: {
                type: "object",
                properties: {
                  path: { type: "string" },
                  language: { type: "string" },
                  framework: { type: "string" },
                  size: { type: "string", enum: ["small", "medium", "large"] },
                },
              },
              userIntent: {
                type: "object",
                properties: {
                  action: {
                    type: "string",
                    enum: [
                      "analyze",
                      "recommend",
                      "deploy",
                      "troubleshoot",
                      "learn",
                    ],
                  },
                  urgency: { type: "string", enum: ["low", "medium", "high"] },
                  experience: {
                    type: "string",
                    enum: ["novice", "intermediate", "expert"],
                  },
                },
              },
              temporalContext: {
                type: "object",
                properties: {
                  recency: {
                    type: "string",
                    enum: ["recent", "all", "historical"],
                  },
                  timeRange: {
                    type: "object",
                    properties: {
                      start: { type: "string" },
                      end: { type: "string" },
                    },
                  },
                },
              },
            },
          },
          options: {
            type: "object",
            properties: {
              maxResults: { type: "number", default: 10 },
              minRelevance: { type: "number", default: 0.3 },
              includeReasoning: { type: "boolean", default: true },
            },
          },
        },
        required: ["query", "context"],
      },
    },
  • Full ContextualMemoryRetrieval class providing the handler implementation and supporting helper methods for candidate retrieval, scoring, ranking, and insight generation.
    export class ContextualMemoryRetrieval {
      private memoryManager: MemoryManager;
      private knowledgeGraph: KnowledgeGraph;
      private embeddingCache: Map<string, SemanticEmbedding>;
      private readonly maxCacheSize = 1000;
      private readonly similarityThreshold = 0.6;
    
      constructor(memoryManager: MemoryManager, knowledgeGraph: KnowledgeGraph) {
        this.memoryManager = memoryManager;
        this.knowledgeGraph = knowledgeGraph;
        this.embeddingCache = new Map();
      }
    
      /**
       * Retrieve contextually relevant memories
       */
      async retrieve(
        query: string,
        context: RetrievalContext,
        options?: {
          maxResults?: number;
          minRelevance?: number;
          includeReasoning?: boolean;
        },
      ): Promise<RetrievalResult> {
        const startTime = Date.now();
        const maxResults = options?.maxResults || 10;
        const minRelevance = options?.minRelevance || 0.3;
    
        // Get candidate memories based on basic filtering
        const candidates = await this.getCandidateMemories(query, context);
    
        // Score and rank candidates
        const scoredMatches = await this.scoreAndRankCandidates(
          candidates,
          query,
          context,
        );
    
        // Filter by relevance threshold
        const relevantMatches = scoredMatches
          .filter((match) => match.relevanceScore >= minRelevance)
          .slice(0, maxResults);
    
        // Generate insights from matches
        const insights = await this.generateInsights(relevantMatches, context);
    
        const processingTime = Date.now() - startTime;
    
        return {
          matches: relevantMatches,
          metadata: {
            queryContext: context,
            totalCandidates: candidates.length,
            processingTime,
            fallbackUsed: relevantMatches.length === 0 && candidates.length > 0,
          },
          insights,
        };
      }
    
      /**
       * Get candidate memories using multiple retrieval strategies
       */
      private async getCandidateMemories(
        query: string,
        context: RetrievalContext,
      ): Promise<MemoryEntry[]> {
        const candidates = new Map<string, MemoryEntry>();
    
        // Strategy 1: Text-based search
        const textMatches = await this.memoryManager.search(query, {
          sortBy: "timestamp",
        });
        textMatches.forEach((memory) => candidates.set(memory.id, memory));
    
        // Strategy 2: Context-based filtering
        if (context.currentProject) {
          const contextMatches = await this.getContextBasedCandidates(
            context.currentProject,
          );
          contextMatches.forEach((memory) => candidates.set(memory.id, memory));
        }
    
        // Strategy 3: Intent-based retrieval
        if (context.userIntent) {
          const intentMatches = await this.getIntentBasedCandidates(
            context.userIntent,
          );
          intentMatches.forEach((memory) => candidates.set(memory.id, memory));
        }
    
        // Strategy 4: Temporal filtering
        if (context.temporalContext) {
          const temporalMatches = await this.getTemporalCandidates(
            context.temporalContext,
          );
          temporalMatches.forEach((memory) => candidates.set(memory.id, memory));
        }
    
        // Strategy 5: Knowledge graph traversal
        const graphMatches = await this.getGraphBasedCandidates(query, context);
        graphMatches.forEach((memory) => candidates.set(memory.id, memory));
    
        return Array.from(candidates.values());
      }
    
      /**
       * Get candidates based on current project context
       */
      private async getContextBasedCandidates(
        project: NonNullable<RetrievalContext["currentProject"]>,
      ): Promise<MemoryEntry[]> {
        const searchCriteria = [];
    
        // Language-based search
        searchCriteria.push(
          this.memoryManager
            .search("", { sortBy: "timestamp" })
            .then((memories) =>
              memories.filter(
                (m) =>
                  m.data.language?.primary === project.language ||
                  m.metadata.tags?.includes(project.language),
              ),
            ),
        );
    
        // Framework-based search
        if (project.framework) {
          searchCriteria.push(
            this.memoryManager
              .search("", { sortBy: "timestamp" })
              .then((memories) =>
                memories.filter(
                  (m) =>
                    m.data.framework?.name === project.framework ||
                    (project.framework &&
                      m.metadata.tags?.includes(project.framework)),
                ),
              ),
          );
        }
    
        // Project size similarity
        if (project.size) {
          searchCriteria.push(
            this.memoryManager
              .search("", { sortBy: "timestamp" })
              .then((memories) =>
                memories.filter(
                  (m) =>
                    this.categorizeProjectSize(m.data.stats?.files || 0) ===
                    project.size,
                ),
              ),
          );
        }
    
        const results = await Promise.all(searchCriteria);
        const allMatches = results.flat();
    
        // Deduplicate
        const unique = new Map<string, MemoryEntry>();
        allMatches.forEach((memory) => unique.set(memory.id, memory));
    
        return Array.from(unique.values());
      }
    
      /**
       * Get candidates based on user intent
       */
      private async getIntentBasedCandidates(
        intent: NonNullable<RetrievalContext["userIntent"]>,
      ): Promise<MemoryEntry[]> {
        const intentTypeMap = {
          analyze: ["analysis", "evaluation", "assessment"],
          recommend: ["recommendation", "suggestion", "advice"],
          deploy: ["deployment", "publish", "release"],
          troubleshoot: ["error", "issue", "problem", "debug"],
          learn: ["tutorial", "guide", "example", "pattern"],
        };
    
        const searchTerms = intentTypeMap[intent.action] || [intent.action];
        const searches = searchTerms.map((term) =>
          this.memoryManager.search(term, { sortBy: "timestamp" }),
        );
    
        const results = await Promise.all(searches);
        const allMatches = results.flat();
    
        // Filter by experience level
        return allMatches.filter((memory) => {
          if (intent.experience === "novice") {
            return (
              !memory.metadata.tags?.includes("advanced") &&
              !memory.metadata.tags?.includes("expert")
            );
          } else if (intent.experience === "expert") {
            return (
              memory.metadata.tags?.includes("advanced") ||
              memory.metadata.tags?.includes("expert") ||
              memory.data.complexity === "complex"
            );
          }
          return true; // intermediate gets all
        });
      }
    
      /**
       * Get candidates based on temporal context
       */
      private async getTemporalCandidates(
        temporal: NonNullable<RetrievalContext["temporalContext"]>,
      ): Promise<MemoryEntry[]> {
        const searchOptions: any = { sortBy: "timestamp" };
    
        if (temporal.timeRange) {
          // Use memory manager's built-in time filtering
          const allMemories = await this.memoryManager.search("", searchOptions);
    
          return allMemories.filter((memory) => {
            const memoryTime = new Date(memory.timestamp);
            const start = new Date(temporal.timeRange!.start);
            const end = new Date(temporal.timeRange!.end);
            return memoryTime >= start && memoryTime <= end;
          });
        }
    
        if (temporal.recency === "recent") {
          const cutoff = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); // Last 7 days
          const allMemories = await this.memoryManager.search("", searchOptions);
    
          return allMemories.filter(
            (memory) => new Date(memory.timestamp) > cutoff,
          );
        }
    
        if (temporal.recency === "historical") {
          const cutoff = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000); // Older than 90 days
          const allMemories = await this.memoryManager.search("", searchOptions);
    
          return allMemories.filter(
            (memory) => new Date(memory.timestamp) < cutoff,
          );
        }
    
        return this.memoryManager.search("", searchOptions);
      }
    
      /**
       * Get candidates using knowledge graph traversal
       */
      private async getGraphBasedCandidates(
        query: string,
        context: RetrievalContext,
      ): Promise<MemoryEntry[]> {
        if (!context.currentProject) return [];
    
        // Find relevant nodes in the knowledge graph
        const graphQuery = {
          nodeTypes: ["project", "technology"],
          properties: context.currentProject.language
            ? {
                language: context.currentProject.language,
              }
            : undefined,
          maxDepth: 2,
        };
    
        const graphResult = this.knowledgeGraph.query(graphQuery);
        const relevantNodeIds = graphResult.nodes.map((node) => node.id);
    
        // Find memories associated with these nodes
        const memories: MemoryEntry[] = [];
        const allMemories = await this.memoryManager.search("", {
          sortBy: "timestamp",
        });
    
        for (const memory of allMemories) {
          const projectNodeId = `project:${memory.metadata.projectId}`;
          const techNodeId = memory.metadata.ssg
            ? `tech:${memory.metadata.ssg}`
            : null;
    
          if (
            relevantNodeIds.includes(projectNodeId) ||
            (techNodeId && relevantNodeIds.includes(techNodeId))
          ) {
            memories.push(memory);
          }
        }
    
        return memories;
      }
    
      /**
       * Score and rank candidates based on contextual relevance
       */
      private async scoreAndRankCandidates(
        candidates: MemoryEntry[],
        query: string,
        context: RetrievalContext,
      ): Promise<ContextualMatch[]> {
        const matches: ContextualMatch[] = [];
    
        for (const memory of candidates) {
          const contextualFactors = await this.calculateContextualFactors(
            memory,
            query,
            context,
          );
    
          const relevanceScore = this.calculateOverallRelevance(contextualFactors);
          const reasoning = this.generateReasoning(
            memory,
            contextualFactors,
            context,
          );
          const confidence = this.calculateConfidence(contextualFactors, memory);
    
          matches.push({
            memory,
            relevanceScore,
            contextualFactors,
            reasoning,
            confidence,
          });
        }
    
        // Sort by relevance score (descending)
        return matches.sort((a, b) => b.relevanceScore - a.relevanceScore);
      }
    
      /**
       * Calculate contextual factors for scoring
       */
      private async calculateContextualFactors(
        memory: MemoryEntry,
        query: string,
        context: RetrievalContext,
      ): Promise<ContextualMatch["contextualFactors"]> {
        const semantic = await this.calculateSemanticSimilarity(memory, query);
        const temporal = await this.calculateTemporalRelevance(memory, context);
        const structural = this.calculateStructuralRelevance(memory, context);
        const intentional = this.calculateIntentionalRelevance(memory, context);
    
        return { semantic, temporal, structural, intentional };
      }
    
      /**
       * Calculate semantic similarity using simple text matching
       * (In a production system, this would use embeddings)
       */
      private async calculateSemanticSimilarity(
        memory: MemoryEntry,
        query: string,
      ): Promise<number> {
        const queryTerms = query.toLowerCase().split(/\s+/);
        const memoryText = JSON.stringify(memory.data).toLowerCase();
        const metadataText = JSON.stringify(memory.metadata).toLowerCase();
    
        let matches = 0;
        for (const term of queryTerms) {
          if (memoryText.includes(term) || metadataText.includes(term)) {
            matches++;
          }
        }
    
        return queryTerms.length > 0 ? matches / queryTerms.length : 0;
      }
    
      /**
       * Calculate temporal relevance based on recency and context
       */
      private calculateTemporalRelevance(
        memory: MemoryEntry,
        context: RetrievalContext,
      ): Promise<number> {
        const memoryDate = new Date(memory.timestamp);
        const now = new Date();
        const daysSince =
          (now.getTime() - memoryDate.getTime()) / (1000 * 60 * 60 * 24);
    
        // Base score decreases with age
        let score = Math.exp(-daysSince / 30); // Half-life of 30 days
    
        // Boost for explicit temporal preferences
        if (context.temporalContext?.recency === "recent" && daysSince <= 7) {
          score *= 1.5;
        } else if (
          context.temporalContext?.recency === "historical" &&
          daysSince >= 90
        ) {
          score *= 1.3;
        }
    
        // Consider time constraints
        if (context.sessionContext?.timeConstraints) {
          const urgencyMultiplier =
            context.userIntent?.urgency === "high" ? 1.2 : 1.0;
          score *= urgencyMultiplier;
        }
    
        return Promise.resolve(Math.min(score, 1.0));
      }
    
      /**
       * Calculate structural relevance based on project similarity
       */
      private calculateStructuralRelevance(
        memory: MemoryEntry,
        context: RetrievalContext,
      ): number {
        if (!context.currentProject) return 0.5; // Neutral when no project context
    
        let score = 0;
        let factors = 0;
    
        // Language match
        if (memory.data.language?.primary === context.currentProject.language) {
          score += 0.4;
        }
        factors++;
    
        // Framework match
        if (
          context.currentProject.framework &&
          memory.data.framework?.name === context.currentProject.framework
        ) {
          score += 0.3;
        }
        factors++;
    
        // Size similarity
        if (context.currentProject.size) {
          const memorySize = this.categorizeProjectSize(
            memory.data.stats?.files || 0,
          );
          if (memorySize === context.currentProject.size) {
            score += 0.2;
          }
        }
        factors++;
    
        // Type relevance
        if (
          memory.type === "analysis" &&
          context.userIntent?.action === "analyze"
        ) {
          score += 0.1;
        } else if (
          memory.type === "recommendation" &&
          context.userIntent?.action === "recommend"
        ) {
          score += 0.1;
        }
        factors++;
    
        return factors > 0 ? score / factors : 0;
      }
    
      /**
       * Calculate intentional relevance based on user intent
       */
      private calculateIntentionalRelevance(
        memory: MemoryEntry,
        context: RetrievalContext,
      ): number {
        if (!context.userIntent) return 0.5; // Neutral when no intent
    
        let score = 0;
    
        // Action alignment
        const actionTypeMap = {
          analyze: ["analysis", "evaluation"],
          recommend: ["recommendation"],
          deploy: ["deployment"],
          troubleshoot: ["deployment", "configuration"],
          learn: ["analysis", "recommendation"],
        };
    
        const relevantTypes = actionTypeMap[context.userIntent.action] || [];
        if (relevantTypes.includes(memory.type)) {
          score += 0.5;
        }
    
        // Experience level alignment
        if (context.userIntent.experience === "novice") {
          // Prefer simpler, more successful cases
          if (
            memory.data.status === "success" ||
            memory.data.complexity !== "complex"
          ) {
            score += 0.3;
          }
        } else if (context.userIntent.experience === "expert") {
          // Prefer complex or edge cases
          if (
            memory.data.complexity === "complex" ||
            memory.metadata.tags?.includes("advanced")
          ) {
            score += 0.3;
          }
        }
    
        // Urgency consideration
        if (context.userIntent.urgency === "high") {
          // Prefer recent, successful cases
          const daysSince =
            (Date.now() - new Date(memory.timestamp).getTime()) /
            (1000 * 60 * 60 * 24);
          if (daysSince <= 7 && memory.data.status === "success") {
            score += 0.2;
          }
        }
    
        return Math.min(score, 1.0);
      }
    
      /**
       * Calculate overall relevance score
       */
      private calculateOverallRelevance(
        factors: ContextualMatch["contextualFactors"],
      ): number {
        // Weighted combination of factors
        const weights = {
          semantic: 0.3,
          temporal: 0.2,
          structural: 0.3,
          intentional: 0.2,
        };
    
        return (
          factors.semantic * weights.semantic +
          factors.temporal * weights.temporal +
          factors.structural * weights.structural +
          factors.intentional * weights.intentional
        );
      }
    
      /**
       * Generate reasoning for why a memory was selected
       */
      private generateReasoning(
        memory: MemoryEntry,
        factors: ContextualMatch["contextualFactors"],
        context: RetrievalContext,
      ): string[] {
        const reasoning: string[] = [];
    
        if (factors.semantic > 0.7) {
          reasoning.push("High semantic similarity to query");
        }
    
        if (factors.temporal > 0.8) {
          reasoning.push("Recently relevant information");
        }
    
        if (factors.structural > 0.6) {
          reasoning.push(
            `Similar project structure (${
              memory.data.language?.primary || "unknown"
            })`,
          );
        }
    
        if (factors.intentional > 0.7) {
          reasoning.push(
            `Matches user intent for ${
              context.userIntent?.action || "general"
            } action`,
          );
        }
    
        if (
          memory.data.status === "success" &&
          context.userIntent?.urgency === "high"
        ) {
          reasoning.push("Proven successful approach for urgent needs");
        }
    
        if (memory.metadata.ssg && context.currentProject?.framework) {
          reasoning.push(
            `Experience with ${memory.metadata.ssg} for similar projects`,
          );
        }
    
        return reasoning.length > 0 ? reasoning : ["General relevance to query"];
      }
    
      /**
       * Calculate confidence in the match
       */
      private calculateConfidence(
        factors: ContextualMatch["contextualFactors"],
        memory: MemoryEntry,
      ): number {
        let confidence = (factors.semantic + factors.structural) / 2;
    
        // Boost confidence for successful outcomes
        if (memory.data.status === "success") {
          confidence *= 1.2;
        }
    
        // Boost confidence for recent data
        const daysSince =
          (Date.now() - new Date(memory.timestamp).getTime()) /
          (1000 * 60 * 60 * 24);
        if (daysSince <= 30) {
          confidence *= 1.1;
        }
    
        // Boost confidence for rich metadata
        if (memory.metadata.tags && memory.metadata.tags.length > 2) {
          confidence *= 1.05;
        }
    
        return Math.min(confidence, 1.0);
      }
    
      /**
       * Generate insights from retrieved matches
       */
      private async generateInsights(
        matches: ContextualMatch[],
        context: RetrievalContext,
      ): Promise<RetrievalResult["insights"]> {
        const patterns: string[] = [];
        const recommendations: string[] = [];
        const gaps: string[] = [];
    
        if (matches.length === 0) {
          gaps.push("No relevant memories found for current context");
          recommendations.push(
            "Consider expanding search criteria or building more experience",
          );
          return { patterns, recommendations, gaps };
        }
    
        // Analyze patterns in successful matches
        const successfulMatches = matches.filter(
          (m) => m.memory.data.status === "success" && m.relevanceScore > 0.6,
        );
    
        if (successfulMatches.length >= 2) {
          // Find common SSGs
          const ssgs = new Map<string, number>();
          successfulMatches.forEach((match) => {
            if (match.memory.metadata.ssg) {
              ssgs.set(
                match.memory.metadata.ssg,
                (ssgs.get(match.memory.metadata.ssg) || 0) + 1,
              );
            }
          });
    
          if (ssgs.size > 0) {
            const topSSG = Array.from(ssgs.entries()).sort(
              ([, a], [, b]) => b - a,
            )[0];
            patterns.push(
              `${topSSG[0]} appears in ${topSSG[1]} successful similar projects`,
            );
            recommendations.push(
              `Consider ${topSSG[0]} based on successful precedents`,
            );
          }
    
          // Find common success factors
          const commonFactors = this.findCommonSuccessFactors(successfulMatches);
          patterns.push(...commonFactors);
        }
    
        // Identify gaps
        if (
          context.userIntent?.action === "deploy" &&
          matches.filter((m) => m.memory.type === "deployment").length === 0
        ) {
          gaps.push("Limited deployment experience for similar projects");
          recommendations.push(
            "Proceed cautiously with deployment and document the process",
          );
        }
    
        if (
          context.userIntent?.experience === "novice" &&
          matches.every((m) => m.confidence < 0.7)
        ) {
          gaps.push("Limited beginner-friendly resources for this context");
          recommendations.push(
            "Consider consulting documentation or seeking expert guidance",
          );
        }
    
        return { patterns, recommendations, gaps };
      }
    
      /**
       * Find common success factors across matches
       */
      private findCommonSuccessFactors(matches: ContextualMatch[]): string[] {
        const factors: string[] = [];
    
        const hasTests = matches.filter(
          (m) => m.memory.data.testing?.hasTests,
        ).length;
        if (hasTests / matches.length > 0.7) {
          factors.push("Projects with testing have higher success rates");
        }
    
        const hasCI = matches.filter((m) => m.memory.data.ci?.hasCI).length;
        if (hasCI / matches.length > 0.6) {
          factors.push("CI/CD adoption correlates with deployment success");
        }
    
        const simpleProjects = matches.filter(
          (m) => m.memory.data.complexity !== "complex",
        ).length;
        if (simpleProjects / matches.length > 0.8) {
          factors.push("Simpler project structures show more reliable outcomes");
        }
    
        return factors;
      }
    
      /**
       * Categorize project size for comparison
       */
      private categorizeProjectSize(
        fileCount: number,
      ): "small" | "medium" | "large" {
        if (fileCount < 50) return "small";
        if (fileCount < 200) return "medium";
        return "large";
      }
    
      /**
       * Get contextual suggestions for improving retrieval
       */
      async getSuggestions(context: RetrievalContext): Promise<{
        queryImprovements: string[];
        contextEnhancements: string[];
        learningOpportunities: string[];
      }> {
        const suggestions = {
          queryImprovements: [] as string[],
          contextEnhancements: [] as string[],
          learningOpportunities: [] as string[],
        };
    
        // Analyze current context completeness
        if (!context.currentProject) {
          suggestions.contextEnhancements.push(
            "Provide current project information for better matches",
          );
        }
    
        if (!context.userIntent) {
          suggestions.contextEnhancements.push(
            "Specify your intent (analyze, recommend, deploy, etc.) for targeted results",
          );
        }
    
        if (!context.temporalContext) {
          suggestions.contextEnhancements.push(
            "Set temporal preferences (recent vs. historical) for relevance",
          );
        }
    
        // Analyze retrieval patterns
        const recentSearches = await this.memoryManager.search("search", {
          sortBy: "timestamp",
        });
        if (recentSearches.length < 5) {
          suggestions.learningOpportunities.push(
            "System will improve with more usage and data",
          );
        }
    
        // Check for data gaps
        if (context.currentProject?.language) {
          const languageMemories = await this.memoryManager.search(
            context.currentProject.language,
          );
          if (languageMemories.length < 3) {
            suggestions.learningOpportunities.push(
              `More experience needed with ${context.currentProject.language} projects`,
            );
          }
        }
    
        return suggestions;
      }
    
      /**
       * Clear embedding cache
       */
      clearCache(): void {
        this.embeddingCache.clear();
      }
    
      /**
       * Get retrieval statistics
       */
      getStatistics(): {
        cacheSize: number;
        cacheHitRate: number;
        averageRetrievalTime: number;
        commonContextTypes: Record<string, number>;
      } {
        // This would track actual usage statistics in a real implementation
        return {
          cacheSize: this.embeddingCache.size,
          cacheHitRate: 0.85, // Placeholder
          averageRetrievalTime: 150, // ms
          commonContextTypes: {
            project_analysis: 45,
            ssg_recommendation: 38,
            deployment_troubleshooting: 12,
            learning_assistance: 5,
          },
        };
      }
    }

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/tosin2013/documcp'

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