Skip to main content
Glama

Think

think

Break down complex problems into manageable steps with structured reasoning, enabling planning with revisions, analysis with course correction, and confidence tracking for multi-step challenges.

Instructions

Add a thought to the reasoning chain.

Use for:

  • Complex multi-step problems

  • Planning with room for revision

  • Analysis that might need course correction

Features:

  • subSteps: Micro-action plan (max 5)

  • alternatives: Quick options comparison

  • quickExtension: Inline critique/elaboration (replaces extend_thought tool)

Returns progress bar, confidence, and next action hint.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
thoughtYesYour thinking step
nextThoughtNeededYesMore thinking needed?
thoughtNumberYesCurrent number
totalThoughtsYesEstimated total
confidenceNoConfidence 1-10
subStepsNoMicro-actions (max 5)
alternativesNoOptions to compare
goalNoSession goal (set on first thought)
quickExtensionNoInline extension (replaces extend_thought)
isRevisionNoRevising previous thought?
revisesThoughtNoWhich thought to revise
branchFromThoughtNoBranch point
branchIdNoBranch identifier
showTreeNoShow ASCII tree

Implementation Reference

  • The core handler function processThought in ThinkingService that executes the logic for the 'think' tool. Handles validation, branching, stagnation detection, coaching nudges, quick extensions, dead-end warnings, and returns progress information.
    processThought(input: ThoughtInput): ThinkingResult {
      // Smart auto-reset: if thoughtNumber=1 and history not empty, start fresh session
      // SYNCHRONOUS reset to avoid race conditions
      if (input.thoughtNumber === 1 && this.thoughtHistory.length > 0 && !input.isRevision) {
        console.error('šŸ”„ New session detected (thought #1), clearing previous state...');
        this.reset(); // Synchronous clear
        // Clear persistence file asynchronously (non-blocking)
        this.clearSession().catch((err) => console.error('Failed to clear session:', err));
      }
    
      // Generate new sessionId for first thought of session (v2.11.0)
      if (input.thoughtNumber === 1 && !input.isRevision) {
        this.currentSessionId = new Date().toISOString();
        console.error(`šŸ†” New session ID: ${this.currentSessionId}`);
      }
    
      // Auto-adjust totalThoughts if exceeded
      if (input.thoughtNumber > input.totalThoughts) {
        input.totalThoughts = input.thoughtNumber;
      }
    
      // EMPTY THOUGHT VALIDATION - reject meaningless input
      if (!input.thought || !input.thought.trim()) {
        return {
          thoughtNumber: input.thoughtNumber,
          totalThoughts: input.totalThoughts,
          nextThoughtNeeded: true,
          branches: Array.from(this.branches.keys()),
          thoughtHistoryLength: this.thoughtHistory.length,
          contextSummary: this.generateContextSummary(),
          thoughtTree: this.generateAsciiTree(),
          isError: true,
          errorMessage: '🚫 REJECTED: Empty thought. Provide meaningful content.',
          warning: '🚫 REJECTED: Empty thought. Provide meaningful content.',
        };
      }
    
      // SESSION GOAL (v2.10.0) - Save goal from first thought
      if (input.goal && input.thoughtNumber === 1) {
        this.sessionGoal = input.goal;
        console.error(`šŸŽÆ Session goal set: ${input.goal.substring(0, 50)}...`);
      }
    
      // HARD DUPLICATE REJECTION - reject before adding to history
      const duplicateError = this.checkDuplicateStrict(input);
      if (duplicateError) {
        return {
          thoughtNumber: input.thoughtNumber,
          totalThoughts: input.totalThoughts,
          nextThoughtNeeded: true,
          branches: Array.from(this.branches.keys()),
          thoughtHistoryLength: this.thoughtHistory.length,
          contextSummary: this.generateContextSummary(),
          thoughtTree: this.generateAsciiTree(),
          isError: true,
          errorMessage: duplicateError,
          warning: duplicateError,
        };
      }
    
      // BRANCH VALIDATION - reject if branchFromThought references non-existent thought
      const branchError = this.validateBranchSource(input);
      if (branchError) {
        return {
          thoughtNumber: input.thoughtNumber,
          totalThoughts: input.totalThoughts,
          nextThoughtNeeded: true,
          branches: Array.from(this.branches.keys()),
          thoughtHistoryLength: this.thoughtHistory.length,
          contextSummary: this.generateContextSummary(),
          thoughtTree: this.generateAsciiTree(),
          isError: true,
          errorMessage: branchError,
          warning: branchError,
        };
      }
    
      // Validate sequence (includes shallow/circular revision check)
      const validation = this.validateSequence(input);
      
      // HARD REJECTION for invalid revisions (shallow, circular, non-existent target)
      if (!validation.valid && input.isRevision) {
        return {
          thoughtNumber: input.thoughtNumber,
          totalThoughts: input.totalThoughts,
          nextThoughtNeeded: true,
          branches: Array.from(this.branches.keys()),
          thoughtHistoryLength: this.thoughtHistory.length,
          contextSummary: this.generateContextSummary(),
          thoughtTree: this.generateAsciiTree(),
          isError: true,
          errorMessage: validation.warning,
          warning: validation.warning,
        };
      }
    
      // Check for stagnation before adding new thought
      const stagnationWarning = this.detectStagnation(input.thought);
    
      // Create record with timestamp and sessionId (v2.11.0)
      const record: ThoughtRecord = {
        ...input,
        timestamp: Date.now(),
        sessionId: this.currentSessionId,
      };
    
      this.thoughtHistory.push(record);
      this.lastThoughtNumber = input.thoughtNumber;
    
      // Invalidate Fuse index for recall_thought (v3.4.0)
      this.invalidateFuseIndex();
    
      // Handle branching
      if (input.branchFromThought && input.branchId) {
        const branchHistory = this.branches.get(input.branchId) ?? [];
        branchHistory.push(record);
        this.branches.set(input.branchId, branchHistory);
      }
    
      // Log to stderr for debugging
      const prefix = input.isRevision
        ? 'šŸ”„ Revision'
        : input.branchFromThought
          ? '🌿 Branch'
          : 'šŸ’­ Thought';
      const confidenceStr = input.confidence ? ` [conf: ${input.confidence}/10]` : '';
      console.error(
        `${prefix} ${input.thoughtNumber}/${input.totalThoughts}${confidenceStr}: ${input.thought.substring(0, 80)}...`
      );
    
      // Save session asynchronously (fire and forget)
      this.saveSession().catch((err) => console.error('Failed to save session:', err));
    
      // Combine warnings
      const warning = [validation.warning, stagnationWarning].filter(Boolean).join('\n');
    
      // QUICK EXTENSION (v3.1.0) - Process inline extension if provided
      if (input.quickExtension) {
        this.processQuickExtension(input.thoughtNumber, input.quickExtension);
      }
    
      // LATERAL THINKING TRIGGER - check for overly linear thinking
      // v5.0.1: Pass isFinishing flag to show subSteps check only at end
      let systemAdvice = this.checkLateralThinking(!input.nextThoughtNeeded);
    
      // DEAD ENDS CHECK (v3.3.0) - Warn if heading towards rejected path
      const deadEndWarning = this.checkDeadEnds(input.thoughtNumber);
      if (deadEndWarning) {
        systemAdvice = systemAdvice ? `${systemAdvice}\n${deadEndWarning}` : deadEndWarning;
      }
    
      // PROACTIVE COACH v3.1.0 - Enhanced nudges for thought quality
      const coachNudges = this.generateProactiveNudges(input);
      if (coachNudges) {
        systemAdvice = systemAdvice ? `${systemAdvice}\n${coachNudges}` : coachNudges;
      }
    
      // PRE-CONSOLIDATION AUDIT (v2.9.2) - Quality gate before finishing
      if (!input.nextThoughtNeeded) {
        const auditAdvice = this.performPreConsolidationAudit();
        if (auditAdvice) {
          systemAdvice = systemAdvice ? `${systemAdvice}\n${auditAdvice}` : auditAdvice;
        }
      }
    
      // v4.6.0: Generate nudge only if no other warnings/advice (avoid noise)
      const shouldSkipNudge = !!(warning || systemAdvice);
      const nudge = this.nudgeService.generateNudge(input, this.getCurrentSessionThoughts(), shouldSkipNudge);
    
      return {
        thoughtNumber: input.thoughtNumber,
        totalThoughts: input.totalThoughts,
        nextThoughtNeeded: input.nextThoughtNeeded,
        branches: Array.from(this.branches.keys()),
        thoughtHistoryLength: this.thoughtHistory.length,
        contextSummary: this.generateContextSummary(),
        thoughtTree: this.generateAsciiTree(),
        // v4.2.0: Lazy Mermaid - removed from hot path, use export_session for diagrams
        thoughtTreeMermaid: undefined,
        warning: warning || undefined,
        averageConfidence: this.calculateAverageConfidence(),
        systemAdvice,
        sessionGoal: this.sessionGoal,
        nudge,
      };
    }
  • src/index.ts:68-127 (registration)
    Registration of the 'think' tool using McpServer.registerTool, including title, description, inputSchema, and the handler callback.
    server.registerTool('think', { title: 'Think', description: THINK_DESCRIPTION, inputSchema: thinkSchema },
      async (args) => {
        try {
          const result = thinkingService.processThought({
            thought: args.thought as string,
            nextThoughtNeeded: args.nextThoughtNeeded as boolean,
            thoughtNumber: args.thoughtNumber as number,
            totalThoughts: args.totalThoughts as number,
            isRevision: args.isRevision as boolean | undefined,
            revisesThought: args.revisesThought as number | undefined,
            branchFromThought: args.branchFromThought as number | undefined,
            branchId: args.branchId as string | undefined,
            confidence: args.confidence as number | undefined,
            subSteps: args.subSteps as string[] | undefined,
            alternatives: args.alternatives as string[] | undefined,
            goal: args.goal as string | undefined,
            quickExtension: args.quickExtension as QuickExtension | undefined,
          });
    
          if (result.isError) {
            return { content: [{ type: 'text' as const, text: `Error: ${result.errorMessage}` }], isError: true };
          }
    
          // Progress bar
          const current = result.thoughtNumber;
          const total = result.totalThoughts;
          const filled = Math.round((current / total) * 10);
          const progressBar = 'ā–ˆ'.repeat(filled) + 'ā–‘'.repeat(10 - filled);
    
          // Status detection
          const hasBlocker = result.warning?.includes('BLOCKER') || result.warning?.includes('STAGNATION');
          const status = hasBlocker ? 'BLOCKED' : result.warning ? 'WARNING' : 'OK';
          const nearEnd = current >= total - 1;
          const nextAction = hasBlocker ? 'revise' : nearEnd ? 'think_done' : 'continue';
    
          // Conditional tree - ONLY when explicitly requested
          const showTree = args.showTree === true;
    
          // v5.0.1: Show systemAdvice ONLY when there are real issues
          const conf = result.averageConfidence ?? 10;
          const hasRealIssue = status !== 'OK' || conf < 7;
          const showAdvice = hasRealIssue && result.systemAdvice;
    
          const text = [
            result.sessionGoal ? `šŸŽÆ ${result.sessionGoal}\n` : '',
            `[${progressBar}] ${current}/${total}`,
            result.averageConfidence ? ` | conf: ${result.averageConfidence}/10` : '',
            result.warning ? `\nāš ļø ${result.warning}` : '',
            showTree ? `\n\n${result.thoughtTree}` : '',
            showAdvice ? `\n${result.systemAdvice}` : '',
            result.nudge ? `\nšŸ’” ${result.nudge}` : '',
            `\n[${status}|next:${nextAction}]`,
          ].filter(Boolean).join('');
    
          return { content: [{ type: 'text' as const, text }] };
        } catch (error) {
          return { content: [{ type: 'text' as const, text: `Error: ${error instanceof Error ? error.message : 'Unknown'}` }], isError: true };
        }
      }
    );
  • Zod input schema definition for the 'think' tool parameters.
    const thinkSchema = {
      thought: z.string().describe('Your thinking step'),
      nextThoughtNeeded: z.boolean().describe('More thinking needed?'),
      thoughtNumber: z.number().int().min(1).describe('Current number'),
      totalThoughts: z.number().int().min(1).describe('Estimated total'),
      confidence: z.number().min(1).max(10).optional().describe('Confidence 1-10'),
      subSteps: z.array(z.string()).max(5).optional().describe('Micro-actions (max 5)'),
      alternatives: z.array(z.string()).max(5).optional().describe('Options to compare'),
      goal: z.string().optional().describe('Session goal (set on first thought)'),
      quickExtension: z.object({
        type: z.enum(['critique', 'elaboration', 'correction', 'alternative_scenario', 'assumption_testing', 'innovation', 'optimization', 'polish']),
        content: z.string(),
        impact: z.enum(['low', 'medium', 'high', 'blocker']).optional(),
      }).optional().describe('Inline extension (replaces extend_thought)'),
      isRevision: z.boolean().optional().describe('Revising previous thought?'),
      revisesThought: z.number().int().min(1).optional().describe('Which thought to revise'),
      branchFromThought: z.number().int().min(1).optional().describe('Branch point'),
      branchId: z.string().optional().describe('Branch identifier'),
      showTree: z.boolean().optional().describe('Show ASCII tree'),
    };

Tool Definition Quality

Score is being calculated. Check back soon.

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/GofMan5/think-mcp'

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