tachibot-mcp 2.0.2
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.
- package/.env.example +260 -0
- package/CHANGELOG.md +54 -0
- package/CODE_OF_CONDUCT.md +56 -0
- package/CONTRIBUTING.md +54 -0
- package/Dockerfile +36 -0
- package/LICENSE +644 -0
- package/README.md +201 -0
- package/SECURITY.md +95 -0
- package/dist/personality/komaai-expressions.js +12 -0
- package/dist/profiles/balanced.json +33 -0
- package/dist/profiles/code_focus.json +33 -0
- package/dist/profiles/full.json +33 -0
- package/dist/profiles/minimal.json +33 -0
- package/dist/profiles/research_power.json +33 -0
- package/dist/scripts/build-profiles.js +46 -0
- package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
- package/dist/src/application/services/focus/FocusTool.service.js +109 -0
- package/dist/src/application/services/focus/ModeRegistry.js +46 -0
- package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
- package/dist/src/application/services/focus/modes/status.mode.js +50 -0
- package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
- package/dist/src/collaborative-orchestrator.js +391 -0
- package/dist/src/config/model-constants.js +188 -0
- package/dist/src/config/model-defaults.js +57 -0
- package/dist/src/config/model-preferences.js +382 -0
- package/dist/src/config/timeout-config.js +130 -0
- package/dist/src/config.js +173 -0
- package/dist/src/domain/interfaces/IFocusMode.js +5 -0
- package/dist/src/domain/interfaces/IProvider.js +6 -0
- package/dist/src/domain/interfaces/ITool.js +5 -0
- package/dist/src/focus-deep.js +245 -0
- package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
- package/dist/src/mcp-client.js +90 -0
- package/dist/src/memory/index.js +17 -0
- package/dist/src/memory/memory-config.js +135 -0
- package/dist/src/memory/memory-interface.js +174 -0
- package/dist/src/memory/memory-manager.js +383 -0
- package/dist/src/memory/providers/devlog-provider.js +385 -0
- package/dist/src/memory/providers/hybrid-provider.js +399 -0
- package/dist/src/memory/providers/local-provider.js +388 -0
- package/dist/src/memory/providers/mem0-provider.js +337 -0
- package/dist/src/modes/architect.js +477 -0
- package/dist/src/modes/auditor.js +362 -0
- package/dist/src/modes/challenger.js +841 -0
- package/dist/src/modes/code-reviewer.js +382 -0
- package/dist/src/modes/commit-guardian.js +424 -0
- package/dist/src/modes/documentation-writer.js +572 -0
- package/dist/src/modes/scout.js +587 -0
- package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
- package/dist/src/modes/shared/helpers/index.js +17 -0
- package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
- package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
- package/dist/src/modes/test-architect.js +767 -0
- package/dist/src/modes/verifier.js +378 -0
- package/dist/src/monitoring/performance-monitor.js +435 -0
- package/dist/src/optimization/batch-executor.js +121 -0
- package/dist/src/optimization/context-pruner.js +196 -0
- package/dist/src/optimization/cost-monitor.js +338 -0
- package/dist/src/optimization/index.js +65 -0
- package/dist/src/optimization/model-router.js +264 -0
- package/dist/src/optimization/result-cache.js +114 -0
- package/dist/src/optimization/token-optimizer.js +257 -0
- package/dist/src/optimization/token-tracker.js +118 -0
- package/dist/src/orchestrator-instructions.js +128 -0
- package/dist/src/orchestrator-lite.js +139 -0
- package/dist/src/orchestrator.js +191 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
- package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
- package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
- package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
- package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
- package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
- package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
- package/dist/src/profiles/balanced.js +37 -0
- package/dist/src/profiles/code_focus.js +37 -0
- package/dist/src/profiles/debug_intensive.js +59 -0
- package/dist/src/profiles/full.js +37 -0
- package/dist/src/profiles/minimal.js +37 -0
- package/dist/src/profiles/research_code.js +59 -0
- package/dist/src/profiles/research_power.js +37 -0
- package/dist/src/profiles/types.js +5 -0
- package/dist/src/profiles/workflow_builder.js +53 -0
- package/dist/src/prompt-engineer-lite.js +78 -0
- package/dist/src/prompt-engineer.js +399 -0
- package/dist/src/reasoning-chain.js +508 -0
- package/dist/src/sequential-thinking.js +291 -0
- package/dist/src/server-diagnostic.js +74 -0
- package/dist/src/server-raw.js +158 -0
- package/dist/src/server-simple.js +58 -0
- package/dist/src/server.js +514 -0
- package/dist/src/session/session-logger.js +617 -0
- package/dist/src/session/session-manager.js +571 -0
- package/dist/src/session/session-tools.js +400 -0
- package/dist/src/tools/advanced-modes.js +200 -0
- package/dist/src/tools/claude-integration.js +356 -0
- package/dist/src/tools/consolidated/ai-router.js +174 -0
- package/dist/src/tools/consolidated/ai-tool.js +48 -0
- package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
- package/dist/src/tools/consolidated/environment-detector.js +80 -0
- package/dist/src/tools/consolidated/index.js +50 -0
- package/dist/src/tools/consolidated/search-tool.js +110 -0
- package/dist/src/tools/consolidated/workflow-tool.js +238 -0
- package/dist/src/tools/gemini-tools.js +329 -0
- package/dist/src/tools/grok-enhanced.js +376 -0
- package/dist/src/tools/grok-tools.js +299 -0
- package/dist/src/tools/lmstudio-tools.js +223 -0
- package/dist/src/tools/openai-tools.js +498 -0
- package/dist/src/tools/openrouter-tools.js +317 -0
- package/dist/src/tools/optimized-wrapper.js +204 -0
- package/dist/src/tools/perplexity-tools.js +294 -0
- package/dist/src/tools/pingpong-tool.js +343 -0
- package/dist/src/tools/qwen-wrapper.js +74 -0
- package/dist/src/tools/tool-router.js +444 -0
- package/dist/src/tools/unified-ai-provider.js +260 -0
- package/dist/src/tools/workflow-runner.js +425 -0
- package/dist/src/tools/workflow-validator-tool.js +107 -0
- package/dist/src/types.js +23 -0
- package/dist/src/utils/input-validator.js +130 -0
- package/dist/src/utils/model-router.js +91 -0
- package/dist/src/utils/progress-stream.js +255 -0
- package/dist/src/utils/provider-router.js +88 -0
- package/dist/src/utils/smart-api-client.js +146 -0
- package/dist/src/utils/table-builder.js +218 -0
- package/dist/src/utils/timestamp-formatter.js +134 -0
- package/dist/src/utils/tool-compressor.js +257 -0
- package/dist/src/utils/tool-config.js +201 -0
- package/dist/src/validators/dependency-graph-validator.js +147 -0
- package/dist/src/validators/interpolation-validator.js +222 -0
- package/dist/src/validators/output-usage-validator.js +151 -0
- package/dist/src/validators/syntax-validator.js +102 -0
- package/dist/src/validators/tool-registry-validator.js +123 -0
- package/dist/src/validators/tool-types.js +97 -0
- package/dist/src/validators/types.js +8 -0
- package/dist/src/validators/workflow-validator.js +134 -0
- package/dist/src/visualizer-lite.js +42 -0
- package/dist/src/visualizer.js +179 -0
- package/dist/src/workflows/circuit-breaker.js +199 -0
- package/dist/src/workflows/custom-workflows.js +451 -0
- package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
- package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
- package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
- package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
- package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
- package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
- package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
- package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
- package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
- package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
- package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
- package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
- package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
- package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
- package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
- package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
- package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
- package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
- package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
- package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
- package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
- package/dist/src/workflows/fallback-strategies.js +373 -0
- package/dist/src/workflows/message-queue.js +455 -0
- package/dist/src/workflows/model-router.js +189 -0
- package/dist/src/workflows/orchestrator-examples.js +174 -0
- package/dist/src/workflows/orchestrator-integration.js +200 -0
- package/dist/src/workflows/self-healing.js +524 -0
- package/dist/src/workflows/tool-mapper.js +407 -0
- package/dist/src/workflows/tool-orchestrator.js +796 -0
- package/dist/src/workflows/workflow-engine.js +573 -0
- package/dist/src/workflows/workflow-parser.js +283 -0
- package/dist/src/workflows/workflow-types.js +95 -0
- package/dist/src/workflows.js +568 -0
- package/dist/test-workflow-file-output.js +93 -0
- package/docs/API_KEYS.md +570 -0
- package/docs/CLAUDE_CODE_SETUP.md +181 -0
- package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
- package/docs/CONFIGURATION.md +745 -0
- package/docs/FOCUS_MODES.md +240 -0
- package/docs/INSTALLATION_BOTH.md +145 -0
- package/docs/TERMS.md +352 -0
- package/docs/TOOLS_REFERENCE.md +1622 -0
- package/docs/TOOL_PARAMETERS.md +496 -0
- package/docs/TOOL_PROFILES.md +236 -0
- package/docs/WORKFLOWS.md +987 -0
- package/docs/WORKFLOW_OUTPUT.md +198 -0
- package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
- package/docs/workflows/design-brainstorm.md +335 -0
- package/package.json +97 -0
- package/profiles/balanced.json +37 -0
- package/profiles/code_focus.json +37 -0
- package/profiles/debug_intensive.json +34 -0
- package/profiles/full.json +37 -0
- package/profiles/minimal.json +37 -0
- package/profiles/research_power.json +37 -0
- package/profiles/workflow_builder.json +37 -0
- package/smithery.yaml +66 -0
- package/start.sh +8 -0
- package/tools.config.json +81 -0
- package/tsconfig.json +18 -0
- package/workflows/accessibility-code-audit.yaml +92 -0
- package/workflows/code-architecture-review.yaml +202 -0
- package/workflows/code-review.yaml +142 -0
- package/workflows/core/iterative-problem-solver.yaml +283 -0
- package/workflows/creative-brainstorm-yaml.yaml +215 -0
- package/workflows/pingpong.yaml +141 -0
- package/workflows/system/README.md +412 -0
- package/workflows/system/challenger.yaml +175 -0
- package/workflows/system/scout.yaml +164 -0
- package/workflows/system/verifier.yaml +133 -0
- package/workflows/ultra-creative-brainstorm.yaml +318 -0
- package/workflows/ux-research-flow.yaml +92 -0
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CRITICAL FIX FOR MCPB: Redirect console.warn to console.error
|
|
3
|
+
// This prevents FastMCP's warnings from writing to stdout (which corrupts MCP JSON-RPC)
|
|
4
|
+
// FastMCP writes "[FastMCP warning] could not infer client capabilities" during init
|
|
5
|
+
// Must be done BEFORE any imports that use console
|
|
6
|
+
console.warn = function (...args) {
|
|
7
|
+
// Redirect all console.warn to stderr via console.error
|
|
8
|
+
console.error('[WARN]', ...args);
|
|
9
|
+
};
|
|
10
|
+
// Load environment variables FIRST, before any other imports
|
|
11
|
+
import { config as dotenvConfig } from 'dotenv';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = path.dirname(__filename);
|
|
16
|
+
// Load .env from project root (dist/src -> go up 2 levels)
|
|
17
|
+
// IMPORTANT: Use override:true to replace any env vars injected by Claude Code
|
|
18
|
+
const envPath = path.resolve(__dirname, '../../.env');
|
|
19
|
+
const envResult = dotenvConfig({
|
|
20
|
+
path: envPath,
|
|
21
|
+
override: true // Force override of existing env vars
|
|
22
|
+
});
|
|
23
|
+
// Debug: Log API key status (for troubleshooting)
|
|
24
|
+
if (process.env.DEBUG === 'true') {
|
|
25
|
+
console.error('[ENV] Loaded from:', envPath);
|
|
26
|
+
console.error('[ENV] API Keys present:', {
|
|
27
|
+
OPENROUTER: !!process.env.OPENROUTER_API_KEY,
|
|
28
|
+
PERPLEXITY: !!process.env.PERPLEXITY_API_KEY,
|
|
29
|
+
OPENAI: !!process.env.OPENAI_API_KEY,
|
|
30
|
+
GEMINI: !!process.env.GOOGLE_API_KEY,
|
|
31
|
+
GROK: !!process.env.GROK_API_KEY,
|
|
32
|
+
ANTHROPIC: !!process.env.ANTHROPIC_API_KEY
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
import { FastMCP, UserError } from "fastmcp";
|
|
36
|
+
import { z } from "zod";
|
|
37
|
+
import { InstructionOrchestrator } from "./orchestrator-instructions.js";
|
|
38
|
+
import { validateToolInput, sanitizeForLogging } from "./utils/input-validator.js";
|
|
39
|
+
import { isToolEnabled, logToolConfiguration } from "./utils/tool-config.js";
|
|
40
|
+
// import { WorkflowVisualizerLite } from "./visualizer-lite.js"; // Unused - removed
|
|
41
|
+
import { collaborativeOrchestrator } from "./collaborative-orchestrator.js";
|
|
42
|
+
import { sequentialThinking, NextThoughtSchema } from "./sequential-thinking.js";
|
|
43
|
+
import { getProviderInfo } from "./tools/unified-ai-provider.js";
|
|
44
|
+
import { getAllPerplexityTools, isPerplexityAvailable } from "./tools/perplexity-tools.js";
|
|
45
|
+
import { getAllGrokTools, isGrokAvailable } from "./tools/grok-tools.js";
|
|
46
|
+
import { registerWorkflowTools } from "./tools/workflow-runner.js";
|
|
47
|
+
import { validateWorkflowTool, validateWorkflowFileTool } from "./tools/workflow-validator-tool.js";
|
|
48
|
+
import { canRunFocusDeep } from "./focus-deep.js";
|
|
49
|
+
import { loadConfig } from "./config.js";
|
|
50
|
+
// import { registerSessionTools } from "./session/session-tools.js"; // Removed - not needed for minimal tool set
|
|
51
|
+
import { getAllAdvancedTools, areAdvancedModesAvailable } from "./tools/advanced-modes.js";
|
|
52
|
+
import { isOpenAIAvailable, getAllOpenAITools } from "./tools/openai-tools.js";
|
|
53
|
+
import { isGeminiAvailable, geminiBrainstormTool, geminiAnalyzeCodeTool } from "./tools/gemini-tools.js";
|
|
54
|
+
import { isOpenRouterAvailable } from "./tools/openrouter-tools.js";
|
|
55
|
+
// import { registerGPT5Tools, isGPT5Available } from "./tools/openai-gpt5-fixed.js"; // DISABLED - using regular openai-tools.ts
|
|
56
|
+
import { initializeOptimizations } from "./optimization/index.js";
|
|
57
|
+
import { FocusModeRegistry } from "./application/services/focus/FocusModeRegistry.js";
|
|
58
|
+
import { FocusToolService } from "./application/services/focus/FocusTool.service.js";
|
|
59
|
+
import { TachibotStatusMode } from "./application/services/focus/modes/tachibot-status.mode.js";
|
|
60
|
+
import { FocusDeepMode } from "./application/services/focus/modes/focus-deep.mode.js";
|
|
61
|
+
// Initialize optimizations (Phase 1)
|
|
62
|
+
// Note: Optimization system initialized but not actively used yet
|
|
63
|
+
// Cost limits are NOT enforced - set limits in provider dashboards instead
|
|
64
|
+
initializeOptimizations({
|
|
65
|
+
enableCaching: process.env.TACHI_ENABLE_CACHE !== 'false',
|
|
66
|
+
enableBatching: process.env.TACHI_ENABLE_BATCHING !== 'false',
|
|
67
|
+
});
|
|
68
|
+
// Create a new MCP server - TachiBot MCP v2.0
|
|
69
|
+
const server = new FastMCP({
|
|
70
|
+
name: "tachibot-mcp",
|
|
71
|
+
version: "2.0.0", // 12 consolidated tools, 2.6k tokens
|
|
72
|
+
});
|
|
73
|
+
// Load configuration
|
|
74
|
+
const config = loadConfig();
|
|
75
|
+
// Initialize Focus Tool Service with extracted modes
|
|
76
|
+
const focusModeRegistry = new FocusModeRegistry();
|
|
77
|
+
focusModeRegistry.register(new TachibotStatusMode());
|
|
78
|
+
focusModeRegistry.register(new FocusDeepMode());
|
|
79
|
+
const focusToolService = new FocusToolService(focusModeRegistry, collaborativeOrchestrator);
|
|
80
|
+
// Initialize orchestrator
|
|
81
|
+
const orchestrator = new InstructionOrchestrator();
|
|
82
|
+
// Set MCP server reference for collaborative orchestrator
|
|
83
|
+
collaborativeOrchestrator.setMCPServer(server);
|
|
84
|
+
// Track registered tools to prevent duplicates
|
|
85
|
+
const registeredTools = new Set();
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Helper function to safely register tools
|
|
88
|
+
// ============================================================================
|
|
89
|
+
function safeAddTool(tool) {
|
|
90
|
+
// Check if tool is enabled in configuration
|
|
91
|
+
if (!isToolEnabled(tool.name)) {
|
|
92
|
+
return; // Skip disabled tools silently (logging handled by isToolEnabled)
|
|
93
|
+
}
|
|
94
|
+
if (!registeredTools.has(tool.name)) {
|
|
95
|
+
server.addTool(tool);
|
|
96
|
+
registeredTools.add(tool.name);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.warn(`⚠️ Skipping duplicate tool registration: ${tool.name}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Add the original "think" tool (unchanged for backward compatibility)
|
|
103
|
+
safeAddTool({
|
|
104
|
+
name: "think",
|
|
105
|
+
description: "Log reasoning",
|
|
106
|
+
parameters: z.object({
|
|
107
|
+
thought: z.string()
|
|
108
|
+
}),
|
|
109
|
+
execute: async (args, context) => {
|
|
110
|
+
const { log } = context;
|
|
111
|
+
// Validate and sanitize input
|
|
112
|
+
const validation = validateToolInput(args.thought);
|
|
113
|
+
if (!validation.valid) {
|
|
114
|
+
throw new UserError(validation.error || "Invalid thought input");
|
|
115
|
+
}
|
|
116
|
+
const thought = validation.sanitized;
|
|
117
|
+
log.info("Thinking process", { thought: sanitizeForLogging(thought) });
|
|
118
|
+
return thought;
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
// Add the new "focus" tool with multiple reasoning strategies
|
|
122
|
+
safeAddTool({
|
|
123
|
+
name: "focus",
|
|
124
|
+
description: "Multi-model reasoning",
|
|
125
|
+
parameters: z.object({
|
|
126
|
+
query: z.string(),
|
|
127
|
+
mode: z.enum([
|
|
128
|
+
"simple", "debug", "deep-reasoning", "code-brainstorm",
|
|
129
|
+
"architecture-debate", "research", "analyze",
|
|
130
|
+
"focus-deep", "tachibot-status"
|
|
131
|
+
]).optional(),
|
|
132
|
+
context: z.string().optional(),
|
|
133
|
+
domain: z.enum([
|
|
134
|
+
"architecture", "algorithms", "debugging", "security",
|
|
135
|
+
"performance", "api_design", "database", "frontend",
|
|
136
|
+
"backend", "devops", "testing"
|
|
137
|
+
]).optional(),
|
|
138
|
+
tokenEfficient: z.boolean().optional(),
|
|
139
|
+
rounds: z.number().optional(),
|
|
140
|
+
executeNow: z.boolean().optional(),
|
|
141
|
+
models: z.array(z.string()).optional(),
|
|
142
|
+
temperature: z.number().optional(),
|
|
143
|
+
saveSession: z.boolean().optional(),
|
|
144
|
+
maxTokensPerRound: z.number().optional(),
|
|
145
|
+
pingPongStyle: z.enum(["competitive", "collaborative", "debate", "build-upon"]).optional()
|
|
146
|
+
}),
|
|
147
|
+
execute: async (args, mcpContext) => {
|
|
148
|
+
const { log } = mcpContext;
|
|
149
|
+
let { query, mode = "simple", context, domain, tokenEfficient = false, rounds = 5, executeNow = true, models, temperature = 0.7, saveSession = true, maxTokensPerRound = 2000, pingPongStyle = "collaborative" } = args;
|
|
150
|
+
// Validate and sanitize input
|
|
151
|
+
const queryValidation = validateToolInput(query);
|
|
152
|
+
if (!queryValidation.valid) {
|
|
153
|
+
throw new UserError(queryValidation.error || "Invalid query input");
|
|
154
|
+
}
|
|
155
|
+
query = queryValidation.sanitized; // Replace with sanitized version
|
|
156
|
+
const contextValidation = context ? validateToolInput(context) : { valid: true, sanitized: context };
|
|
157
|
+
if (!contextValidation.valid) {
|
|
158
|
+
throw new UserError(contextValidation.error || "Invalid context input");
|
|
159
|
+
}
|
|
160
|
+
context = contextValidation.sanitized; // Replace with sanitized version
|
|
161
|
+
log.info("Focus session started", {
|
|
162
|
+
query: sanitizeForLogging(query),
|
|
163
|
+
mode,
|
|
164
|
+
context: context ? sanitizeForLogging(context) : undefined,
|
|
165
|
+
tokenEfficient
|
|
166
|
+
});
|
|
167
|
+
// Initialize orchestrator if needed
|
|
168
|
+
await orchestrator.initialize();
|
|
169
|
+
// Try FocusToolService first (handles extracted modes and delegate modes)
|
|
170
|
+
try {
|
|
171
|
+
const result = await focusToolService.execute({
|
|
172
|
+
query,
|
|
173
|
+
mode,
|
|
174
|
+
context,
|
|
175
|
+
domain,
|
|
176
|
+
tokenEfficient,
|
|
177
|
+
rounds,
|
|
178
|
+
models,
|
|
179
|
+
temperature
|
|
180
|
+
});
|
|
181
|
+
return result.output;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
// Mode not handled by service - fall through to legacy switch
|
|
185
|
+
if (error instanceof Error && !error.message.includes('not handled by FocusToolService')) {
|
|
186
|
+
// Real error, not just mode not found - rethrow
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Legacy modes not yet migrated to FocusToolService
|
|
191
|
+
// These modes have complex conditional logic that needs further refactoring
|
|
192
|
+
switch (mode) {
|
|
193
|
+
case "research":
|
|
194
|
+
case "investigate":
|
|
195
|
+
case "solve":
|
|
196
|
+
case "analyze":
|
|
197
|
+
case "synthesis":
|
|
198
|
+
case "integrate":
|
|
199
|
+
case "fact-check":
|
|
200
|
+
case "verify":
|
|
201
|
+
case "validate":
|
|
202
|
+
// These modes not yet implemented - return plan for now
|
|
203
|
+
try {
|
|
204
|
+
const plan = orchestrator.generateOrchestrationPlan(mode, query, context);
|
|
205
|
+
// Token-efficient response
|
|
206
|
+
if (tokenEfficient) {
|
|
207
|
+
return `TachiBot orchestrating...\n\n${plan.visualGuide}`;
|
|
208
|
+
}
|
|
209
|
+
// Full response
|
|
210
|
+
return `${orchestrator.formatInstructions(plan)}
|
|
211
|
+
|
|
212
|
+
🎯 **Next Steps**: Execute the tools above in sequence, then call focus with mode="reflect" to synthesize results.`;
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
216
|
+
log.error("Orchestration error", { error: errorMessage });
|
|
217
|
+
return `Error generating orchestration plan: ${errorMessage}`;
|
|
218
|
+
}
|
|
219
|
+
case "debug":
|
|
220
|
+
return `🔍 DEBUG MODE ACTIVE
|
|
221
|
+
|
|
222
|
+
Debug Analysis for: "${query}"
|
|
223
|
+
${context ? `Context: ${context}` : ''}
|
|
224
|
+
|
|
225
|
+
• Workflow Options: creative, research, solve, synthesis, fact-check
|
|
226
|
+
• Available Tools: gemini_brainstorm, perplexity_research, openai_reason, think
|
|
227
|
+
• Token Mode: ${tokenEfficient ? 'Efficient' : 'Full'}
|
|
228
|
+
• Ready for orchestration
|
|
229
|
+
|
|
230
|
+
Use one of the workflow modes to generate an execution plan.`;
|
|
231
|
+
case "reflect":
|
|
232
|
+
case "review":
|
|
233
|
+
return `🪞 REFLECTION MODE - COLLECTIVE SYNTHESIS
|
|
234
|
+
|
|
235
|
+
## 🧠 TachiBot Collective Synthesis
|
|
236
|
+
|
|
237
|
+
To synthesize results from your orchestration:
|
|
238
|
+
|
|
239
|
+
1. **Review Outputs**: Examine results from each tool in the workflow
|
|
240
|
+
2. **Identify Patterns**: Look for convergent themes and insights
|
|
241
|
+
3. **Resolve Contradictions**: Address any conflicting information
|
|
242
|
+
4. **Extract Key Insights**: Distill the most important findings
|
|
243
|
+
5. **Create Action Plan**: Develop next steps based on synthesis
|
|
244
|
+
|
|
245
|
+
### Tips for Effective Synthesis:
|
|
246
|
+
• Compare creative ideas with analytical validation
|
|
247
|
+
• Look for unexpected connections between tools
|
|
248
|
+
• Consider both immediate and long-term implications
|
|
249
|
+
• Identify knowledge gaps that need further exploration
|
|
250
|
+
|
|
251
|
+
Ready to help synthesize your collective intelligence results!`;
|
|
252
|
+
default: // simple mode
|
|
253
|
+
return `🎯 FOCUS MODE ACTIVE
|
|
254
|
+
|
|
255
|
+
Enhanced reasoning for: "${query}"
|
|
256
|
+
${context ? `Context: ${context}` : ''}
|
|
257
|
+
|
|
258
|
+
## 🧠 Collaborative Reasoning Modes:
|
|
259
|
+
• **deep-reasoning**: Multi-model collaboration with critique and synthesis
|
|
260
|
+
• **code-brainstorm**: Technical brainstorming for coding solutions
|
|
261
|
+
• **dynamic-debate**: Models argue different perspectives with rebuttals
|
|
262
|
+
• **architecture-debate**: Models debate architectural approaches
|
|
263
|
+
• **algorithm-optimize**: Iterative algorithm improvement
|
|
264
|
+
• **security-audit**: Multi-model security analysis
|
|
265
|
+
• **api-design**: Collaborative API design
|
|
266
|
+
• **debug-detective**: Collaborative debugging session
|
|
267
|
+
• **performance-council**: Team-based performance optimization
|
|
268
|
+
|
|
269
|
+
## 🔧 Classic Modes:
|
|
270
|
+
• **research/investigate**: Deep investigation with evidence
|
|
271
|
+
• **solve/analyze**: Systematic problem-solving
|
|
272
|
+
• **synthesis/integrate**: Combine multiple perspectives
|
|
273
|
+
• **fact-check/verify**: Validate claims with evidence
|
|
274
|
+
|
|
275
|
+
## 🚀 For Advanced Multi-Round Workflows:
|
|
276
|
+
Use the **workflow** tool for complex multi-step tasks with file-based outputs:
|
|
277
|
+
• \`workflow --name brainstorm-workflow\` - 7-step comprehensive brainstorming
|
|
278
|
+
• \`workflow --name pingpong-debate-3rounds\` - 3-round multi-model debate
|
|
279
|
+
• Workflows bypass the 25k MCP token limit by saving results to files
|
|
280
|
+
|
|
281
|
+
## 📚 Help Commands:
|
|
282
|
+
• \`focus --mode list-templates\` - See all available templates
|
|
283
|
+
• \`focus --mode examples\` - See example workflows
|
|
284
|
+
• \`workflow --action list\` - See all available workflows
|
|
285
|
+
|
|
286
|
+
## Example Usage:
|
|
287
|
+
\`\`\`
|
|
288
|
+
focus --mode deep-reasoning "How to scale a real-time collaboration system"
|
|
289
|
+
focus --mode dynamic-debate "TypeScript vs JavaScript for large codebases" --temperature 0.9
|
|
290
|
+
focus --mode code-brainstorm "Optimize React component performance"
|
|
291
|
+
focus --mode architecture-debate "Microservices vs Monolith for MVP"
|
|
292
|
+
focus --mode debug-detective "Memory leak in React app"
|
|
293
|
+
|
|
294
|
+
# For complex multi-round tasks, use workflows instead:
|
|
295
|
+
workflow --name pingpong-debate-3rounds --input '{"problem": "Revolutionary features for social media apps"}'
|
|
296
|
+
workflow --name brainstorm-workflow --input '{"topic": "AI-powered code review tools"}'
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
## 💡 Advanced Ping-Pong Features:
|
|
300
|
+
- **Multi-model ecosystem**: Grok + Claude Code + Qwen + OpenAI + Perplexity + Gemini
|
|
301
|
+
- **Configurable rounds**: 1-30 rounds (with cost warnings)
|
|
302
|
+
- **Custom model selection**: Pick your dream team
|
|
303
|
+
- **Interaction styles**: competitive, collaborative, debate, build-upon
|
|
304
|
+
- **Temperature control**: 0 (focused) to 1 (very creative)
|
|
305
|
+
- **Auto-save sessions**: Timestamped for later review
|
|
306
|
+
|
|
307
|
+
Focus session ready. Choose a mode to begin orchestration.`;
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
// Add Sequential Thinking tool
|
|
312
|
+
safeAddTool({
|
|
313
|
+
name: "nextThought",
|
|
314
|
+
description: "Sequential thinking",
|
|
315
|
+
parameters: NextThoughtSchema,
|
|
316
|
+
execute: async (args, context) => {
|
|
317
|
+
const { log } = context;
|
|
318
|
+
try {
|
|
319
|
+
// Validate and sanitize thought input
|
|
320
|
+
const validation = validateToolInput(args.thought);
|
|
321
|
+
if (!validation.valid) {
|
|
322
|
+
throw new UserError(validation.error || "Invalid thought input");
|
|
323
|
+
}
|
|
324
|
+
const thought = validation.sanitized;
|
|
325
|
+
const result = sequentialThinking.nextThought(thought, args.nextThoughtNeeded, args.thoughtNumber, args.totalThoughts, args.isRevision, args.revisesThought, args.branchFromThought, args.model);
|
|
326
|
+
log.info("Sequential thought added", {
|
|
327
|
+
thoughtNumber: result.thoughtAdded.number,
|
|
328
|
+
model: result.thoughtAdded.model
|
|
329
|
+
});
|
|
330
|
+
return result.guidance;
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
334
|
+
log.error("Sequential thinking error", { error: errorMessage });
|
|
335
|
+
return `Error in sequential thinking: ${errorMessage}`;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
// Skip registering generic unified AI tools - we have specific provider tools
|
|
340
|
+
// Commenting out to save ~1.5k tokens as these are redundant
|
|
341
|
+
// const unifiedAITools = getUnifiedAITools();
|
|
342
|
+
// unifiedAITools.forEach(tool => {
|
|
343
|
+
// safeAddTool(tool);
|
|
344
|
+
// });
|
|
345
|
+
// Get provider info for status display
|
|
346
|
+
const providerInfo = getProviderInfo();
|
|
347
|
+
const availableProviders = Object.entries(providerInfo)
|
|
348
|
+
.filter(([_, info]) => info.available)
|
|
349
|
+
.map(([name]) => name);
|
|
350
|
+
console.error(`✅ Available AI providers: ${availableProviders.join(', ')}`);
|
|
351
|
+
// Register Perplexity tools separately (custom API, not OpenAI-compatible)
|
|
352
|
+
if (isPerplexityAvailable()) {
|
|
353
|
+
const perplexityTools = getAllPerplexityTools();
|
|
354
|
+
perplexityTools.forEach(tool => {
|
|
355
|
+
safeAddTool(tool);
|
|
356
|
+
});
|
|
357
|
+
console.error(`✅ Registered ${perplexityTools.length} Perplexity tools (custom API)`);
|
|
358
|
+
}
|
|
359
|
+
// Register Grok tools separately (custom API, not OpenAI-compatible)
|
|
360
|
+
if (isGrokAvailable()) {
|
|
361
|
+
const grokTools = getAllGrokTools();
|
|
362
|
+
grokTools.forEach(tool => {
|
|
363
|
+
safeAddTool(tool);
|
|
364
|
+
});
|
|
365
|
+
console.error(`✅ Registered ${grokTools.length} Grok tools (custom API)`);
|
|
366
|
+
}
|
|
367
|
+
// Register all OpenAI tools (includes gpt5_analyze, gpt5_reason, openai_compare, etc.)
|
|
368
|
+
if (isOpenAIAvailable()) {
|
|
369
|
+
const openaiTools = getAllOpenAITools();
|
|
370
|
+
openaiTools.forEach(tool => {
|
|
371
|
+
safeAddTool(tool);
|
|
372
|
+
});
|
|
373
|
+
console.error(`✅ Registered ${openaiTools.length} OpenAI tools (GPT-5 suite)`);
|
|
374
|
+
}
|
|
375
|
+
// Async initialization function to handle dynamic imports and startup
|
|
376
|
+
async function initializeServer() {
|
|
377
|
+
try {
|
|
378
|
+
// Register select Gemini tools (brainstorm and analyze)
|
|
379
|
+
if (isGeminiAvailable()) {
|
|
380
|
+
const { geminiAnalyzeTextTool } = await import("./tools/gemini-tools.js");
|
|
381
|
+
const geminiTools = [
|
|
382
|
+
geminiBrainstormTool, // Creative brainstorming
|
|
383
|
+
geminiAnalyzeCodeTool, // Code analysis
|
|
384
|
+
geminiAnalyzeTextTool // Text analysis (sentiment, summary, etc.)
|
|
385
|
+
];
|
|
386
|
+
geminiTools.forEach(tool => {
|
|
387
|
+
safeAddTool(tool);
|
|
388
|
+
});
|
|
389
|
+
console.error(`✅ Registered ${geminiTools.length} Gemini tools (brainstorm, code analysis, text analysis)`);
|
|
390
|
+
}
|
|
391
|
+
// Register OpenRouter tools (Qwen3 Coder, Kimi - selective based on flags)
|
|
392
|
+
if (isOpenRouterAvailable()) {
|
|
393
|
+
const { qwenCoderTool, qwenCompetitiveTool, kimiThinkingTool } = await import("./tools/openrouter-tools.js");
|
|
394
|
+
// Always register qwen_coder
|
|
395
|
+
safeAddTool(qwenCoderTool);
|
|
396
|
+
let toolCount = 1;
|
|
397
|
+
// Always register kimi_thinking (advanced agentic reasoning)
|
|
398
|
+
safeAddTool(kimiThinkingTool);
|
|
399
|
+
toolCount++;
|
|
400
|
+
// Optional: Enable for competitive programming (LeetCode grinding)
|
|
401
|
+
if (process.env.ENABLE_QWEN_COMPETITIVE === 'true') {
|
|
402
|
+
safeAddTool(qwenCompetitiveTool);
|
|
403
|
+
toolCount++;
|
|
404
|
+
console.error(`🏆 Competitive programming mode enabled (qwen_competitive)`);
|
|
405
|
+
}
|
|
406
|
+
console.error(`✅ Registered ${toolCount} OpenRouter tools (Qwen3, Kimi)`);
|
|
407
|
+
}
|
|
408
|
+
// Register workflow tools
|
|
409
|
+
registerWorkflowTools(server);
|
|
410
|
+
console.error(`✅ Registered workflow tools (execute, list, create, visualize)`);
|
|
411
|
+
// Register workflow validator tools
|
|
412
|
+
safeAddTool(validateWorkflowTool);
|
|
413
|
+
safeAddTool(validateWorkflowFileTool);
|
|
414
|
+
console.error(`✅ Registered workflow validator tools`);
|
|
415
|
+
// Session management tools removed - not needed for minimal TachiBot
|
|
416
|
+
// Register advanced mode tools (Verifier, Challenger, Scout, etc.)
|
|
417
|
+
if (areAdvancedModesAvailable()) {
|
|
418
|
+
const advancedTools = getAllAdvancedTools();
|
|
419
|
+
advancedTools.forEach(tool => {
|
|
420
|
+
safeAddTool(tool);
|
|
421
|
+
});
|
|
422
|
+
console.error(`✅ Registered ${advancedTools.length} advanced mode tools`);
|
|
423
|
+
}
|
|
424
|
+
// Log startup information
|
|
425
|
+
const perplexityCount = isPerplexityAvailable() ? getAllPerplexityTools().length : 0;
|
|
426
|
+
const grokCount = isGrokAvailable() ? getAllGrokTools().length : 0;
|
|
427
|
+
const openaiCount = isOpenAIAvailable() ? getAllOpenAITools().length : 0;
|
|
428
|
+
const geminiCount = isGeminiAvailable() ? 3 : 0; // gemini_brainstorm, gemini_analyze_code, gemini_analyze_text
|
|
429
|
+
const qwenCount = isOpenRouterAvailable() ? 1 : 0; // qwen_coder (plus competitive if enabled)
|
|
430
|
+
const advancedCount = areAdvancedModesAvailable() ? getAllAdvancedTools().length : 0;
|
|
431
|
+
const workflowCount = 4; // workflow tools
|
|
432
|
+
const coreCount = 3; // think, focus, nextThought
|
|
433
|
+
const totalTools = coreCount + perplexityCount + grokCount + openaiCount + geminiCount + qwenCount + advancedCount + workflowCount;
|
|
434
|
+
console.error(`🚀 TachiBot MCP Server v5.0 - Minimal Tool Set Edition`);
|
|
435
|
+
console.error(`Mode: ${config.isClaudeCode ? 'Claude Code' : 'Standalone'}`);
|
|
436
|
+
console.error(`Tools registered: ${registeredTools.size} active (${totalTools} available)`);
|
|
437
|
+
logToolConfiguration();
|
|
438
|
+
if (config.isClaudeCode) {
|
|
439
|
+
console.error(`Claude model: ${config.claudeModel}`);
|
|
440
|
+
}
|
|
441
|
+
console.error(`Focus-Deep: ${canRunFocusDeep().quality} quality`);
|
|
442
|
+
// API Key Status (quick check)
|
|
443
|
+
const apiStatus = {
|
|
444
|
+
OpenRouter: !!process.env.OPENROUTER_API_KEY,
|
|
445
|
+
Perplexity: !!process.env.PERPLEXITY_API_KEY,
|
|
446
|
+
OpenAI: !!process.env.OPENAI_API_KEY,
|
|
447
|
+
Gemini: !!process.env.GOOGLE_API_KEY,
|
|
448
|
+
Grok: !!process.env.GROK_API_KEY
|
|
449
|
+
};
|
|
450
|
+
const configured = Object.entries(apiStatus).filter(([_, v]) => v).map(([k, _]) => k);
|
|
451
|
+
if (configured.length > 0) {
|
|
452
|
+
console.error(`🔑 API Keys: ${configured.join(', ')}`);
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
console.error(`⚠️ No API keys configured. Add them to .env to enable external tools.`);
|
|
456
|
+
}
|
|
457
|
+
console.error(`Ready for orchestration!`);
|
|
458
|
+
// Start the server with stdio transport
|
|
459
|
+
console.error("🚀 Starting server with stdio transport...");
|
|
460
|
+
server.start({
|
|
461
|
+
transportType: "stdio",
|
|
462
|
+
});
|
|
463
|
+
console.error("✅ Server.start() called successfully");
|
|
464
|
+
// Keep the process alive with a heartbeat
|
|
465
|
+
// This ensures the server doesn't exit prematurely
|
|
466
|
+
const heartbeatInterval = setInterval(() => {
|
|
467
|
+
// Heartbeat to keep process alive
|
|
468
|
+
// Log every 30 seconds to show we're still alive
|
|
469
|
+
const now = new Date().toISOString();
|
|
470
|
+
console.error(`💓 Heartbeat: Server still alive at ${now}`);
|
|
471
|
+
}, 30000); // Every 30 seconds
|
|
472
|
+
console.error("✅ Heartbeat interval established");
|
|
473
|
+
console.error("✅ Server started successfully and listening for MCP commands");
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
console.error("❌ Server initialization failed:", error);
|
|
477
|
+
process.exit(1);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
// Debug: Log that the script is starting
|
|
481
|
+
console.error("🔧 TachiBot MCP Server starting up...");
|
|
482
|
+
console.error(`🔧 Node version: ${process.version}`);
|
|
483
|
+
console.error(`🔧 Working directory: ${process.cwd()}`);
|
|
484
|
+
// Keep the process alive
|
|
485
|
+
console.error("📌 Setting up process.stdin.resume() to keep process alive");
|
|
486
|
+
process.stdin.resume();
|
|
487
|
+
// Handle process termination gracefully
|
|
488
|
+
process.on('SIGINT', () => {
|
|
489
|
+
console.error('Received SIGINT, shutting down gracefully...');
|
|
490
|
+
process.exit(0);
|
|
491
|
+
});
|
|
492
|
+
process.on('SIGTERM', () => {
|
|
493
|
+
console.error('Received SIGTERM, shutting down gracefully...');
|
|
494
|
+
process.exit(0);
|
|
495
|
+
});
|
|
496
|
+
// Catch unhandled promise rejections
|
|
497
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
498
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
499
|
+
// Don't exit on unhandled rejection - log and continue
|
|
500
|
+
});
|
|
501
|
+
// Catch uncaught exceptions
|
|
502
|
+
process.on('uncaughtException', (error) => {
|
|
503
|
+
console.error('Uncaught Exception:', error);
|
|
504
|
+
// For MCP servers, we should try to continue if possible
|
|
505
|
+
// Only exit if it's a critical error
|
|
506
|
+
if (error.message?.includes('EADDRINUSE') || error.message?.includes('EACCES')) {
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
// Initialize and start the server
|
|
511
|
+
initializeServer().catch((error) => {
|
|
512
|
+
console.error("❌ Fatal error during server startup:", error);
|
|
513
|
+
process.exit(1);
|
|
514
|
+
});
|