├── .gitignore ├── LICENSE ├── README.md ├── examples.md ├── package-lock.json ├── package.json ├── src ├── branchManager.ts ├── index.ts └── types.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | 7 | # TypeScript 8 | dist/ 9 | build/ 10 | *.tsbuildinfo 11 | 12 | # IDE/Editor 13 | .vscode/ 14 | .idea/ 15 | *.swp 16 | *.swo 17 | .DS_Store 18 | Thumbs.db 19 | 20 | # Environment variables 21 | .env 22 | .env.local 23 | .env.*.local 24 | 25 | # Logs 26 | logs/ 27 | *.log 28 | 29 | # Testing 30 | coverage/ 31 | 32 | # Temporary files 33 | tmp/ 34 | temp/ 35 | 36 | # Debug files 37 | .node-debug/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Mike Siles 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Branch Thinking 2 | 3 | An MCP server that implements branch-based thought navigation, with support for: 4 | - Multiple branches of thought 5 | - Branch navigation (list, focus, history) 6 | - Cross-references between related thoughts 7 | - Insight generation from key points 8 | - Branch priority tracking 9 | 10 | This is based on the `sequential-thinking` tool available here: 11 | https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking 12 | 13 | ## Features 14 | 15 | - **Branch Management**: Create and navigate between different lines of thought 16 | - **Cross References**: Link related thoughts across branches with typed relationships 17 | - **Insights**: Automatically generate insights from key points in thoughts 18 | - **Priority Tracking**: Track branch priorities based on confidence and connections 19 | 20 | ## Commands 21 | 22 | - `list`: Show all branches with their current status 23 | - `focus [branchId]`: Switch focus to a specific branch 24 | - `history [branchId?]`: Show the history of thoughts in a branch 25 | 26 | ## Installation 27 | Place this project in your custom MCP tool directory. 28 | 29 | ```bash 30 | npm install 31 | npm run build 32 | ``` 33 | 34 | Add to your `claude_desktop_config.json`: 35 | ```json 36 | "branch-thinking": { 37 | "command": "node", 38 | "args": [ 39 | "/your-custom-mcp-dir-here/branch-thinking/dist/index.js" 40 | ] 41 | } 42 | ``` 43 | 44 | ## Tips 45 | Claude often will not use tools unless explicitly prompted to do so. 46 | 47 | If you want to use this tool without being prompted, add to either your Claude Profile Settings (or a system prompt) something like so: 48 | 49 | 50 | _If I ask you to "think step by step," "think before you respond," or "use chain of thought," that means use the branch-thinking tool. Don't hesitate to use the branch-thinking tool on your own if you think your response would benefit from multiple steps._ 51 | 52 | ## Credits 53 | I can't pretend that I wrote most of this code. Most of it was generated by Claude. The concept was my own, and so were testing, fixes, and implementation. 54 | -------------------------------------------------------------------------------- /examples.md: -------------------------------------------------------------------------------- 1 | # Branch Thinking Examples 2 | 3 | Below are some examples of prompts that can be used with the branch-thinking MCP tool. You should prepend instructions for Claude to explicitly use branch-thinking if your system prompt or Claude profile settings do not do so already. See the README. 4 | 5 | ## Adversarial Thinking / Red Teaming 6 | 7 | Analyze security from multiple perspectives, tracking attack vectors and defenses: 8 | 9 | ```javascript 10 | // Main branch - system description 11 | { 12 | "content": "Proposed system: Users can reset passwords via email link plus answering two security questions.", 13 | "type": "system_design", 14 | "keyPoints": ["email verification", "security questions", "password reset"] 15 | } 16 | 17 | // Attack branch - examining vulnerabilities 18 | { 19 | "content": "Examining potential social engineering vectors targeting the security question system.", 20 | "type": "threat_analysis", 21 | "branchId": "attack-vectors", 22 | "crossRefs": [{ 23 | "toBranch": "main-[timestamp]", 24 | "type": "analyzes", 25 | "reason": "Identifying vulnerabilities in security questions", 26 | "strength": 0.9 27 | }], 28 | "keyPoints": ["social media mining", "phishing risks", "question predictability"] 29 | } 30 | 31 | // Defense branch - countermeasures 32 | { 33 | "content": "Implement ML-based anomaly detection for suspicious reset patterns.", 34 | "type": "mitigation", 35 | "branchId": "defense-ml", 36 | "crossRefs": [{ 37 | "toBranch": "attack-vectors", 38 | "type": "counters", 39 | "reason": "Detects automated social engineering attempts", 40 | "strength": 0.85 41 | }] 42 | } 43 | ``` 44 | 45 | ## Scientific Method Application 46 | 47 | Apply scientific method to problem investigation: 48 | 49 | ```javascript 50 | // Main observation 51 | { 52 | "content": "System exhibits 2-3 second delays during peak hours despite hardware upgrades.", 53 | "type": "observation", 54 | "keyPoints": ["peak hours", "latency", "hardware sufficient"] 55 | } 56 | 57 | // First hypothesis 58 | { 59 | "content": "Network congestion at the load balancer level is causing request queuing.", 60 | "type": "hypothesis", 61 | "branchId": "network-hypothesis", 62 | "crossRefs": [{ 63 | "toBranch": "main-[timestamp]", 64 | "type": "explains", 65 | "reason": "Network bottleneck could explain timing correlation", 66 | "strength": 0.75 67 | }] 68 | } 69 | 70 | // Experiment design 71 | { 72 | "content": "Deploy network monitoring at load balancer with packet analysis during peak hours.", 73 | "type": "experiment", 74 | "branchId": "network-test", 75 | "crossRefs": [{ 76 | "toBranch": "network-hypothesis", 77 | "type": "tests", 78 | "reason": "Will verify network congestion theory", 79 | "strength": 0.9 80 | }] 81 | } 82 | ``` 83 | 84 | ## Design Pattern Exploration 85 | 86 | Compare and combine different design patterns: 87 | 88 | ```javascript 89 | // Main requirement 90 | { 91 | "content": "Need to design a plugin system that allows third-party developers to extend application functionality.", 92 | "type": "requirement", 93 | "keyPoints": ["extensibility", "third-party", "plugin interface"] 94 | } 95 | 96 | // Strategy Pattern approach 97 | { 98 | "content": "Implement using Strategy pattern: define plugin interface, allow runtime loading of implementations.", 99 | "type": "pattern_analysis", 100 | "branchId": "strategy-pattern", 101 | "keyPoints": ["interface definition", "runtime loading", "loose coupling"] 102 | } 103 | 104 | // Observer Pattern combination 105 | { 106 | "content": "Use Observer pattern for plugins to react to application events without tight coupling.", 107 | "type": "pattern_analysis", 108 | "branchId": "observer-pattern", 109 | "crossRefs": [{ 110 | "toBranch": "strategy-pattern", 111 | "type": "complements", 112 | "reason": "Can combine with Strategy for event-driven plugins", 113 | "strength": 0.85 114 | }] 115 | } 116 | ``` 117 | 118 | ## Debate Mapping 119 | 120 | Map out complex debates and positions: 121 | 122 | ```javascript 123 | // Central claim 124 | { 125 | "content": "AI monitoring systems should be mandatory in all production code deployments.", 126 | "type": "claim", 127 | "keyPoints": ["AI monitoring", "mandatory implementation", "production code"] 128 | } 129 | 130 | // Supporting argument 131 | { 132 | "content": "AI systems can detect anomalies and potential failures faster than human monitoring.", 133 | "type": "argument_pro", 134 | "branchId": "pro-detection", 135 | "crossRefs": [{ 136 | "toBranch": "main-[timestamp]", 137 | "type": "supports", 138 | "reason": "Demonstrates clear technical advantage", 139 | "strength": 0.9 140 | }] 141 | } 142 | 143 | // Counter argument 144 | { 145 | "content": "False positives from AI systems could lead to unnecessary downtime and team fatigue.", 146 | "type": "argument_con", 147 | "branchId": "con-reliability", 148 | "crossRefs": [{ 149 | "toBranch": "pro-detection", 150 | "type": "challenges", 151 | "reason": "Questions reliability assumption", 152 | "strength": 0.8 153 | }] 154 | } 155 | ``` 156 | 157 | ## Strategy Development 158 | 159 | Develop strategic plans with scenarios and responses: 160 | 161 | ```javascript 162 | // Main strategy 163 | { 164 | "content": "Propose migrating our on-premise systems to cloud infrastructure over 18 months.", 165 | "type": "strategy", 166 | "keyPoints": ["cloud migration", "18-month timeline", "on-premise transition"] 167 | } 168 | 169 | // Risk scenario 170 | { 171 | "content": "What if we experience data sovereignty issues in key markets?", 172 | "type": "scenario", 173 | "branchId": "sovereignty-risk", 174 | "crossRefs": [{ 175 | "toBranch": "main-[timestamp]", 176 | "type": "risk_analysis", 177 | "reason": "Critical regulatory consideration", 178 | "strength": 0.9 179 | }] 180 | } 181 | 182 | // Response plan 183 | { 184 | "content": "Hybrid cloud approach using local data centers for affected regions.", 185 | "type": "response", 186 | "branchId": "hybrid-solution", 187 | "crossRefs": [{ 188 | "toBranch": "sovereignty-risk", 189 | "type": "addresses", 190 | "reason": "Provides regulatory compliance solution", 191 | "strength": 0.95 192 | }] 193 | } 194 | ``` 195 | 196 | ## Complex Debugging 197 | 198 | Navigate complex debugging scenarios: 199 | 200 | ```javascript 201 | // Bug description 202 | { 203 | "content": "Users report random session terminations during file uploads larger than 100MB.", 204 | "type": "bug_report", 205 | "keyPoints": ["session termination", "large uploads", "intermittent"] 206 | } 207 | 208 | // First hypothesis 209 | { 210 | "content": "Timeout settings in load balancer might be too aggressive for large uploads.", 211 | "type": "hypothesis", 212 | "branchId": "timeout-theory", 213 | "crossRefs": [{ 214 | "toBranch": "main-[timestamp]", 215 | "type": "explains", 216 | "reason": "Would account for size correlation", 217 | "strength": 0.8 218 | }] 219 | } 220 | 221 | // Test plan 222 | { 223 | "content": "Monitor timeout events in load balancer logs during large file uploads.", 224 | "type": "test", 225 | "branchId": "timeout-test", 226 | "crossRefs": [{ 227 | "toBranch": "timeout-theory", 228 | "type": "validates", 229 | "reason": "Will confirm timeout hypothesis", 230 | "strength": 0.9 231 | }] 232 | } 233 | ``` 234 | 235 | ## Requirements Analysis 236 | 237 | Break down complex requirements: 238 | 239 | ```javascript 240 | // Main requirements 241 | { 242 | "content": "Need secure but user-friendly authentication for mobile banking app.", 243 | "type": "requirement", 244 | "keyPoints": ["security", "user experience", "mobile context"] 245 | } 246 | 247 | // User needs branch 248 | { 249 | "content": "Users want quick access without remembering complex passwords.", 250 | "type": "user_requirement", 251 | "branchId": "user-needs", 252 | "crossRefs": [{ 253 | "toBranch": "main-[timestamp]", 254 | "type": "stakeholder_input", 255 | "reason": "Primary user concern", 256 | "strength": 0.9 257 | }] 258 | } 259 | 260 | // Security requirements 261 | { 262 | "content": "Must meet FFIEC authentication guidelines and protect against common mobile attack vectors.", 263 | "type": "security_requirement", 264 | "branchId": "security-needs", 265 | "crossRefs": [{ 266 | "toBranch": "user-needs", 267 | "type": "constrains", 268 | "reason": "May limit some quick-access options", 269 | "strength": 0.7 270 | }] 271 | } 272 | ``` 273 | 274 | ## Trade-off Analysis 275 | 276 | Analyze complex trade-offs between different approaches: 277 | 278 | ```javascript 279 | // Main context 280 | { 281 | "content": "Need to choose a state management approach for a large-scale React application with real-time updates.", 282 | "type": "context", 283 | "keyPoints": ["large scale", "real-time", "React", "state management"] 284 | } 285 | 286 | // Redux analysis 287 | { 288 | "content": "Using Redux with middleware for real-time updates. Provides centralized store and clear data flow.", 289 | "type": "solution", 290 | "branchId": "redux-approach", 291 | "keyPoints": ["centralized", "middleware", "predictable"], 292 | "confidence": 0.85 293 | } 294 | 295 | // Context+Hooks alternative 296 | { 297 | "content": "Using React Context with custom hooks for local state. More flexible but potential prop drilling issues.", 298 | "type": "solution", 299 | "branchId": "context-approach", 300 | "crossRefs": [{ 301 | "toBranch": "redux-approach", 302 | "type": "alternative", 303 | "reason": "Lighter weight solution with different trade-offs", 304 | "strength": 0.8 305 | }] 306 | } 307 | ``` 308 | 309 | ## System Evolution Planning 310 | 311 | Plan system evolution over time: 312 | 313 | ```javascript 314 | // Current state 315 | { 316 | "content": "Current logging system uses ELK stack with custom parsers, serving 100GB/day.", 317 | "type": "analysis", 318 | "keyPoints": ["ELK stack", "custom parsers", "100GB daily"] 319 | } 320 | 321 | // Short-term improvements 322 | { 323 | "content": "Optimize Elasticsearch indices and implement log rotation policies.", 324 | "type": "plan", 325 | "branchId": "short-term", 326 | "crossRefs": [{ 327 | "toBranch": "main-[timestamp]", 328 | "type": "enhances", 329 | "reason": "Immediate optimizations for current system", 330 | "strength": 0.9 331 | }] 332 | } 333 | 334 | // Long-term vision 335 | { 336 | "content": "Transition to cloud-native observability platform with OpenTelemetry.", 337 | "type": "vision", 338 | "branchId": "long-term", 339 | "crossRefs": [{ 340 | "toBranch": "short-term", 341 | "type": "builds_upon", 342 | "reason": "Evolution of logging architecture", 343 | "strength": 0.7 344 | }] 345 | } 346 | ``` 347 | 348 | ## Feature Decomposition 349 | 350 | Break down complex features: 351 | 352 | ```javascript 353 | // Feature request 354 | { 355 | "content": "Implement 'collaborative document editing' with real-time updates and conflict resolution.", 356 | "type": "feature", 357 | "keyPoints": ["collaboration", "real-time", "conflict resolution"] 358 | } 359 | 360 | // UI/UX component 361 | { 362 | "content": "Design user interface for concurrent editing and conflict visualization.", 363 | "type": "ui_design", 364 | "branchId": "ui-layer", 365 | "keyPoints": ["cursor tracking", "change highlighting", "conflict indicators"] 366 | } 367 | 368 | // Data model 369 | { 370 | "content": "Implement CRDT data structure for text with vector clocks.", 371 | "type": "technical", 372 | "branchId": "data-layer", 373 | "crossRefs": [{ 374 | "toBranch": "ui-layer", 375 | "type": "supports", 376 | "reason": "Provides data structure for real-time updates", 377 | "strength": 0.9 378 | }] 379 | } 380 | ``` 381 | 382 | ## Risk Assessment/Mitigation 383 | 384 | Analyze and mitigate risks: 385 | 386 | ```javascript 387 | // Risk overview 388 | { 389 | "content": "Identify and assess risks in transitioning from monolith to microservices.", 390 | "type": "assessment", 391 | "keyPoints": ["architectural change", "service boundaries", "operational complexity"] 392 | } 393 | 394 | // Technical risks 395 | { 396 | "content": "Inter-service communication reliability, data consistency across services, deployment complexity.", 397 | "type": "risk_category", 398 | "branchId": "technical-risks", 399 | "keyPoints": ["network reliability", "data consistency", "deployment"] 400 | } 401 | 402 | // Mitigation strategies 403 | { 404 | "content": "Implement circuit breakers, saga pattern for transactions, automated deployment pipeline.", 405 | "type": "mitigation", 406 | "branchId": "technical-mitigations", 407 | "crossRefs": [{ 408 | "toBranch": "technical-risks", 409 | "type": "addresses", 410 | "reason": "Direct mitigation of identified risks", 411 | "strength": 0.9 412 | }] 413 | } 414 | ``` 415 | 416 | ## Competitive Analysis 417 | 418 | Analyze competitive positioning: 419 | 420 | ```javascript 421 | // Market overview 422 | { 423 | "content": "Developer productivity tools market analysis, focusing on CI/CD space.", 424 | "type": "market_analysis", 425 | "keyPoints": ["CI/CD", "developer tools", "market segments"] 426 | } 427 | 428 | // Competitor analysis 429 | { 430 | "content": "Market leader focuses on enterprise, strong integration ecosystem but complex pricing.", 431 | "type": "competitor_analysis", 432 | "branchId": "competitor-a", 433 | "keyPoints": ["enterprise focus", "integrations", "complex pricing"] 434 | } 435 | 436 | // Differentiation strategy 437 | { 438 | "content": "Focus on developer experience with AI-assisted workflow optimization.", 439 | "type": "strategy", 440 | "branchId": "differentiation", 441 | "crossRefs": [{ 442 | "toBranch": "competitor-a", 443 | "type": "differentiates", 444 | "reason": "Targets pain points in competitor offering", 445 | "strength": 0.9 446 | }] 447 | } 448 | ``` 449 | 450 | ## API Design Evolution 451 | 452 | Plan API versioning and evolution: 453 | 454 | ```javascript 455 | // Current API 456 | { 457 | "content": "RESTful API serving mobile and web clients, considering breaking changes needed.", 458 | "type": "context", 459 | "keyPoints": ["REST", "multiple clients", "breaking changes"] 460 | } 461 | 462 | // URI versioning approach 463 | { 464 | "content": "Version in URI path (/v2/resources). Simple but leads to code duplication.", 465 | "type": "approach", 466 | "branchId": "uri-version", 467 | "keyPoints": ["path versioning", "code duplication", "client simplicity"] 468 | } 469 | 470 | // Header versioning alternative 471 | { 472 | "content": "Version in Accept header. Cleaner URLs but more complex client handling.", 473 | "type": "approach", 474 | "branchId": "header-version", 475 | "crossRefs": [{ 476 | "toBranch": "uri-version", 477 | "type": "alternative", 478 | "reason": "Different trade-offs in complexity vs. cleanliness", 479 | "strength": 0.85 480 | }] 481 | } 482 | ``` 483 | 484 | ## Technology Stack Migration 485 | 486 | Plan technology migrations: 487 | 488 | ```javascript 489 | // Migration scope 490 | { 491 | "content": "Large Angular 8 application with 200+ components needs migration to React 18.", 492 | "type": "context", 493 | "keyPoints": ["Angular 8", "React 18", "large application"] 494 | } 495 | 496 | // Parallel approach 497 | { 498 | "content": "Run both frameworks simultaneously, migrate feature by feature.", 499 | "type": "strategy", 500 | "branchId": "parallel-migration", 501 | "keyPoints": ["dual frameworks", "feature migration", "gradual transition"] 502 | } 503 | 504 | // State management bridge 505 | { 506 | "content": "Implement framework-agnostic state management using Redux.", 507 | "type": "technical", 508 | "branchId": "state-bridge", 509 | "crossRefs": [{ 510 | "toBranch": "parallel-migration", 511 | "type": "enables", 512 | "reason": "Allows data sharing between frameworks", 513 | "strength": 0.9 514 | }] 515 | } 516 | ``` -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@modelcontextprotocol/server-branch-thinking", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@modelcontextprotocol/server-branch-thinking", 9 | "version": "0.1.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@modelcontextprotocol/sdk": "0.5.0", 13 | "chalk": "^5.3.0" 14 | }, 15 | "bin": { 16 | "mcp-server-branch-thinking": "dist/index.js" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^22", 20 | "typescript": "^5.3.3" 21 | } 22 | }, 23 | "node_modules/@modelcontextprotocol/sdk": { 24 | "version": "0.5.0", 25 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.5.0.tgz", 26 | "integrity": "sha512-RXgulUX6ewvxjAG0kOpLMEdXXWkzWgaoCGaA2CwNW7cQCIphjpJhjpHSiaPdVCnisjRF/0Cm9KWHUuIoeiAblQ==", 27 | "dependencies": { 28 | "content-type": "^1.0.5", 29 | "raw-body": "^3.0.0", 30 | "zod": "^3.23.8" 31 | } 32 | }, 33 | "node_modules/@types/node": { 34 | "version": "22.10.6", 35 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.6.tgz", 36 | "integrity": "sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==", 37 | "dev": true, 38 | "dependencies": { 39 | "undici-types": "~6.20.0" 40 | } 41 | }, 42 | "node_modules/bytes": { 43 | "version": "3.1.2", 44 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 45 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 46 | "engines": { 47 | "node": ">= 0.8" 48 | } 49 | }, 50 | "node_modules/chalk": { 51 | "version": "5.4.1", 52 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", 53 | "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", 54 | "engines": { 55 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 56 | }, 57 | "funding": { 58 | "url": "https://github.com/chalk/chalk?sponsor=1" 59 | } 60 | }, 61 | "node_modules/content-type": { 62 | "version": "1.0.5", 63 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 64 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 65 | "engines": { 66 | "node": ">= 0.6" 67 | } 68 | }, 69 | "node_modules/depd": { 70 | "version": "2.0.0", 71 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 72 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 73 | "engines": { 74 | "node": ">= 0.8" 75 | } 76 | }, 77 | "node_modules/http-errors": { 78 | "version": "2.0.0", 79 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 80 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 81 | "dependencies": { 82 | "depd": "2.0.0", 83 | "inherits": "2.0.4", 84 | "setprototypeof": "1.2.0", 85 | "statuses": "2.0.1", 86 | "toidentifier": "1.0.1" 87 | }, 88 | "engines": { 89 | "node": ">= 0.8" 90 | } 91 | }, 92 | "node_modules/iconv-lite": { 93 | "version": "0.6.3", 94 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 95 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 96 | "dependencies": { 97 | "safer-buffer": ">= 2.1.2 < 3.0.0" 98 | }, 99 | "engines": { 100 | "node": ">=0.10.0" 101 | } 102 | }, 103 | "node_modules/inherits": { 104 | "version": "2.0.4", 105 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 106 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 107 | }, 108 | "node_modules/raw-body": { 109 | "version": "3.0.0", 110 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 111 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 112 | "dependencies": { 113 | "bytes": "3.1.2", 114 | "http-errors": "2.0.0", 115 | "iconv-lite": "0.6.3", 116 | "unpipe": "1.0.0" 117 | }, 118 | "engines": { 119 | "node": ">= 0.8" 120 | } 121 | }, 122 | "node_modules/safer-buffer": { 123 | "version": "2.1.2", 124 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 125 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 126 | }, 127 | "node_modules/setprototypeof": { 128 | "version": "1.2.0", 129 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 130 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 131 | }, 132 | "node_modules/statuses": { 133 | "version": "2.0.1", 134 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 135 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 136 | "engines": { 137 | "node": ">= 0.8" 138 | } 139 | }, 140 | "node_modules/toidentifier": { 141 | "version": "1.0.1", 142 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 143 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 144 | "engines": { 145 | "node": ">=0.6" 146 | } 147 | }, 148 | "node_modules/typescript": { 149 | "version": "5.7.3", 150 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", 151 | "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", 152 | "dev": true, 153 | "bin": { 154 | "tsc": "bin/tsc", 155 | "tsserver": "bin/tsserver" 156 | }, 157 | "engines": { 158 | "node": ">=14.17" 159 | } 160 | }, 161 | "node_modules/undici-types": { 162 | "version": "6.20.0", 163 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 164 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 165 | "dev": true 166 | }, 167 | "node_modules/unpipe": { 168 | "version": "1.0.0", 169 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 170 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 171 | "engines": { 172 | "node": ">= 0.8" 173 | } 174 | }, 175 | "node_modules/zod": { 176 | "version": "3.24.1", 177 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", 178 | "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", 179 | "funding": { 180 | "url": "https://github.com/sponsors/colinhacks" 181 | } 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@modelcontextprotocol/server-branch-thinking", 3 | "version": "0.1.0", 4 | "description": "MCP server for managing branching thoughts with insights and cross-references", 5 | "license": "MIT", 6 | "type": "module", 7 | "bin": { 8 | "mcp-server-branch-thinking": "dist/index.js" 9 | }, 10 | "files": [ 11 | "dist" 12 | ], 13 | "scripts": { 14 | "build": "tsc && chmod +x dist/index.js", 15 | "prepare": "npm run build", 16 | "watch": "tsc --watch" 17 | }, 18 | "dependencies": { 19 | "@modelcontextprotocol/sdk": "0.5.0", 20 | "chalk": "^5.3.0" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^22", 24 | "typescript": "^5.3.3" 25 | } 26 | } -------------------------------------------------------------------------------- /src/branchManager.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import { ThoughtBranch, ThoughtData, Insight, CrossReference, InsightType, CrossRefType, BranchingThoughtInput } from './types.js'; 3 | 4 | export class BranchManager { 5 | private branches: Map = new Map(); 6 | private insightCounter = 0; 7 | private thoughtCounter = 0; 8 | private crossRefCounter = 0; 9 | private activeBranchId: string | null = null; 10 | 11 | generateId(prefix: string): string { 12 | const timestamp = Date.now(); 13 | const random = Math.floor(Math.random() * 1000); 14 | return `${prefix}-${timestamp}-${random}`; 15 | } 16 | 17 | createBranch(branchId: string, parentBranchId?: string): ThoughtBranch { 18 | const branch: ThoughtBranch = { 19 | id: branchId, 20 | parentBranchId, 21 | state: 'active', 22 | priority: 1.0, 23 | confidence: 1.0, 24 | thoughts: [], 25 | insights: [], 26 | crossRefs: [] 27 | }; 28 | this.branches.set(branchId, branch); 29 | // Set as active if it's the first branch 30 | if (!this.activeBranchId) { 31 | this.activeBranchId = branchId; 32 | } 33 | return branch; 34 | } 35 | 36 | private createInsight( 37 | type: InsightType, 38 | content: string, 39 | context: string[], 40 | parentInsights?: string[] 41 | ): Insight { 42 | return { 43 | id: `insight-${++this.insightCounter}`, 44 | type, 45 | content, 46 | context, 47 | parentInsights, 48 | applicabilityScore: 1.0, 49 | supportingEvidence: {} 50 | }; 51 | } 52 | 53 | private createCrossReference( 54 | fromBranch: string, 55 | toBranch: string, 56 | type: CrossRefType, 57 | reason: string, 58 | strength: number 59 | ): CrossReference { 60 | return { 61 | id: `xref-${++this.crossRefCounter}`, 62 | fromBranch, 63 | toBranch, 64 | type, 65 | reason, 66 | strength, 67 | touchpoints: [] 68 | }; 69 | } 70 | 71 | addThought(input: BranchingThoughtInput): ThoughtData { 72 | // Use active branch if no branchId provided 73 | const branchId = input.branchId || this.activeBranchId || this.generateId('branch'); 74 | let branch = this.branches.get(branchId); 75 | 76 | if (!branch) { 77 | branch = this.createBranch(branchId, input.parentBranchId); 78 | } 79 | 80 | const thought: ThoughtData = { 81 | id: `thought-${++this.thoughtCounter}`, 82 | content: input.content, 83 | branchId: branch.id, 84 | timestamp: new Date(), 85 | metadata: { 86 | type: input.type, 87 | confidence: input.confidence || 1.0, 88 | keyPoints: input.keyPoints || [] 89 | } 90 | }; 91 | 92 | branch.thoughts.push(thought); 93 | 94 | // Create insights if key points are provided 95 | if (input.keyPoints) { 96 | const insight = this.createInsight( 97 | 'observation', 98 | `Identified key points: ${input.keyPoints.join(', ')}`, 99 | [input.type], 100 | input.relatedInsights 101 | ); 102 | branch.insights.push(insight); 103 | } 104 | 105 | // Create cross references if specified 106 | if (input.crossRefs) { 107 | input.crossRefs.forEach(ref => { 108 | const crossRef = this.createCrossReference( 109 | branch!.id, 110 | ref.toBranch, 111 | ref.type, 112 | ref.reason, 113 | ref.strength 114 | ); 115 | branch!.crossRefs.push(crossRef); 116 | }); 117 | } 118 | 119 | this.updateBranchMetrics(branch); 120 | return thought; 121 | } 122 | 123 | private updateBranchMetrics(branch: ThoughtBranch): void { 124 | const avgConfidence = branch.thoughts.reduce((sum, t) => sum + t.metadata.confidence, 0) / branch.thoughts.length; 125 | const insightScore = branch.insights.length * 0.1; 126 | const crossRefScore = branch.crossRefs.reduce((sum, ref) => sum + ref.strength, 0) * 0.1; 127 | 128 | branch.priority = avgConfidence + insightScore + crossRefScore; 129 | branch.confidence = avgConfidence; 130 | } 131 | 132 | getBranch(branchId: string): ThoughtBranch | undefined { 133 | return this.branches.get(branchId); 134 | } 135 | 136 | getAllBranches(): ThoughtBranch[] { 137 | return Array.from(this.branches.values()); 138 | } 139 | 140 | getActiveBranch(): ThoughtBranch | undefined { 141 | return this.activeBranchId ? this.branches.get(this.activeBranchId) : undefined; 142 | } 143 | 144 | setActiveBranch(branchId: string): void { 145 | if (!this.branches.has(branchId)) { 146 | throw new Error(`Branch ${branchId} not found`); 147 | } 148 | this.activeBranchId = branchId; 149 | } 150 | 151 | getBranchHistory(branchId: string): string { 152 | const branch = this.branches.get(branchId); 153 | if (!branch) { 154 | throw new Error(`Branch ${branchId} not found`); 155 | } 156 | 157 | const header = chalk.blue(`History for branch: ${branchId} (${branch.state})`); 158 | const timeline = branch.thoughts.map((t, i) => { 159 | const timestamp = t.timestamp.toLocaleTimeString(); 160 | const number = chalk.gray(`${i + 1}.`); 161 | const content = t.content; 162 | const type = chalk.yellow(`[${t.metadata.type}]`); 163 | const points = t.metadata.keyPoints.length > 0 164 | ? chalk.green(`\n Key Points: ${t.metadata.keyPoints.join(', ')}`) 165 | : ''; 166 | return `${number} ${timestamp} ${type}\n ${content}${points}`; 167 | }).join('\n\n'); 168 | 169 | const insights = branch.insights.map(i => 170 | chalk.yellow(`→ ${i.content}`) 171 | ).join('\n'); 172 | 173 | return ` 174 | ┌───────────────────────────────────────────── 175 | │ ${header} 176 | ├───────────────────────────────────────────── 177 | ${timeline} 178 | ${insights ? ` 179 | ├───────────────────────────────────────────── 180 | │ Insights: 181 | ${insights}` : ''} 182 | └─────────────────────────────────────────────`; 183 | } 184 | 185 | formatBranchStatus(branch: ThoughtBranch): string { 186 | const isActive = branch.id === this.activeBranchId; 187 | const header = `${chalk.blue('Branch:')} ${branch.id} (${branch.state})${isActive ? chalk.green(' [ACTIVE]') : ''}`; 188 | const stats = `Priority: ${branch.priority.toFixed(2)} | Confidence: ${branch.confidence.toFixed(2)}`; 189 | const thoughts = branch.thoughts.map(t => 190 | ` ${chalk.green('•')} ${t.content} (${t.metadata.type})` 191 | ).join('\n'); 192 | const insights = branch.insights.map(i => 193 | ` ${chalk.yellow('→')} ${i.content}` 194 | ).join('\n'); 195 | const crossRefs = branch.crossRefs.map(r => 196 | ` ${chalk.magenta('↔')} ${r.toBranch}: ${r.reason} (${r.strength.toFixed(2)})` 197 | ).join('\n'); 198 | 199 | return ` 200 | ┌───────────────────────────────────────────── 201 | │ ${header} 202 | │ ${stats} 203 | ├───────────────────────────────────────────── 204 | │ Thoughts: 205 | ${thoughts} 206 | │ Insights: 207 | ${insights} 208 | │ Cross References: 209 | ${crossRefs} 210 | └─────────────────────────────────────────────`; 211 | } 212 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 5 | import { 6 | CallToolRequestSchema, 7 | ListToolsRequestSchema, 8 | Tool, 9 | } from "@modelcontextprotocol/sdk/types.js"; 10 | import { BranchManager } from './branchManager.js'; 11 | import { BranchingThoughtInput } from './types.js'; 12 | import chalk from 'chalk'; 13 | 14 | class BranchingThoughtServer { 15 | private branchManager = new BranchManager(); 16 | 17 | processThought(input: unknown): { content: Array<{ type: string; text: string }>; isError?: boolean } { 18 | try { 19 | const inputData = input as any; 20 | 21 | // Handle commands if present 22 | if (inputData.command) { 23 | return this.handleCommand(inputData.command); 24 | } 25 | 26 | // Handle regular thought input 27 | const thoughtInput = input as BranchingThoughtInput; 28 | const thought = this.branchManager.addThought(thoughtInput); 29 | const branch = this.branchManager.getBranch(thought.branchId)!; 30 | 31 | // Format the response with the branch status 32 | const formattedStatus = this.branchManager.formatBranchStatus(branch); 33 | console.error(formattedStatus); // Display in the console 34 | 35 | return { 36 | content: [{ 37 | type: "text", 38 | text: JSON.stringify({ 39 | thoughtId: thought.id, 40 | branchId: thought.branchId, 41 | branchState: branch.state, 42 | branchPriority: branch.priority, 43 | numInsights: branch.insights.length, 44 | numCrossRefs: branch.crossRefs.length, 45 | activeBranch: this.branchManager.getActiveBranch()?.id 46 | }, null, 2) 47 | }] 48 | }; 49 | } catch (error) { 50 | return { 51 | content: [{ 52 | type: "text", 53 | text: JSON.stringify({ 54 | error: error instanceof Error ? error.message : String(error), 55 | status: 'failed' 56 | }, null, 2) 57 | }], 58 | isError: true 59 | }; 60 | } 61 | } 62 | 63 | private handleCommand(command: { type: string; branchId?: string }): { content: Array<{ type: string; text: string }> } { 64 | try { 65 | switch (command.type) { 66 | case 'list': { 67 | const branches = this.branchManager.getAllBranches(); 68 | const activeBranchId = this.branchManager.getActiveBranch()?.id; 69 | const output = branches.map(b => { 70 | const isActive = b.id === activeBranchId; 71 | const prefix = isActive ? chalk.green('→') : ' '; 72 | return `${prefix} ${b.id} [${b.state}] - ${b.thoughts[b.thoughts.length - 1]?.content.slice(0, 50)}...`; 73 | }).join('\n'); 74 | 75 | return { 76 | content: [{ 77 | type: "text", 78 | text: `Current Branches:\n${output}` 79 | }] 80 | }; 81 | } 82 | 83 | case 'focus': { 84 | if (!command.branchId) { 85 | throw new Error('branchId required for focus command'); 86 | } 87 | this.branchManager.setActiveBranch(command.branchId); 88 | const branch = this.branchManager.getBranch(command.branchId)!; 89 | const formattedStatus = this.branchManager.formatBranchStatus(branch); 90 | console.error(formattedStatus); 91 | 92 | return { 93 | content: [{ 94 | type: "text", 95 | text: JSON.stringify({ 96 | status: 'success', 97 | message: `Now focused on branch: ${command.branchId}`, 98 | activeBranch: command.branchId 99 | }, null, 2) 100 | }] 101 | }; 102 | } 103 | 104 | case 'history': { 105 | const branchId = command.branchId || this.branchManager.getActiveBranch()?.id; 106 | if (!branchId) { 107 | throw new Error('No active branch and no branchId provided'); 108 | } 109 | const branch = this.branchManager.getBranch(branchId)!; 110 | const history = this.branchManager.getBranchHistory(branchId); 111 | 112 | return { 113 | content: [{ 114 | type: "text", 115 | text: history 116 | }] 117 | }; 118 | } 119 | 120 | default: 121 | throw new Error(`Unknown command: ${command.type}`); 122 | } 123 | } catch (error) { 124 | return { 125 | content: [{ 126 | type: "text", 127 | text: JSON.stringify({ 128 | error: error instanceof Error ? error.message : String(error), 129 | status: 'failed' 130 | }, null, 2) 131 | }] 132 | }; 133 | } 134 | } 135 | } 136 | 137 | const BRANCHING_THOUGHT_TOOL: Tool = { 138 | name: "branch-thinking", 139 | description: `A tool for managing multiple branches of thought with insights and cross-references. 140 | 141 | Each thought can: 142 | - Belong to a specific branch 143 | - Generate insights 144 | - Create cross-references to other branches 145 | - Include confidence scores and key points 146 | 147 | The system tracks: 148 | - Branch priorities and states 149 | - Relationships between thoughts 150 | - Accumulated insights 151 | - Cross-branch connections 152 | 153 | Commands: 154 | - list: Show all branches and their status 155 | - focus [branchId]: Switch focus to a specific branch 156 | - history [branchId?]: Show the history of thoughts in a branch (uses active branch if none specified)`, 157 | inputSchema: { 158 | type: "object", 159 | properties: { 160 | content: { 161 | type: "string", 162 | description: "The thought content" 163 | }, 164 | branchId: { 165 | type: "string", 166 | description: "Optional: ID of the branch (generated if not provided)" 167 | }, 168 | parentBranchId: { 169 | type: "string", 170 | description: "Optional: ID of the parent branch" 171 | }, 172 | type: { 173 | type: "string", 174 | description: "Type of thought (e.g., 'analysis', 'hypothesis', 'observation')" 175 | }, 176 | confidence: { 177 | type: "number", 178 | description: "Optional: Confidence score (0-1)" 179 | }, 180 | keyPoints: { 181 | type: "array", 182 | items: { type: "string" }, 183 | description: "Optional: Key points identified in the thought" 184 | }, 185 | relatedInsights: { 186 | type: "array", 187 | items: { type: "string" }, 188 | description: "Optional: IDs of related insights" 189 | }, 190 | crossRefs: { 191 | type: "array", 192 | items: { 193 | type: "object", 194 | properties: { 195 | toBranch: { type: "string" }, 196 | type: { type: "string" }, 197 | reason: { type: "string" }, 198 | strength: { type: "number" } 199 | } 200 | }, 201 | description: "Optional: Cross-references to other branches" 202 | }, 203 | command: { 204 | type: "object", 205 | description: "Optional: Navigation command", 206 | properties: { 207 | type: { 208 | type: "string", 209 | enum: ["list", "focus", "history"], 210 | description: "Command type" 211 | }, 212 | branchId: { 213 | type: "string", 214 | description: "Branch ID for commands that require it" 215 | } 216 | }, 217 | required: ["type"] 218 | } 219 | }, 220 | anyOf: [ 221 | { required: ["content", "type"] }, 222 | { required: ["command"] } 223 | ] 224 | } 225 | }; 226 | 227 | const server = new Server( 228 | { 229 | name: "branch-thinking-server", 230 | version: "0.1.0", 231 | }, 232 | { 233 | capabilities: { 234 | tools: {}, 235 | }, 236 | } 237 | ); 238 | 239 | const thinkingServer = new BranchingThoughtServer(); 240 | 241 | server.setRequestHandler(ListToolsRequestSchema, async () => ({ 242 | tools: [BRANCHING_THOUGHT_TOOL], 243 | })); 244 | 245 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 246 | if (request.params.name === "branch-thinking") { 247 | return thinkingServer.processThought(request.params.arguments); 248 | } 249 | 250 | return { 251 | content: [{ 252 | type: "text", 253 | text: `Unknown tool: ${request.params.name}` 254 | }], 255 | isError: true 256 | }; 257 | }); 258 | 259 | async function runServer() { 260 | const transport = new StdioServerTransport(); 261 | await server.connect(transport); 262 | console.error("Branch Thinking MCP Server running on stdio"); 263 | } 264 | 265 | runServer().catch((error) => { 266 | console.error("Fatal error running server:", error); 267 | process.exit(1); 268 | }); -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export type BranchState = 'active' | 'suspended' | 'completed' | 'dead_end'; 2 | export type InsightType = 'behavioral_pattern' | 'feature_integration' | 'observation' | 'connection'; 3 | export type CrossRefType = 'complementary' | 'contradictory' | 'builds_upon' | 'alternative'; 4 | 5 | export interface ThoughtData { 6 | id: string; 7 | content: string; 8 | branchId: string; 9 | timestamp: Date; 10 | metadata: { 11 | type: string; 12 | confidence: number; 13 | keyPoints: string[]; 14 | }; 15 | } 16 | 17 | export interface Insight { 18 | id: string; 19 | type: InsightType; 20 | content: string; 21 | context: string[]; 22 | parentInsights?: string[]; 23 | applicabilityScore: number; 24 | supportingEvidence: { 25 | crossRefs?: string[]; 26 | pattern?: string; 27 | data?: string[]; 28 | }; 29 | } 30 | 31 | export interface CrossReference { 32 | id: string; 33 | fromBranch: string; 34 | toBranch: string; 35 | type: CrossRefType; 36 | reason: string; 37 | strength: number; 38 | touchpoints: Array<{ 39 | fromThought: string; 40 | toThought: string; 41 | connection: string; 42 | }>; 43 | relatedInsights?: string[]; 44 | } 45 | 46 | export interface ThoughtBranch { 47 | id: string; 48 | parentBranchId?: string; 49 | state: BranchState; 50 | priority: number; 51 | confidence: number; 52 | thoughts: ThoughtData[]; 53 | insights: Insight[]; 54 | crossRefs: CrossReference[]; 55 | } 56 | 57 | export interface BranchingThoughtInput { 58 | content: string; 59 | branchId?: string; 60 | parentBranchId?: string; 61 | type: string; 62 | confidence?: number; 63 | keyPoints?: string[]; 64 | relatedInsights?: string[]; 65 | crossRefs?: Array<{ 66 | toBranch: string; 67 | type: CrossRefType; 68 | reason: string; 69 | strength: number; 70 | }>; 71 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ES2020", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "outDir": "./dist", 8 | "rootDir": "./src", 9 | "strict": true 10 | }, 11 | "include": ["src/**/*"] 12 | } --------------------------------------------------------------------------------