Skip to content

Commit 35dfcf2

Browse files
authored
examples: Fix SSE streaming issue by moving logging from HTTP to MCP middlewarre (#614)
In `examples/http`, previous HTTP-level logging middleware blocked SSE streaming because `handler.ServeHTTP()` does not return until the connection closes for GET requests (SSE streams). This prevented response headers from being sent to the client. Changes: - Replace HTTP-level logging handler with MCP middleware pattern - Implement logging at the MCP protocol layer using mcp.Middleware - Add middleware to server using AddReceivingMiddleware() - Simplify main.go by removing HTTP handler wrapping This allows SSE streams to work properly while still providing detailed logging for all MCP protocol-level method calls. Fixes #632
1 parent d297272 commit 35dfcf2

File tree

2 files changed

+46
-43
lines changed

2 files changed

+46
-43
lines changed

examples/http/logging_middleware.go

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,49 @@
55
package main
66

77
import (
8+
"context"
89
"log"
9-
"net/http"
1010
"time"
11-
)
12-
13-
// responseWriter wraps http.ResponseWriter to capture the status code.
14-
type responseWriter struct {
15-
http.ResponseWriter
16-
statusCode int
17-
}
1811

19-
func (rw *responseWriter) WriteHeader(code int) {
20-
rw.statusCode = code
21-
rw.ResponseWriter.WriteHeader(code)
22-
}
12+
"github.com/modelcontextprotocol/go-sdk/mcp"
13+
)
2314

24-
func loggingHandler(handler http.Handler) http.Handler {
25-
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
26-
start := time.Now()
27-
28-
// Create a response writer wrapper to capture status code.
29-
wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
30-
31-
// Log request details.
32-
log.Printf("[REQUEST] %s | %s | %s %s",
33-
start.Format(time.RFC3339),
34-
r.RemoteAddr,
35-
r.Method,
36-
r.URL.Path)
37-
38-
// Call the actual handler.
39-
handler.ServeHTTP(wrapped, r)
40-
41-
// Log response details.
42-
duration := time.Since(start)
43-
log.Printf("[RESPONSE] %s | %s | %s %s | Status: %d | Duration: %v",
44-
time.Now().Format(time.RFC3339),
45-
r.RemoteAddr,
46-
r.Method,
47-
r.URL.Path,
48-
wrapped.statusCode,
49-
duration)
50-
})
15+
// createLoggingMiddleware creates an MCP middleware that logs method calls.
16+
func createLoggingMiddleware() mcp.Middleware {
17+
return func(next mcp.MethodHandler) mcp.MethodHandler {
18+
return func(
19+
ctx context.Context,
20+
method string,
21+
req mcp.Request,
22+
) (mcp.Result, error) {
23+
start := time.Now()
24+
sessionID := req.GetSession().ID()
25+
26+
// Log request details.
27+
log.Printf("[REQUEST] Session: %s | Method: %s",
28+
sessionID,
29+
method)
30+
31+
// Call the actual handler.
32+
result, err := next(ctx, method, req)
33+
34+
// Log response details.
35+
duration := time.Since(start)
36+
37+
if err != nil {
38+
log.Printf("[RESPONSE] Session: %s | Method: %s | Status: ERROR | Duration: %v | Error: %v",
39+
sessionID,
40+
method,
41+
duration,
42+
err)
43+
} else {
44+
log.Printf("[RESPONSE] Session: %s | Method: %s | Status: OK | Duration: %v",
45+
sessionID,
46+
method,
47+
duration)
48+
}
49+
50+
return result, err
51+
}
52+
}
5153
}

examples/http/main.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ func runServer(url string) {
117117
Version: "1.0.0",
118118
}, nil)
119119

120+
// Add MCP-level logging middleware.
121+
server.AddReceivingMiddleware(createLoggingMiddleware())
122+
120123
// Add the cityTime tool.
121124
mcp.AddTool(server, &mcp.Tool{
122125
Name: "cityTime",
@@ -128,13 +131,11 @@ func runServer(url string) {
128131
return server
129132
}, nil)
130133

131-
handlerWithLogging := loggingHandler(handler)
132-
133134
log.Printf("MCP server listening on %s", url)
134135
log.Printf("Available tool: cityTime (cities: nyc, sf, boston)")
135136

136-
// Start the HTTP server with logging handler.
137-
if err := http.ListenAndServe(url, handlerWithLogging); err != nil {
137+
// Start the HTTP server.
138+
if err := http.ListenAndServe(url, handler); err != nil {
138139
log.Fatalf("Server failed: %v", err)
139140
}
140141
}

0 commit comments

Comments
 (0)