Skip to main content
Glama
index.ts31.9 kB
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from "@modelcontextprotocol/sdk/types.js"; import chalk from 'chalk'; interface AtomData { atomId: string; content: string; atomType: 'premise' | 'reasoning' | 'hypothesis' | 'verification' | 'conclusion'; dependencies: string[]; confidence: number; created: number; isVerified: boolean; depth?: number; } interface DecompositionState { originalAtomId: string; subAtoms: string[]; isCompleted: boolean; } class AtomOfThoughtsServer { protected atoms: Record<string, AtomData> = {}; protected atomOrder: string[] = []; private verifiedConclusions: string[] = []; private decompositionStates: Record<string, DecompositionState> = {}; public maxDepth: number = 5; // Default maximum depth private currentDecompositionId: string | null = null; constructor(maxDepth?: number) { if (maxDepth !== undefined && maxDepth > 0) { this.maxDepth = maxDepth; } } protected validateAtomData(input: unknown): AtomData { const data = input as Record<string, unknown>; if (!data.atomId || typeof data.atomId !== 'string') { throw new Error('Invalid atomId: must be a string'); } if (!data.content || typeof data.content !== 'string') { throw new Error('Invalid content: must be a string'); } if (!data.atomType || typeof data.atomType !== 'string' || !['premise', 'reasoning', 'hypothesis', 'verification', 'conclusion'].includes(data.atomType as string)) { throw new Error('Invalid atomType: must be one of premise, reasoning, hypothesis, verification, conclusion'); } if (!Array.isArray(data.dependencies)) { throw new Error('Invalid dependencies: must be an array of atom IDs'); } if (typeof data.confidence !== 'number' || data.confidence < 0 || data.confidence > 1) { throw new Error('Invalid confidence: must be a number between 0 and 1'); } return { atomId: data.atomId as string, content: data.content as string, atomType: data.atomType as 'premise' | 'reasoning' | 'hypothesis' | 'verification' | 'conclusion', dependencies: data.dependencies as string[], confidence: data.confidence as number, created: data.created as number || Date.now(), isVerified: data.isVerified as boolean || false, depth: data.depth as number | undefined, }; } protected formatAtom(atomData: AtomData): string { const { atomId, content, atomType, dependencies, confidence, isVerified, depth } = atomData; let typeColor; let typeSymbol; switch (atomType) { case 'premise': typeColor = chalk.blue; typeSymbol = '🔍'; break; case 'reasoning': typeColor = chalk.green; typeSymbol = '🧠'; break; case 'hypothesis': typeColor = chalk.yellow; typeSymbol = '💡'; break; case 'verification': typeColor = chalk.magenta; typeSymbol = '✓'; break; case 'conclusion': typeColor = chalk.red; typeSymbol = '🏆'; break; } const depthInfo = depth !== undefined ? ` [Depth: ${depth}/${this.maxDepth}]` : ''; const header = typeColor(`${typeSymbol} ${atomType.toUpperCase()}: ${atomId}${depthInfo} ${isVerified ? '(✓ Verified)' : ''}`); const confidenceBar = this.generateConfidenceBar(confidence); const dependenciesText = dependencies.length > 0 ? `Dependencies: ${dependencies.join(', ')}` : 'No dependencies'; const border = '─'.repeat(Math.max(header.length, content.length, dependenciesText.length) + 4); return ` ┌${border}┐ │ ${header} │ ├${border}┤ │ ${content.padEnd(border.length - 2)} │ │ ${confidenceBar.padEnd(border.length - 2)} │ │ ${dependenciesText.padEnd(border.length - 2)} │ └${border}┘`; } private generateConfidenceBar(confidence: number): string { const barLength = 20; const filledBars = Math.round(confidence * barLength); const emptyBars = barLength - filledBars; return `Confidence: [${chalk.green('█'.repeat(filledBars))}${chalk.gray('░'.repeat(emptyBars))}] ${(confidence * 100).toFixed(0)}%`; } private validateDependencies(dependencies: string[]): boolean { return dependencies.every(depId => this.atoms[depId] !== undefined); } private updateConfidence(atomId: string, newConfidence: number) { if (this.atoms[atomId]) { this.atoms[atomId].confidence = Math.max(0, Math.min(1, newConfidence)); } } protected verifyAtom(atomId: string, isVerified: boolean) { if (this.atoms[atomId]) { this.atoms[atomId].isVerified = isVerified; if (isVerified && this.atoms[atomId].atomType === 'conclusion') { this.verifiedConclusions.push(atomId); } else if (!isVerified && this.atoms[atomId].atomType === 'conclusion') { this.verifiedConclusions = this.verifiedConclusions.filter(id => id !== atomId); } // Trigger contraction if a verification atom verifies a hypothesis if (isVerified && this.atoms[atomId].atomType === 'verification') { const verifiedHypothesisIds = this.atoms[atomId].dependencies.filter( depId => this.atoms[depId] && this.atoms[depId].atomType === 'hypothesis' ); if (verifiedHypothesisIds.length > 0) { // Mark the hypotheses as verified verifiedHypothesisIds.forEach(hypId => { this.atoms[hypId].isVerified = true; }); // Check if this should trigger a contraction this.checkForContraction(verifiedHypothesisIds); } } } } // New method for decomposition public startDecomposition(atomId: string): string { if (!this.atoms[atomId]) { throw new Error(`Atom with ID ${atomId} not found`); } // Generate a unique ID for this decomposition const decompositionId = `decomp_${Date.now()}`; this.decompositionStates[decompositionId] = { originalAtomId: atomId, subAtoms: [], isCompleted: false }; this.currentDecompositionId = decompositionId; console.error(chalk.cyan(`🔍 Starting decomposition of atom ${atomId} (ID: ${decompositionId})`)); return decompositionId; } // Add a sub-atom to an ongoing decomposition public addToDecomposition(decompositionId: string, atomId: string): boolean { if (!this.decompositionStates[decompositionId]) { throw new Error(`Decomposition with ID ${decompositionId} not found`); } if (this.decompositionStates[decompositionId].isCompleted) { throw new Error(`Decomposition ${decompositionId} is already completed`); } if (!this.atoms[atomId]) { throw new Error(`Atom with ID ${atomId} not found`); } // Calculate depth for the new atom const parentDepth = this.atoms[this.decompositionStates[decompositionId].originalAtomId].depth || 0; this.atoms[atomId].depth = parentDepth + 1; // Check if we've hit the maximum depth if (this.atoms[atomId].depth >= this.maxDepth) { console.error(chalk.yellow(`⚠️ Maximum depth ${this.maxDepth} reached with atom ${atomId}`)); } this.decompositionStates[decompositionId].subAtoms.push(atomId); console.error(chalk.cyan(`➕ Added atom ${atomId} to decomposition ${decompositionId}`)); return true; } // Complete a decomposition public completeDecomposition(decompositionId: string): boolean { if (!this.decompositionStates[decompositionId]) { throw new Error(`Decomposition with ID ${decompositionId} not found`); } this.decompositionStates[decompositionId].isCompleted = true; if (this.currentDecompositionId === decompositionId) { this.currentDecompositionId = null; } console.error(chalk.green(`✅ Completed decomposition ${decompositionId}`)); return true; } // Contraction mechanism private checkForContraction(verifiedAtomIds: string[]): void { // Find decomposition states that have these atoms as sub-atoms for (const [decompId, state] of Object.entries(this.decompositionStates)) { if (state.isCompleted && verifiedAtomIds.some(id => state.subAtoms.includes(id)) && this.areAllSubAtomsVerified(state.subAtoms)) { // All sub-atoms are verified, perform contraction this.performContraction(decompId); } } } private areAllSubAtomsVerified(atomIds: string[]): boolean { return atomIds.every(id => this.atoms[id] && this.atoms[id].isVerified); } private performContraction(decompositionId: string): void { const state = this.decompositionStates[decompositionId]; if (!state) return; const originalAtom = this.atoms[state.originalAtomId]; if (!originalAtom) return; // Calculate combined confidence from sub-atoms const subAtomConfidences = state.subAtoms.map(id => this.atoms[id]?.confidence || 0); const averageConfidence = subAtomConfidences.reduce((sum, conf) => sum + conf, 0) / subAtomConfidences.length; // Mark the original atom as verified with the calculated confidence originalAtom.confidence = averageConfidence; originalAtom.isVerified = true; console.error(chalk.magenta(`🔄 Contracted decomposition ${decompositionId} back to atom ${state.originalAtomId} with confidence ${(averageConfidence * 100).toFixed(0)}%`)); // If the contracted atom is a hypothesis and is verified with high confidence, // we might want to automatically create a conclusion based on it if (originalAtom.atomType === 'hypothesis' && originalAtom.confidence >= 0.8) { this.suggestConclusion(originalAtom); } } protected suggestConclusion(verifiedHypothesis: AtomData): string { // Create a new conclusion atom based on the verified hypothesis const conclusionId = `C${Object.keys(this.atoms).filter(id => id.startsWith('C')).length + 1}`; const conclusionAtom: AtomData = { atomId: conclusionId, content: `Based on verified hypothesis: ${verifiedHypothesis.content}`, atomType: 'conclusion', dependencies: [verifiedHypothesis.atomId], confidence: verifiedHypothesis.confidence * 0.9, // Slightly lower confidence for the derived conclusion created: Date.now(), isVerified: false, depth: verifiedHypothesis.depth, // Same depth as the hypothesis }; this.atoms[conclusionId] = conclusionAtom; this.atomOrder.push(conclusionId); console.error(chalk.green(`🏆 Suggested conclusion ${conclusionId} based on verified hypothesis ${verifiedHypothesis.atomId}`)); return conclusionId; } // Check if we should automatically terminate based on depth or verified conclusions protected shouldTerminate(): boolean { // Check if we have any atoms at max depth const atMaxDepth = Object.values(this.atoms).some(atom => atom.depth !== undefined && atom.depth >= this.maxDepth); // Check if we have any verified conclusions with high confidence const hasStrongConclusion = this.verifiedConclusions.some(id => this.atoms[id] && this.atoms[id].confidence >= 0.9); return atMaxDepth || hasStrongConclusion; } // Get the termination status and reason public getTerminationStatus(): { shouldTerminate: boolean; reason: string } { const atMaxDepth = Object.values(this.atoms).some(atom => atom.depth !== undefined && atom.depth >= this.maxDepth); const hasStrongConclusion = this.verifiedConclusions.some(id => this.atoms[id] && this.atoms[id].confidence >= 0.9); if (atMaxDepth && hasStrongConclusion) { return { shouldTerminate: true, reason: 'Maximum depth reached and strong conclusion found' }; } else if (atMaxDepth) { return { shouldTerminate: true, reason: 'Maximum depth reached' }; } else if (hasStrongConclusion) { return { shouldTerminate: true, reason: 'Strong conclusion found' }; } else { return { shouldTerminate: false, reason: 'Continue reasoning' }; } } // Get the best conclusion if we should terminate public getBestConclusion(): AtomData | null { if (this.verifiedConclusions.length === 0) return null; // Sort by confidence and return the highest const sortedConclusions = [...this.verifiedConclusions] .map(id => this.atoms[id]) .filter(atom => atom !== undefined) .sort((a, b) => b.confidence - a.confidence); return sortedConclusions[0] || null; } public processAtom(input: unknown): { content: Array<{ type: string; text: string }>; isError?: boolean } { try { const validatedInput = this.validateAtomData(input); // Validate dependencies if they exist if (validatedInput.dependencies.length > 0 && !this.validateDependencies(validatedInput.dependencies)) { throw new Error('Invalid dependencies: one or more dependency atoms do not exist'); } // Set depth based on dependencies if not specified if (validatedInput.depth === undefined) { const depthsOfDependencies = validatedInput.dependencies .map(depId => (this.atoms[depId]?.depth !== undefined ? this.atoms[depId].depth! : 0)) .filter(depth => depth !== undefined); validatedInput.depth = depthsOfDependencies.length > 0 ? Math.max(...depthsOfDependencies) + 1 : 0; } // Check if this would exceed max depth if (validatedInput.depth > this.maxDepth) { console.error(chalk.yellow(`⚠️ Warning: Atom ${validatedInput.atomId} exceeds maximum depth ${this.maxDepth}`)); } // Store the atom this.atoms[validatedInput.atomId] = validatedInput; // Add to order if it's new if (!this.atomOrder.includes(validatedInput.atomId)) { this.atomOrder.push(validatedInput.atomId); } // Automatically add to current decomposition if there is one if (this.currentDecompositionId) { try { this.addToDecomposition(this.currentDecompositionId, validatedInput.atomId); } catch (e: any) { console.error(`Could not add atom to current decomposition: ${e.message}`); } } // Format and display the atom const formattedAtom = this.formatAtom(validatedInput); console.error(formattedAtom); // If it's a verification atom that verifies something, process it if (validatedInput.atomType === 'verification' && validatedInput.isVerified) { validatedInput.dependencies.forEach(depId => { if (this.atoms[depId]) { this.verifyAtom(depId, true); } }); } // Check for termination const terminationStatus = this.getTerminationStatus(); let bestConclusion = null; if (terminationStatus.shouldTerminate) { bestConclusion = this.getBestConclusion(); console.error(chalk.red(`🛑 Termination condition met: ${terminationStatus.reason}`)); if (bestConclusion) { console.error(chalk.green(`🏆 Best conclusion: ${bestConclusion.atomId} - ${bestConclusion.content}`)); } } // Get atoms required for the response const dependentAtoms = this.getDependentAtoms(validatedInput.atomId); const conflictingAtoms = this.findConflictingAtoms(validatedInput); return { content: [{ type: "text", text: JSON.stringify({ atomId: validatedInput.atomId, atomType: validatedInput.atomType, isVerified: validatedInput.isVerified, confidence: validatedInput.confidence, depth: validatedInput.depth, atomsCount: Object.keys(this.atoms).length, dependentAtoms, conflictingAtoms, verifiedConclusions: this.verifiedConclusions, terminationStatus, bestConclusion: bestConclusion ? { atomId: bestConclusion.atomId, content: bestConclusion.content, confidence: bestConclusion.confidence } : null, currentDecomposition: this.currentDecompositionId }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error), status: 'failed' }, null, 2) }], isError: true }; } } // Get atoms that depend on the given atom private getDependentAtoms(atomId: string): string[] { return Object.keys(this.atoms).filter(id => this.atoms[id].dependencies.includes(atomId) ); } // Find atoms that might conflict with this one private findConflictingAtoms(atom: AtomData): string[] { if (atom.atomType !== 'conclusion' && atom.atomType !== 'hypothesis') { return []; } // For conclusions and hypotheses, look for others with similar types but different content return Object.keys(this.atoms).filter(id => { const otherAtom = this.atoms[id]; return id !== atom.atomId && (otherAtom.atomType === 'conclusion' || otherAtom.atomType === 'hypothesis') && otherAtom.content !== atom.content && // Simple heuristic for conflict: share at least one dependency atom.dependencies.some(dep => otherAtom.dependencies.includes(dep)); }); } } // Creating a lightweight version of the AtomOfThoughtsServer class AtomOfThoughtsLightServer extends AtomOfThoughtsServer { constructor() { // Lower max depth for faster processing super(3); } // Override to simplify the verification process public processAtom(input: unknown): { content: Array<{ type: string; text: string }>; isError?: boolean } { try { const validatedInput = this.validateAtomData(input); // Store the atom this.atoms[validatedInput.atomId] = validatedInput; // Add to order if it's new if (!this.atomOrder.includes(validatedInput.atomId)) { this.atomOrder.push(validatedInput.atomId); } // Format and display the atom with simplified output const formattedAtom = this.formatAtom(validatedInput); console.error(formattedAtom); // Quick verification - if verification atom, immediately verify dependencies if (validatedInput.atomType === 'verification' && validatedInput.isVerified) { validatedInput.dependencies.forEach(depId => { if (this.atoms[depId]) { this.verifyAtom(depId, true); } }); } // Faster conclusion suggestion - if hypothesis with high confidence, suggest conclusion immediately if (validatedInput.atomType === 'hypothesis' && validatedInput.confidence >= 0.8) { this.suggestConclusion(validatedInput); } // Simplified termination check const shouldTerminate = this.shouldTerminate(); const bestConclusion = shouldTerminate ? this.getBestConclusion() : null; // Basic response with less processing return { content: [{ type: "text", text: JSON.stringify({ atomId: validatedInput.atomId, atomType: validatedInput.atomType, isVerified: validatedInput.isVerified, confidence: validatedInput.confidence, atomsCount: Object.keys(this.atoms).length, bestConclusion: bestConclusion ? { atomId: bestConclusion.atomId, content: bestConclusion.content, confidence: bestConclusion.confidence } : null }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error), status: 'failed' }, null, 2) }], isError: true }; } } } const AOT_TOOL: Tool = { name: "AoT", description: `Atom of Thoughts (AoT) is a tool for solving complex problems by decomposing them into independent, reusable atomic units of thought. Unlike traditional sequential thinking, this tool enables more powerful problem solving by allowing atomic units of thought to form dependencies with each other. When to use: - Solving problems requiring complex reasoning - Generating hypotheses that need verification from multiple perspectives - Deriving high-confidence conclusions in scenarios where accuracy is crucial - Minimizing logical errors in critical tasks - Decision-making requiring multiple verification steps Atom types: - premise: Basic assumptions or given information for problem solving - reasoning: Logical reasoning process based on other atoms - hypothesis: Proposed solutions or intermediate conclusions - verification: Process to evaluate the validity of other atoms (especially hypotheses) - conclusion: Verified hypotheses or final problem solutions Parameter descriptions: - atomId: Unique identifier for the atom (e.g., 'A1', 'H2') - content: Actual content of the atom - atomType: Type of atom (one of: premise, reasoning, hypothesis, verification, conclusion) - dependencies: List of IDs of other atoms this atom depends on - confidence: Confidence level of this atom (value between 0-1) - isVerified: Whether this atom has been verified - depth: Depth level of this atom (in the decomposition-contraction process) Additional features: 1. Decomposition-Contraction mechanism: - Decompose atoms into smaller sub-atoms and contract back after verification - startDecomposition(atomId): Start atom decomposition - addToDecomposition(decompositionId, atomId): Add sub-atom to decomposition - completeDecomposition(decompositionId): Complete decomposition process 2. Automatic termination mechanism: - Automatically terminate when reaching maximum depth or finding high-confidence conclusion - getTerminationStatus(): Return termination status and reason - getBestConclusion(): Return highest confidence conclusion Usage method: 1. Understand the problem and define necessary premise atoms 2. Create reasoning atoms based on premises 3. Create hypothesis atoms based on reasoning 4. Create verification atoms to verify hypotheses 5. Derive conclusion atoms based on verified hypotheses 6. Use atom decomposition to explore deeper when necessary 7. Present the high-confidence conclusion atom as the final answer`, inputSchema: { type: "object", properties: { atomId: { type: "string", description: "Unique identifier for the atom" }, content: { type: "string", description: "Actual content of the atom" }, atomType: { type: "string", enum: ["premise", "reasoning", "hypothesis", "verification", "conclusion"], description: "Type of atom" }, dependencies: { type: "array", items: { type: "string" }, description: "List of IDs of other atoms this atom depends on" }, confidence: { type: "number", minimum: 0, maximum: 1, description: "Confidence level of this atom (value between 0-1)" }, isVerified: { type: "boolean", description: "Whether this atom has been verified" }, depth: { type: "number", description: "Depth level of this atom in the decomposition-contraction mechanism" } }, required: ["atomId", "content", "atomType", "dependencies", "confidence"] } }; const AOT_LIGHT_TOOL: Tool = { name: "AoT-light", description: `A lightweight version of Atom of Thoughts (AoT) designed for faster processing and quicker results. This streamlined version sacrifices some depth of analysis for speed, making it ideal for time-sensitive reasoning tasks. When to use: - Quick brainstorming sessions requiring atomic thought organization - Time-sensitive problem solving where speed is prioritized over exhaustive analysis - Simpler reasoning tasks that don't require deep decomposition - Initial exploration before using the full AoT for deeper analysis - Learning or demonstration purposes where response time is important Key differences from full AoT: - Lower maximum depth (3 instead of 5) for faster processing - Simplified verification process - Immediate conclusion suggestion for high-confidence hypotheses - Reduced computational overhead and response payload - Optimized for speed rather than exhaustive analysis Atom types and parameters are the same as the full AoT tool.`, inputSchema: { type: "object", properties: { atomId: { type: "string", description: "Unique identifier for the atom" }, content: { type: "string", description: "Actual content of the atom" }, atomType: { type: "string", enum: ["premise", "reasoning", "hypothesis", "verification", "conclusion"], description: "Type of atom" }, dependencies: { type: "array", items: { type: "string" }, description: "List of IDs of other atoms this atom depends on" }, confidence: { type: "number", minimum: 0, maximum: 1, description: "Confidence level of this atom (value between 0-1)" }, isVerified: { type: "boolean", description: "Whether this atom has been verified" }, depth: { type: "number", description: "Depth level of this atom (optional, defaults to 0)" } }, required: ["atomId", "content", "atomType", "dependencies", "confidence"] } }; // Command handler to expose decomposition-contraction functionality const ATOM_COMMANDS_TOOL: Tool = { name: "atomcommands", description: `A command tool to control the decomposition-contraction mechanism and automatic termination of Atom of Thoughts. Use this tool to access advanced features of AoT: 1. Decomposition (decompose): Decompose a specified atom into smaller sub-atoms 2. Complete decomposition (complete_decomposition): Complete an ongoing decomposition process 3. Check termination status (termination_status): Check the termination status of the current AoT process 4. Get best conclusion (best_conclusion): Get the verified conclusion with the highest confidence 5. Change settings (set_max_depth): Change the maximum depth limit Command descriptions: - command: Command to execute (decompose, complete_decomposition, termination_status, best_conclusion, set_max_depth) - atomId: Atom ID to use with the command (only required for decompose command) - decompositionId: ID of the decomposition process (only required for complete_decomposition command) - maxDepth: Maximum depth value to set (only required for set_max_depth command)`, inputSchema: { type: "object", properties: { command: { type: "string", enum: ["decompose", "complete_decomposition", "termination_status", "best_conclusion", "set_max_depth"], description: "Command to execute" }, atomId: { type: "string", description: "Atom ID to use with the command" }, decompositionId: { type: "string", description: "ID of the decomposition process to complete" }, maxDepth: { type: "number", description: "Maximum depth value to set" } }, required: ["command"] } }; // Server setup const server = new Server( { name: "atom-of-thoughts", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); const atomServer = new AtomOfThoughtsServer(); const atomLightServer = new AtomOfThoughtsLightServer(); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [AOT_TOOL, AOT_LIGHT_TOOL, ATOM_COMMANDS_TOOL], })); server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "AoT") { return atomServer.processAtom(request.params.arguments); } else if (request.params.name === "AoT-light") { return atomLightServer.processAtom(request.params.arguments); } else if (request.params.name === "atomcommands") { try { const params = request.params.arguments as Record<string, unknown>; const command = params.command as string; let result: any = { status: 'error', message: 'Unknown command' }; switch (command) { case 'decompose': const atomId = params.atomId as string; if (!atomId) throw new Error('atomId is required for decompose command'); const decompositionId = atomServer.startDecomposition(atomId); result = { status: 'success', command: 'decompose', decompositionId, message: `Started decomposition of atom ${atomId}` }; break; case 'complete_decomposition': const decompId = params.decompositionId as string; if (!decompId) throw new Error('decompositionId is required for complete_decomposition command'); const completed = atomServer.completeDecomposition(decompId); result = { status: 'success', command: 'complete_decomposition', completed, message: `Completed decomposition ${decompId}` }; break; case 'termination_status': const status = atomServer.getTerminationStatus(); result = { status: 'success', command: 'termination_status', ...status }; break; case 'best_conclusion': const bestConclusion = atomServer.getBestConclusion(); result = { status: 'success', command: 'best_conclusion', conclusion: bestConclusion ? { atomId: bestConclusion.atomId, content: bestConclusion.content, confidence: bestConclusion.confidence } : null }; break; case 'set_max_depth': const maxDepth = params.maxDepth as number; if (typeof maxDepth !== 'number' || maxDepth <= 0) throw new Error('maxDepth must be a positive number'); atomServer.maxDepth = maxDepth; result = { status: 'success', command: 'set_max_depth', maxDepth, message: `Maximum depth set to ${maxDepth}` }; break; } return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ status: 'error', error: error instanceof Error ? error.message : String(error) }, null, 2) }], isError: true }; } } return { content: [{ type: "text", text: `Unknown tool: ${request.params.name}` }], isError: true }; }); async function runServer() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("Atom of Thoughts MCP Server running on stdio"); } runServer().catch((error) => { console.error("Fatal error running server:", error); process.exit(1); });

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/kbsooo/MCP_Atom_of_Thoughts'

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