bolayishere/sequentialthinking-mcp
0
1package main2 3import (4 "context"5 "fmt"6 "log"7 "net/http"8 "os"9 "sync"10 11 "github.com/mark3labs/mcp-go/mcp"12 "github.com/mark3labs/mcp-go/server"13)14 15type Thought struct {16 Thought string17 ThoughtNumber float6418 TotalThoughts float6419 NextThoughtNeeded bool20 IsRevision bool21 RevisesThought float6422 BranchFromThought float6423 BranchId string24}25 26var (27 thoughtHistory []Thought28 mutex sync.Mutex29)30 31func main() {32 33 s := server.NewMCPServer(34 "Sequential Thinking",35 "1.0.0",36 )37 38 tool := mcp.NewTool(39 "sequentialthinking",40 41 mcp.WithDescription(42 "Dynamic and reflective problem-solving through thoughts",43 ),44 45 mcp.WithString(46 "thought",47 mcp.Required(),48 mcp.Description("Current thinking step"),49 ),50 51 mcp.WithNumber(52 "thoughtNumber",53 mcp.Required(),54 mcp.Description("Current thought number"),55 ),56 57 mcp.WithNumber(58 "totalThoughts",59 mcp.Required(),60 mcp.Description("Estimated total thoughts"),61 ),62 63 mcp.WithBoolean(64 "nextThoughtNeeded",65 mcp.Required(),66 mcp.Description("Whether another thought step is needed"),67 ),68 69 mcp.WithBoolean(70 "isRevision",71 mcp.Description("Whether this revises a previous thought"),72 ),73 74 mcp.WithNumber(75 "revisesThought",76 mcp.Description("Which thought is revised"),77 ),78 79 mcp.WithNumber(80 "branchFromThought",81 mcp.Description("Branch starting thought"),82 ),83 84 mcp.WithString(85 "branchId",86 mcp.Description("Branch identifier"),87 ),88 )89 90 s.AddTool(91 tool,92 93 func(94 ctx context.Context,95 request mcp.CallToolRequest,96 ) (*mcp.CallToolResult, error) {97 98 thought, err := request.RequireString("thought")99 if err != nil {100 return mcp.NewToolResultError(err.Error()), nil101 }102 103 thoughtNumber := request.GetFloat("thoughtNumber", 1)104 105 totalThoughts := request.GetFloat("totalThoughts", 1)106 107 nextNeeded := request.GetBool("nextThoughtNeeded", false)108 109 isRevision := request.GetBool("isRevision", false)110 111 revisesThought := request.GetFloat("revisesThought", 0)112 113 branchFromThought := request.GetFloat("branchFromThought", 0)114 115 branchId := request.GetString("branchId", "")116 117 entry := Thought{118 Thought: thought,119 ThoughtNumber: thoughtNumber,120 TotalThoughts: totalThoughts,121 NextThoughtNeeded: nextNeeded,122 IsRevision: isRevision,123 RevisesThought: revisesThought,124 BranchFromThought: branchFromThought,125 BranchId: branchId,126 }127 128 mutex.Lock()129 thoughtHistory = append(thoughtHistory, entry)130 mutex.Unlock()131 132 response := ""133 134 if branchId != "" {135 response += fmt.Sprintf(136 "๐ฟ Branch: %s\n",137 branchId,138 )139 }140 141 if isRevision {142 response += fmt.Sprintf(143 "โ Revising Thought #%v\n\n",144 revisesThought,145 )146 }147 148 response += fmt.Sprintf(149 "๐ง Thought %v/%v\n\n%s\n\n",150 thoughtNumber,151 totalThoughts,152 thought,153 )154 155 response += fmt.Sprintf(156 "โก Next Thought Needed: %v\n",157 nextNeeded,158 )159 160 response += fmt.Sprintf(161 "\n๐ Total Stored Thoughts: %d",162 len(thoughtHistory),163 )164 165 return mcp.NewToolResultText(response), nil166 },167 )168 169 port := os.Getenv("PORT")170 171 if port == "" {172 port = "7860"173 }174 175 httpServer := server.NewStreamableHTTPServer(s)176 177 http.Handle("/mcp", httpServer)178 179 http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {180 w.WriteHeader(200)181 w.Write([]byte("ok"))182 })183 184 log.Println("Sequential Thinking MCP running on port", port)185 186 log.Fatal(http.ListenAndServe(":"+port, nil))187}