Skip to content

Commit 6c6243c

Browse files
authored
mcp: NewClient and NewServer take Implementation (#113)
Change the name and version arguments to NewClient and NewServer to a `*Implementation`, to future-proof against the spec. Fixes #109.
1 parent b4febf1 commit 6c6243c

File tree

19 files changed

+76
-69
lines changed

19 files changed

+76
-69
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func main() {
7272
ctx := context.Background()
7373

7474
// Create a new client, with no features.
75-
client := mcp.NewClient("mcp-client", "v1.0.0", nil)
75+
client := mcp.NewClient(&mcp.Implementation{Name: "mcp-client", Version: "v1.0.0"}, nil)
7676

7777
// Connect to a server over stdin/stdout
7878
transport := mcp.NewCommandTransport(exec.Command("myserver"))
@@ -125,7 +125,7 @@ func SayHi(ctx context.Context, cc *mcp.ServerSession, params *mcp.CallToolParam
125125

126126
func main() {
127127
// Create a server with a single tool.
128-
server := mcp.NewServer("greeter", "v1.0.0", nil)
128+
server := mcp.NewServer(&mcp.Implementation{Name: "greeter", Version: "v1.0.0"}, nil)
129129

130130
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
131131
// Run the server over stdin/stdout, until the client disconnects

design/design.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ Sessions are created from either `Client` or `Server` using the `Connect` method
323323
324324
```go
325325
type Client struct { /* ... */ }
326-
func NewClient(name, version string, opts *ClientOptions) *Client
326+
func NewClient(impl *Implementation, opts *ClientOptions) *Client
327327
func (*Client) Connect(context.Context, Transport) (*ClientSession, error)
328328
func (*Client) Sessions() iter.Seq[*ClientSession]
329329
// Methods for adding/removing client features are described below.
@@ -338,7 +338,7 @@ func (*ClientSession) Wait() error
338338
// For example: ClientSession.ListTools.
339339

340340
type Server struct { /* ... */ }
341-
func NewServer(name, version string, opts *ServerOptions) *Server
341+
func NewServer(impl *Implementation, opts *ServerOptions) *Server
342342
func (*Server) Connect(context.Context, Transport) (*ServerSession, error)
343343
func (*Server) Sessions() iter.Seq[*ServerSession]
344344
// Methods for adding/removing server features are described below.
@@ -356,7 +356,7 @@ func (*ServerSession) Wait() error
356356
Here's an example of these APIs from the client side:
357357
358358
```go
359-
client := mcp.NewClient("mcp-client", "v1.0.0", nil)
359+
client := mcp.NewClient(&mcp.Implementation{Name:"mcp-client", Version:"v1.0.0"}, nil)
360360
// Connect to a server over stdin/stdout
361361
transport := mcp.NewCommandTransport(exec.Command("myserver"))
362362
session, err := client.Connect(ctx, transport)
@@ -371,7 +371,7 @@ A server that can handle that client call would look like this:
371371
372372
```go
373373
// Create a server with a single tool.
374-
server := mcp.NewServer("greeter", "v1.0.0", nil)
374+
server := mcp.NewServer(&mcp.Implementation{Name:"greeter", Version:"v1.0.0"}, nil)
375375
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
376376
// Run the server over stdin/stdout, until the client disconnects.
377377
if err := server.Run(context.Background(), mcp.NewStdioTransport()); err != nil {

examples/completion/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func main() {
4040

4141
// Create the MCP Server instance and assign the handler.
4242
// No server running, just showing the configuration.
43-
_ = mcp.NewServer("myServer", "v1.0.0", &mcp.ServerOptions{
43+
_ = mcp.NewServer(&mcp.Implementation{Name: "server"}, &mcp.ServerOptions{
4444
CompletionHandler: myCompletionHandler,
4545
})
4646

examples/hello/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func PromptHi(ctx context.Context, ss *mcp.ServerSession, params *mcp.GetPromptP
4242
func main() {
4343
flag.Parse()
4444

45-
server := mcp.NewServer("greeter", "v0.0.1", nil)
45+
server := mcp.NewServer(&mcp.Implementation{Name: "greeter"}, nil)
4646
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
4747
server.AddPrompt(&mcp.Prompt{Name: "greet"}, PromptHi)
4848
server.AddResource(&mcp.Resource{

examples/memory/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func main() {
9191
kb := knowledgeBase{s: kbStore}
9292

9393
// Setup MCP server with knowledge base tools
94-
server := mcp.NewServer("memory", "v0.0.1", nil)
94+
server := mcp.NewServer(&mcp.Implementation{Name: "memory"}, nil)
9595
mcp.AddTool(server, &mcp.Tool{
9696
Name: "create_entities",
9797
Description: "Create multiple new entities in the knowledge graph",

examples/sse/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ func main() {
3434
log.Fatal("http address not set")
3535
}
3636

37-
server1 := mcp.NewServer("greeter1", "v0.0.1", nil)
37+
server1 := mcp.NewServer(&mcp.Implementation{Name: "greeter1"}, nil)
3838
mcp.AddTool(server1, &mcp.Tool{Name: "greet1", Description: "say hi"}, SayHi)
3939

40-
server2 := mcp.NewServer("greeter2", "v0.0.1", nil)
40+
server2 := mcp.NewServer(&mcp.Implementation{Name: "greeter2"}, nil)
4141
mcp.AddTool(server2, &mcp.Tool{Name: "greet2", Description: "say hello"}, SayHi)
4242

4343
log.Printf("MCP servers serving at %s", *httpAddr)

internal/readme/client/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func main() {
1717
ctx := context.Background()
1818

1919
// Create a new client, with no features.
20-
client := mcp.NewClient("mcp-client", "v1.0.0", nil)
20+
client := mcp.NewClient(&mcp.Implementation{Name: "mcp-client", Version: "v1.0.0"}, nil)
2121

2222
// Connect to a server over stdin/stdout
2323
transport := mcp.NewCommandTransport(exec.Command("myserver"))

internal/readme/server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func SayHi(ctx context.Context, cc *mcp.ServerSession, params *mcp.CallToolParam
2424

2525
func main() {
2626
// Create a server with a single tool.
27-
server := mcp.NewServer("greeter", "v1.0.0", nil)
27+
server := mcp.NewServer(&mcp.Implementation{Name: "greeter", Version: "v1.0.0"}, nil)
2828

2929
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
3030
// Run the server over stdin/stdout, until the client disconnects

mcp/client.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ import (
1919
// A Client is an MCP client, which may be connected to an MCP server
2020
// using the [Client.Connect] method.
2121
type Client struct {
22-
name string
23-
version string
22+
impl *Implementation
2423
opts ClientOptions
2524
mu sync.Mutex
2625
roots *featureSet[*Root]
@@ -29,15 +28,19 @@ type Client struct {
2928
receivingMethodHandler_ MethodHandler[*ClientSession]
3029
}
3130

32-
// NewClient creates a new Client.
31+
// NewClient creates a new [Client].
3332
//
3433
// Use [Client.Connect] to connect it to an MCP server.
3534
//
35+
// The first argument must not be nil.
36+
//
3637
// If non-nil, the provided options configure the Client.
37-
func NewClient(name, version string, opts *ClientOptions) *Client {
38+
func NewClient(impl *Implementation, opts *ClientOptions) *Client {
39+
if impl == nil {
40+
panic("nil Implementation")
41+
}
3842
c := &Client{
39-
name: name,
40-
version: version,
43+
impl: impl,
4144
roots: newFeatureSet(func(r *Root) string { return r.URI }),
4245
sendingMethodHandler_: defaultSendingMethodHandler[*ClientSession],
4346
receivingMethodHandler_: defaultReceivingMethodHandler[*ClientSession],
@@ -118,7 +121,7 @@ func (c *Client) Connect(ctx context.Context, t Transport) (cs *ClientSession, e
118121

119122
params := &InitializeParams{
120123
ProtocolVersion: latestProtocolVersion,
121-
ClientInfo: &implementation{Name: c.name, Version: c.version},
124+
ClientInfo: c.impl,
122125
Capabilities: caps,
123126
}
124127
res, err := handleSend[*InitializeResult](ctx, cs, methodInitialize, params)

mcp/cmd_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ func TestMain(m *testing.M) {
3232
func runServer() {
3333
ctx := context.Background()
3434

35-
server := mcp.NewServer("greeter", "v0.0.1", nil)
35+
server := mcp.NewServer(testImpl, nil)
3636
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
3737
if err := server.Run(ctx, mcp.NewStdioTransport()); err != nil {
3838
log.Fatal(err)
3939
}
4040
}
4141

4242
func TestServerRunContextCancel(t *testing.T) {
43-
server := mcp.NewServer("greeter", "v0.0.1", nil)
43+
server := mcp.NewServer(&mcp.Implementation{Name: "greeter", Version: "v0.0.1"}, nil)
4444
mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
4545

4646
ctx, cancel := context.WithCancel(context.Background())
@@ -55,7 +55,7 @@ func TestServerRunContextCancel(t *testing.T) {
5555
}()
5656

5757
// send a ping to the server to ensure it's running
58-
client := mcp.NewClient("client", "v0.0.1", nil)
58+
client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil)
5959
session, err := client.Connect(ctx, clientTransport)
6060
if err != nil {
6161
t.Fatal(err)
@@ -87,7 +87,7 @@ func TestServerInterrupt(t *testing.T) {
8787

8888
cmd := createServerCommand(t)
8989

90-
client := mcp.NewClient("client", "v0.0.1", nil)
90+
client := mcp.NewClient(testImpl, nil)
9191
session, err := client.Connect(ctx, mcp.NewCommandTransport(cmd))
9292
if err != nil {
9393
t.Fatal(err)
@@ -125,7 +125,7 @@ func TestCmdTransport(t *testing.T) {
125125

126126
cmd := createServerCommand(t)
127127

128-
client := mcp.NewClient("client", "v0.0.1", nil)
128+
client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil)
129129
session, err := client.Connect(ctx, mcp.NewCommandTransport(cmd))
130130
if err != nil {
131131
t.Fatal(err)
@@ -174,3 +174,5 @@ func requireExec(t *testing.T) {
174174
t.Skip("unsupported OS")
175175
}
176176
}
177+
178+
var testImpl = &mcp.Implementation{Name: "test", Version: "v1.0.0"}

0 commit comments

Comments
 (0)