Skip to main content
Glama

think-strategies

Apply structured reasoning strategies like Chain of Thought or ReAct to solve complex problems through guided think-act-reflect workflows.

Instructions

Core thinking tool for structured problem-solving using 10 reasoning strategies. Choose your strategy (linear, chain_of_thought, react, rewoo, scratchpad, self_ask, self_consistency, step_back, tree_of_thoughts, trilemma) and engage in guided thinking with think→act→reflect workflows. Plan actions with 'plannedActions', integrate results with 'actionResults'. Use think-tools for utilities and think-session-manager for session persistence.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
thoughtYes
nextThoughtNeededNo
thoughtNumberNo
totalThoughtsNo
strategyNo
sessionPurposeNo
qualityRatingNo
actionNo
observationNo
finalAnswerNo
plannedActionsNo
actionResultsNo

Implementation Reference

  • Zod schema defining the input parameters for the think-strategies tool, including core fields like thought, strategy, numbering, and optional strategy-specific and action-related parameters.
    const thinkingSchema = {
      thought: z.string(),
      nextThoughtNeeded: z.boolean().optional(),  // Made optional for auto-completion
      thoughtNumber: z.number().optional(),         // Made optional for auto-completion
      totalThoughts: z.number().optional(),         // Made optional for auto-completion
      strategy: z.string().optional(),              // Made optional for auto-completion
      
      // Session metadata for knowledge building
      sessionPurpose: z.string().optional(),
      qualityRating: z.object({
        usefulness: z.number().min(1).max(5).optional(),
        effectiveness: z.number().min(1).max(5).optional(),
        clarity: z.number().min(1).max(5).optional(),
        insights: z.number().min(1).max(5).optional(),
        strategyFit: z.number().min(1).max(5).optional(),
        efficiency: z.number().min(1).max(5).optional(),
        actionability: z.number().min(1).max(5).optional(),
        reflection: z.string().optional()
      }).optional(),
      
      // Strategy-specific parameters
      action: z.string().optional(),
      observation: z.string().optional(),
      finalAnswer: z.string().optional(),
      
      // Action integration for think→act→reflect workflow
      plannedActions: z.array(z.object({
        server: z.string(),
        tool: z.string(),
        parameters: z.record(z.any()).optional(),
        expectedInfo: z.string().optional()
      })).optional(),
      
      actionResults: z.array(z.object({
        success: z.boolean(),
        result: z.any().optional(),
        error: z.string().optional(),
        server: z.string(),
        tool: z.string(),
        timestamp: z.string()
      })).optional()
    };
  • index.js:1715-1736 (registration)
    Registration of the 'think-strategies' MCP tool, including name, long description, schema reference, and inline handler function that delegates to SequentialThinkingServer.processThought.
    server.tool(
      "think-strategies", 
      "Core thinking tool for structured problem-solving using 10 reasoning strategies. Choose your strategy (linear, chain_of_thought, react, rewoo, scratchpad, self_ask, self_consistency, step_back, tree_of_thoughts, trilemma) and engage in guided thinking with think→act→reflect workflows. Plan actions with 'plannedActions', integrate results with 'actionResults'. Use think-tools for utilities and think-session-manager for session persistence.",
      thinkingSchema,
      async (args) => {
        try {
          console.error("DEBUG: Tool handler called with args:", JSON.stringify(args, null, 2));
          const result = await thinkingServer.processThought(args);
          console.error("DEBUG: Tool handler result:", JSON.stringify(result, null, 2));
          return {
            content: [{
              type: "text",
              text: JSON.stringify(result, null, 2)
            }]
          };
        } catch (error) {
          console.error("DEBUG: Error in tool handler:", error);
          console.error("DEBUG: Error stack:", error.stack);
          throw error;
        }
      }
    );
  • Core handler implementation in SequentialThinkingServer.processThought(): validates input with auto-completion, manages strategy stages and transitions, handles semantic parameter routing, processes thoughts, formats output, saves sessions, and builds semantic responses for next steps.
    async processThought(input) {
        try {
            console.error("DEBUG: processThought called with:", JSON.stringify(input, null, 2));
            const validatedInput = this.validateThoughtData(input);
            
            // If we're waiting for strategy selection, return early
            if (validatedInput.status === 'waiting_for_strategy') {
                return validatedInput;
            }
            
            // Log strategy start
            if (this.stageManager.isFirstStage() && validatedInput.thoughtNumber === 1) {
                console.error(chalk.green(`🎯 Starting ${this.strategy} strategy`));
                console.error(chalk.cyan(`📍 Stage: ${this.stageManager.getCurrentStage()}`));
            }
            
            // Normal thought processing
            if (validatedInput.thoughtNumber > validatedInput.totalThoughts) {
                validatedInput.totalThoughts = validatedInput.thoughtNumber;
            }
            
            // Update dual numbering system
            this.absoluteThoughtNumber++;
            
            // Handle branching - reset sequence number for new branches
            if (validatedInput.branchFromThought && validatedInput.branchId) {
                // Reset sequence numbering for new branch
                this.sequenceThoughtNumber = 1;
                console.error(chalk.green(`🌿 New branch ${validatedInput.branchId} started from thought A${validatedInput.branchFromThought}`));
            } else {
                this.sequenceThoughtNumber++;
            }
            
            // Add dual numbering to validated input
            validatedInput.absoluteNumber = this.absoluteThoughtNumber;
            validatedInput.sequenceNumber = this.sequenceThoughtNumber;
            
            this.thoughtHistory.push(validatedInput);
            
            if (validatedInput.branchFromThought && validatedInput.branchId) {
                if (!this.branches[validatedInput.branchId]) {
                    this.branches[validatedInput.branchId] = [];
                }
                this.branches[validatedInput.branchId].push(validatedInput);
            }
            
            const formattedThought = this.formatThought({
                ...validatedInput,
                strategy: this.strategy,
                currentStage: this.stageManager.getCurrentStage()
            });
            console.error(formattedThought);
            
            // Handle session metadata updates
            if (validatedInput.sessionPurpose) {
                this.sessionPurpose = validatedInput.sessionPurpose;
            }
            if (validatedInput.qualityRating) {
                this.qualityRating = validatedInput.qualityRating;
            }
    
            // Save session incrementally after each thought (for resilience)
            if (this.storage) {
                try {
                    const savedPath = await this.storage.saveSession(
                        this.sessionId,
                        this.thoughtHistory,
                        this.branches,
                        this.sessionPurpose,
                        this.qualityRating,
                        this.sessionStartTime
                    );
                    
                    // Only log completion message for final thought
                    if (!validatedInput.nextThoughtNeeded) {
                        console.error(chalk.green(`✅ Thinking session completed and saved to: ${savedPath}`));
                    }
                } catch (saveError) {
                    console.error(chalk.red(`❌ Error saving thinking session: ${saveError.message}`));
                }
            }
            
            // Build semantic routing response
            const semanticResponse = this.parameterRouter.buildSemanticResponse(
                this.strategy,
                this.stageManager.getCurrentStage(),
                this.thoughtHistory,
                this.sessionId
            );
            
            // Build response with auto-completion hints if present
            const response = {
                ...semanticResponse,
                thoughtNumber: validatedInput.thoughtNumber,
                totalThoughts: validatedInput.totalThoughts,
                nextThoughtNeeded: validatedInput.nextThoughtNeeded,
                sessionSaved: !validatedInput.nextThoughtNeeded
            };
            
            // Include auto-completion hints to help agents
            if (validatedInput._autoCompletionHints) {
                response.autoCompletionNote = "🔮 Parameters auto-completed from context. Include these in your next call:";
                response.autoCompleted = validatedInput._autoCompletionHints;
            }
            
            return response;
        }
        catch (error) {
            console.error("DEBUG: Error in processThought:", error);
            console.error("DEBUG: Error stack:", error.stack);
            return {
                error: error instanceof Error ? error.message : String(error),
                status: 'failed'
            };
        }
    }
  • SequentialThinkingServer class providing the main state management, session handling, stage transitions, MCP client integration, action planning/execution, parameter inference, and thought processing logic for the think-strategies tool.
    class SequentialThinkingServer {
        thoughtHistory = [];
        branches = {};
        sessionId = null;
        storage = null;
        stageManager = null;
        parameterRouter = null;
        strategy = null;
        isInitialized = false;
        
        // Session metadata for knowledge building
        sessionPurpose = null;
        qualityRating = null;
        sessionStartTime = null;
        
        // MCP client integration
        mcpClientManager = null;
        pendingActions = [];
        actionResults = [];
        
        // Dual numbering system
        absoluteThoughtNumber = 0;
        sequenceThoughtNumber = 0;
        
        constructor(storage) {
            this.storage = storage;
            this.parameterRouter = new ParameterRouter();
            this.mcpClientManager = new MCPClientManager();
            console.error(chalk.blue("Sequential Thinking Server initialized - waiting for strategy selection"));
        }
        
        resetSession(strategy) {
            if (!strategy) {
                throw new Error("Strategy must be specified when resetting session");
            }
            
            this.thoughtHistory = [];
            this.branches = {};
            this.sessionId = this.generateSessionId(strategy);
            this.strategy = strategy;
            this.stageManager = new StageManager(strategy);
            this.isInitialized = true;
            
            // Reset session metadata
            this.sessionPurpose = null;
            this.qualityRating = null;
            this.sessionStartTime = new Date().toISOString();
            
            // Reset dual numbering system
            this.absoluteThoughtNumber = 0;
            this.sequenceThoughtNumber = 0;
            
            // Reset action tracking
            this.pendingActions = [];
            this.actionResults = [];
            
            console.error(`New thinking session started with ID: ${this.sessionId} using strategy: ${strategy}`);
        }
        
        generateSessionId(strategy) {
            const timestamp = new Date().toISOString()
                .replace(/[-:]/g, '')
                .replace('T', '-')
                .replace(/\..+/, '');
            return `${strategy}-session-${timestamp}`;
        }
    
        // Action planning and execution methods
        async connectToMCPServer(serverName, command, args = []) {
            try {
                await this.mcpClientManager.connectToServer(serverName, command, args);
                return {
                    success: true,
                    message: `Connected to ${serverName}`,
                    connectedServers: this.mcpClientManager.getConnectedServers()
                };
            } catch (error) {
                return {
                    success: false,
                    error: error.message,
                    connectedServers: this.mcpClientManager.getConnectedServers()
                };
            }
        }
    
        async executeAction(action) {
            const { server, tool, parameters, context } = action;
            
            if (!this.mcpClientManager.isConnected(server)) {
                throw new Error(`Not connected to MCP server: ${server}`);
            }
    
            console.error(chalk.blue(`🎯 Executing planned action: ${server}.${tool}`));
            const result = await this.mcpClientManager.executeToolCall(server, tool, parameters, {
                ...context,
                sessionId: this.sessionId,
                strategy: this.strategy,
                thoughtNumber: this.absoluteThoughtNumber
            });
    
            this.actionResults.push(result);
            console.error(chalk.green(`✅ Action completed: ${server}.${tool}`));
            
            return result;
        }
    
        async executePendingActions() {
            if (this.pendingActions.length === 0) {
                return [];
            }
    
            console.error(chalk.cyan(`⚡ Executing ${this.pendingActions.length} pending actions`));
            const results = [];
    
            for (const action of this.pendingActions) {
                try {
                    const result = await this.executeAction(action);
                    results.push(result);
                } catch (error) {
                    console.error(chalk.red(`❌ Action failed: ${error.message}`));
                    results.push({
                        success: false,
                        error: error.message,
                        action: action
                    });
                }
            }
    
            this.pendingActions = []; // Clear pending actions after execution
            return results;
        }
    
        planAction(server, tool, parameters, expectedInfo) {
            const action = {
                server,
                tool,
                parameters,
                expectedInfo,
                plannedAt: new Date().toISOString(),
                context: {
                    sessionId: this.sessionId,
                    strategy: this.strategy,
                    currentStage: this.stageManager.getCurrentStage()
                }
            };
    
            this.pendingActions.push(action);
            console.error(chalk.yellow(`📋 Planned action: ${server}.${tool} - ${expectedInfo}`));
            
            return action;
        }
    
        inferMissingParameters(input) {
            const inferred = { ...input };
            const autoCompleted = {};
            
            // Auto-complete strategy from context or parameter hints
            if (!inferred.strategy) {
                // Priority 1: Use active session strategy
                if (this.isInitialized && this.strategy) {
                    inferred.strategy = this.strategy;
                    autoCompleted.strategy = this.strategy;
                }
                // Priority 2: Infer from strategy-specific parameters
                else if (inferred.action && ['thought', 'action', 'observation'].includes(inferred.action)) {
                    inferred.strategy = 'react';
                    autoCompleted.strategy = 'react (from action parameter)';
                }
                else if (inferred.approaches || inferred.approachId || inferred.evaluationScore) {
                    inferred.strategy = 'tree_of_thoughts';
                    autoCompleted.strategy = 'tree_of_thoughts (from ToT parameters)';
                }
                else if (inferred.objectives || inferred.tradeOffMatrix || inferred.equilibriumReached) {
                    inferred.strategy = 'trilemma';
                    autoCompleted.strategy = 'trilemma (from objectives)';
                }
                else if (inferred.reasoningApproach || inferred.currentElement || inferred.cycleNumber) {
                    inferred.strategy = 'cyclic_reasoning';
                    autoCompleted.strategy = 'cyclic_reasoning (from cycle parameters)';
                }
                else if (inferred.subQuestion || inferred.subQuestionAnswer) {
                    inferred.strategy = 'self_ask';
                    autoCompleted.strategy = 'self_ask (from sub-questions)';
                }
                else if (inferred.generalPrinciple) {
                    inferred.strategy = 'step_back';
                    autoCompleted.strategy = 'step_back (from principle)';
                }
                else if (inferred.reasoningPathId || inferred.pathAnswers) {
                    inferred.strategy = 'self_consistency';
                    autoCompleted.strategy = 'self_consistency (from paths)';
                }
                else if (inferred.planningPhase || inferred.toolCalls) {
                    inferred.strategy = 'rewoo';
                    autoCompleted.strategy = 'rewoo (from planning)';
                }
                else if (inferred.stateVariables) {
                    inferred.strategy = 'scratchpad';
                    autoCompleted.strategy = 'scratchpad (from state)';
                }
                // Priority 3: Analyze thought content
                else if (inferred.thought) {
                    const thoughtLower = inferred.thought.toLowerCase();
                    if (thoughtLower.includes('observe') || thoughtLower.includes('action:')) {
                        inferred.strategy = 'react';
                        autoCompleted.strategy = 'react (from thought keywords)';
                    } else if (thoughtLower.includes('approach') || thoughtLower.includes('branch')) {
                        inferred.strategy = 'tree_of_thoughts';
                        autoCompleted.strategy = 'tree_of_thoughts (from thought keywords)';
                    } else if (thoughtLower.includes('step back') || thoughtLower.includes('principle')) {
                        inferred.strategy = 'step_back';
                        autoCompleted.strategy = 'step_back (from thought keywords)';
                    } else if (thoughtLower.includes('trade-off') || thoughtLower.includes('balance')) {
                        inferred.strategy = 'trilemma';
                        autoCompleted.strategy = 'trilemma (from thought keywords)';
                    } else {
                        inferred.strategy = 'chain_of_thought';
                        autoCompleted.strategy = 'chain_of_thought (default)';
                    }
                }
                else {
                    inferred.strategy = 'chain_of_thought';
                    autoCompleted.strategy = 'chain_of_thought (default)';
                }
            }
            
            // Auto-complete thoughtNumber from session history
            if (inferred.thoughtNumber === undefined || inferred.thoughtNumber === null) {
                if (this.thoughtHistory && this.thoughtHistory.length > 0) {
                    const lastThought = this.thoughtHistory[this.thoughtHistory.length - 1];
                    inferred.thoughtNumber = (lastThought.thoughtNumber || 0) + 1;
                    autoCompleted.thoughtNumber = `${inferred.thoughtNumber} (continued from ${lastThought.thoughtNumber})`;
                } else {
                    inferred.thoughtNumber = 1;
                    autoCompleted.thoughtNumber = '1 (session start)';
                }
            }
            
            // Auto-complete totalThoughts based on context
            if (inferred.totalThoughts === undefined || inferred.totalThoughts === null) {
                if (inferred.nextThoughtNeeded === false) {
                    inferred.totalThoughts = inferred.thoughtNumber;
                    autoCompleted.totalThoughts = `${inferred.totalThoughts} (marked complete)`;
                } else {
                    // Strategy-specific estimates for typical completion
                    const strategyEstimates = {
                        linear: 3,
                        chain_of_thought: 5,
                        react: 7,
                        rewoo: 6,
                        scratchpad: 5,
                        self_ask: 8,
                        self_consistency: 6,
                        step_back: 4,
                        tree_of_thoughts: 10,
                        trilemma: 8,
                        cyclic_reasoning: 9
                    };
                    const estimate = strategyEstimates[inferred.strategy] || 5;
                    inferred.totalThoughts = Math.max(inferred.thoughtNumber + 1, estimate);
                    autoCompleted.totalThoughts = `${inferred.totalThoughts} (estimated for ${inferred.strategy})`;
                }
            }
            
            // Auto-complete nextThoughtNeeded from context
            if (typeof inferred.nextThoughtNeeded !== 'boolean') {
                if (inferred.finalAnswer || inferred.equilibriumReached || inferred.hypothesis) {
                    inferred.nextThoughtNeeded = false;
                    autoCompleted.nextThoughtNeeded = 'false (solution reached)';
                } else if (inferred.thoughtNumber >= inferred.totalThoughts) {
                    inferred.nextThoughtNeeded = false;
                    autoCompleted.nextThoughtNeeded = 'false (reached total)';
                } else {
                    inferred.nextThoughtNeeded = true;
                    autoCompleted.nextThoughtNeeded = 'true (continuing)';
                }
            }
            
            // Provide default thought if missing
            if (!inferred.thought) {
                inferred.thought = 'Continuing analysis...';
                autoCompleted.thought = 'default placeholder';
            }
            
            // Store auto-completion hints for response
            if (Object.keys(autoCompleted).length > 0) {
                inferred._autoCompletionHints = autoCompleted;
                console.error(chalk.cyan('🔮 Parameters auto-completed:'));
                Object.entries(autoCompleted).forEach(([key, value]) => {
                    console.error(chalk.cyan(`   • ${key}: ${value}`));
                });
            }
            
            return inferred;
        }
    
        validateThoughtData(input) {
            // Apply intelligent parameter inference to auto-complete missing values
            const data = this.inferMissingParameters(input);
            
            // Check if this is a strategy selection or reset request
            if (data.strategy && (!data.thoughtNumber || data.thoughtNumber === 1)) {
                // Capture sessionPurpose before reset
                const capturedSessionPurpose = data.sessionPurpose;
                
                this.resetSession(data.strategy);
                
                // Restore sessionPurpose after reset
                if (capturedSessionPurpose) {
                    this.sessionPurpose = capturedSessionPurpose;
                }
                
                // Build semantic response for initial state
                const semanticResponse = this.parameterRouter.buildSemanticResponse(
                    this.strategy,
                    this.stageManager.getCurrentStage(),
                    this.thoughtHistory,
                    this.sessionId
                );
                
                return {
                    ...semanticResponse,
                    thought: data.thought || '',
                    thoughtNumber: 1,
                    totalThoughts: data.totalThoughts || 1,
                    nextThoughtNeeded: true
                };
            }
            
            // Check if a strategy has been selected
            if (!this.isInitialized) {
                return {
                    error: "No strategy selected. Please select a strategy first.",
                    availableStrategies: Object.keys(strategyConfig.strategyStages),
                    status: 'waiting_for_strategy',
                    nextThoughtNeeded: true
                };
            }
            
            // Validate required parameters for all strategies (now with self-healing applied)
            if (!data.thought || typeof data.thought !== 'string') {
                throw new Error('Invalid thought: must be a string');
            }
            if (!data.thoughtNumber || typeof data.thoughtNumber !== 'number') {
                throw new Error('Invalid thoughtNumber: must be a number');
            }
            if (!data.totalThoughts || typeof data.totalThoughts !== 'number') {
                throw new Error('Invalid totalThoughts: must be a number');
            }
            if (typeof data.nextThoughtNeeded !== 'boolean') {
                throw new Error('Invalid nextThoughtNeeded: must be a boolean');
            }
            
            // Determine action taken based on provided parameters
            const action = this.parameterRouter.determineActionTaken(
                this.strategy,
                this.stageManager.getCurrentStage(),
                data
            );
            
            // Handle automatic stage transitions
            if (action && action.nextState && !action.isGlobal) {
                // Transition to next state if action determines it
                if (this.stageManager.canTransitionTo(action.nextState)) {
                    this.stageManager.transitionTo(action.nextState);
                    console.error(chalk.cyan(`🔄 Transitioned to: ${action.nextState} (via ${action.actionName})`));
                }
            } else if (data.currentStage && data.currentStage !== this.stageManager.getCurrentStage()) {
                // Manual stage transition (backward compatibility)
                if (!this.stageManager.canTransitionTo(data.currentStage)) {
                    throw new Error(`Invalid stage transition from ${this.stageManager.getCurrentStage()} to ${data.currentStage}`);
                }
                this.stageManager.transitionTo(data.currentStage);
            } else if (this.strategy === 'cyclic_reasoning') {
                // Handle cyclic reasoning automatic transitions
                const nextStage = this.stageManager.determineNextCyclicStage(data);
                if (nextStage && this.stageManager.canTransitionTo(nextStage)) {
                    this.stageManager.transitionTo(nextStage);
                    console.error(chalk.cyan(`🔄 Cyclic transition to: ${nextStage}`));
                }
            }
            
            // Handle strategy switching
            if (action && action.actionName === 'switch_strategy' && data.strategy !== this.strategy) {
                const preserveHistory = data.preserveHistory || false;
                const oldHistory = preserveHistory ? [...this.thoughtHistory] : [];
                this.resetSession(data.strategy);
                if (preserveHistory) {
                    this.thoughtHistory = oldHistory;
                }
                console.error(chalk.magenta(`🔀 Switched strategy to: ${data.strategy}`));
            }
            
            // Handle action planning - if plannedActions are provided, add them to pending actions
            if (data.plannedActions && Array.isArray(data.plannedActions)) {
                for (const actionPlan of data.plannedActions) {
                    const { server, tool, parameters, expectedInfo } = actionPlan;
                    if (server && tool) {
                        this.planAction(server, tool, parameters, expectedInfo || `Execute ${server}.${tool}`);
                    }
                }
            }
            
            // Handle action results - if actionResults are provided, integrate them
            if (data.actionResults && Array.isArray(data.actionResults)) {
                this.actionResults.push(...data.actionResults);
                console.error(chalk.green(`📥 Integrated ${data.actionResults.length} action results`));
            }
            
            // Return validated data
            return {
                ...data,
                strategy: this.strategy,
                currentStage: this.stageManager.getCurrentStage(),
                pendingActions: this.pendingActions.length,
                actionResults: this.actionResults
            };
        }
    
        formatThought(thoughtData) {
            const { 
                thoughtNumber, 
                totalThoughts, 
                thought, 
                isRevision, 
                revisesThought, 
                branchFromThought, 
                branchId,
                strategy,
                currentStage,
                nextThoughtNeeded,
                absoluteNumber,
                sequenceNumber
            } = thoughtData;
            
            let prefix = '';
            let context = '';
            
            if (isRevision) {
                prefix = chalk.yellow('🔄 Revision');
                context = ` (revising thought ${revisesThought})`;
            }
            else if (branchFromThought) {
                prefix = chalk.green('🌿 Branch');
                context = ` (from thought ${branchFromThought}, ID: ${branchId})`;
            }
            else {
                prefix = chalk.blue('💭 Thought');
                context = '';
            }
            
            const strategyInfo = chalk.magenta(`[${strategy}]`);
            const stageInfo = chalk.cyan(`[Stage: ${currentStage}]`);
            const dualNumbering = absoluteNumber ? chalk.gray(`[A${absoluteNumber}|S${sequenceNumber}]`) : '';
            const header = `${prefix} ${thoughtNumber}/${totalThoughts}${context} ${dualNumbering} ${strategyInfo} ${stageInfo}`;
            const border = '─'.repeat(Math.max(header.length, (thought || '').length) + 4);
            
            // Add continuation hint if more thoughts are needed
            let output = `
    ┌${border}┐
    │ ${header} │
    ├${border}┤
    │ ${(thought || '').padEnd(border.length - 2)} │`;
    
            if (nextThoughtNeeded) {
                const continuationHint = "Continue with your next thought step without stopping";
                const hintBorder = '─'.repeat(Math.max(continuationHint.length + 4, border.length));
                output += `
    ├${hintBorder}┤
    │ ${chalk.green(continuationHint).padEnd(hintBorder.length - 2)} │`;
            }
            
            output += `
    └${border}┘`;
            
            return output;
        }
    
        async processThought(input) {
            try {
                console.error("DEBUG: processThought called with:", JSON.stringify(input, null, 2));
                const validatedInput = this.validateThoughtData(input);
                
                // If we're waiting for strategy selection, return early
                if (validatedInput.status === 'waiting_for_strategy') {
                    return validatedInput;
                }
                
                // Log strategy start
                if (this.stageManager.isFirstStage() && validatedInput.thoughtNumber === 1) {
                    console.error(chalk.green(`🎯 Starting ${this.strategy} strategy`));
                    console.error(chalk.cyan(`📍 Stage: ${this.stageManager.getCurrentStage()}`));
                }
                
                // Normal thought processing
                if (validatedInput.thoughtNumber > validatedInput.totalThoughts) {
                    validatedInput.totalThoughts = validatedInput.thoughtNumber;
                }
                
                // Update dual numbering system
                this.absoluteThoughtNumber++;
                
                // Handle branching - reset sequence number for new branches
                if (validatedInput.branchFromThought && validatedInput.branchId) {
                    // Reset sequence numbering for new branch
                    this.sequenceThoughtNumber = 1;
                    console.error(chalk.green(`🌿 New branch ${validatedInput.branchId} started from thought A${validatedInput.branchFromThought}`));
                } else {
                    this.sequenceThoughtNumber++;
                }
                
                // Add dual numbering to validated input
                validatedInput.absoluteNumber = this.absoluteThoughtNumber;
                validatedInput.sequenceNumber = this.sequenceThoughtNumber;
                
                this.thoughtHistory.push(validatedInput);
                
                if (validatedInput.branchFromThought && validatedInput.branchId) {
                    if (!this.branches[validatedInput.branchId]) {
                        this.branches[validatedInput.branchId] = [];
                    }
                    this.branches[validatedInput.branchId].push(validatedInput);
                }
                
                const formattedThought = this.formatThought({
                    ...validatedInput,
                    strategy: this.strategy,
                    currentStage: this.stageManager.getCurrentStage()
                });
                console.error(formattedThought);
                
                // Handle session metadata updates
                if (validatedInput.sessionPurpose) {
                    this.sessionPurpose = validatedInput.sessionPurpose;
                }
                if (validatedInput.qualityRating) {
                    this.qualityRating = validatedInput.qualityRating;
                }
    
                // Save session incrementally after each thought (for resilience)
                if (this.storage) {
                    try {
                        const savedPath = await this.storage.saveSession(
                            this.sessionId,
                            this.thoughtHistory,
                            this.branches,
                            this.sessionPurpose,
                            this.qualityRating,
                            this.sessionStartTime
                        );
                        
                        // Only log completion message for final thought
                        if (!validatedInput.nextThoughtNeeded) {
                            console.error(chalk.green(`✅ Thinking session completed and saved to: ${savedPath}`));
                        }
                    } catch (saveError) {
                        console.error(chalk.red(`❌ Error saving thinking session: ${saveError.message}`));
                    }
                }
                
                // Build semantic routing response
                const semanticResponse = this.parameterRouter.buildSemanticResponse(
                    this.strategy,
                    this.stageManager.getCurrentStage(),
                    this.thoughtHistory,
                    this.sessionId
                );
                
                // Build response with auto-completion hints if present
                const response = {
                    ...semanticResponse,
                    thoughtNumber: validatedInput.thoughtNumber,
                    totalThoughts: validatedInput.totalThoughts,
                    nextThoughtNeeded: validatedInput.nextThoughtNeeded,
                    sessionSaved: !validatedInput.nextThoughtNeeded
                };
                
                // Include auto-completion hints to help agents
                if (validatedInput._autoCompletionHints) {
                    response.autoCompletionNote = "🔮 Parameters auto-completed from context. Include these in your next call:";
                    response.autoCompleted = validatedInput._autoCompletionHints;
                }
                
                return response;
            }
            catch (error) {
                console.error("DEBUG: Error in processThought:", error);
                console.error("DEBUG: Error stack:", error.stack);
                return {
                    error: error instanceof Error ? error.message : String(error),
                    status: 'failed'
                };
            }
        }
    }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'think→act→reflect workflows' and integration with planned actions and results, but lacks critical behavioral details: it doesn't specify whether this tool performs read-only operations or mutations, what happens to session state, whether there are rate limits, authentication requirements, or what the output format looks like. For a complex tool with 12 parameters, this is a significant gap.

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

