Skip to main content
Glama

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'), };

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