Commit fe64f8b

mo khan <mo@mokhan.ca>
2025-06-22 06:01:21
refactor: rename folders to be consistent
1 parent 0bff639
cmd/fetch/main.go
@@ -4,21 +4,21 @@ import (
 	"context"
 	"log"
 
-	"github.com/xlgmokha/mcp/pkg/fetchserver"
+	"github.com/xlgmokha/mcp/pkg/fetch"
 	"github.com/xlgmokha/mcp/pkg/mcp"
 )
 
 func main() {
-	server := fetchserver.New()
-	
+	server := fetch.New()
+
 	// Set up basic initialization
 	server.SetInitializeHandler(func(req mcp.InitializeRequest) (mcp.InitializeResult, error) {
 		// Use default initialization
 		return mcp.InitializeResult{}, nil
 	})
-	
+
 	ctx := context.Background()
 	if err := server.Run(ctx); err != nil {
 		log.Fatalf("Server error: %v", err)
 	}
-}
\ No newline at end of file
+}
cmd/filesystem/main.go
@@ -5,7 +5,7 @@ import (
 	"log"
 	"os"
 
-	"github.com/xlgmokha/mcp/pkg/fsserver"
+	"github.com/xlgmokha/mcp/pkg/filesystem"
 	"github.com/xlgmokha/mcp/pkg/mcp"
 )
 
@@ -16,16 +16,16 @@ func main() {
 	}
 
 	allowedDirs := os.Args[1:]
-	server := fsserver.New(allowedDirs)
-	
+	server := filesystem.New(allowedDirs)
+
 	// Set up basic initialization
 	server.SetInitializeHandler(func(req mcp.InitializeRequest) (mcp.InitializeResult, error) {
 		// Use default initialization
 		return mcp.InitializeResult{}, nil
 	})
-	
+
 	ctx := context.Background()
 	if err := server.Run(ctx); err != nil {
 		log.Fatalf("Server error: %v", err)
 	}
-}
\ No newline at end of file
+}
cmd/git/main.go
@@ -4,21 +4,21 @@ import (
 	"context"
 	"log"
 
-	"github.com/xlgmokha/mcp/pkg/gitserver"
+	"github.com/xlgmokha/mcp/pkg/git"
 	"github.com/xlgmokha/mcp/pkg/mcp"
 )
 
 func main() {
-	server := gitserver.New()
-	
+	server := git.New()
+
 	// Set up basic initialization
 	server.SetInitializeHandler(func(req mcp.InitializeRequest) (mcp.InitializeResult, error) {
 		// Use default initialization
 		return mcp.InitializeResult{}, nil
 	})
-	
+
 	ctx := context.Background()
 	if err := server.Run(ctx); err != nil {
 		log.Fatalf("Server error: %v", err)
 	}
-}
\ No newline at end of file
+}
cmd/memory/main.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 
 	"github.com/xlgmokha/mcp/pkg/mcp"
