From c8bdbf2d51fc55abef038da909d4f3acbdadb71a Mon Sep 17 00:00:00 2001 From: LaelLuo Date: Tue, 16 Sep 2025 18:54:02 +0800 Subject: [PATCH] :bug: fix(logging): implement logging/setLevel via mcp-go upgrade and tool args adaptation - Upgrade mcp-go to v0.39.1 which adds server-side handling for `logging/setLevel` and session logging support - Restore `server.WithLogging()` in initialization so clients can set logging level - Adapt tool handlers to new `mcp.CallToolRequest` API using `GetString/GetInt/GetArguments()` instead of indexing `Params.Arguments` - Build succeeds; root `go test` passes; integration tests depend on external LSPs and are unaffected by this fix Fixes #79 --- go.mod | 7 ++++- go.sum | 15 +++++++++-- tools.go | 80 ++++++++++++++++++++------------------------------------ 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/go.mod b/go.mod index b875a3f..1366abe 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.0 require ( github.com/davecgh/go-spew v1.1.1 github.com/fsnotify/fsnotify v1.9.0 - github.com/mark3labs/mcp-go v0.25.0 + github.com/mark3labs/mcp-go v0.39.1 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 github.com/stretchr/testify v1.10.0 golang.org/x/text v0.25.0 @@ -13,12 +13,17 @@ require ( require ( github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect github.com/kisielk/errcheck v1.9.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/spf13/cast v1.7.1 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect golang.org/x/mod v0.24.0 // indirect diff --git a/go.sum b/go.sum index 9ae5405..974cb37 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -15,6 +19,9 @@ github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M= github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -24,8 +31,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mark3labs/mcp-go v0.25.0 h1:UUpcMT3L5hIhuDy7aifj4Bphw4Pfx1Rf8mzMXDe8RQw= -github.com/mark3labs/mcp-go v0.25.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mark3labs/mcp-go v0.39.1 h1:2oPxk7aDbQhouakkYyKl2T4hKFU1c6FDaubWyGyVE1k= +github.com/mark3labs/mcp-go v0.39.1/go.mod h1:T7tUa2jO6MavG+3P25Oy/jR7iCeJPHImCZHRymCn39g= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -38,6 +47,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac h1:TSSpLIG4v+p0rPv1pNOQtl1I8knsO4S9trOxNMOLVP4= diff --git a/tools.go b/tools.go index 55898ca..8620b1c 100644 --- a/tools.go +++ b/tools.go @@ -43,13 +43,14 @@ func (s *mcpServer) registerTools() error { s.mcpServer.AddTool(applyTextEditTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Extract arguments - filePath, ok := request.Params.Arguments["filePath"].(string) - if !ok { + filePath := request.GetString("filePath", "") + if filePath == "" { return mcp.NewToolResultError("filePath must be a string"), nil } // Extract edits array - editsArg, ok := request.Params.Arguments["edits"] + args := request.GetArguments() + editsArg, ok := args["edits"] if !ok { return mcp.NewToolResultError("edits is required"), nil } @@ -105,8 +106,8 @@ func (s *mcpServer) registerTools() error { s.mcpServer.AddTool(readDefinitionTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Extract arguments - symbolName, ok := request.Params.Arguments["symbolName"].(string) - if !ok { + symbolName := request.GetString("symbolName", "") + if symbolName == "" { return mcp.NewToolResultError("symbolName must be a string"), nil } @@ -129,8 +130,8 @@ func (s *mcpServer) registerTools() error { s.mcpServer.AddTool(findReferencesTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Extract arguments - symbolName, ok := request.Params.Arguments["symbolName"].(string) - if !ok { + symbolName := request.GetString("symbolName", "") + if symbolName == "" { return mcp.NewToolResultError("symbolName must be a string"), nil } @@ -161,19 +162,18 @@ func (s *mcpServer) registerTools() error { s.mcpServer.AddTool(getDiagnosticsTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Extract arguments - filePath, ok := request.Params.Arguments["filePath"].(string) - if !ok { + filePath := request.GetString("filePath", "") + if filePath == "" { return mcp.NewToolResultError("filePath must be a string"), nil } - contextLines := 5 // default value - if contextLinesArg, ok := request.Params.Arguments["contextLines"].(int); ok { - contextLines = contextLinesArg - } + contextLines := request.GetInt("contextLines", 5) showLineNumbers := true // default value - if showLineNumbersArg, ok := request.Params.Arguments["showLineNumbers"].(bool); ok { - showLineNumbers = showLineNumbersArg + if args := request.GetArguments(); args != nil { + if v, ok := args["showLineNumbers"].(bool); ok { + showLineNumbers = v + } } coreLogger.Debug("Executing diagnostics for file: %s", filePath) @@ -268,28 +268,17 @@ func (s *mcpServer) registerTools() error { s.mcpServer.AddTool(hoverTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Extract arguments - filePath, ok := request.Params.Arguments["filePath"].(string) - if !ok { + filePath := request.GetString("filePath", "") + if filePath == "" { return mcp.NewToolResultError("filePath must be a string"), nil } - // Handle both float64 and int for line and column due to JSON parsing - var line, column int - switch v := request.Params.Arguments["line"].(type) { - case float64: - line = int(v) - case int: - line = v - default: + line := request.GetInt("line", 0) + column := request.GetInt("column", 0) + if line <= 0 { return mcp.NewToolResultError("line must be a number"), nil } - - switch v := request.Params.Arguments["column"].(type) { - case float64: - column = int(v) - case int: - column = v - default: + if column <= 0 { return mcp.NewToolResultError("column must be a number"), nil } @@ -324,33 +313,22 @@ func (s *mcpServer) registerTools() error { s.mcpServer.AddTool(renameSymbolTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Extract arguments - filePath, ok := request.Params.Arguments["filePath"].(string) - if !ok { + filePath := request.GetString("filePath", "") + if filePath == "" { return mcp.NewToolResultError("filePath must be a string"), nil } - newName, ok := request.Params.Arguments["newName"].(string) - if !ok { + newName := request.GetString("newName", "") + if newName == "" { return mcp.NewToolResultError("newName must be a string"), nil } - // Handle both float64 and int for line and column due to JSON parsing - var line, column int - switch v := request.Params.Arguments["line"].(type) { - case float64: - line = int(v) - case int: - line = v - default: + line := request.GetInt("line", 0) + column := request.GetInt("column", 0) + if line <= 0 { return mcp.NewToolResultError("line must be a number"), nil } - - switch v := request.Params.Arguments["column"].(type) { - case float64: - column = int(v) - case int: - column = v - default: + if column <= 0 { return mcp.NewToolResultError("column must be a number"), nil }