Skip to main content
Glama
cyqlelabs

MCP Dual-Cycle Reasoner

by cyqlelabs

store_experience

Capture and store problem-solution pairs with outcomes to enhance AI reasoning and recovery using case-based reasoning within the MCP Dual-Cycle Reasoner framework.

Instructions

Store a case for future case-based reasoning

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
outcomeYesWhether the solution was successful
problem_descriptionYesSimple description of the problem
solutionYesWhat action resolved the issue

Implementation Reference

  • The handler function in the Adjudicator class that implements the core logic for storing an experience case: extracts semantic features, computes confidence scores, checks for duplicates, enhances the case, and stores it in the case base with pruning.
    async storeExperience(case_: Case): Promise<void> {
      if (!this.isInitialized) {
        await this.initialize();
      }
      // Extract semantic features for better retrieval
      try {
        // Check if semantic analyzer is available
        if (!semanticAnalyzer.isReady()) {
          throw new Error('SemanticAnalyzer is not ready');
        }
    
        const problemFeatures = await semanticAnalyzer.extractSemanticFeatures(
          case_.problem_description,
          this.semanticIntents
        );
        const solutionFeatures = await semanticAnalyzer.extractSemanticFeatures(
          case_.solution,
          this.semanticIntents
        );
    
        // Combine features from both problem and solution
        const combinedFeatures = {
          intents: [...(problemFeatures.intents || []), ...(solutionFeatures.intents || [])],
          sentiment: case_.outcome ? 'positive' : 'negative',
          keywords: this.extractKeywords(case_.problem_description + ' ' + case_.solution),
        };
    
        // Calculate initial confidence score based on various factors
        const confidenceScore = this.calculateCaseConfidence(
          case_,
          problemFeatures,
          solutionFeatures
        );
    
        // Enhance the case with computed features
        const enhancedCase: Case = {
          ...case_,
          semantic_features: combinedFeatures as any,
          confidence_score: confidenceScore,
          usage_count: 0,
          success_rate: case_.outcome ? 1.0 : 0.0,
        };
    
        // Check for duplicates and quality
        if (this.isDuplicateCase(enhancedCase)) {
          this.updateExistingCase(enhancedCase);
          return;
        }
    
        if (confidenceScore < 0.3) {
          console.warn('Case rejected due to low confidence score:', confidenceScore);
          return;
        }
    
        // Store the case
        this.caseBase.push(enhancedCase);
        this.updateIndex(enhancedCase);
    
        // Manage case base size with intelligent pruning
        if (this.caseBase.length > 1000) {
          this.pruneeCaseBase();
        }
      } catch (error) {
        console.error('Error storing experience:', error);
        // Fallback to simple storage
        this.caseBase.push(case_);
      }
    }
  • Zod schema defining the input parameters for the store_experience tool, including problem_description, solution, outcome, context, and difficulty_level.
    export const StoreExperienceInputSchema = z.object({
      problem_description: z.string().describe(DESCRIPTIONS.PROBLEM_DESCRIPTION),
      solution: z.string().describe(DESCRIPTIONS.SOLUTION),
      outcome: z.boolean().describe(DESCRIPTIONS.OUTCOME),
      context: z.string().optional().describe('The context in which this case occurred'),
      difficulty_level: z
        .enum(['low', 'medium', 'high'])
        .optional()
        .describe('The difficulty level of this case'),
    });
  • src/server.ts:470-524 (registration)
    Registers the 'store_experience' tool with FastMCP server, including schema (overridden but references StoreExperienceInputSchema), description, and execute handler that validates input, constructs Case, and delegates to Adjudicator.storeExperience.
    private addStoreExperienceTool(): void {
      this.server.addTool({
        name: 'store_experience',
        description: 'Store a case for future case-based reasoning',
        parameters: z.object({
          problem_description: z.string().describe(DESCRIPTIONS.PROBLEM_DESCRIPTION),
          solution: z.string().describe(DESCRIPTIONS.SOLUTION),
          outcome: z.boolean().describe(DESCRIPTIONS.OUTCOME),
        }),
        annotations: {
          title: 'Store Experience Case',
          readOnlyHint: false,
          destructiveHint: false,
          idempotentHint: false,
          openWorldHint: false,
        },
        execute: async (args, { log, session }) => {
          try {
            const sessionEngine = this.getSessionEngine(session);
            const sessionId = this.sessionIds.get(session);
            const validatedArgs = StoreExperienceInputSchema.parse(args);
    
            log.info('Storing experience case', {
              problemDescription: validatedArgs.problem_description,
              solution: validatedArgs.solution,
              outcome: validatedArgs.outcome,
              sessionId,
            });
    
            const caseData = {
              problem_description: validatedArgs.problem_description,
              solution: validatedArgs.solution,
              outcome: validatedArgs.outcome,
              context: validatedArgs.context,
              difficulty_level: validatedArgs.difficulty_level,
            };
    
            const adjudicator = (sessionEngine as any).adjudicator;
            const storedCase = CaseSchema.parse(caseData);
            await adjudicator.storeExperience(storedCase);
    
            log.info('Experience case stored successfully', {
              caseId: storedCase.id || 'new',
              outcome: storedCase.outcome ? 'success' : 'failure',
            });
    
            return `✅ Experience stored: Case ${storedCase.id || 'new'} added to case base`;
          } catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            log.error('Failed to store experience', { error: errorMessage });
            throw new UserError(`Failed to store experience: ${errorMessage}`);
          }
        },
      });
    }
Behavior3/5

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

Annotations cover key behavioral traits: readOnlyHint=false (mutation), destructiveHint=false (non-destructive), idempotentHint=false (non-idempotent), and openWorldHint=false (closed-world). The description adds minimal context by implying persistence for 'future case-based reasoning,' but doesn't detail side effects like storage limits, auth needs, or error handling. No contradiction with annotations exists.

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?

The description is a single, efficient sentence: 'Store a case for future case-based reasoning.' It's front-loaded with the core action and purpose, with no wasted words. Every element earns its place by clearly stating the tool's function.

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

Completeness3/5

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

Given the tool's moderate complexity (mutation with three parameters), annotations provide safety and idempotency info, but no output schema exists. The description is minimal, covering only the basic purpose without details on return values or error cases. It's adequate as a starting point but lacks depth for full contextual understanding.

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 description coverage is 100%, with clear descriptions for all three parameters: outcome, problem_description, and solution. The description doesn't add meaning beyond the schema, such as formatting examples or constraints. With high schema coverage, the baseline score of 3 is appropriate, as the description doesn't compensate but doesn't need to.

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

Purpose4/5

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

The description clearly states the tool's purpose: 'Store a case for future case-based reasoning.' It specifies the verb 'store' and the resource 'a case,' making the action explicit. However, it doesn't differentiate from sibling tools like 'retrieve_similar_cases,' which is related but serves a different function (retrieval vs. storage).

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites, such as when case storage is appropriate, or contrast it with siblings like 'configure_detection' or 'process_trace_update.' Usage is implied only by the purpose, with no explicit context or exclusions provided.

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

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