feat: deprecated logger in client & add Logger in ClientOption (#738)

Fix #708

1. deprecated logger in client
2. add Logger in ClientOption
3. add unit test for Logger
This commit is contained in:
FanOne 2026-01-05 23:41:31 +08:00 • committed by GitHub
commit 61be548803
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 10 deletions

View file

@ -18,6 +18,7 @@ import (
"time"
"github.com/google/jsonschema-go/jsonschema"
"github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2"
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
)
@ -25,8 +26,9 @@ import (
// A Client is an MCP client, which may be connected to an MCP server
// using the [Client.Connect] method.
type Client struct {
impl *Implementation
opts ClientOptions
impl *Implementation
opts ClientOptions
// Deprecated
logger *slog.Logger // TODO: file proposal to export this
mu sync.Mutex
roots *featureSet[*Root]
@ -42,25 +44,34 @@ type Client struct {
// The first argument must not be nil.
//
// If non-nil, the provided options configure the Client.
func NewClient(impl *Implementation, opts *ClientOptions) *Client {
func NewClient(impl *Implementation, options *ClientOptions) *Client {
if impl == nil {
panic("nil Implementation")
}
c := &Client{
var opts ClientOptions
if options != nil {
opts = *options
}
options = nil // prevent reuse
if opts.Logger == nil { // ensure we have a logger
opts.Logger = ensureLogger(nil)
}
return &Client{
impl: impl,
opts: opts,
logger: ensureLogger(nil), // ensure we have a logger
roots: newFeatureSet(func(r *Root) string { return r.URI }),
sendingMethodHandler_: defaultSendingMethodHandler,
receivingMethodHandler_: defaultReceivingMethodHandler[*ClientSession],
}
if opts != nil {
c.opts = *opts
}
return c
}
// ClientOptions configures the behavior of the client.
type ClientOptions struct {
// Logger may be set to a non-nil value to enable logging of client activity.
Logger *slog.Logger
// CreateMessageHandler handles incoming requests for sampling/createMessage.
//
// Setting CreateMessageHandler to a non-nil value automatically causes the
@ -407,7 +418,7 @@ func changeAndNotify[P Params](c *Client, notification string, params P, change
}
}
c.mu.Unlock()
notifySessions(sessions, notification, params, c.logger)
notifySessions(sessions, notification, params, c.opts.Logger)
}
// shouldSendListChangedNotification checks if the client's capabilities allow

View file

@ -7,6 +7,7 @@ package mcp
import (
"context"
"fmt"
"log/slog"
"testing"
"github.com/google/go-cmp/cmp"
@ -165,6 +166,23 @@ func TestClientPaginateBasic(t *testing.T) {
}
}
func TestClientLogger(t *testing.T) {
// Case 1: No logger provided
c1 := NewClient(&Implementation{Name: "test", Version: "1.0"}, nil)
if c1.opts.Logger == nil {
t.Error("expected default logger, got nil")
}
// Case 2: Logger provided
logger := slog.Default()
c2 := NewClient(&Implementation{Name: "test", Version: "1.0"}, &ClientOptions{
Logger: logger,
})
if c2.opts.Logger != logger {
t.Error("expected provided logger, got different one")
}
}
func TestClientPaginateVariousPageSizes(t *testing.T) {
ctx := context.Background()
for i := 1; i < len(allItems)+1; i++ {

View file

@ -58,7 +58,7 @@ type Server struct {
type ServerOptions struct {
// Optional instructions for connected clients.
Instructions string
// If non-nil, log server activity.
// Logger may be set to a non-nil value to enable logging of server activity.
Logger *slog.Logger
// If non-nil, called when "notifications/initialized" is received.
InitializedHandler func(context.Context, *InitializedRequest)