Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions mcp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ import (
"time"

"github.com/google/jsonschema-go/jsonschema"

"github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2"
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
)

// 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]
Expand All @@ -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 {
// If non-nil, log client activity.
Logger *slog.Logger
// CreateMessageHandler handles incoming requests for sampling/createMessage.
//
// Setting CreateMessageHandler to a non-nil value automatically causes the
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions mcp/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package mcp
import (
"context"
"fmt"
"log/slog"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -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++ {
Expand Down