diff --git a/.changeset/patch-fix-http-transport-go-sdk.md b/.changeset/patch-fix-http-transport-go-sdk.md new file mode 100644 index 000000000..62e345b2e --- /dev/null +++ b/.changeset/patch-fix-http-transport-go-sdk.md @@ -0,0 +1,7 @@ +--- +"gh-aw": patch +--- + +Fix HTTP transport usage of go-sdk + +Fixed the MCP server HTTP transport implementation to use the correct `NewStreamableHTTPHandler` API from go-sdk instead of the deprecated SSE handler. Also added request/response logging middleware and changed configuration validation errors to warnings to allow server startup in test environments. diff --git a/pkg/cli/mcp_server.go b/pkg/cli/mcp_server.go index 2d1e681a0..d6b82d82e 100644 --- a/pkg/cli/mcp_server.go +++ b/pkg/cli/mcp_server.go @@ -3,6 +3,7 @@ package cli import ( "context" "fmt" + "log" "net/http" "os" "os/exec" @@ -58,8 +59,10 @@ Examples: // runMCPServer starts the MCP server on stdio or HTTP transport func runMCPServer(port int, cmdPath string) error { // Validate that the CLI and secrets are properly configured + // Note: Validation failures are logged as warnings but don't prevent server startup + // This allows the server to start in test environments or non-repository directories if err := validateMCPServerConfiguration(cmdPath); err != nil { - return fmt.Errorf("configuration validation failed: %w", err) + fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Configuration validation warning: %v", err))) } // Create the server configuration @@ -288,18 +291,55 @@ func createMCPServer(cmdPath string) *mcp.Server { return server } +// responseWriter wraps http.ResponseWriter to capture the status code. +type responseWriter struct { + http.ResponseWriter + statusCode int +} + +func loggingHandler(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + // Create a response writer wrapper to capture status code. + wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK} + + // Log request details. + log.Printf("[REQUEST] %s | %s | %s %s", + start.Format(time.RFC3339), + r.RemoteAddr, + r.Method, + r.URL.Path) + + // Call the actual handler. + handler.ServeHTTP(wrapped, r) + + // Log response details. + duration := time.Since(start) + log.Printf("[RESPONSE] %s | %s | %s %s | Status: %d | Duration: %v", + time.Now().Format(time.RFC3339), + r.RemoteAddr, + r.Method, + r.URL.Path, + wrapped.statusCode, + duration) + }) +} + // runHTTPServer runs the MCP server with HTTP/SSE transport func runHTTPServer(server *mcp.Server, port int) error { - // Create SSE handler - handler := mcp.NewSSEHandler(func(*http.Request) *mcp.Server { + // Create the streamable HTTP handler. + handler := mcp.NewStreamableHTTPHandler(func(req *http.Request) *mcp.Server { return server - }) + }, nil) + + handlerWithLogging := loggingHandler(handler) // Create HTTP server addr := fmt.Sprintf(":%d", port) httpServer := &http.Server{ Addr: addr, - Handler: handler, + Handler: handlerWithLogging, } fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Starting MCP server on http://localhost%s", addr)))