-	"github.com/xlgmokha/mcp/pkg/memoryserver"
+	"github.com/xlgmokha/mcp/pkg/memory"
 )
 
 func main() {
@@ -21,16 +21,16 @@ func main() {
 		memoryFile = filepath.Join(homeDir, ".mcp_memory.json")
 	}
 
-	server := memoryserver.New(memoryFile)
-	
+	server := memory.New(memoryFile)
+
 	// Set up basic initialization
 	server.SetInitializeHandler(func(req mcp.InitializeRequest) (mcp.InitializeResult, error) {
 		// Use default initialization
 		return mcp.InitializeResult{}, nil
 	})
-	
+
 	ctx := context.Background()
 	if err := server.Run(ctx); err != nil {
 		log.Fatalf("Server error: %v", err)
 	}
-}
\ No newline at end of file
+}
cmd/sequential-thinking/main.go
@@ -5,20 +5,20 @@ import (
 	"log"
 
 	"github.com/xlgmokha/mcp/pkg/mcp"
-	"github.com/xlgmokha/mcp/pkg/thinkingserver"
+	"github.com/xlgmokha/mcp/pkg/thinking"
 )
 
 func main() {
-	server := thinkingserver.New()
-	
+	server := thinking.New()
+
 	// Set up basic initialization
 	server.SetInitializeHandler(func(req mcp.InitializeRequest) (mcp.InitializeResult, error) {
 		// Use default initialization
 		return mcp.InitializeResult{}, nil
 	})
-	
+
 	ctx := context.Background()
 	if err := server.Run(ctx); err != nil {
 		log.Fatalf("Server error: %v", err)
 	}
-}
\ No newline at end of file
+}
cmd/time/main.go
@@ -5,20 +5,20 @@ import (
 	"log"
 
 	"github.com/xlgmokha/mcp/pkg/mcp"
-	"github.com/xlgmokha/mcp/pkg/timeserver"
+	"github.com/xlgmokha/mcp/pkg/time"
 )
 
 func main() {
-	server := timeserver.New()
-	
+	server := time.New()
+
 	// Set up basic initialization
 	server.SetInitializeHandler(func(req mcp.InitializeRequest) (mcp.InitializeResult, error) {
 		// Use default initialization
 		return mcp.InitializeResult{}, nil
 	})
-	
+
 	ctx := context.Background()
 	if err := server.Run(ctx); err != nil {
 		log.Fatalf("Server error: %v", err)
 	}
-}
\ No newline at end of file
+}
pkg/fetchserver/server.go → pkg/fetch/server.go
@@ -1,4 +1,4 @@
-package fetchserver
+package fetch
 
 import (
 	"encoding/json"
@@ -76,7 +76,7 @@ func (fs *Server) ListTools() []mcp.Tool {
 						"default":     5000,
 					},
 					"start_index": map[string]interface{}{
-						"type":        "integer", 
+						"type":        "integer",
 						"description": "Start reading content from this character index. Defaults to 0",
 						"minimum":     0,
 						"default":     0,
@@ -192,7 +192,7 @@ func (fs *Server) fetchContent(urlStr string, maxLength, startIndex int, raw boo
 
 	// Get content type
 	contentType := resp.Header.Get("Content-Type")
-	
+
 	// Process content
 	var content string
 	if raw || !isHTMLContent(string(body), contentType) {
@@ -246,7 +246,7 @@ func isHTMLContent(content, contentType string) bool {
 	if len(prefix) > 100 {
 		prefix = prefix[:100]
 	}
-	
+
 	return strings.Contains(strings.ToLower(prefix), "<html")
 }
 
@@ -358,11 +358,11 @@ func (fs *Server) stripHTMLTags(content string) string {
 	// Remove HTML tags using regex
 	re := regexp.MustCompile(`<[^>]*>`)
 	text := re.ReplaceAllString(content, " ")
-	
+
 	// Clean up whitespace
 	re = regexp.MustCompile(`\s+`)
 	text = re.ReplaceAllString(text, " ")
-	
+
 	return strings.TrimSpace(text)
 }
 
@@ -370,13 +370,13 @@ func (fs *Server) cleanMarkdown(content string) string {
 	// Remove excessive newlines
 	re := regexp.MustCompile(`\n{3,}`)
 	content = re.ReplaceAllString(content, "\n\n")
-	
+
 	// Remove excessive spaces
 	re = regexp.MustCompile(` {2,}`)
 	content = re.ReplaceAllString(content, " ")
-	
+
 	// Trim whitespace
 	content = strings.TrimSpace(content)
-	
+
 	return content
-}
\ No newline at end of file
+}
pkg/fetchserver/server_test.go → pkg/fetch/server_test.go
@@ -1,4 +1,4 @@
-package fetchserver
+package fetch
 
 import (
 	"net/http"
@@ -148,7 +148,7 @@ func TestServer_FetchWithMaxLength(t *testing.T) {
 	if !contains(textContent.Text, "\"length\": 100") {
 		t.Fatalf("Expected content length to be exactly 100 chars, got: %s", textContent.Text)
 	}
-	
+
 	if !contains(textContent.Text, "\"truncated\": true") {
 		t.Fatalf("Expected truncated flag to be true, got: %s", textContent.Text)
 	}
@@ -341,4 +341,4 @@ func TestServer_ListTools(t *testing.T) {
 // Helper functions
 func contains(s, substr string) bool {
 	return strings.Contains(s, substr)
-}
\ No newline at end of file
+}
pkg/fsserver/server.go → pkg/filesystem/server.go
@@ -1,4 +1,4 @@
-package fsserver
+package filesystem
 
 import (
 	"fmt"
@@ -20,7 +20,7 @@ type Server struct {
 // New creates a new Filesystem MCP server
 func New(allowedDirs []string) *Server {
 	server := mcp.NewServer("secure-filesystem-server", "0.2.0")
-	
+
 	// Normalize and validate allowed directories
 	normalizedDirs := make([]string, len(allowedDirs))
 	for i, dir := range allowedDirs {
@@ -30,15 +30,15 @@ func New(allowedDirs []string) *Server {
 		}
 		normalizedDirs[i] = filepath.Clean(absPath)
 	}
-	
+
 	fsServer := &Server{
 		Server:             server,
 		allowedDirectories: normalizedDirs,
 	}
-	
+
 	// Register all filesystem tools
 	fsServer.registerTools()
-	
+
 	return fsServer
 }
 
@@ -539,7 +539,7 @@ func (fs *Server) HandleListDirectoryWithSizes(req mcp.CallToolRequest) (mcp.Cal
 			totalFiles++
 			totalSize += entry.size
 		}
-		
+
 		formatted = append(formatted, fmt.Sprintf("%s %-30s %s", prefix, entry.name, sizeStr))
 	}
 
@@ -672,7 +672,7 @@ func (fs *Server) HandleListAllowedDirectories(req mcp.CallToolRequest) (mcp.Cal
 func (fs *Server) validatePath(requestedPath string) (string, error) {
 	expandedPath := expandHome(requestedPath)
 	var absolute string
-	
+
 	if filepath.IsAbs(expandedPath) {
 		absolute = filepath.Clean(expandedPath)
 	} else {
@@ -886,7 +886,7 @@ func (fs *Server) buildDirectoryTree(rootPath string) (string, error) {
 		var result []TreeEntry
 		for _, entry := range entries {
 			entryPath := filepath.Join(currentPath, entry.Name())
-			
+
 			// Validate each path
 			if _, err := fs.validatePath(entryPath); err != nil {
 				continue // Skip unauthorized paths
@@ -956,4 +956,4 @@ func (fs *Server) searchFiles(rootPath, pattern string, excludePatterns []string
 	})
 
 	return results, err
-}
\ No newline at end of file
+}
pkg/fsserver/server_test.go → pkg/filesystem/server_test.go
@@ -1,4 +1,4 @@
-package fsserver
+package filesystem
 
 import (
 	"os"
@@ -139,7 +139,7 @@ func TestFilesystemServer_ListDirectory(t *testing.T) {
 	// Create test files and directories
 	testFile := filepath.Join(tempDir, "test.txt")
 	testDir := filepath.Join(tempDir, "subdir")
-	
+
 	if err := os.WriteFile(testFile, []byte("test"), 0644); err != nil {
 		t.Fatal(err)
 	}
@@ -293,9 +293,9 @@ func TestFilesystemServer_EditFile(t *testing.T) {
 
 // Helper functions
 func contains(s, substr string) bool {
-	return len(s) > 0 && len(substr) > 0 && 
-		   (s == substr || (len(s) >= len(substr) && 
-		   findSubstring(s, substr)))
+	return len(s) > 0 && len(substr) > 0 &&
+		(s == substr || (len(s) >= len(substr) &&
+			findSubstring(s, substr)))
 }
 
 func findSubstring(s, substr string) bool {
@@ -305,4 +305,4 @@ func findSubstring(s, substr string) bool {
 		}
 	}
 	return false
-}
\ No newline at end of file
+}
pkg/gitserver/server.go → pkg/git/server.go
@@ -1,4 +1,4 @@
-package gitserver
+package git
 
 import (
 	"fmt"
@@ -19,14 +19,14 @@ type Server struct {
 // New creates a new Git MCP server
 func New() *Server {
 	server := mcp.NewServer("mcp-git", "1.0.0")
-	
+
 	gitServer := &Server{
 		Server: server,
 	}
-	
+
 	// Register all git tools
 	gitServer.registerTools()
-	
+
 	return gitServer
 }
 
@@ -501,7 +501,7 @@ func (gs *Server) runGitCommand(repoPath string, args ...string) (string, error)
 
 	cmd := exec.Command("git", args...)
 	cmd.Dir = repoPath
-	
+
 	output, err := cmd.CombinedOutput()
 	if err != nil {
 		return "", fmt.Errorf("%v: %s", err, string(output))
@@ -527,4 +527,4 @@ func (gs *Server) convertToStringSlice(input interface{}) ([]string, error) {
 	default:
 		return nil, fmt.Errorf("input is not a slice")
 	}
-}
\ No newline at end of file
+}
pkg/gitserver/server_test.go → pkg/git/server_test.go
@@ -1,4 +1,4 @@
-package gitserver
+package git
 
 import (
 	"fmt"
@@ -23,7 +23,7 @@ func TestGitServer_GitStatus(t *testing.T) {
 	}
 
 	server := New()
-	
+
 	// Test git status
 	req := mcp.CallToolRequest{
 		Name: "git_status",
@@ -65,7 +65,7 @@ func TestGitServer_GitInit(t *testing.T) {
 	defer os.RemoveAll(tempDir)
 
 	server := New()
-	
+
 	// Test git init
 	req := mcp.CallToolRequest{
 		Name: "git_init",
@@ -120,7 +120,7 @@ func TestGitServer_GitAdd(t *testing.T) {
 	}
 
 	server := New()
-	
+
 	// Test git add
 	req := mcp.CallToolRequest{
 		Name: "git_add",
@@ -186,23 +186,23 @@ func initGitRepo(dir string) error {
 			"repo_path": dir,
 		},
 	}
-	
+
 	result, err := server.HandleGitInit(req)
 	if err != nil {
 		return err
 	}
-	
+
 	if result.IsError {
 		return fmt.Errorf("git init failed")
 	}
-	
+
 	return nil
 }
 
 func contains(s, substr string) bool {
-	return len(s) > 0 && len(substr) > 0 && 
-		   (s == substr || (len(s) >= len(substr) && 
-		   findSubstring(s, substr)))
+	return len(s) > 0 && len(substr) > 0 &&
+		(s == substr || (len(s) >= len(substr) &&
+			findSubstring(s, substr)))
 }
 
 func findSubstring(s, substr string) bool {
@@ -212,4 +212,4 @@ func findSubstring(s, substr string) bool {
 		}
 	}
 	return false
-}
\ No newline at end of file
+}
pkg/mcp/server.go
@@ -15,22 +15,22 @@ type Server struct {
 	name         string
 	version      string
 	capabilities ServerCapabilities
-	
+
 	// Handler functions
 	toolHandlers     map[string]ToolHandler
 	promptHandlers   map[string]PromptHandler
 	resourceHandlers map[string]ResourceHandler
-	
+
 	// Lifecycle handlers
 	initializeHandler func(InitializeRequest) (InitializeResult, error)
 	shutdownHandler   func() error
-	
+
 	mu sync.RWMutex
 }
 
 // Handler types
 type ToolHandler func(CallToolRequest) (CallToolResult, error)
-type PromptHandler func(GetPromptRequest) (GetPromptResult, error) 
+type PromptHandler func(GetPromptRequest) (GetPromptResult, error)
 type ResourceHandler func(ReadResourceRequest) (ReadResourceResult, error)
 
 // NewServer creates a new MCP server
@@ -85,7 +85,7 @@ func (s *Server) SetShutdownHandler(handler func() error) {
 func (s *Server) ListTools() []Tool {
 	s.mu.RLock()
 	defer s.mu.RUnlock()
-	
+
 	tools := make([]Tool, 0, len(s.toolHandlers))
 	for name := range s.toolHandlers {
 		// Tools will be defined by individual servers
@@ -99,7 +99,7 @@ func (s *Server) ListTools() []Tool {
 			},
 		})
 	}
-	
+
 	return tools
 }
 
@@ -107,31 +107,31 @@ func (s *Server) ListTools() []Tool {
 func (s *Server) Run(ctx context.Context) error {
 	scanner := bufio.NewScanner(os.Stdin)
 	encoder := json.NewEncoder(os.Stdout)
-	
+
 	for scanner.Scan() {
 		line := scanner.Bytes()
-		
+
 		var req JSONRPCRequest
 		if err := json.Unmarshal(line, &req); err != nil {
 			s.sendError(encoder, nil, ParseError, "Parse error")
 			continue
 		}
-		
+
 		response := s.handleRequest(req)
 		if err := encoder.Encode(response); err != nil {
 			log.Printf("Error encoding response: %v", err)
 		}
-		
+
 		// Check for shutdown
 		if req.Method == "shutdown" {
 			break
 		}
 	}
-	
+
 	if err := scanner.Err(); err != nil {
 		return fmt.Errorf("scanner error: %w", err)
 	}
-	
+
 	return nil
 }
 
@@ -166,7 +166,7 @@ func (s *Server) handleInitialize(req JSONRPCRequest) JSONRPCResponse {
 	if err := json.Unmarshal(req.Params, &initReq); err != nil {
 		return s.createErrorResponse(req.ID, InvalidParams, "Invalid params")
 	}
-	
+
 	result := InitializeResult{
 		ProtocolVersion: "2024-11-05",
 		Capabilities:    s.capabilities,
@@ -175,13 +175,13 @@ func (s *Server) handleInitialize(req JSONRPCRequest) JSONRPCResponse {
 			Version: s.version,
 		},
 	}
-	
+
 	if s.initializeHandler != nil {
 		if customResult, err := s.initializeHandler(initReq); err == nil {
 			result = customResult
 		}
 	}
-	
+
 	return s.createSuccessResponse(req.ID, result)
 }
 
@@ -197,7 +197,7 @@ func (s *Server) handleShutdown(req JSONRPCRequest) JSONRPCResponse {
 	if s.shutdownHandler != nil {
 		s.shutdownHandler()
 	}
-	
+
 	return s.createSuccessResponse(req.ID, nil)
 }
 
@@ -212,20 +212,20 @@ func (s *Server) handleCallTool(req JSONRPCRequest) JSONRPCResponse {
 	if err := json.Unmarshal(req.Params, &callReq); err != nil {
 		return s.createErrorResponse(req.ID, InvalidParams, "Invalid params")
 	}
-	
+
 	s.mu.RLock()
 	handler, exists := s.toolHandlers[callReq.Name]
 	s.mu.RUnlock()
-	
+
 	if !exists {
 		return s.createErrorResponse(req.ID, MethodNotFound, "Tool not found")
 	}
-	
+
 	result, err := handler(callReq)
 	if err != nil {
 		return s.createErrorResponse(req.ID, InternalError, err.Error())
 	}
-	
+
 	return s.createSuccessResponse(req.ID, result)
 }
 
@@ -240,20 +240,20 @@ func (s *Server) handleGetPrompt(req JSONRPCRequest) JSONRPCResponse {
 	if err := json.Unmarshal(req.Params, &promptReq); err != nil {
 		return s.createErrorResponse(req.ID, InvalidParams, "Invalid params")
 	}
-	
+
 	s.mu.RLock()
 	handler, exists := s.promptHandlers[promptReq.Name]
 	s.mu.RUnlock()
-	
+
 	if !exists {
 		return s.createErrorResponse(req.ID, MethodNotFound, "Prompt not found")
 	}
-	
+
 	result, err := handler(promptReq)
 	if err != nil {
 		return s.createErrorResponse(req.ID, InternalError, err.Error())
 	}
-	
+
 	return s.createSuccessResponse(req.ID, result)
 }
 
@@ -268,20 +268,20 @@ func (s *Server) handleReadResource(req JSONRPCRequest) JSONRPCResponse {
 	if err := json.Unmarshal(req.Params, &readReq); err != nil {
 		return s.createErrorResponse(req.ID, InvalidParams, "Invalid params")
 	}
-	
+
 	s.mu.RLock()
 	handler, exists := s.resourceHandlers[readReq.URI]
 	s.mu.RUnlock()
-	
+
 	if !exists {
 		return s.createErrorResponse(req.ID, MethodNotFound, "Resource not found")
 	}
-	
+
 	result, err := handler(readReq)
 	if err != nil {
 		return s.createErrorResponse(req.ID, InternalError, err.Error())
 	}
-	
+
 	return s.createSuccessResponse(req.ID, result)
 }
 
@@ -292,7 +292,7 @@ func (s *Server) createSuccessResponse(id *int, result interface{}) JSONRPCRespo
 		rawMsg := json.RawMessage(bytes)
 		resultBytes = &rawMsg
 	}
-	
+
 	return JSONRPCResponse{
 		JSONRPC: "2.0",
 		ID:      id,
@@ -337,4 +337,4 @@ func NewToolError(message string) CallToolResult {
 		Content: []Content{NewTextContent("Error: " + message)},
 		IsError: true,
 	}
-}
\ No newline at end of file
+}
pkg/mcp/types.go
@@ -42,8 +42,8 @@ type InitializeRequest struct {
 }
 
 type Capabilities struct {
-	Roots       *RootsCapability       `json:"roots,omitempty"`
-	Sampling    *SamplingCapability    `json:"sampling,omitempty"`
+	Roots        *RootsCapability       `json:"roots,omitempty"`
+	Sampling     *SamplingCapability    `json:"sampling,omitempty"`
 	Experimental map[string]interface{} `json:"experimental,omitempty"`
 }
 
@@ -59,10 +59,10 @@ type ClientInfo struct {
 }
 
 type InitializeResult struct {
-	ProtocolVersion   string            `json:"protocolVersion"`
-	Capabilities      ServerCapabilities `json:"capabilities"`
-	ServerInfo        ServerInfo        `json:"serverInfo"`
-	Instructions      string            `json:"instructions,omitempty"`
+	ProtocolVersion string             `json:"protocolVersion"`
+	Capabilities    ServerCapabilities `json:"capabilities"`
+	ServerInfo      ServerInfo         `json:"serverInfo"`
+	Instructions    string             `json:"instructions,omitempty"`
 }
 
 type ServerCapabilities struct {
@@ -166,7 +166,7 @@ type GetPromptResult struct {
 	Messages    []PromptMessage `json:"messages"`
 }
 
-// Resource types  
+// Resource types
 type Resource struct {
 	URI         string `json:"uri"`
 	Name        string `json:"name"`
@@ -225,4 +225,4 @@ type ProgressNotification struct {
 	ProgressToken string  `json:"progressToken"`
 	Progress      float64 `json:"progress"`
 	Total         float64 `json:"total,omitempty"`
-}
\ No newline at end of file
+}
pkg/memoryserver/server.go → pkg/memory/server.go
@@ -1,4 +1,4 @@
-package memoryserver
+package memory
 
 import (
 	"encoding/json"
@@ -801,4 +801,4 @@ func (ms *Server) saveGraph() error {
 	}
 
 	return os.WriteFile(ms.memoryFile, data, 0644)
-}
\ No newline at end of file
+}
pkg/memoryserver/server_test.go → pkg/memory/server_test.go
@@ -1,4 +1,4 @@
-package memoryserver
+package memory
 
 import (
 	"path/filepath"
@@ -26,7 +26,7 @@ func TestMemoryServer_CreateEntities(t *testing.T) {
 				},
 				map[string]interface{}{
 					"name":         "Anthropic",
-					"entityType":   "organization", 
+					"entityType":   "organization",
 					"observations": []interface{}{"AI safety company"},
 				},
 			},
@@ -552,4 +552,4 @@ func TestMemoryServer_Persistence(t *testing.T) {
 // Helper functions
 func contains(s, substr string) bool {
 	return strings.Contains(s, substr)
-}
\ No newline at end of file
+}
pkg/thinkingserver/server.go → pkg/thinking/server.go
@@ -1,4 +1,4 @@
-package thinkingserver
+package thinking
 
 import (
 	"encoding/json"
@@ -16,21 +16,21 @@ type Server struct {
 
 // ThinkingSession represents a thinking session with sequential thoughts
 type ThinkingSession struct {
-	Thoughts      []Thought `json:"thoughts"`
-	CurrentThought int      `json:"current_thought"`
-	TotalThoughts int       `json:"total_thoughts"`
-	Status        string    `json:"status"` // "active", "completed"
+	Thoughts       []Thought `json:"thoughts"`
+	CurrentThought int       `json:"current_thought"`
+	TotalThoughts  int       `json:"total_thoughts"`
+	Status         string    `json:"status"` // "active", "completed"
 }
 
 // Thought represents a single thought in the sequence
 type Thought struct {
-	Number           int    `json:"number"`
-	Content          string `json:"content"`
-	IsRevision       bool   `json:"is_revision,omitempty"`
-	RevisesThought   *int   `json:"revises_thought,omitempty"`
-	BranchFromThought *int  `json:"branch_from_thought,omitempty"`
-	BranchID         string `json:"branch_id,omitempty"`
-	NeedsMoreThoughts bool  `json:"needs_more_thoughts,omitempty"`
+	Number            int    `json:"number"`
+	Content           string `json:"content"`
+	IsRevision        bool   `json:"is_revision,omitempty"`
+	RevisesThought    *int   `json:"revises_thought,omitempty"`
+	BranchFromThought *int   `json:"branch_from_thought,omitempty"`
+	BranchID          string `json:"branch_id,omitempty"`
+	NeedsMoreThoughts bool   `json:"needs_more_thoughts,omitempty"`
 }
 
 // ThinkingResponse represents the response structure
@@ -241,18 +241,18 @@ func (sts *Server) HandleSequentialThinking(req mcp.CallToolRequest) (mcp.CallTo
 
 	// Add context information
 	var contextInfo []string
-	
+
 	if isRevision && revisesThought != nil {
 		contextInfo = append(contextInfo, fmt.Sprintf("Revising thought %d", *revisesThought))
 	}
-	
+
 	if branchFromThought != nil {
 		contextInfo = append(contextInfo, fmt.Sprintf("Branching from thought %d", *branchFromThought))
 		if branchID != "" {
 			contextInfo = append(contextInfo, fmt.Sprintf("Branch: %s", branchID))
 		}
 	}
-	
+
 	if needsMoreThoughts {
 		contextInfo = append(contextInfo, "Requesting additional thoughts beyond initial estimate")
 	}
@@ -268,13 +268,13 @@ func (sts *Server) HandleSequentialThinking(req mcp.CallToolRequest) (mcp.CallTo
 func (sts *Server) extractSolution(finalThought string) string {
 	// Simple heuristic to extract a solution from the final thought
 	content := strings.ToLower(finalThought)
-	
+
 	// Look for solution indicators (with and without colons)
 	solutionKeywords := []string{
 		"solution:",
 		"solution is",
 		"answer:",
-		"answer is", 
+		"answer is",
 		"conclusion:",
 		"final answer:",
 		"result:",
@@ -283,7 +283,7 @@ func (sts *Server) extractSolution(finalThought string) string {
 		"therefore the",
 		"in conclusion:",
 	}
-	
+
 	for _, keyword := range solutionKeywords {
 		if idx := strings.Index(content, keyword); idx != -1 {
 			// Extract text after the keyword
@@ -302,7 +302,7 @@ func (sts *Server) extractSolution(finalThought string) string {
 			}
 		}
 	}
-	
+
 	// If no explicit solution found, return the last sentence or a portion
 	sentences := strings.Split(strings.TrimSpace(finalThought), ".")
 	if len(sentences) > 0 {
@@ -314,57 +314,57 @@ func (sts *Server) extractSolution(finalThought string) string {
 			return lastSentence
 		}
 	}
-	
+
 	return "Solution extracted from final thought"
 }
 
 func (sts *Server) formatThinkingResult(response ThinkingResponse, thought Thought, contextInfo []string) string {
 	var result strings.Builder
-	
+
 	// Header
-	result.WriteString(fmt.Sprintf("🧠 Sequential Thinking - Thought %d/%d\n", 
+	result.WriteString(fmt.Sprintf("🧠 Sequential Thinking - Thought %d/%d\n",
 		response.ThoughtNumber, response.TotalThoughts))
 	result.WriteString("═══════════════════════════════════════\n\n")
-	
+
 	// Context information if any
 	if len(contextInfo) > 0 {
 		result.WriteString("📝 Context: " + strings.Join(contextInfo, ", ") + "\n\n")
 	}
-	
+
 	// Main thought content
 	result.WriteString("💭 Current Thought:\n")
 	result.WriteString(response.Thought + "\n\n")
-	
+
 	// Progress indicator
 	progressBar := sts.createProgressBar(response.ThoughtNumber, response.TotalThoughts)
 	result.WriteString("📊 Progress: " + progressBar + "\n\n")
-	
+
 	// Status
 	statusEmoji := "🔄"
 	if response.Status == "completed" {
 		statusEmoji = "✅"
 	}
 	result.WriteString(fmt.Sprintf("%s Status: %s\n", statusEmoji, response.Status))
-	
+
 	if response.NextThoughtNeeded {
 		result.WriteString("⏭️  Next thought needed\n")
 	} else {
 		result.WriteString("🏁 Thinking sequence complete\n")
 	}
-	
+
 	// Solution if available
 	if response.Solution != "" {
 		result.WriteString("\n🎯 Extracted Solution:\n")
 		result.WriteString(response.Solution + "\n")
 	}
-	
+
 	// JSON data for programmatic access
 	result.WriteString("\n📋 Structured Data:\n")
 	jsonData, _ := json.MarshalIndent(response, "", "  ")
 	result.WriteString("```json\n")
 	result.WriteString(string(jsonData))
 	result.WriteString("\n```")
-	
+
 	return result.String()
 }
 
@@ -372,15 +372,15 @@ func (sts *Server) createProgressBar(current, total int) string {
 	if total <= 0 {
 		return "[████████████████████] 100%"
 	}
-	
+
 	percentage := float64(current) / float64(total) * 100
 	if percentage > 100 {
 		percentage = 100
 	}
-	
+
 	barLength := 20
 	filledLength := int(percentage / 100 * float64(barLength))
-	
+
 	bar := "["
 	for i := 0; i < barLength; i++ {
 		if i < filledLength {
@@ -390,6 +390,6 @@ func (sts *Server) createProgressBar(current, total int) string {
 		}
 	}
 	bar += "] " + strconv.Itoa(int(percentage)) + "%"
-	
+
 	return bar
-}
\ No newline at end of file
+}
pkg/thinkingserver/server_test.go → pkg/thinking/server_test.go
@@ -1,4 +1,4 @@
-package thinkingserver
+package thinking
 
 import (
 	"strings"
@@ -13,10 +13,10 @@ func TestServer_BasicThinking(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":            "Let me analyze this problem step by step.",
-			"nextThoughtNeeded":  true,
-			"thoughtNumber":      1,
-			"totalThoughts":      3,
+			"thought":           "Let me analyze this problem step by step.",
+			"nextThoughtNeeded": true,
+			"thoughtNumber":     1,
+			"totalThoughts":     3,
 		},
 	}
 
@@ -57,10 +57,10 @@ func TestServer_CompletedThinking(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":            "Therefore, the solution is 42.",
-			"nextThoughtNeeded":  false,
-			"thoughtNumber":      3,
-			"totalThoughts":      3,
+			"thought":           "Therefore, the solution is 42.",
+			"nextThoughtNeeded": false,
+			"thoughtNumber":     3,
+			"totalThoughts":     3,
 		},
 	}
 
@@ -101,12 +101,12 @@ func TestServer_RevisionThinking(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":            "Actually, let me reconsider my previous analysis.",
-			"nextThoughtNeeded":  true,
-			"thoughtNumber":      4,
-			"totalThoughts":      5,
-			"isRevision":         true,
-			"revisesThought":     2,
+			"thought":           "Actually, let me reconsider my previous analysis.",
+			"nextThoughtNeeded": true,
+			"thoughtNumber":     4,
+			"totalThoughts":     5,
+			"isRevision":        true,
+			"revisesThought":    2,
 		},
 	}
 
@@ -142,12 +142,12 @@ func TestServer_BranchThinking(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":             "Let me explore an alternative approach.",
-			"nextThoughtNeeded":   true,
-			"thoughtNumber":       6,
-			"totalThoughts":       8,
-			"branchFromThought":   3,
-			"branchId":            "alternative_path",
+			"thought":           "Let me explore an alternative approach.",
+			"nextThoughtNeeded": true,
+			"thoughtNumber":     6,
+			"totalThoughts":     8,
+			"branchFromThought": 3,
+			"branchId":          "alternative_path",
 		},
 	}
 
@@ -182,11 +182,11 @@ func TestServer_NeedsMoreThoughts(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":             "I realize I need more steps to solve this.",
-			"nextThoughtNeeded":   true,
-			"thoughtNumber":       5,
-			"totalThoughts":       5,
-			"needsMoreThoughts":   true,
+			"thought":           "I realize I need more steps to solve this.",
+			"nextThoughtNeeded": true,
+			"thoughtNumber":     5,
+			"totalThoughts":     5,
+			"needsMoreThoughts": true,
 		},
 	}
 
@@ -252,10 +252,10 @@ func TestServer_InvalidParams(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":            "Test thought",
-			"nextThoughtNeeded":  true,
-			"thoughtNumber":      0, // Invalid: must be >= 1
-			"totalThoughts":      3,
+			"thought":           "Test thought",
+			"nextThoughtNeeded": true,
+			"thoughtNumber":     0, // Invalid: must be >= 1
+			"totalThoughts":     3,
 		},
 	}
 
@@ -285,10 +285,10 @@ func TestServer_SolutionExtraction(t *testing.T) {
 	req := mcp.CallToolRequest{
 		Name: "sequentialthinking",
 		Arguments: map[string]interface{}{
-			"thought":            "After careful analysis, the answer is: The optimal solution involves using a binary search algorithm.",
-			"nextThoughtNeeded":  false,
-			"thoughtNumber":      3,
-			"totalThoughts":      3,
+			"thought":           "After careful analysis, the answer is: The optimal solution involves using a binary search algorithm.",
+			"nextThoughtNeeded": false,
+			"thoughtNumber":     3,
+			"totalThoughts":     3,
 		},
 	}
 
@@ -371,4 +371,4 @@ func TestServer_ProgressBar(t *testing.T) {
 // Helper functions
 func contains(s, substr string) bool {
 	return strings.Contains(s, substr)
-}
\ No newline at end of file
+}
pkg/timeserver/server.go → pkg/time/server.go
@@ -1,4 +1,4 @@
-package timeserver
+package time
 
 import (
 	"encoding/json"
@@ -33,18 +33,18 @@ type TimeConversionResult struct {
 // New creates a new Time MCP server
 func New() *Server {
 	server := mcp.NewServer("mcp-time", "1.0.0")
-	
+
 	// Get local timezone
 	localTZ := getLocalTimezone()
-	
+
 	timeServer := &Server{
 		Server:        server,
 		localTimezone: localTZ,
 	}
-	
+
 	// Register all time tools
 	timeServer.registerTools()
-	
+
 	return timeServer
 }
 
@@ -155,7 +155,7 @@ func (ts *Server) getCurrentTime(timezone string) (*TimeResult, error) {
 	}
 
 	currentTime := time.Now().In(loc)
-	
+
 	return &TimeResult{
 		Timezone: timezone,
 		Datetime: currentTime.Format("2006-01-02T15:04:05-07:00"),
@@ -193,7 +193,7 @@ func (ts *Server) convertTime(sourceTimezone, timeStr, targetTimezone string) (*
 	// Use current date in source timezone
 	now := time.Now().In(sourceLoc)
 	sourceTime := time.Date(now.Year(), now.Month(), now.Day(), hour, minute, 0, 0, sourceLoc)
-	
+
 	// Convert to target timezone
 	targetTime := sourceTime.In(targetLoc)
 
@@ -240,14 +240,14 @@ func getLocalTimezone() string {
 func isDST(t time.Time) bool {
 	// Check if time is in daylight saving time
 	_, offset := t.Zone()
-	
+
 	// Create time in January (standard time) and July (potentially DST)
 	jan := time.Date(t.Year(), 1, 1, 12, 0, 0, 0, t.Location())
 	jul := time.Date(t.Year(), 7, 1, 12, 0, 0, 0, t.Location())
-	
+
 	_, janOffset := jan.Zone()
 	_, julOffset := jul.Zone()
-	
+
 	// If offsets are different, the timezone observes DST
 	if janOffset != julOffset {
 		// We're in DST if current offset matches the "more positive" offset
@@ -258,7 +258,7 @@ func isDST(t time.Time) bool {
 			return offset == janOffset
 		}
 	}
-	
+
 	// No DST observed in this timezone
 	return false
 }
@@ -280,4 +280,4 @@ func formatTimeDifference(hours float64) string {
 		formatted = strings.TrimRight(formatted, ".")
 		return formatted + "h"
 	}
-}
\ No newline at end of file
+}
pkg/timeserver/server_test.go → pkg/time/server_test.go
@@ -1,4 +1,4 @@
-package timeserver
+package time
 
 import (
 	"strings"
@@ -203,4 +203,4 @@ func TestServer_ConvertTimeWithDST(t *testing.T) {
 // Helper functions
 func contains(s, substr string) bool {
 	return strings.Contains(s, substr)
-}
\ No newline at end of file
+}
go.mod
@@ -2,10 +2,4 @@ module github.com/xlgmokha/mcp
 
 go 1.24.0
 
-require github.com/spf13/cobra v1.9.1
-
-require (
-	github.com/inconshreveable/mousetrap v1.1.0 // indirect
-	github.com/spf13/pflag v1.0.6 // indirect
-	golang.org/x/net v0.41.0 // indirect
-)
+require golang.org/x/net v0.41.0
go.sum
@@ -1,12 +1,2 @@
-github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
-github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
-github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
 golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=