Skip to main content
Glama
cyqlelabs

MCP Dual-Cycle Reasoner

by cyqlelabs

retrieve_similar_cases

Use this tool to find and retrieve similar cases from the case base based on a provided problem description. Input a description and specify the maximum number of results for precise matching.

Instructions

Retrieve similar cases from the case base

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
max_resultsNoMaximum number of cases to return
problem_descriptionYesSimple description of the problem

Implementation Reference

  • The execute handler for the 'retrieve_similar_cases' tool. It validates input using the schema, retrieves the session's DualCycleEngine, calls getSimilarCases on it with filters, simplifies the result by removing internal fields, and returns JSON.
    execute: async (args, { log, reportProgress, session }) => { try { const sessionEngine = this.getSessionEngine(session); const sessionId = this.sessionIds.get(session); const validatedArgs = RetrieveSimilarCasesInputSchema.parse(args); log.info('Retrieving similar cases', { problemDescription: validatedArgs.problem_description, maxResults: validatedArgs.max_results, sessionId, }); await reportProgress({ progress: 0, total: 2 }); const filters = { context_filter: validatedArgs.context_filter, difficulty_filter: validatedArgs.difficulty_filter, outcome_filter: validatedArgs.outcome_filter, min_similarity: validatedArgs.min_similarity, }; const result = await sessionEngine.getSimilarCases( validatedArgs.problem_description, validatedArgs.max_results, filters ); await reportProgress({ progress: 2, total: 2 }); log.info('Similar cases retrieved', { casesFound: result.length, maxResults: validatedArgs.max_results, }); const simplifiedResult = result.map((caseItem: any) => { const { semantic_features, similarity_metrics, ...rest } = caseItem; return rest; }); return JSON.stringify(simplifiedResult, null, 2); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); log.error('Failed to retrieve similar cases', { error: errorMessage }); throw new UserError(`Failed to retrieve similar cases: {errorMessage}`); } },
  • src/server.ts:527-588 (registration)
    The registration of the 'retrieve_similar_cases' tool using FastMCP's addTool method within addRetrieveSimilarCasesTool().
    this.server.addTool({ name: 'retrieve_similar_cases', description: 'Retrieve similar cases from the case base', parameters: z.object({ problem_description: z.string().describe(DESCRIPTIONS.PROBLEM_DESCRIPTION), max_results: z.number().optional().default(5).describe(DESCRIPTIONS.MAX_RESULTS), }), annotations: { title: 'Retrieve Similar Cases', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, execute: async (args, { log, reportProgress, session }) => { try { const sessionEngine = this.getSessionEngine(session); const sessionId = this.sessionIds.get(session); const validatedArgs = RetrieveSimilarCasesInputSchema.parse(args); log.info('Retrieving similar cases', { problemDescription: validatedArgs.problem_description, maxResults: validatedArgs.max_results, sessionId, }); await reportProgress({ progress: 0, total: 2 }); const filters = { context_filter: validatedArgs.context_filter, difficulty_filter: validatedArgs.difficulty_filter, outcome_filter: validatedArgs.outcome_filter, min_similarity: validatedArgs.min_similarity, }; const result = await sessionEngine.getSimilarCases( validatedArgs.problem_description, validatedArgs.max_results, filters ); await reportProgress({ progress: 2, total: 2 }); log.info('Similar cases retrieved', { casesFound: result.length, maxResults: validatedArgs.max_results, }); const simplifiedResult = result.map((caseItem: any) => { const { semantic_features, similarity_metrics, ...rest } = caseItem; return rest; }); return JSON.stringify(simplifiedResult, null, 2); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); log.error('Failed to retrieve similar cases', { error: errorMessage }); throw new UserError(`Failed to retrieve similar cases: {errorMessage}`); } }, }); }
  • Zod schema for validating input parameters to the retrieve_similar_cases tool.
    export const RetrieveSimilarCasesInputSchema = z.object({ problem_description: z.string().describe(DESCRIPTIONS.PROBLEM_DESCRIPTION), max_results: z.number().default(5).describe(DESCRIPTIONS.MAX_RESULTS), context_filter: z.string().optional().describe('Filter cases by context'), difficulty_filter: z .enum(['low', 'medium', 'high']) .optional() .describe('Filter cases by difficulty level'), outcome_filter: z.boolean().optional().describe('Filter cases by outcome (success/failure)'), min_similarity: z.number().min(0).max(1).optional().describe('Minimum similarity threshold'), });
  • Wrapper method in DualCycleEngine that delegates to Adjudicator's retrieveSimilarCases.
    async getSimilarCases( problemDescription: string, maxResults: number = 5, filters: { context_filter?: string; difficulty_filter?: 'low' | 'medium' | 'high'; outcome_filter?: boolean; min_similarity?: number; } = {} ): Promise<Case[]> { return await this.adjudicator.retrieveSimilarCases( problemDescription, maxResults, filters, this.sessionId ); }
  • Core implementation in Adjudicator class performing semantic feature extraction, filtering, enhanced similarity calculation (semantic + traditional NLP), sorting, and fallback retrieval.
    async retrieveSimilarCases( problemDescription: string, maxResults: number = 5, filters: { context_filter?: string; difficulty_filter?: 'low' | 'medium' | 'high'; outcome_filter?: boolean; min_similarity?: number; } = {}, sessionId?: string ): Promise<Case[]> { if (!this.isInitialized) { await this.initialize(); } try { // Check if semantic analyzer is available if (!semanticAnalyzer.isReady()) { throw new Error('SemanticAnalyzer is not ready'); } // Extract semantic features from the query const queryFeatures = await semanticAnalyzer.extractSemanticFeatures( problemDescription, this.semanticIntents ); // Filter cases based on provided filters let filteredCases = this.caseBase; if (filters.context_filter) { filteredCases = filteredCases.filter( (case_) => case_.context?.includes(filters.context_filter!) || case_.problem_description.includes(filters.context_filter!) ); } if (filters.difficulty_filter) { filteredCases = filteredCases.filter( (case_) => case_.difficulty_level === filters.difficulty_filter ); } if (filters.outcome_filter !== undefined) { filteredCases = filteredCases.filter((case_) => case_.outcome === filters.outcome_filter); } // Calculate enhanced similarity scores const scoredCases = await Promise.all( filteredCases.map(async (case_) => { const rawSimilarity = await this.calculateEnhancedSimilarity( problemDescription, case_.problem_description, queryFeatures, case_.semantic_features, sessionId ); return { case: case_, similarity: rawSimilarity, rawSimilarity: rawSimilarity, }; }) ); // Filter by minimum similarity threshold (more restrictive due to inflated semantic scores) const minSimilarity = filters.min_similarity || 0.6; const validCases = scoredCases.filter((item) => item.similarity >= minSimilarity); // Sort by similarity and success rate const sortedCases = validCases.sort((a, b) => { // Primary sort by similarity if (Math.abs(a.similarity - b.similarity) > 0.05) { return b.similarity - a.similarity; } // Secondary sort by success rate for similar cases const aSuccessRate = a.case.success_rate || (a.case.outcome ? 1 : 0); const bSuccessRate = b.case.success_rate || (b.case.outcome ? 1 : 0); return bSuccessRate - aSuccessRate; }); // Update usage statistics and calculate dynamic confidence/validation scores const results = sortedCases.slice(0, maxResults); results.forEach((item) => { item.case.usage_count = (item.case.usage_count || 0) + 1; // Calculate dynamic confidence score based on similarity to query // Higher similarity = higher confidence in the match const similarityConfidence = Math.min(1.0, item.rawSimilarity * 1.2); // Boost good similarities const usageBonus = Math.min(0.1, (item.case.usage_count || 0) * 0.02); const outcomeBonus = item.case.outcome ? 0.1 : 0; // Dynamic confidence score reflecting match quality item.case.confidence_score = Math.max( 0, Math.min(1, similarityConfidence + usageBonus + outcomeBonus) ); // Add similarity metrics to the case for reference item.case.similarity_metrics = { ...item.case.similarity_metrics, raw_similarity: item.rawSimilarity, combined_similarity: item.rawSimilarity, }; }); return results.map((item) => item.case); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error( 'Error retrieving similar cases, falling back to simple matching:', errorMessage ); // Fallback to simple similarity matching return this.fallbackRetrieveSimilarCases(problemDescription, maxResults); } }

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/cyqlelabs/mcp-dual-cycle-reasoner'

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