Added sequential thinking module
This commit is contained in:
162
mcpServer/modules/sequentialthinking/index.ts
Normal file
162
mcpServer/modules/sequentialthinking/index.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import * as http from "http";
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
||||
import { z } from "zod";
|
||||
import { SequentialThinkingServer } from "./lib.js";
|
||||
|
||||
const server = new McpServer({
|
||||
name: "sequential-thinking-server",
|
||||
version: "0.2.0",
|
||||
});
|
||||
|
||||
const thinkingServer = new SequentialThinkingServer();
|
||||
|
||||
server.registerTool(
|
||||
"sequentialthinking",
|
||||
{
|
||||
title: "Sequential Thinking",
|
||||
description: `A detailed tool for dynamic and reflective problem-solving through thoughts.
|
||||
This tool helps analyze problems through a flexible thinking process that can adapt and evolve.
|
||||
Each thought can build on, question, or revise previous insights as understanding deepens.
|
||||
|
||||
When to use this tool:
|
||||
- Breaking down complex problems into steps
|
||||
- Planning and design with room for revision
|
||||
- Analysis that might need course correction
|
||||
- Problems where the full scope might not be clear initially
|
||||
- Problems that require a multi-step solution
|
||||
- Tasks that need to maintain context over multiple steps
|
||||
- Situations where irrelevant information needs to be filtered out
|
||||
|
||||
Key features:
|
||||
- You can adjust total_thoughts up or down as you progress
|
||||
- You can question or revise previous thoughts
|
||||
- You can add more thoughts even after reaching what seemed like the end
|
||||
- You can express uncertainty and explore alternative approaches
|
||||
- Not every thought needs to build linearly - you can branch or backtrack
|
||||
- Generates a solution hypothesis
|
||||
- Verifies the hypothesis based on the Chain of Thought steps
|
||||
- Repeats the process until satisfied
|
||||
- Provides a correct answer
|
||||
|
||||
Parameters explained:
|
||||
- thought: Your current thinking step, which can include:
|
||||
* Regular analytical steps
|
||||
* Revisions of previous thoughts
|
||||
* Questions about previous decisions
|
||||
* Realizations about needing more analysis
|
||||
* Changes in approach
|
||||
* Hypothesis generation
|
||||
* Hypothesis verification
|
||||
- nextThoughtNeeded: True if you need more thinking, even if at what seemed like the end
|
||||
- thoughtNumber: Current number in sequence (can go beyond initial total if needed)
|
||||
- totalThoughts: Current estimate of thoughts needed (can be adjusted up/down)
|
||||
- isRevision: A boolean indicating if this thought revises previous thinking
|
||||
- revisesThought: If is_revision is true, which thought number is being reconsidered
|
||||
- branchFromThought: If branching, which thought number is the branching point
|
||||
- branchId: Identifier for the current branch (if any)
|
||||
- needsMoreThoughts: If reaching end but realizing more thoughts needed
|
||||
|
||||
You should:
|
||||
1. Start with an initial estimate of needed thoughts, but be ready to adjust
|
||||
2. Feel free to question or revise previous thoughts
|
||||
3. Don't hesitate to add more thoughts if needed, even at the "end"
|
||||
4. Express uncertainty when present
|
||||
5. Mark thoughts that revise previous thinking or branch into new paths
|
||||
6. Ignore information that is irrelevant to the current step
|
||||
7. Generate a solution hypothesis when appropriate
|
||||
8. Verify the hypothesis based on the Chain of Thought steps
|
||||
9. Repeat the process until satisfied with the solution
|
||||
10. Provide a single, ideally correct answer as the final output
|
||||
11. Only set nextThoughtNeeded to false when truly done and a satisfactory answer is reached`,
|
||||
inputSchema: {
|
||||
thought: z.string().describe("Your current thinking step"),
|
||||
nextThoughtNeeded: z.boolean().describe("Whether another thought step is needed"),
|
||||
thoughtNumber: z.number().int().min(1).describe("Current thought number (numeric value, e.g., 1, 2, 3)"),
|
||||
totalThoughts: z.number().int().min(1).describe("Estimated total thoughts needed (numeric value, e.g., 5, 10)"),
|
||||
isRevision: z.boolean().optional().describe("Whether this revises previous thinking"),
|
||||
revisesThought: z.number().int().min(1).optional().describe("Which thought is being reconsidered"),
|
||||
branchFromThought: z.number().int().min(1).optional().describe("Branching point thought number"),
|
||||
branchId: z.string().optional().describe("Branch identifier"),
|
||||
needsMoreThoughts: z.boolean().optional().describe("If more thoughts are needed")
|
||||
},
|
||||
outputSchema: {
|
||||
thoughtNumber: z.number(),
|
||||
totalThoughts: z.number(),
|
||||
nextThoughtNeeded: z.boolean(),
|
||||
branches: z.array(z.string()),
|
||||
thoughtHistoryLength: z.number()
|
||||
},
|
||||
},
|
||||
async (args) => {
|
||||
const result = thinkingServer.processThought(args);
|
||||
|
||||
if (result.isError) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse the JSON response to get structured content
|
||||
const parsedContent = JSON.parse(result.content[0].text);
|
||||
|
||||
return {
|
||||
content: result.content,
|
||||
structuredContent: parsedContent
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const sseTransportsBySessionId = new Map<string, SSEServerTransport>();
|
||||
|
||||
function runServer() {
|
||||
const port = Number(process.env.MCP_PORT ?? process.env.SSE_PORT ?? 3000);
|
||||
|
||||
const httpServer = http.createServer(async (req, res) => {
|
||||
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
||||
const pathname = url.pathname;
|
||||
|
||||
if (req.method === "GET" && (pathname === "/sse" || pathname === "/")) {
|
||||
try {
|
||||
const transport = new SSEServerTransport("/messages", res);
|
||||
sseTransportsBySessionId.set(transport.sessionId, transport);
|
||||
transport.onclose = () => {
|
||||
sseTransportsBySessionId.delete(transport.sessionId);
|
||||
};
|
||||
await server.connect(transport);
|
||||
console.error("Sequential Thinking MCP Server: new SSE client connected");
|
||||
} catch (error) {
|
||||
console.error("SSE connection error:", error);
|
||||
if (!res.headersSent) {
|
||||
res.writeHead(500).end("Internal server error");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method === "POST" && pathname === "/messages") {
|
||||
const sessionId = url.searchParams.get("sessionId");
|
||||
if (!sessionId) {
|
||||
res.writeHead(400).end("Missing sessionId query parameter");
|
||||
return;
|
||||
}
|
||||
const transport = sseTransportsBySessionId.get(sessionId);
|
||||
if (!transport) {
|
||||
res.writeHead(404).end("Unknown session");
|
||||
return;
|
||||
}
|
||||
await transport.handlePostMessage(req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(404).end("Not found");
|
||||
});
|
||||
|
||||
httpServer.listen(port, () => {
|
||||
console.error(`Sequential Thinking MCP Server running on SSE at http://localhost:${port}`);
|
||||
console.error(" GET /sse – open SSE stream (then POST to /messages?sessionId=...)");
|
||||
console.error(" POST /messages?sessionId=<id> – send MCP messages");
|
||||
});
|
||||
}
|
||||
|
||||
runServer();
|
||||
Reference in New Issue
Block a user