Conciseness3/5

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

The description is reasonably concise with three sentences, but could be more front-loaded. The first sentence effectively introduces the core purpose, but the subsequent sentences mix usage guidance and parameter references without clear structural separation. Some phrases like 'engage in guided thinking' are somewhat vague and could be more precise.

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

Completeness2/5

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

Given the tool's complexity (12 parameters with nested objects, no output schema, no annotations), the description is inadequate. It doesn't explain the tool's behavioral characteristics, provides minimal parameter guidance, and offers no information about return values or error handling. For a sophisticated thinking tool with workflow capabilities, much more context is needed about how the tool actually operates and what agents should expect.

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

Parameters2/5

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

With 0% schema description coverage and 12 parameters (many complex nested objects), the description provides minimal parameter guidance. It mentions 'strategy' parameter with 10 options and references 'plannedActions' and 'actionResults,' but doesn't explain the purpose or relationships of most parameters like 'thought,' 'qualityRating,' 'finalAnswer,' or the various numeric fields. The description fails to compensate for the complete lack of schema descriptions.

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 as 'Core thinking tool for structured problem-solving using 10 reasoning strategies' with specific verbs ('engage in guided thinking') and resources ('think→act→reflect workflows'). It distinguishes from siblings by mentioning 'think-tools for utilities and think-session-manager for session persistence,' though it doesn't fully explain how this tool differs functionally from those siblings beyond being the 'core' tool.

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 provides clear context for when to use this tool ('structured problem-solving') and explicitly names alternatives ('think-tools for utilities and think-session-manager for session persistence'), giving good guidance on tool selection. However, it doesn't specify when NOT to use this tool or provide detailed exclusion criteria, keeping it from a perfect score.

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/aaronsb/think-strategies'

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