Documentation
¶
Overview ¶
Package logging provides logging integration between zap loggers and Model Context Protocol (MCP) clients.
This package enables applications to send logs both to traditional outputs (files, console) via zap and to MCP clients via ServerSession.
Basic Usage ¶
At application startup, create a base logger:
cfg := &logging.LoggingConfig{}
baseLogger, err := cfg.BuildBase()
if err != nil {
log.Fatal(err)
}
defer baseLogger.Sync()
Use the base logger for general application logging:
baseLogger.Info("Application starting", zap.String("version", "1.0"))
In request handlers where you have access to mcp.ServerSession, create a request-scoped logger that sends to both destinations:
func HandleRequest(ctx context.Context, ss *mcp.ServerSession) {
reqLogger, err := logging.NewRequestLogger(ctx, baseLogger, ss)
if err != nil {
// Handle error
return
}
// This log goes to both base logger output AND MCP client
reqLogger.Info("Processing request",
zap.String("method", "POST"),
zap.Duration("elapsed", time.Since(start)),
)
}
MCP Integration ¶
The package automatically converts zap log levels to MCP levels:
- zap.DebugLevel → "debug"
- zap.InfoLevel → "info"
- zap.WarnLevel → "warning"
- zap.ErrorLevel → "error"
- zap.DPanicLevel → "critical"
- zap.PanicLevel → "alert"
- zap.FatalLevel → "emergency"
All logs are sent to MCP clients regardless of level - the ServerSession determines whether to actually transmit them based on client preferences.
Index ¶
- Constants
- func BaseFromContext(ctx context.Context) *zap.Logger
- func FromContext(ctx context.Context) *zap.Logger
- func NewMcpCoreWithContext(ctx context.Context, ss *mcp.ServerSession) (zapcore.Core, error)
- func NewRequestLogger(ctx context.Context, baseLogger *zap.Logger, ss *mcp.ServerSession) (*zap.Logger, error)
- func WithBaseLogger(ctx context.Context, logger *zap.Logger) context.Context
- func WithLoggingMiddleware(base *zap.Logger) mcp.Middleware
- func WithRequestLogger(ctx context.Context, logger *zap.Logger) context.Context
- type LoggingConfig
Constants ¶
const ( LevelDebug = zapcore.DebugLevel LevelInfo = zapcore.InfoLevel LevelWarning = zapcore.WarnLevel LevelError = zapcore.ErrorLevel LevelCritical = zapcore.DPanicLevel LevelAlert = zapcore.PanicLevel LevelEmergency = zapcore.FatalLevel )
Variables ¶
This section is empty.
Functions ¶
func BaseFromContext ¶
BaseFromContext retrieves the base logger stored in the context by WithBaseLogger. This logger only sends logs to server-side outputs (files, console) and should be used for security events that should not be visible to MCP clients. If no logger is found or the stored value is not a *zap.Logger, it returns a no-op logger to ensure safe operation without panics.
func FromContext ¶
FromContext retrieves the request-scoped logger stored in the context by WithRequestLogger. This logger sends logs to both server-side and MCP client. If no logger is found or the stored value is not a *zap.Logger, it returns a no-op logger to ensure safe operation without panics.
func NewMcpCoreWithContext ¶
func NewRequestLogger ¶
func NewRequestLogger(ctx context.Context, baseLogger *zap.Logger, ss *mcp.ServerSession) (*zap.Logger, error)
NewRequestLogger creates a request-scoped logger that sends logs to both the base logger and the MCP client via ServerSession.
Performance: This function is designed to be called per-request. It reuses the pre-built baseLogger (created once at startup) and only creates the lightweight MCP core and tee wrapper.
Usage:
- Build baseLogger once at startup: baseLogger, _ := cfg.BuildBase()
- Call this function per-request: reqLogger, err := NewRequestLogger(ctx, baseLogger, session)
func WithBaseLogger ¶
WithBaseLogger stores the base logger in the given context, making it available for server-side security logging via BaseFromContext throughout the request lifecycle.
func WithLoggingMiddleware ¶
func WithLoggingMiddleware(base *zap.Logger) mcp.Middleware
WithLoggingMiddleware creates an MCP middleware that adds request-scoped logging. It extracts the ServerSession from incoming requests and creates a request-specific logger that can be retrieved using FromContext. It also stores the base logger for server-side security logging. If session extraction or logger creation fails, it logs a warning and continues the request chain without error.
Types ¶
type LoggingConfig ¶
type LoggingConfig struct {
// Level is the minimum enabled logging level (debug, info, warn, error, dpanic, panic, fatal)
Level string `json:"level,omitempty" jsonschema:"optional"`
// Development puts the logger in development mode
Development bool `json:"development,omitempty" jsonschema:"optional"`
// DisableCaller stops annotating logs with the calling function's file name and line number
DisableCaller bool `json:"disableCaller,omitempty" jsonschema:"optional"`
// DisableStacktrace completely disables automatic stacktrace capturing
DisableStacktrace bool `json:"disableStacktrace,omitempty" jsonschema:"optional"`
// Encoding sets the logger's encoding ("json" or "console")
Encoding string `json:"encoding,omitempty" jsonschema:"optional"`
// OutputPaths is a list of URLs or file paths to write logging output to
OutputPaths []string `json:"outputPaths,omitempty" jsonschema:"optional"`
// ErrorOutputPaths is a list of URLs to write internal logger errors to
ErrorOutputPaths []string `json:"errorOutputPaths,omitempty" jsonschema:"optional"`
// InitialFields is a collection of fields to add to the root logger
InitialFields map[string]interface{} `json:"initialFields,omitempty" jsonschema:"optional"`
// EnableMcpLogs controls whether logs are sent to MCP clients
EnableMcpLogs *bool `json:"enableMcpLogs,omitempty" jsonschema:"optional"`
}
LoggingConfig provides a JSON-schema friendly configuration for logging that can be converted to a zap.Config when needed.
func (*LoggingConfig) BuildBase ¶
func (lc *LoggingConfig) BuildBase() (*zap.Logger, error)
BuildBase creates a base logger from the configuration. This should be called once at application startup and the resulting logger should be reused throughout the application's lifetime.
For request-scoped logging that also sends to MCP clients, use NewRequestLogger with the base logger returned from this method.
func (*LoggingConfig) MCPLogsEnabled ¶
func (lc *LoggingConfig) MCPLogsEnabled() bool
MCPLogsEnabled returns whether the mcp logs are enabled, defaulting to true if unset