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:
parent
e66c23fae4
commit
61be548803
3 changed files with 39 additions and 10 deletions
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/jsonschema-go/jsonschema"
|
"github.com/google/jsonschema-go/jsonschema"
|
||||||
|
|
||||||
"github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2"
|
"github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2"
|
||||||
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
|
"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
|
// A Client is an MCP client, which may be connected to an MCP server
|
||||||
// using the [Client.Connect] method.
|
// using the [Client.Connect] method.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
impl *Implementation
|
impl *Implementation
|
||||||
opts ClientOptions
|
opts ClientOptions
|
||||||
|
// Deprecated
|
||||||
logger *slog.Logger // TODO: file proposal to export this
|
logger *slog.Logger // TODO: file proposal to export this
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
roots *featureSet[*Root]
|
roots *featureSet[*Root]
|
||||||
|
|
@ -42,25 +44,34 @@ type Client struct {
|
||||||
// The first argument must not be nil.
|
// The first argument must not be nil.
|
||||||
//
|
//
|
||||||
// If non-nil, the provided options configure the Client.
|
// 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 {
|
if impl == nil {
|
||||||
panic("nil Implementation")
|
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,
|
impl: impl,
|
||||||
|
opts: opts,
|
||||||
logger: ensureLogger(nil), // ensure we have a logger
|
logger: ensureLogger(nil), // ensure we have a logger
|
||||||
roots: newFeatureSet(func(r *Root) string { return r.URI }),
|
roots: newFeatureSet(func(r *Root) string { return r.URI }),
|
||||||
sendingMethodHandler_: defaultSendingMethodHandler,
|
sendingMethodHandler_: defaultSendingMethodHandler,
|
||||||
receivingMethodHandler_: defaultReceivingMethodHandler[*ClientSession],
|
receivingMethodHandler_: defaultReceivingMethodHandler[*ClientSession],
|
||||||
}
|
}
|
||||||
if opts != nil {
|
|
||||||
c.opts = *opts
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientOptions configures the behavior of the client.
|
// ClientOptions configures the behavior of the client.
|
||||||
type ClientOptions struct {
|
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.
|
// CreateMessageHandler handles incoming requests for sampling/createMessage.
|
||||||
//
|
//
|
||||||
// Setting CreateMessageHandler to a non-nil value automatically causes the
|
// 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()
|
c.mu.Unlock()
|
||||||
notifySessions(sessions, notification, params, c.logger)
|
notifySessions(sessions, notification, params, c.opts.Logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldSendListChangedNotification checks if the client's capabilities allow
|
// shouldSendListChangedNotification checks if the client's capabilities allow
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package mcp
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"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) {
|
func TestClientPaginateVariousPageSizes(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
for i := 1; i < len(allItems)+1; i++ {
|
for i := 1; i < len(allItems)+1; i++ {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ type Server struct {
|
||||||
type ServerOptions struct {
|
type ServerOptions struct {
|
||||||
// Optional instructions for connected clients.
|
// Optional instructions for connected clients.
|
||||||
Instructions string
|
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
|
Logger *slog.Logger
|
||||||
// If non-nil, called when "notifications/initialized" is received.
|
// If non-nil, called when "notifications/initialized" is received.
|
||||||
InitializedHandler func(context.Context, *InitializedRequest)
|
InitializedHandler func(context.Context, *InitializedRequest)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue