@nbiish/cognitive-tools-mcp 0.8.5 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/LICENSE +4 -4
  2. package/README.md +4 -3
  3. package/build/index.js +364 -151
  4. package/integration-prompts/integration-prompt-13.md +81 -0
  5. package/integration-prompts/new-prompts/integration-prompt.md +81 -0
  6. package/integration-tool-descriptions/new-description/tool-schema.ts +506 -0
  7. package/package.json +2 -2
  8. /package/integration-prompts/{integration-prompt-01.md → old-prompts/integration-prompt-01.md} +0 -0
  9. /package/integration-prompts/{integration-prompt-02.md → old-prompts/integration-prompt-02.md} +0 -0
  10. /package/integration-prompts/{integration-prompt-03.md → old-prompts/integration-prompt-03.md} +0 -0
  11. /package/integration-prompts/{integration-prompt-04.md → old-prompts/integration-prompt-04.md} +0 -0
  12. /package/integration-prompts/{integration-prompt-05.md → old-prompts/integration-prompt-05.md} +0 -0
  13. /package/integration-prompts/{integration-prompt-06.md → old-prompts/integration-prompt-06.md} +0 -0
  14. /package/integration-prompts/{integration-prompt-07.md → old-prompts/integration-prompt-07.md} +0 -0
  15. /package/integration-prompts/{integration-prompt-08.md → old-prompts/integration-prompt-08.md} +0 -0
  16. /package/integration-prompts/{integration-prompt-09.md → old-prompts/integration-prompt-09.md} +0 -0
  17. /package/integration-prompts/{integration-prompt-10.md → old-prompts/integration-prompt-10.md} +0 -0
  18. /package/integration-prompts/{integration-prompt-11.md → old-prompts/integration-prompt-11.md} +0 -0
  19. /package/integration-prompts/{integration-prompt-12.md → old-prompts/integration-prompt-12.md} +0 -0
  20. /package/integration-tool-descriptions/{tool-descriptions-01.ts → old-descriptions/tool-descriptions-01.ts} +0 -0
  21. /package/integration-tool-descriptions/{tool-descriptions-02.ts → old-descriptions/tool-descriptions-02.ts} +0 -0
  22. /package/integration-tool-descriptions/{tool-descriptions-03.ts → old-descriptions/tool-descriptions-03.ts} +0 -0
  23. /package/integration-tool-descriptions/{tool-descriptions-04.ts → old-descriptions/tool-descriptions-04.ts} +0 -0
  24. /package/integration-tool-descriptions/{tool-descriptions-05.md → old-descriptions/tool-descriptions-05.md} +0 -0
package/build/index.js CHANGED
@@ -1,196 +1,409 @@
1
1
  #!/usr/bin/env node
2
+ /**
3
+ * -----------------------------------------------------------------------------
4
+ * Gikendaasowin Aabajichiganan - Cognitive Tools MCP Server
5
+ *
6
+ * Description: Provides a suite of cognitive tools for an AI Pair Programmer
7
+ * to structure its reasoning, plan actions, analyze results,
8
+ * and iteratively refine its work (Chain of Draft). Integrates
9
+ * with generic external environment tools for comprehensive interaction.
10
+ * Designed to be used with the corresponding integration prompt
11
+ * focused on iterative refinement and tool integration.
12
+ * Protocol: Model Context Protocol (MCP) over stdio.
13
+ * -----------------------------------------------------------------------------
14
+ */
2
15
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
16
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
17
  import { z } from "zod";
