mcp-sequential-thinking

repository·master·Indexed 21 days ago

https://github.com/arben-adm/mcp-sequential-thinking

A Model Context Protocol (MCP) server version 0.6.0 designed for structured, progressive thinking. It enables AI models to break complex problems into stages (Problem Definition, Research, Analysis, Synthesis, and Conclusion), manage revisions and branching, and maintain persistent, crash-recoverable session logs via append-only JSONL. Includes tools for recording thoughts (process_thought), generating summaries, and exporting/importing sessions.

Tokens
14.6K
Snippets
33
Records
40
Agent score
75%

What's inside mcp-sequential-thinking

  1. How this server differs from the official sequential-thinking server

    master

    While the official MCP sequential-thinking server provides the core paradigm (numbered thoughts, revisions, and branching held in memory), this implementation is designed for durable and analyzable sessions.

    Key Advantages:

    • Persistence: Sessions survive restarts via an append-only JSONL log with crash recovery and automatic migration.
    • Thinking Stages: Thoughts are categorized into cognitive stages (Problem Definition, Research, Analysis, Synthesis, Conclusion), allowing for stage-based filtering and completeness checks.
    • Analysis: Provides rich summaries including branch and revision statistics, and enables related-thought detection via stages and tags.
  2. Implement collaborative thinking features

    master

    To support multi-user environments, you can extend the base ThoughtData model into a CollaborativeThoughtData model. This allows you to track authorship, comments, and social signals like upvotes.

    Data Models

    • User: Represents a participant with id, name, and email.
    • Comment: Represents a user's feedback on a thought, containing id, user_id, content, and timestamp.
    • CollaborativeThoughtData: Extends ThoughtData with created_by, last_modified_by, comments (List of Comment), and upvotes (Set of user IDs).
    • CollaborativeSession: Manages a group of users and their shared CollaborativeThoughtData list.

    Key Operations

    • CollaborativeThoughtData.add_comment(user_id, content): Appends a new comment.
    • CollaborativeThoughtData.toggle_upvote(user_id): Adds or removes a user's upvote.
    • CollaborativeSession.add_participant(user): Adds a user to the session.
    from pydantic import BaseModel, Field
    from typing import Dict, List, Optional, Set
    from datetime import datetime
    import uuid
    
    class CollaborativeThoughtData(ThoughtData):
        created_by: str
        last_modified_by: str
        comments: List[Comment] = Field(default_factory=list)
        upvotes: Set[str] = Field(default_factory=set)
    
        def add_comment(self, user_id: str, content: str) -> Comment:
            # ...
    
        def toggle_upvote(self, user_id: str) -> bool:
            # ...
  3. How Sequential Thinking works and data persistence

    master

    The server facilitates structured, progressive thinking by organizing thoughts through standard cognitive stages: Problem Definition, Research, Analysis, Synthesis, and Conclusion.

    Core Mechanics

    • Thought Lifecycle: Each thought is validated via Pydantic models, categorized into stages, and stored with metadata.
    • Features: Supports revisions, branching (forking alternative reasoning), thought tracking, and summary generation.
    • Persistence: Sessions are stored as an append-only JSONL log. This ensures thread-safety and automatic recovery from crashes (the last line of an interrupted write is automatically recovered).

    Storage Location

    By default, sessions are persisted at: ~/.mcp_sequential_thinking/current_session.jsonl

    You can override this directory by setting the MCP_STORAGE_DIR environment variable.

  4. Implement advanced thought analysis with NLP

    master

    You can enhance the server by adding an AdvancedAnalyzer that uses TfidfVectorizer and cosine_similarity from sklearn to find similar thoughts within a session. This allows the system to identify patterns or recurring themes in the thinking process.

    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.metrics.pairwise import cosine_similarity
    import numpy as np
    
    class AdvancedAnalyzer:
        """Advanced thought analysis using NLP techniques."""
    
        def __init__(self):
            """Initialize the analyzer."""
            self.vectorizer = TfidfVectorizer()
            self.thought_vectors = None
            self.thoughts = []
    
        def add_thought(self, thought: ThoughtData) -> None:
            """Add a thought to the analyzer."""
            self.thoughts.append(thought)
            # Recompute vectors
            self._compute_vectors()
    
        def _compute_vectors(self) -> None:
            """Compute TF-IDF vectors for all thoughts."""
            if not self.thoughts:
                return
    
            thought_texts = [t.thought for t in self.thoughts]
            self.thought_vectors = self.vectorizer.fit_transform(thought_texts)
    
        def find_similar_thoughts(self, thought: ThoughtData, top_n: int = 3) -> List[Tuple[ThoughtData, float]]:
            """Find thoughts similar to the given thought using cosine similarity."""
            if thought not in self.thoughts:
                self.add_thought(thought)
    
            thought_idx = self.thoughts.index(thought)
            thought_vector = self.thought_vectors[thought_idx]
    
            # Compute similarities
            similarities = cosine_similarity(thought_vector, self.thought_vectors).flatten()
    
            # Get top N similar thoughts (excluding self)
            similar_indices = np.argsort(similarities)[::-1][1:top_n+1]
    
            return [(self.thoughts[idx], similarities[idx]) for idx in similar_indices]
  5. Install and run Sequential Thinking MCP Server

    master

    The Sequential Thinking MCP server can be run without a permanent installation using uvx, or installed via pip. It requires Python 3.10 or higher and the uv package manager.

    Quick Start

    Run via uvx (Recommended):

    uvx mcp-sequential-thinking

    Install via pip:

    pip install mcp-sequential-thinking
    mcp-sequential-thinking
  6. Modify thinking stages via ThoughtStage enum

    master

    You can customize the workflow stages by modifying the ThoughtStage enum in models.py. This allows you to define custom lifecycle steps for the thinking process, such as OBSERVE, HYPOTHESIZE, or EXPERIMENT.

    class ThoughtStage(Enum):
        """Custom thinking stages for your specific workflow."""
        OBSERVE = "Observe"
        HYPOTHESIZE = "Hypothesize"
        EXPERIMENT = "Experiment"
        ANALYZE = "Analyze"
        CONCLUDE = "Conclude"
  7. Extend the ThoughtData class

    master

    To include additional metadata in your thinking process, extend the ThoughtData class using Pydantic. This allows you to add fields like confidence_level or supporting_evidence and implement custom validation logic.

    from pydantic import Field, field_validator
    class EnhancedThoughtData(ThoughtData):
        """Enhanced thought data with additional fields."""
        confidence_level: float = 0.0
        supporting_evidence: List[str] = Field(default_factory=list)
        counter_arguments: List[str] = Field(default_factory=list)
    
        @field_validator('confidence_level')
        def validate_confidence_level(cls, value):
            """Validate confidence level."""
            if not 0.0 <= value <= 1.0:
                raise ValueError("Confidence level must be between 0.0 and 1.0")
            return value
  8. Add visualization tools to thought data

    master

    You can implement visualization capabilities for your Sequential Thinking server using matplotlib. Two useful patterns are creating a pie chart for stage distribution and a timeline for the thinking process. Both methods return a base64 encoded PNG string formatted as a data URI (data:image/png;base64,...), which is ideal for web-based or UI-driven clients.

    Key methods to implement:

    • create_stage_distribution_chart(thoughts: List[ThoughtData]) -> str
    • create_thinking_timeline(thoughts: List[ThoughtData]) -> str
    import matplotlib.pyplot as plt
    import io
    import base64
    from typing import List, Dict, Any
    
    class ThoughtVisualizer:
        @staticmethod
        def create_stage_distribution_chart(thoughts: List[ThoughtData]) -> str:
            # ... implementation returns base64 PNG string
            return f"data:image/png;base64,{img_str}"
    
        @staticmethod
        def create_thinking_timeline(thoughts: List[ThoughtData]) -> str:
            # ... implementation returns base64 PNG string
            return f"data:image/png;base64,{img_str}"
  9. Create custom MCP prompts

    master

    Use the @mcp.prompt() decorator to define custom prompts that guide the LLM through specific stages of the thinking process, such as problem_definition_prompt or research_prompt. These prompts can include SystemMessage and UserMessage to set context and instructions.

    from mcp.server.fastmcp.prompts import base
    
    @mcp.prompt()
    def problem_definition_prompt(problem_statement: str) -> list[base.Message]:
        """Create a prompt for the Problem Definition stage."""
        return [
            base.SystemMessage(
                "You are a structured thinking assistant helping to define a problem clearly."
            ),
            base.UserMessage(f"I need to define this problem: {problem_statement}"),
            base.UserMessage(
                "Please help me create a clear problem definition by addressing:\n"
                "1. What is the core issue?\n"
                "2. Who is affected?\n"
                "3. What are the boundaries of the problem?\n"
                "4. What would a solution look like?\n"
                "5. What constraints exist?"
            )
        ]
    
    @mcp.prompt()
    def research_prompt(problem_definition: str) -> list[base.Message]:
        """Create a prompt for the Research stage."""
        return [
            base.SystemMessage(
                "You are a research assistant helping to gather information about a problem."
            ),
            base.UserMessage(f"I've defined this problem: {problem_definition}"),
            base.UserMessage(
                "Please help me research this problem by:\n"
                "1. Identifying key information needed\n"
                "2. Suggesting reliable sources\n"
                "3. Outlining research questions\n"
                "4. Proposing a research plan"
            )
        ]
  10. Set up a development environment for Sequential Thinking

    master

    To develop the server from source, follow these steps using uv:

    1. Create and activate a virtual environment

      uv venv
      .venv\Scripts\activate  # Windows
      source .venv/bin/activate  # Unix
    2. Install dependencies

      • Standard install: uv pip install -e .
      • With testing tools: uv pip install -e ".[dev]"
      • With all optional dependencies: uv pip install -e ".[all]"
    3. Run the server

      uv run -m mcp_sequential_thinking.server
      # OR
      mcp-sequential-thinking
    4. Run tests

      pytest
      # With coverage
      pytest --cov=mcp_sequential_thinking
    uv venv
    source .venv/bin/activate
    uv pip install -e .
  11. Add database persistence with SQLAlchemy

    master

    To persist thought data across sessions, implement a database-backed storage solution. This involves creating a SQLAlchemy ThoughtModel that maps to the ThoughtData structure and a DatabaseStorage class to handle session management and data insertion.

    from sqlalchemy import create_engine, Column, Integer, String, Float, Boolean, ForeignKey
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker, relationship
    
    Base = declarative_base()
    
    class ThoughtModel(Base):
        """SQLAlchemy model for thought data."""
        __tablename__ = "thoughts"
    
        id = Column(Integer, primary_key=True)
        thought = Column(String, nullable=False)
        thought_number = Column(Integer, nullable=False)
        total_thoughts = Column(Integer, nullable=False)
        next_thought_needed = Column(Boolean, nullable=False)
        stage = Column(String, nullable=False)
        timestamp = Column(String, nullable=False)
    
        tags = relationship("TagModel", back_populates="thought")
        axioms = relationship("AxiomModel", back_populates="thought")
        assumptions = relationship("AssumptionModel", back_populates="thought")
    
    class DatabaseStorage:
        """Database-backed storage for thought data."""
    
        def __init__(self, db_url: str = "sqlite:///thoughts.db"):
            """Initialize database connection."""
            self.engine = create_engine(db_url)
            Base.metadata.create_all(self.engine)
            self.Session = sessionmaker(bind=self.engine)
    
        def add_thought(self, thought: ThoughtData) -> None:
            """Add a thought to the database."""
            with self.Session() as session:
                # Convert ThoughtData to ThoughtModel
                thought_model = ThoughtModel(
                    thought=thought.thought,
                    thought_number=thought.thought_number,
                    total_thoughts=thought.total_thoughts,
                    next_thought_needed=thought.next_thought_needed,
                    stage=thought.stage.value,
                    timestamp=thought.timestamp
                )
    
                session.add(thought_model)
                session.commit()
  12. Integrate with a Web UI via FastAPI

    master

    You can expose the Sequential Thinking server's functionality through a FastAPI web interface. This allows external clients to POST new thoughts to /thoughts/, GET all thoughts from /thoughts/, or retrieve a process summary from /summary/. Ensure CORS is configured if the UI is hosted on a different origin.

    from fastapi import FastAPI, HTTPException
    from fastapi.middleware.cors import CORSMiddleware
    from pydantic import BaseModel
    
    app = FastAPI(title="Sequential Thinking UI")
    
    # Enable CORS
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    class ThoughtRequest(BaseModel):
        """Request model for adding a thought."""
        thought: str
        thought_number: int
        total_thoughts: int
        next_thought_needed: bool
        stage: str
        tags: List[str] = []
        axioms_used: List[str] = []
        assumptions_challenged: List[str] = []
    
    @app.post("/thoughts/")
    async def add_thought(request: ThoughtRequest):
        """Add a new thought."""
        try:
            # Convert stage string to enum
            thought_stage = ThoughtStage.from_string(request.stage)
    
            # Create thought data
            thought_data = ThoughtData(
                thought=request.thought,
                thought_number=request.thought_number,
                total_thoughts=request.total_thoughts,
                next_thought_needed=request.next_thought_needed,
                stage=thought_stage,
                tags=request.tags,
                axioms_used=request.axioms_used,
                assumptions_challenged=request.assumptions_challenged
            )
    
            # Store thought
            storage.add_thought(thought_data)
    
            # Analyze the thought
            all_thoughts = storage.get_all_thoughts()
            analysis = ThoughtAnalyzer.analyze_thought(thought_data, all_thoughts)
    
            return analysis
        except Exception as e:
            raise HTTPException(status_code=400, detail=str(e))
    
    @app.get("/thoughts/")
    async def get_thoughts():
        """Get all thoughts."""
        all_thoughts = storage.get_all_thoughts()
        return {
            "thoughts": [t.to_dict() for t in all_thoughts]
        }
    
    @app.get("/summary/")
    async def get_summary():
        """Get a summary of the thinking process."""
        all_thoughts = storage.get_all_thoughts()
        return ThoughtAnalyzer.generate_summary(all_thoughts)