This example demonstrates server side logging using the mcp.Middleware system.
()
| 17 | |
| 18 | // This example demonstrates server side logging using the mcp.Middleware system. |
| 19 | func main() { |
| 20 | // Create a logger for demonstration purposes. |
| 21 | logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ |
| 22 | Level: slog.LevelInfo, |
| 23 | ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr { |
| 24 | // Simplify timestamp format for consistent output. |
| 25 | if a.Key == slog.TimeKey { |
| 26 | return slog.String("time", "2025-01-01T00:00:00Z") |
| 27 | } |
| 28 | return a |
| 29 | }, |
| 30 | })) |
| 31 | |
| 32 | loggingMiddleware := func(next mcp.MethodHandler) mcp.MethodHandler { |
| 33 | return func( |
| 34 | ctx context.Context, |
| 35 | method string, |
| 36 | req mcp.Request, |
| 37 | ) (mcp.Result, error) { |
| 38 | logger.Info("MCP method started", |
| 39 | "method", method, |
| 40 | "session_id", req.GetSession().ID(), |
| 41 | "has_params", req.GetParams() != nil, |
| 42 | ) |
| 43 | // Log more for tool calls. |
| 44 | if ctr, ok := req.(*mcp.CallToolRequest); ok { |
| 45 | logger.Info("Calling tool", |
| 46 | "name", ctr.Params.Name, |
| 47 | "args", ctr.Params.Arguments) |
| 48 | } |
| 49 | |
| 50 | start := time.Now() |
| 51 | result, err := next(ctx, method, req) |
| 52 | duration := time.Since(start) |
| 53 | if err != nil { |
| 54 | logger.Error("MCP method failed", |
| 55 | "method", method, |
| 56 | "session_id", req.GetSession().ID(), |
| 57 | "duration_ms", duration.Milliseconds(), |
| 58 | "err", err, |
| 59 | ) |
| 60 | } else { |
| 61 | logger.Info("MCP method completed", |
| 62 | "method", method, |
| 63 | "session_id", req.GetSession().ID(), |
| 64 | "duration_ms", duration.Milliseconds(), |
| 65 | "has_result", result != nil, |
| 66 | ) |
| 67 | // Log more for tool results. |
| 68 | if ctr, ok := result.(*mcp.CallToolResult); ok { |
| 69 | logger.Info("tool result", |
| 70 | "isError", ctr.IsError, |
| 71 | "structuredContent", ctr.StructuredContent) |
| 72 | } |
| 73 | } |
| 74 | return result, err |
| 75 | } |
| 76 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…