5
- // Create the MCP server - Version aligned with prompt
18
+ import { exec } from 'child_process'; // For executeTerminalCommand
19
+ import vm from 'vm'; // For safer executeCode
20
+ import fs from 'fs/promises'; // For file operations
21
+ // Helper function to promisify exec
22
+ import { promisify } from 'util';
23
+ const execPromise = promisify(exec);
24
+ // --- Server Definition ---
6
25
  const server = new McpServer({
7
26
  name: "gikendaasowin-aabajichiganan-mcp",
8
- version: "0.8.5", // Updated version to match prompt
9
- description: "ᑭᑫᓐᑖᓱᐎᓐ ᐋᐸᒋᒋᑲᓇᓐ - Gikendaasowin Aabajichiganan - (Cognitive Tools v0.8.5): SOTA reasoning suite aligned with AI Pair Programmer Prompt v0.8.1+. Enforces structured deliberation via `think` after explicit assessment or action results. Returns generated cognitive content (thoughts, plans, CoT, critiques, summaries) for explicit analysis and action planning, optimizing for cognitive enhancement and effective tool integration."
10
- });
11
- // --- Core Cognitive Deliberation Tools ---
12
- server.tool("think",
13
- // Main Description: Central hub, returns thought for explicit context and action planning.
14
- "MANDATORY Cognitive Hub for planning, analysis (incl. prior action/tool results), verification, risk assessment, and self-correction. Called after assessment, complex cognitive tools, or external tool execution. Returns the detailed thought text for explicit grounding and to define the immediate next action.", {
15
- // Parameter Description: Input IS the thought.
16
- thought: z.string().describe("Your **detailed** internal monologue following the MANDATORY structure: ## Analysis (incl. results of last action/tool call), ## Plan (defining immediate next action, incl. external tools), ## Verification, ## Anticipated Challenges Analysis & Contingency, ## Risk Assessment, ## Lookahead, ## Self-Correction & Learning.")
27
+ version: "0.9.0", // Version required by MCP SDK
28
+ description: "ᑭᑫᓐᑖᓱᐎᓐ ᐋᐸᒋᒋᑲᓇᓐ - Cognitive Tools Suite: Enables structured, iterative reasoning (Chain of Draft), planning, analysis, and external tool integration for AI Pair Programming."
29
+ });
30
+ // --- Logging Helper ---
31
+ function logToolCall(toolName, details) {
32
+ console.error(`[MCP Server] > Tool Call: ${toolName}${details ? ` - ${details}` : ''}`);
33
+ }
34
+ function logToolResult(toolName, success, resultDetails) {
35
+ console.error(`[MCP Server] < Tool Result: ${toolName} - ${success ? 'Success' : 'Failure'}${resultDetails ? ` - ${resultDetails}` : ''}`);
36
+ }
37
+ function logToolError(toolName, error) {
38
+ const errorMessage = error instanceof Error ? error.message : String(error);
39
+ console.error(`[MCP Server] ! Tool Error: ${toolName} - ${errorMessage}`);
40
+ logToolResult(toolName, false, errorMessage); // Log failure result as well
41
+ // Return a structured error message suitable for the LLM
42
+ return { content: [{ type: "text", text: `Error in ${toolName}: ${errorMessage}` }] };
43
+ }
44
+ // --- Core Cognitive Deliberation & Refinement Tools ---
45
+ server.tool("assess_cuc_n_mode", "**Mandatory Pre-Deliberation/Pre-Sequence Assessment.** Evaluates task Complexity, Uncertainty, Consequence, Novelty (CUC-N) to determine required cognitive depth and initial strategy. MUST be called before starting complex tasks or changing strategy.", {
46
+ assessment_and_choice: z.string().describe("Structured assessment including: 1) Situation Description, 2) CUC-N Ratings (L/M/H), 3) Recommended Initial Strategy (e.g., 'Need to read relevant file for context'), 4) Explicit Mode Selection ('Selected Mode: think' or 'Selected Mode: quick_think').")
47
+ }, async ({ assessment_and_choice }) => {
48
+ logToolCall('assess_cuc_n_mode');
49
+ try {
50
+ // Basic validation for required components
51
+ if (!assessment_and_choice.includes("Selected Mode:") || !assessment_and_choice.includes("CUC-N Ratings:") || !assessment_and_choice.includes("Recommended Initial Strategy:")) {
52
+ throw new Error('Invalid assessment: String must include CUC-N ratings, Recommended Initial Strategy, and explicit Selected Mode.');
53
+ }
54
+ const mode = assessment_and_choice.includes("Selected Mode: think") ? "think" : "quick_think";
55
+ const resultText = `Cognitive Assessment Completed. Proceeding with selected mode: ${mode}. Full Assessment:\n${assessment_and_choice}`;
56
+ logToolResult('assess_cuc_n_mode', true, `Selected mode: ${mode}`);
57
+ return { content: [{ type: "text", text: resultText }] };
58
+ }
59
+ catch (error) {
60
+ return logToolError('assess_cuc_n_mode', error);
61
+ }
62
+ });
63
+ server.tool("think", "**MANDATORY Central Hub for Analysis, Planning, and Refinement.** Called after assessment, complex cognitive tools, *any* external tool execution, or internal draft generation. Analyzes previous step's outcome/draft, plans immediate next action (cognitive or external), verifies, assesses risk, and self-corrects. Returns the thought text for grounding.", {
64
+ thought: z.string().describe("Your **detailed** internal monologue following the MANDATORY structure: ## Analysis (critically evaluate last result/draft, incl. tool errors/warnings), ## Plan (define *immediate* next action & purpose), ## Verification (how to check next step), ## Anticipated Challenges & Contingency, ## Risk Assessment, ## Lookahead, ## Self-Correction & Learning.")
17
65
  }, async ({ thought }) => {
18
- if (!thought || typeof thought !== 'string' || thought.trim().length === 0) {
19
- throw new Error('Invalid thought: Must be non-empty, structured reasoning.');
20
- }
21
- // Ensure mandatory sections are mentioned (basic check)
22
- const requiredSections = ["## Analysis:", "## Plan:", "## Verification:", "## Anticipated Challenges Analysis & Contingency:", "## Risk Assessment:", "## Lookahead:", "## Self-Correction & Learning:"];
23
- // Simple check for presence; more robust parsing could be added if needed
24
- const hasRequiredSections = requiredSections.every(section => thought.includes(section));
25
- if (!hasRequiredSections) {
26
- console.warn(`[CognitiveToolsServer v0.8.5] Warning: 'think' input might be missing some mandatory sections.`);
27
- // Decide whether to throw error or just warn. Warning allows flexibility.
28
- // throw new Error('Invalid thought: Missing one or more mandatory sections (## Analysis:, ## Plan:, etc.).');
29
- }
30
- console.error(`[CognitiveToolsServer v0.8.5] Think Tool Received: ${thought.substring(0, 150)}...`);
31
- // Returns the same thought text received, making it explicit in context.
32
- return { content: [{ type: "text", text: thought }] };
33
- });
34
- server.tool("quick_think",
35
- // Main Description: Unchanged.
36
- "Cognitive Checkpoint ONLY for situations explicitly assessed as strictly Low CUC-N AND simple task nature/confirmation. Use sparingly. Logs brief thought.", {
37
- brief_thought: z.string().describe("Your **concise** thought for strictly simple, low CUC-N situations confirmed by prior assessment or for brief confirmations.")
66
+ logToolCall('think');
67
+ try {
68
+ if (!thought || typeof thought !== 'string' || thought.trim().length === 0) {
69
+ throw new Error('Invalid thought: Must be a non-empty string.');
70
+ }
71
+ // Basic check for mandatory sections (can be made more robust)
72
+ const requiredSections = ["## Analysis:", "## Plan:", "## Verification:", "## Anticipated Challenges & Contingency:", "## Risk Assessment:", "## Lookahead:", "## Self-Correction & Learning:"];
73
+ const missingSections = requiredSections.filter(section => !thought.includes(section));
74
+ if (missingSections.length > 0) {
75
+ console.warn(`[MCP Server] Warning: 'think' input might be missing sections: ${missingSections.join(', ')}`);
76
+ // Allow processing but log warning. Could throw error if strictness is desired.
77
+ }
78
+ logToolResult('think', true, `Thought logged (length: ${thought.length})`);
79
+ // Returns the same thought text received, making it explicit in context.
80
+ return { content: [{ type: "text", text: thought }] };
81
+ }
82
+ catch (error) {
83
+ return logToolError('think', error);
84
+ }
85
+ });
86
+ server.tool("quick_think", "Cognitive Checkpoint ONLY for situations explicitly assessed as strictly Low CUC-N (via assess_cuc_n_mode) or for trivial confirmations where detailed analysis via `think` is unnecessary. Use sparingly.", {
87
+ brief_thought: z.string().describe("Your **concise** thought for strictly simple, low CUC-N situations or brief confirmations.")
38
88
  }, async ({ brief_thought }) => {
39
- if (!brief_thought || typeof brief_thought !== 'string' || brief_thought.trim().length === 0) {
40
- throw new Error('Invalid brief_thought: Must be non-empty.');
41
- }
42
- console.error(`[CognitiveToolsServer v0.8.5] QuickThink Tool Logged: ${brief_thought.substring(0, 100)}...`);
43
- // Simple confirmation remains appropriate for quick_think.
44
- return { content: [{ type: "text", text: `Quick Thought logged successfully.` }] };
45
- });
46
- // --- Mandatory Meta-Cognitive Tools ---
47
- server.tool("assess_cuc_n_mode", // Shortened name to avoid length limitations
48
- // Main Description: Updated name, emphasizes role.
49
- "**Mandatory Pre-Deliberation/Pre-Sequence Assessment.** Must be called BEFORE initiating significant cognitive processes (`think`) or complex action sequences. Evaluates CUC-N, recommends strategy, commits to next thought mode.", {
50
- // Parameter Description: Unchanged.
51
- assessment_and_choice: z.string().describe("Input your assessment *before* calling. MUST include: 1) Situation Description, 2) CUC-N Ratings (L/M/H), 3) Recommended Initial Strategy, 4) Explicit Mode Selection ('Selected Mode: think' or 'Selected Mode: quick_think').")
52
- }, async ({ assessment_and_choice }) => {
53
- const requiredPhrases = ["Complexity", "Uncertainty", "Consequence", "Novelty", "Recommended Initial Strategy", "Selected Mode:"];
54
- const hasRequiredPhrases = requiredPhrases.every(phrase => assessment_and_choice.includes(phrase));
55
- const hasModeSelection = assessment_and_choice.includes("Selected Mode: think") || assessment_and_choice.includes("Selected Mode: quick_think");
56
- if (!assessment_and_choice || typeof assessment_and_choice !== 'string' || !hasRequiredPhrases || !hasModeSelection) {
57
- throw new Error('Invalid assessment: String must include CUC-N ratings, Recommended Initial Strategy, and explicit Selected Mode ("think" or "quick_think").');
58
- }
59
- console.error(`[CognitiveToolsServer v0.8.5] AssessComplexity Tool Signaled: ${assessment_and_choice.substring(0, 150)}...`);
60
- const mode = assessment_and_choice.includes("Selected Mode: think") ? "think" : "quick_think";
61
- // Confirmation guides the next step.
62
- return { content: [{ type: "text", text: `Cognitive Assessment Completed. Proceeding with selected mode: ${mode}. Full Assessment: ${assessment_and_choice}` }] };
63
- });
64
- server.tool("gauge_confidence",
65
- // Main Description: Emphasizes mandatory analysis.
66
- "Meta-Cognitive Checkpoint. Guides internal stating of **confidence (High/Medium/Low) and justification**. Output MUST be analyzed in the mandatory `think` step immediately after; Low/Medium confidence requires specific action planning.", {
67
- // Parameter Description: Unchanged.
89
+ logToolCall('quick_think');
90
+ try {
91
+ if (!brief_thought || typeof brief_thought !== 'string' || brief_thought.trim().length === 0) {
92
+ throw new Error('Invalid brief_thought: Must be non-empty.');
93
+ }
94
+ logToolResult('quick_think', true, `Logged: ${brief_thought.substring(0, 50)}...`);
95
+ return { content: [{ type: "text", text: `Quick Thought logged successfully.` }] };
96
+ }
97
+ catch (error) {
98
+ return logToolError('quick_think', error);
99
+ }
100
+ });
101
+ server.tool("gauge_confidence", "Meta-Cognitive Checkpoint. Guides internal stating of **confidence (High/Medium/Low) and justification** regarding a plan, analysis, or draft. Output MUST be analyzed in the mandatory `think` step immediately after.", {
68
102
  assessment_and_confidence: z.string().describe("Input item being assessed. *Internally determine and state*: 1) Confidence Level (H/M/L). 2) Justification. Call this tool *after* making the assessment.")
69
103
  }, async ({ assessment_and_confidence }) => {
70
- const confidenceRegex = /Confidence Level: (High|Medium|Low)/i;
71
- if (!assessment_and_confidence || typeof assessment_and_confidence !== 'string' || !confidenceRegex.test(assessment_and_confidence)) {
72
- throw new Error('Invalid confidence assessment: String must include "Confidence Level: High/Medium/Low" and justification.');
73
- }
74
- const match = assessment_and_confidence.match(confidenceRegex);
75
- const level = match ? match[1] : "Unknown";
76
- console.error(`[CognitiveToolsServer v0.8.5] GaugeConfidence Tool Signaled: Level ${level}`);
77
- // Confirmation includes level, prepares for mandatory analysis.
78
- return { content: [{ type: "text", text: `Confidence Gauge Completed. Level: ${level}. Assessment Text: ${assessment_and_confidence}. Ready for mandatory post-assessment 'think' analysis (action required if Low/Medium).` }] };
79
- });
80
- // --- Supporting Cognitive Strategy Tools (Accept & Return Generated Text for Analysis) ---
81
- server.tool("plan_and_solve",
82
- // Main Description: Returns plan text for analysis and action planning.
83
- "Guides internal generation of **structured plan text** (incl. Risks/Challenges, potential tool needs). Call this tool *with* the generated plan text. Returns the plan text for mandatory `think` analysis to confirm/refine the immediate next step.", {
84
- // Parameter: Accepts the generated plan.
85
- generated_plan_text: z.string().describe("The **full, structured plan text** you generated internally, including Anticipated Challenges/Risks and potential other tool needs."),
104
+ logToolCall('gauge_confidence');
105
+ try {
106
+ const confidenceRegex = /Confidence Level: (High|Medium|Low)/i;
107
+ if (!assessment_and_confidence || typeof assessment_and_confidence !== 'string' || !confidenceRegex.test(assessment_and_confidence)) {
108
+ throw new Error('Invalid confidence assessment: String must include "Confidence Level: High/Medium/Low" and justification.');
109
+ }
110
+ const match = assessment_and_confidence.match(confidenceRegex);
111
+ const level = match ? match[1] : "Unknown";
112
+ const resultText = `Confidence Gauge Completed. Level: ${level}. Assessment Text: ${assessment_and_confidence}. Ready for mandatory post-assessment 'think' analysis (action required if Low/Medium).`;
113
+ logToolResult('gauge_confidence', true, `Level: ${level}`);
114
+ return { content: [{ type: "text", text: resultText }] };
115
+ }
116
+ catch (error) {
117
+ return logToolError('gauge_confidence', error);
118
+ }
119
+ });
120
+ server.tool("plan_and_solve", "Guides internal generation of a **structured plan draft**. Call this tool *with* the generated plan text. Returns the plan text for mandatory `think` analysis to critically evaluate feasibility, refine, and confirm the first action step.", {
121
+ generated_plan_text: z.string().describe("The **full, structured plan draft** you generated internally, including goals, steps, potential tool needs, and risks."),
86
122
  task_objective: z.string().describe("The original high-level task objective this plan addresses.")
87
123
  }, async ({ generated_plan_text, task_objective }) => {
88
- if (!generated_plan_text || typeof generated_plan_text !== 'string' || generated_plan_text.trim().length === 0) {
89
- throw new Error('Invalid generated_plan_text: Must be non-empty.');
124
+ logToolCall('plan_and_solve', `Objective: ${task_objective.substring(0, 50)}...`);
125
+ try {
126
+ if (!generated_plan_text || typeof generated_plan_text !== 'string' || generated_plan_text.trim().length === 0) {
127
+ throw new Error('Invalid generated_plan_text: Must be non-empty.');
128
+ }
129
+ if (!task_objective || typeof task_objective !== 'string' || task_objective.trim().length === 0) {
130
+ throw new Error('Invalid task_objective.');
131
+ }
132
+ logToolResult('plan_and_solve', true, `Returned plan draft (length: ${generated_plan_text.length})`);
133
+ // Returns the actual plan text received for analysis.
134
+ return { content: [{ type: "text", text: generated_plan_text }] };
90
135
  }
91
- if (!task_objective || typeof task_objective !== 'string' || task_objective.trim().length === 0) {
92
- throw new Error('Invalid task_objective.');
136
+ catch (error) {
137
+ return logToolError('plan_and_solve', error);
93
138
  }
94
- console.error(`[CognitiveToolsServer v0.8.5] PlanAndSolve Tool Received Plan for Objective: ${task_objective.substring(0, 100)}...`);
95
- // Returns the actual plan text received for analysis.
96
- return { content: [{ type: "text", text: generated_plan_text }] };
97
139
  });
98
- server.tool("chain_of_thought",
99
- // Main Description: Returns CoT text for analysis and action planning.
100
- "Guides internal generation of **detailed, step-by-step reasoning text (CoT)**. Call this tool *with* the generated CoT text. Returns the CoT text for mandatory `think` analysis to extract insights and plan the next action.", {
101
- // Parameter: Accepts the generated CoT.
102
- generated_cot_text: z.string().describe("The **full, step-by-step Chain of Thought text** you generated internally, potentially noting needs for other tools."),
140
+ server.tool("chain_of_thought", "Guides internal generation of **detailed, step-by-step reasoning draft (CoT)**. Call this tool *with* the generated CoT text. Returns the CoT text for mandatory `think` analysis to extract insights, identify flaws/gaps, and plan the next concrete action.", {
141
+ generated_cot_text: z.string().describe("The **full, step-by-step Chain of Thought draft** you generated internally."),
103
142
  problem_statement: z.string().describe("The original problem statement this CoT addresses.")
104
143
  }, async ({ generated_cot_text, problem_statement }) => {
105
- if (!generated_cot_text || typeof generated_cot_text !== 'string' || generated_cot_text.trim().length === 0) {
106
- throw new Error('Invalid generated_cot_text: Must be non-empty.');
107
- }
108
- if (!problem_statement || typeof problem_statement !== 'string' || problem_statement.trim().length === 0) {
109
- throw new Error('Invalid problem_statement.');
110
- }
111
- console.error(`[CognitiveToolsServer v0.8.5] ChainOfThought Tool Received CoT for Problem: ${problem_statement.substring(0, 100)}...`);
112
- // Returns the actual CoT text received for analysis.
113
- return { content: [{ type: "text", text: generated_cot_text }] };
114
- });
115
- server.tool("chain_of_draft",
116
- // Main Description: Signal only, reinforces mandatory analysis.
117
- "Guides internal generation of **concise, iterative reasoning draft texts**. Call this tool *after* generating drafts internally. Response confirms generation; drafts MUST be analyzed via mandatory `think`.", {
118
- // Parameter: Still just the problem statement. LLM handles drafts internally.
119
- problem_statement: z.string().describe("Input problem for exploration. *You* (LLM) must now *internally generate brief, iterative draft texts*. Call this tool *after* generation to signal readiness for analysis.")
120
- }, async ({ problem_statement }) => {
121
- if (!problem_statement || typeof problem_statement !== 'string' || problem_statement.trim().length === 0) {
122
- throw new Error('Invalid problem statement.');
123
- }
124
- console.error(`[CognitiveToolsServer v0.8.5] ChainOfDraft Tool Signaled for: ${problem_statement.substring(0, 100)}...`);
125
- // Returns confirmation, strongly reminding LLM of the mandatory next step.
126
- return { content: [{ type: "text", text: `Reasoning drafts generated internally for problem: ${problem_statement}. MANDATORY: Analyze these drafts now in your next 'think' step.` }] };
127
- });
128
- server.tool("reflection",
129
- // Main Description: Returns critique text for analysis and action planning.
130
- "Guides internal critical self-evaluation on prior text. Call this tool *with* the **generated critique text**. Returns the critique text for mandatory `think` analysis to plan corrective actions.", {
131
- // Parameter: Accepts the generated critique.
132
- generated_critique_text: z.string().describe("The **full critique text** you generated internally, identifying flaws and suggesting improvements."),
133
- input_reasoning_or_plan: z.string().describe("The original text that was critiqued.")
134
- }, async ({ generated_critique_text, input_reasoning_or_plan }) => {
135
- if (!generated_critique_text || typeof generated_critique_text !== 'string' || generated_critique_text.trim().length === 0) {
136
- throw new Error('Invalid generated_critique_text: Must be non-empty.');
137
- }
138
- if (!input_reasoning_or_plan || typeof input_reasoning_or_plan !== 'string' || input_reasoning_or_plan.trim().length === 0) {
139
- throw new Error('Invalid input_reasoning_or_plan.');
140
- }
141
- console.error(`[CognitiveToolsServer v0.8.5] Reflection Tool Received Critique for: ${input_reasoning_or_plan.substring(0, 100)}...`);
142
- // Returns the actual critique text received for analysis.
143
- return { content: [{ type: "text", text: generated_critique_text }] };
144
- });
145
- server.tool("synthesize_prior_reasoning",
146
- // Main Description: Returns summary text for analysis and action planning.
147
- "Context Management Tool. Guides internal generation of a **structured summary text** (incl. Key Decisions, Open Questions). Call this tool *with* the generated summary text. Returns the summary for mandatory `think` analysis to inform the next steps.", {
148
- // Parameter: Accepts the generated summary.
149
- generated_summary_text: z.string().describe("The **full, structured summary text** you generated internally."),
150
- context_to_summarize_description: z.string().describe("Description of the reasoning span that was summarized.")
144
+ logToolCall('chain_of_thought', `Problem: ${problem_statement.substring(0, 50)}...`);
145
+ try {
146
+ if (!generated_cot_text || typeof generated_cot_text !== 'string' || generated_cot_text.trim().length === 0) {
147
+ throw new Error('Invalid generated_cot_text: Must be non-empty.');
148
+ }
149
+ if (!problem_statement || typeof problem_statement !== 'string' || problem_statement.trim().length === 0) {
150
+ throw new Error('Invalid problem_statement.');
151
+ }
152
+ logToolResult('chain_of_thought', true, `Returned CoT draft (length: ${generated_cot_text.length})`);
153
+ // Returns the actual CoT text received for analysis.
154
+ return { content: [{ type: "text", text: generated_cot_text }] };
155
+ }
156
+ catch (error) {
157
+ return logToolError('chain_of_thought', error);
158
+ }
159
+ });
160
+ server.tool("chain_of_draft", "Signals that one or more **internal drafts** (code, text, plan fragments) have been generated or refined and are ready for analysis. Call this tool *after* generating/refining draft(s) internally. Response confirms readiness; drafts MUST be analyzed via mandatory `think`.", {
161
+ draft_description: z.string().describe("Brief description of the draft(s) generated/refined internally (e.g., 'Initial code snippet for function X', 'Refined plan section 3').")
162
+ }, async ({ draft_description }) => {
163
+ logToolCall('chain_of_draft', `Description: ${draft_description}`);
164
+ try {
165
+ if (!draft_description || typeof draft_description !== 'string' || draft_description.trim().length === 0) {
166
+ throw new Error('Invalid draft_description.');
167
+ }
168
+ const resultText = `Internal draft(s) ready for analysis: ${draft_description}. MANDATORY: Analyze these draft(s) now in your next 'think' step.`;
169
+ logToolResult('chain_of_draft', true);
170
+ return { content: [{ type: "text", text: resultText }] };
171
+ }
172
+ catch (error) {
173
+ return logToolError('chain_of_draft', error);
174
+ }
175
+ });
176
+ server.tool("reflection", "Guides internal critical self-evaluation on a prior step, draft, or outcome. Call this tool *with* the **generated critique text**. Returns the critique text for mandatory `think` analysis to plan specific corrective actions or refinements.", {
177
+ generated_critique_text: z.string().describe("The **full critique text** you generated internally, identifying flaws, strengths, and suggesting improvements."),
178
+ input_subject_description: z.string().describe("A brief description of the original reasoning, plan, code draft, or action result that was critiqued.")
179
+ }, async ({ generated_critique_text, input_subject_description }) => {
180
+ logToolCall('reflection', `Subject: ${input_subject_description}`);
181
+ try {
182
+ if (!generated_critique_text || typeof generated_critique_text !== 'string' || generated_critique_text.trim().length === 0) {
183
+ throw new Error('Invalid generated_critique_text: Must be non-empty.');
184
+ }
185
+ if (!input_subject_description || typeof input_subject_description !== 'string' || input_subject_description.trim().length === 0) {
186
+ throw new Error('Invalid input_subject_description.');
187
+ }
188
+ logToolResult('reflection', true, `Returned critique (length: ${generated_critique_text.length})`);
189
+ // Returns the actual critique text received for analysis.
190
+ return { content: [{ type: "text", text: generated_critique_text }] };
191
+ }
192
+ catch (error) {
193
+ return logToolError('reflection', error);
194
+ }
195
+ });
196
+ server.tool("synthesize_prior_reasoning", "Context Management Tool. Guides internal generation of a **structured summary** of preceding steps, decisions, or context. Call this tool *with* the generated summary text. Returns the summary for mandatory `think` analysis to consolidate understanding and inform next steps.", {
197
+ generated_summary_text: z.string().describe("The **full, structured summary text** you generated internally (e.g., key decisions, open questions, current state)."),
198
+ context_to_summarize_description: z.string().describe("Description of the reasoning span or context that was summarized.")
151
199
  }, async ({ generated_summary_text, context_to_summarize_description }) => {
152
- if (!generated_summary_text || typeof generated_summary_text !== 'string' || generated_summary_text.trim().length === 0) {
153
- throw new Error('Invalid generated_summary_text: Must be non-empty.');
200
+ logToolCall('synthesize_prior_reasoning', `Context: ${context_to_summarize_description}`);
201
+ try {
202
+ if (!generated_summary_text || typeof generated_summary_text !== 'string' || generated_summary_text.trim().length === 0) {
203
+ throw new Error('Invalid generated_summary_text: Must be non-empty.');
204
+ }
205
+ if (!context_to_summarize_description || typeof context_to_summarize_description !== 'string' || context_to_summarize_description.trim().length === 0) {
206
+ throw new Error('Invalid context_to_summarize_description.');
207
+ }
208
+ logToolResult('synthesize_prior_reasoning', true, `Returned summary (length: ${generated_summary_text.length})`);
209
+ // Returns the actual summary text received for analysis.
210
+ return { content: [{ type: "text", text: generated_summary_text }] };
211
+ }
212
+ catch (error) {
213
+ return logToolError('synthesize_prior_reasoning', error);
214
+ }
215
+ });
216
+ // --- Generic External Environment Tools ---
217
+ // ** File System Operations **
218
+ server.tool("readFile", "Reads the content of a specified file. Essential for getting context before analysis or modification.", {
219
+ filePath: z.string().describe("The path to the file relative to the project root.")
220
+ }, async ({ filePath }) => {
221
+ logToolCall('readFile', `Path: ${filePath}`);
222
+ try {
223
+ const fileContent = await fs.readFile(filePath, 'utf8');
224
+ // Consider limiting the size returned to avoid overwhelming the context window
225
+ const maxSize = 10000; // Example limit: 10k characters
226
+ const truncatedContent = fileContent.length > maxSize ? fileContent.substring(0, maxSize) + "\n... [File truncated]" : fileContent;
227
+ logToolResult('readFile', true, `Read ${truncatedContent.length} chars from ${filePath}`);
228
+ return { content: [{ type: "text", text: truncatedContent }] };
229
+ }
230
+ catch (error) {
231
+ return logToolError('readFile', error);
232
+ }
233
+ });
234
+ server.tool("writeFile", "Writes the provided content to a specified file, overwriting existing content. Use to apply generated code or modifications.", {
235
+ filePath: z.string().describe("The path to the file relative to the project root."),
236
+ content: z.string().describe("The full content to write to the file.")
237
+ }, async ({ filePath, content }) => {
238
+ logToolCall('writeFile', `Path: ${filePath}, Content Length: ${content.length}`);
239
+ try {
240
+ // Ensure directory exists before writing? (Optional, adds robustness)
241
+ // await fs.mkdir(path.dirname(filePath), { recursive: true });
242
+ await fs.writeFile(filePath, content, 'utf8');
243
+ logToolResult('writeFile', true, `Wrote ${content.length} chars to ${filePath}`);
244
+ return { content: [{ type: "text", text: `Successfully wrote content to ${filePath}.` }] };
245
+ }
246
+ catch (error) {
247
+ return logToolError('writeFile', error);
248
+ }
249
+ });
250
+ server.tool("listFiles", "Lists files and directories within a specified directory path.", {
251
+ directoryPath: z.string().describe("The path to the directory relative to the project root (e.g., '.', 'src/components').")
252
+ }, async ({ directoryPath }) => {
253
+ logToolCall('listFiles', `Path: ${directoryPath}`);
254
+ try {
255
+ const entries = await fs.readdir(directoryPath, { withFileTypes: true });
256
+ const listing = entries.map(entry => `${entry.name}${entry.isDirectory() ? '/' : ''}`).join('\n');
257
+ logToolResult('listFiles', true, `Found ${entries.length} entries in ${directoryPath}`);
258
+ return { content: [{ type: "text", text: listing || "[Directory is empty]" }] };
259
+ }
260
+ catch (error) {
261
+ return logToolError('listFiles', error);
262
+ }
263
+ });
264
+ server.tool("createDirectory", "Creates a new directory at the specified path. Use `recursive: true` to create parent directories if needed.", {
265
+ directoryPath: z.string().describe("The path for the new directory relative to the project root."),
266
+ recursive: z.boolean().optional().describe("If true, create parent directories as needed. Defaults to false.")
267
+ }, async ({ directoryPath, recursive = false }) => {
268
+ logToolCall('createDirectory', `Path: ${directoryPath}, Recursive: ${recursive}`);
269
+ try {
270
+ await fs.mkdir(directoryPath, { recursive: recursive });
271
+ logToolResult('createDirectory', true, `Created directory ${directoryPath}`);
272
+ return { content: [{ type: "text", text: `Successfully created directory ${directoryPath}.` }] };
273
+ }
274
+ catch (error) {
275
+ // Handle 'EEXIST' gracefully if directory already exists? Or let it fail?
276
+ // if (error.code === 'EEXIST' && recursive) { /* handle existing */ }
277
+ return logToolError('createDirectory', error);
278
+ }
279
+ });
280
+ server.tool("deleteFile", "Deletes the specified file. Use with caution.", {
281
+ filePath: z.string().describe("The path to the file to delete relative to the project root.")
282
+ }, async ({ filePath }) => {
283
+ logToolCall('deleteFile', `Path: ${filePath}`);
284
+ try {
285
+ await fs.unlink(filePath);
286
+ logToolResult('deleteFile', true, `Deleted file ${filePath}`);
287
+ return { content: [{ type: "text", text: `Successfully deleted file ${filePath}.` }] };
154
288
  }
155
- if (!context_to_summarize_description || typeof context_to_summarize_description !== 'string' || context_to_summarize_description.trim().length === 0) {
156
- throw new Error('Invalid context_to_summarize_description.');
289
+ catch (error) {
290
+ // Handle 'ENOENT' (file not found) gracefully?
291
+ return logToolError('deleteFile', error);
292
+ }
293
+ });
294
+ // ** Code Execution & Terminal **
295
+ server.tool("executeCode", "Executes a provided code snippet in a sandboxed environment. Crucial for testing drafts/logic. Currently supports JavaScript.", {
296
+ codeSnippet: z.string().describe("The code snippet to execute (currently JavaScript)."),
297
+ language: z.string().optional().describe("The language of the snippet (defaults to javascript). Informational for now.")
298
+ }, async ({ codeSnippet, language = 'javascript' }) => {
299
+ // Basic check for language - could expand later
300
+ if (language.toLowerCase() !== 'javascript') {
301
+ return logToolError('executeCode', new Error(`Unsupported language: ${language}. Only JavaScript is currently supported.`));
302
+ }
303
+ logToolCall('executeCode', `Lang: ${language}, Snippet: ${codeSnippet.substring(0, 50)}...`);
304
+ try {
305
+ // Use Node.js vm module for basic sandboxing (better than eval)
306
+ const context = vm.createContext({}); // Create an empty context
307
+ const script = new vm.Script(codeSnippet);
308
+ const result = script.runInContext(context, { timeout: 5000 }); // Add a timeout
309
+ const resultString = typeof result === 'undefined' ? 'undefined' : JSON.stringify(result);
310
+ logToolResult('executeCode', true, `Result: ${resultString.substring(0, 100)}...`);
311
+ return { content: [{ type: "text", text: `Execution Result: ${resultString}` }] };
312
+ }
313
+ catch (error) {
314
+ return logToolError('executeCode', error);
315
+ }
316
+ });
317
+ server.tool("executeTerminalCommand", "Executes a shell command in the project's root directory. Useful for build steps, git operations, running test suites, etc.", {
318
+ command: z.string().describe("The shell command to execute (e.g., 'npm run test', 'git status').")
319
+ }, async ({ command }) => {
320
+ logToolCall('executeTerminalCommand', `Command: ${command}`);
321
+ try {
322
+ // Execute command - consider security implications carefully in production
323
+ // Set a timeout? Limit allowed commands?
324
+ const { stdout, stderr } = await execPromise(command, { timeout: 30000, encoding: 'utf8' }); // 30s timeout
325
+ let resultText = "";
326
+ if (stderr) {
327
+ resultText += `Standard Error:\n${stderr}\n`;
328
+ logToolResult('executeTerminalCommand', false, `Command finished with stderr.`); // Consider stderr as potential failure
329
+ }
330
+ resultText += `Standard Output:\n${stdout}`;
331
+ logToolResult('executeTerminalCommand', true, `Command finished.`);
332
+ // Limit output size?
333
+ const maxSize = 5000;
334
+ if (resultText.length > maxSize) {
335
+ resultText = resultText.substring(0, maxSize) + "\n... [Output truncated]";
336
+ }
337
+ return { content: [{ type: "text", text: resultText }] };
338
+ }
339
+ catch (error) {
340
+ // Error object from exec often includes stdout/stderr which might be useful
341
+ let errorDetails = error instanceof Error ? error.message : String(error);
342
+ if (error.stdout)
343
+ errorDetails += `\nSTDOUT:\n${error.stdout}`;
344
+ if (error.stderr)
345
+ errorDetails += `\nSTDERR:\n${error.stderr}`;
346
+ return logToolError('executeTerminalCommand', errorDetails);
347
+ }
348
+ });
349
+ // ** Web & Information Retrieval **
350
+ server.tool("webSearch", "Performs a web search using an external service (stubbed). Useful for finding API documentation, error explanations, or concepts.", {
351
+ query: z.string().describe("The search query.")
352
+ }, async ({ query }) => {
353
+ logToolCall('webSearch', `Query: ${query}`);
354
+ // --- STUB IMPLEMENTATION ---
355
+ // In a real scenario, this would call a search API (Google, Bing, DuckDuckGo, Brave Search etc.)
356
+ // For now, return a placeholder message.
357
+ const resultText = `[Web Search Stub] Would search for: "${query}". No live search configured.`;
358
+ logToolResult('webSearch', true, 'Stub executed');
359
+ return { content: [{ type: "text", text: resultText }] };
360
+ // --- END STUB ---
361
+ /* // Example using a hypothetical search API client
362
+ try {
363
+ // const searchResults = await searchApiClient.search(query);
364
+ // const formattedResults = formatSearchResults(searchResults); // Process results
365
+ // logToolResult('webSearch', true, `Found results for ${query}`);
366
+ // return { content: [{ type: "text", text: formattedResults }] };
367
+ } catch (error: any) {
368
+ return logToolError('webSearch', error);
157
369
  }
158
- console.error(`[CognitiveToolsServer v0.8.5] SynthesizeReasoning Tool Received Summary for: ${context_to_summarize_description}...`);
159
- // Returns the actual summary text received for analysis.
160
- return { content: [{ type: "text", text: generated_summary_text }] };
370
+ */
161
371
  });
162
- // --- Server Lifecycle and Error Handling (Unchanged) ---
372
+ // --- Server Lifecycle and Error Handling ---
163
373
  process.on('SIGINT', async () => {
164
- console.error('\n[CognitiveToolsServer v0.8.5] Received SIGINT, shutting down gracefully.');
374
+ console.error('\n[MCP Server] Received SIGINT, shutting down gracefully.');
165
375
  await server.close();
166
376
  process.exit(0);
167
377
  });
168
378
  process.on('SIGTERM', async () => {
169
- console.error('\n[CognitiveToolsServer v0.8.5] Received SIGTERM, shutting down gracefully.');
379
+ console.error('\n[MCP Server] Received SIGTERM, shutting down gracefully.');
170
380
  await server.close();
171
381
  process.exit(0);
172
382
  });
173
- process.on('uncaughtException', (error) => {
174
- console.error('[CognitiveToolsServer v0.8.5] FATAL: Uncaught Exception:', error);
175
- server.close().catch(err => console.error('[CognitiveToolsServer v0.8.5] Error during shutdown on uncaughtException:', err)).finally(() => {
383
+ process.on('uncaughtException', (error, origin) => {
384
+ console.error(`[MCP Server] FATAL: Uncaught Exception at: ${origin}`, error);
385
+ server.close().catch(err => console.error('[MCP Server] Error during shutdown on uncaughtException:', err)).finally(() => {
176
386
  process.exit(1);
177
387
  });
178
388
  });
179
389
  process.on('unhandledRejection', (reason, promise) => {
180
- console.error('[CognitiveToolsServer v0.8.5] FATAL: Unhandled Promise Rejection:', reason);
181
- server.close().catch(err => console.error('[CognitiveToolsServer v0.8.5] Error during shutdown on unhandledRejection:', err)).finally(() => {
390
+ console.error('[MCP Server] FATAL: Unhandled Promise Rejection:', reason);
391
+ server.close().catch(err => console.error('[MCP Server] Error during shutdown on unhandledRejection:', err)).finally(() => {
182
392
  process.exit(1);
183
393
  });
184
394
  });
185
- // Start the server
395
+ // --- Start the Server ---
186
396
  async function main() {
187
397
  try {
188
398
  const transport = new StdioServerTransport();
189
399
  await server.connect(transport);
190
- console.error('ᑭᑫᓐᑖᓱᐎᓐ ᐋᐸᒋᒋᑲᓇᓐ - Gikendaasowin Aabajichiganan - (Cognitive Tools v0.8.5) MCP Server running on stdio');
400
+ console.error('-----------------------------------------------------');
401
+ console.error(' ᑭᑫᓐᑖᓱᐎᓐ ᐋᐸᒋᒋᑲᓇᓐ - Cognitive Tools MCP Server');
402
+ console.error(' Status: Running on stdio');
403
+ console.error('-----------------------------------------------------');
191
404
  }
192
405
  catch (error) {
193
- console.error('[CognitiveToolsServer v0.8.5] Fatal error during startup:', error);
406
+ console.error('[MCP Server] Fatal error during startup:', error);
194
407
  process.exit(1);
195
408
  }
196
409
  }