Skip to content

Commit c3063b8

Browse files
authored
Abstract session for SNCloud, Pulsar & Kafka Clients (#49)
1 parent 86e88ca commit c3063b8

File tree

96 files changed

+15168
-12613
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+15168
-12613
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ tmp/
99
# Go
1010
vendor
1111
.cursor/
12+
agents/

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ If you want to access to your StreamNative Cloud, you will need to have followin
8989
# Start MCP server with StreamNative Cloud authentication
9090
bin/snmcp stdio --organization my-org --key-file /path/to/key-file.json
9191

92+
# Start MCP server with StreamNative Cloud authentication and pre-configured context
93+
# When --pulsar-instance and --pulsar-cluster are provided, context management tools are disabled
94+
bin/snmcp stdio --organization my-org --key-file /path/to/key-file.json --pulsar-instance my-instance --pulsar-cluster my-cluster
95+
9296
# Start MCP server with external Kafka
9397
bin/snmcp stdio --use-external-kafka --kafka-bootstrap-servers localhost:9092 --kafka-auth-type SASL_SSL --kafka-auth-mechanism PLAIN --kafka-auth-user user --kafka-auth-pass pass --kafka-use-tls --kafka-schema-registry-url https://sr.local --kafka-schema-registry-auth-user user --kafka-schema-registry-auth-pass pass
9498

@@ -106,6 +110,10 @@ docker run -i --rm -e SNMCP_ORGANIZATION=my-org -e SNMCP_KEY_FILE=/key.json -v /
106110
# Start MCP server with SSE and StreamNative Cloud authentication
107111
snmcp sse --http-addr :9090 --http-path /mcp --organization my-org --key-file /path/to/key-file.json
108112

113+
# Start MCP server with SSE and pre-configured StreamNative Cloud context
114+
# When --pulsar-instance and --pulsar-cluster are provided, context management tools are disabled
115+
snmcp sse --http-addr :9090 --http-path /mcp --organization my-org --key-file /path/to/key-file.json --pulsar-instance my-instance --pulsar-cluster my-cluster
116+
109117
# Start MCP server with SSE and external Kafka
110118
snmcp sse --http-addr :9090 --http-path /mcp --use-external-kafka --kafka-bootstrap-servers localhost:9092
111119

@@ -235,6 +243,8 @@ The StreamNative MCP Server allows you to enable or disable specific groups of f
235243
| `streamnative-cloud`| Manage StreamNative Cloud context and check resource logs | [streamnative_cloud.md](docs/tools/streamnative_cloud.md) |
236244
| `functions-as-tools` | Dynamically exposes deployed Pulsar Functions as invokable MCP tools, with automatic input/output schema handling. | [functions_as_tools.md](docs/tools/functions_as_tools.md) |
237245

246+
> **Note:** When using `--pulsar-instance` and `--pulsar-cluster` flags together, context management tools (`sncloud_context_use_cluster`) are automatically disabled since the context is pre-configured.
247+
238248
You can combine these features as needed using the `--features` flag. For example, to enable only Pulsar client features:
239249
```bash
240250
# Enable only Pulsar client features

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
module github.com/streamnative/streamnative-mcp-server
22

3-
go 1.24.3
3+
go 1.24.4
44

55
require (
66
github.com/99designs/keyring v1.2.2
77
github.com/apache/pulsar-client-go v0.13.1
88
github.com/dgrijalva/jwt-go v3.2.0+incompatible
99
github.com/google/go-cmp v0.7.0
1010
github.com/hamba/avro/v2 v2.28.0
11-
github.com/mark3labs/mcp-go v0.31.0
11+
github.com/mark3labs/mcp-go v0.34.0
1212
github.com/mitchellh/go-homedir v1.1.0
1313
github.com/pkg/errors v0.9.1
1414
github.com/sirupsen/logrus v1.9.3
@@ -80,6 +80,7 @@ require (
8080
github.com/spf13/afero v1.12.0 // indirect
8181
github.com/spf13/cast v1.7.1 // indirect
8282
github.com/spf13/pflag v1.0.6 // indirect
83+
github.com/stretchr/objx v0.5.2 // indirect
8384
github.com/subosito/gotenv v1.6.0 // indirect
8485
github.com/twmb/franz-go/pkg/kmsg v1.9.0 // indirect
8586
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ
129129
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
130130
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
131131
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
132-
github.com/mark3labs/mcp-go v0.31.0 h1:4UxSV8aM770OPmTvaVe/b1rA2oZAjBMhGBfUgOGut+4=
133-
github.com/mark3labs/mcp-go v0.31.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
132+
github.com/mark3labs/mcp-go v0.34.0 h1:eWy7WBGvhk6EyAAyVzivTCprE52iXJwNtvHV6Cv3bR0=
133+
github.com/mark3labs/mcp-go v0.34.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
134134
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
135135
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
136136
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=

go.work

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
go 1.24.3
1+
go 1.24.4
22

33
use .
44

go.work.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
138138
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
139139
github.com/mark3labs/mcp-go v0.23.1 h1:RzTzZ5kJ+HxwnutKA4rll8N/pKV6Wh5dhCmiJUu5S9I=
140140
github.com/mark3labs/mcp-go v0.23.1/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
141-
github.com/mark3labs/mcp-go v0.31.0 h1:4UxSV8aM770OPmTvaVe/b1rA2oZAjBMhGBfUgOGut+4=
142-
github.com/mark3labs/mcp-go v0.31.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
141+
github.com/mark3labs/mcp-go v0.34.0 h1:eWy7WBGvhk6EyAAyVzivTCprE52iXJwNtvHV6Cv3bR0=
142+
github.com/mark3labs/mcp-go v0.34.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
143143
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
144144
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
145145
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=

pkg/cmd/mcp/mcp.go

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,12 @@ package mcp
1919

2020
import (
2121
"slices"
22-
"time"
2322

2423
"github.com/pkg/errors"
2524
"github.com/spf13/cobra"
2625
"github.com/streamnative/streamnative-mcp-server/pkg/auth"
2726
"github.com/streamnative/streamnative-mcp-server/pkg/config"
28-
"github.com/streamnative/streamnative-mcp-server/pkg/kafka"
2927
"github.com/streamnative/streamnative-mcp-server/pkg/mcp"
30-
"github.com/streamnative/streamnative-mcp-server/pkg/pulsar"
3128
)
3229

3330
// ServerOptions is the options for the MCP server commands
@@ -75,20 +72,6 @@ func (o *ServerOptions) Complete() error {
7572
return errors.Wrap(err, "Unable to store the authorization data")
7673
}
7774

78-
err = config.InitSNCloudClient(
79-
issuer.IssuerEndpoint, issuer.Audience, o.KeyFile, o.Options.Server, 30*time.Second, o.Options.Store)
80-
if err != nil {
81-
return errors.Wrap(err, "failed to initialize StreamNative Cloud client")
82-
}
83-
84-
if o.Options.PulsarInstance != "" && o.Options.PulsarCluster != "" {
85-
err = mcp.SetContext(o.Options, o.Options.PulsarInstance, o.Options.PulsarCluster)
86-
if err != nil {
87-
mcp.ResetMcpContext()
88-
return errors.Wrap(err, "failed to set StreamNative Cloud context")
89-
}
90-
}
91-
9275
if len(o.Features) != 0 {
9376
requiredFeatures := []mcp.Feature{
9477
mcp.FeatureStreamNativeCloud,
@@ -108,46 +91,13 @@ func (o *ServerOptions) Complete() error {
10891
return errors.New("kafka-only mode does not support additional features")
10992
}
11093
o.Features = []string{string(mcp.FeatureKafkaClient), string(mcp.FeatureKafkaAdmin), string(mcp.FeatureKafkaAdminSchemaRegistry)}
111-
err := kafka.NewCurrentKafkaContext(kafka.KafkaContext{
112-
BootstrapServers: snConfig.ExternalKafka.BootstrapServers,
113-
AuthType: snConfig.ExternalKafka.AuthType,
114-
AuthMechanism: snConfig.ExternalKafka.AuthMechanism,
115-
AuthUser: snConfig.ExternalKafka.AuthUser,
116-
AuthPass: snConfig.ExternalKafka.AuthPass,
117-
UseTLS: snConfig.ExternalKafka.UseTLS,
118-
ClientKeyFile: snConfig.ExternalKafka.ClientKeyFile,
119-
ClientCertFile: snConfig.ExternalKafka.ClientCertFile,
120-
CaFile: snConfig.ExternalKafka.CaFile,
121-
SchemaRegistryURL: snConfig.ExternalKafka.SchemaRegistryURL,
122-
SchemaRegistryAuthUser: snConfig.ExternalKafka.SchemaRegistryAuthUser,
123-
SchemaRegistryAuthPass: snConfig.ExternalKafka.SchemaRegistryAuthPass,
124-
SchemaRegistryBearerToken: snConfig.ExternalKafka.SchemaRegistryBearerToken,
125-
})
126-
if err != nil {
127-
return errors.Wrap(err, "failed to set external Kafka context")
128-
}
12994
}
13095
case snConfig.ExternalPulsar != nil:
13196
{
13297
if len(o.Features) != 0 {
13398
return errors.New("pulsar-only mode does not support additional features")
13499
}
135100
o.Features = []string{string(mcp.FeatureAllPulsar)}
136-
err := pulsar.NewCurrentPulsarContext(pulsar.PulsarContext{
137-
ServiceURL: snConfig.ExternalPulsar.ServiceURL,
138-
WebServiceURL: snConfig.ExternalPulsar.WebServiceURL,
139-
AuthPlugin: snConfig.ExternalPulsar.AuthPlugin,
140-
AuthParams: snConfig.ExternalPulsar.AuthParams,
141-
Token: snConfig.ExternalPulsar.Token,
142-
TLSAllowInsecureConnection: snConfig.ExternalPulsar.TLSAllowInsecureConnection,
143-
TLSEnableHostnameVerification: snConfig.ExternalPulsar.TLSEnableHostnameVerification,
144-
TLSTrustCertsFilePath: snConfig.ExternalPulsar.TLSTrustCertsFilePath,
145-
TLSCertFile: snConfig.ExternalPulsar.TLSCertFile,
146-
TLSKeyFile: snConfig.ExternalPulsar.TLSKeyFile,
147-
}, nil, nil)
148-
if err != nil {
149-
return errors.Wrap(err, "failed to set external Pulsar context")
150-
}
151101
}
152102
default:
153103
{

pkg/cmd/mcp/server.go

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,23 @@
1818
package mcp
1919

2020
import (
21+
"context"
2122
stdlog "log"
2223
"os"
2324

2425
"github.com/mark3labs/mcp-go/server"
26+
"github.com/pkg/errors"
2527
"github.com/sirupsen/logrus"
28+
"github.com/streamnative/streamnative-mcp-server/pkg/config"
29+
"github.com/streamnative/streamnative-mcp-server/pkg/kafka"
2630
"github.com/streamnative/streamnative-mcp-server/pkg/mcp"
31+
"github.com/streamnative/streamnative-mcp-server/pkg/pulsar"
2732
)
2833

29-
func newMcpServer(configOpts *ServerOptions, logrusLogger *logrus.Logger) *server.MCPServer {
34+
func newMcpServer(_ context.Context, configOpts *ServerOptions, logrusLogger *logrus.Logger) (*mcp.Server, error) {
3035
snConfig := configOpts.Options.LoadConfigOrDie()
3136
var s *server.MCPServer
37+
var mcpServer *mcp.Server
3238
switch {
3339
case snConfig.KeyFile != "":
3440
{
@@ -38,36 +44,66 @@ func newMcpServer(configOpts *ServerOptions, logrusLogger *logrus.Logger) *serve
3844
stdlog.Fatalf("failed to get user name: %v", err)
3945
os.Exit(1)
4046
}
41-
// Create a new MCP server
42-
s = server.NewMCPServer(
43-
"streamnative-mcp-server",
44-
"0.0.1",
45-
server.WithResourceCapabilities(true, true),
46-
server.WithInstructions(mcp.GetStreamNativeCloudServerInstructions(userName, snConfig)),
47-
server.WithLogging())
47+
// Create StreamNative Cloud session and set as default
48+
session, err := config.NewSNCloudSessionFromOptions(configOpts.Options)
49+
if err != nil {
50+
return nil, errors.Wrap(err, "failed to create StreamNative Cloud session")
51+
}
52+
mcpServer = mcp.NewServer("streamnative-mcp-server", "0.0.1", logrusLogger, server.WithInstructions(mcp.GetStreamNativeCloudServerInstructions(userName, snConfig)))
53+
mcpServer.SNCloudSession = session
4854

55+
s = mcpServer.MCPServer
4956
mcp.RegisterPrompts(s)
50-
mcp.RegisterContextTools(s, configOpts.Features)
57+
// Skip context tools if pulsar instance and cluster are provided via CLI
58+
skipContextTools := snConfig.Context.PulsarInstance != "" && snConfig.Context.PulsarCluster != ""
59+
mcp.RegisterContextTools(s, configOpts.Features, skipContextTools)
5160
mcp.StreamNativeAddLogTools(s, configOpts.ReadOnly, configOpts.Features)
5261
mcp.StreamNativeAddResourceTools(s, configOpts.ReadOnly, configOpts.Features)
5362
}
5463
case snConfig.ExternalKafka != nil:
5564
{
56-
s = server.NewMCPServer(
57-
"streamnative-mcp-server/kafka",
58-
"0.0.1",
59-
server.WithResourceCapabilities(true, true),
60-
server.WithInstructions(mcp.GetExternalKafkaServerInstructions(snConfig.ExternalKafka.BootstrapServers)),
61-
server.WithLogging())
65+
ksession, err := kafka.NewSession(kafka.KafkaContext{
66+
BootstrapServers: snConfig.ExternalKafka.BootstrapServers,
67+
AuthType: snConfig.ExternalKafka.AuthType,
68+
AuthMechanism: snConfig.ExternalKafka.AuthMechanism,
69+
AuthUser: snConfig.ExternalKafka.AuthUser,
70+
AuthPass: snConfig.ExternalKafka.AuthPass,
71+
UseTLS: snConfig.ExternalKafka.UseTLS,
72+
ClientKeyFile: snConfig.ExternalKafka.ClientKeyFile,
73+
ClientCertFile: snConfig.ExternalKafka.ClientCertFile,
74+
CaFile: snConfig.ExternalKafka.CaFile,
75+
SchemaRegistryURL: snConfig.ExternalKafka.SchemaRegistryURL,
76+
SchemaRegistryAuthUser: snConfig.ExternalKafka.SchemaRegistryAuthUser,
77+
SchemaRegistryAuthPass: snConfig.ExternalKafka.SchemaRegistryAuthPass,
78+
SchemaRegistryBearerToken: snConfig.ExternalKafka.SchemaRegistryBearerToken,
79+
})
80+
if err != nil {
81+
return nil, errors.Wrap(err, "failed to set external Kafka context")
82+
}
83+
mcpServer = mcp.NewServer("streamnative-mcp-server", "0.0.1", logrusLogger, server.WithInstructions(mcp.GetExternalKafkaServerInstructions(snConfig.ExternalKafka.BootstrapServers)))
84+
mcpServer.KafkaSession = ksession
85+
s = mcpServer.MCPServer
6286
}
6387
case snConfig.ExternalPulsar != nil:
6488
{
65-
s = server.NewMCPServer(
66-
"streamnative-mcp-server/pulsar",
67-
"0.0.1",
68-
server.WithResourceCapabilities(true, true),
69-
server.WithInstructions(mcp.GetExternalPulsarServerInstructions(snConfig.ExternalPulsar.WebServiceURL)),
70-
server.WithLogging())
89+
psession, err := pulsar.NewSession(pulsar.PulsarContext{
90+
ServiceURL: snConfig.ExternalPulsar.ServiceURL,
91+
WebServiceURL: snConfig.ExternalPulsar.WebServiceURL,
92+
AuthPlugin: snConfig.ExternalPulsar.AuthPlugin,
93+
AuthParams: snConfig.ExternalPulsar.AuthParams,
94+
Token: snConfig.ExternalPulsar.Token,
95+
TLSAllowInsecureConnection: snConfig.ExternalPulsar.TLSAllowInsecureConnection,
96+
TLSEnableHostnameVerification: snConfig.ExternalPulsar.TLSEnableHostnameVerification,
97+
TLSTrustCertsFilePath: snConfig.ExternalPulsar.TLSTrustCertsFilePath,
98+
TLSCertFile: snConfig.ExternalPulsar.TLSCertFile,
99+
TLSKeyFile: snConfig.ExternalPulsar.TLSKeyFile,
100+
})
101+
if err != nil {
102+
return nil, errors.Wrap(err, "failed to set external Pulsar context")
103+
}
104+
mcpServer = mcp.NewServer("streamnative-mcp-server", "0.0.1", logrusLogger, server.WithInstructions(mcp.GetExternalPulsarServerInstructions(snConfig.ExternalPulsar.WebServiceURL)))
105+
mcpServer.PulsarSession = psession
106+
s = mcpServer.MCPServer
71107
}
72108
default:
73109
{
@@ -103,5 +139,5 @@ func newMcpServer(configOpts *ServerOptions, logrusLogger *logrus.Logger) *serve
103139
mcp.KafkaAdminAddKafkaConnectTools(s, configOpts.ReadOnly, configOpts.Features)
104140
mcp.KafkaClientAddConsumeTools(s, configOpts.ReadOnly, logrusLogger, configOpts.Features)
105141
mcp.KafkaClientAddProduceTools(s, configOpts.ReadOnly, configOpts.Features)
106-
return s
142+
return mcpServer, nil
107143
}

pkg/cmd/mcp/sse.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/spf13/cobra"
3434
"github.com/streamnative/streamnative-mcp-server/pkg/common"
3535
"github.com/streamnative/streamnative-mcp-server/pkg/mcp"
36+
context2 "github.com/streamnative/streamnative-mcp-server/pkg/mcp"
3637
)
3738

3839
func NewCmdMcpSseServer(configOpts *ServerOptions) *cobra.Command {
@@ -70,16 +71,37 @@ func runSseServer(configOpts *ServerOptions) error {
7071

7172
// 3. Create a new MCP server
7273
ctx = context.WithValue(ctx, common.OptionsKey, configOpts.Options)
73-
mcpServer := newMcpServer(configOpts, logger)
74+
mcpServer, err := newMcpServer(ctx, configOpts, logger)
75+
if err != nil {
76+
return fmt.Errorf("failed to create MCP server: %w", err)
77+
}
78+
79+
// 4. Set the context
80+
ctx = context2.WithSNCloudSession(ctx, mcpServer.SNCloudSession)
81+
ctx = context2.WithPulsarSession(ctx, mcpServer.PulsarSession)
82+
ctx = context2.WithKafkaSession(ctx, mcpServer.KafkaSession)
83+
if configOpts.Options.KeyFile != "" {
84+
if configOpts.Options.PulsarInstance != "" && configOpts.Options.PulsarCluster != "" {
85+
err = mcp.SetContext(ctx, configOpts.Options, configOpts.Options.PulsarInstance, configOpts.Options.PulsarCluster)
86+
if err != nil {
87+
return errors.Wrap(err, "failed to set StreamNative Cloud context")
88+
}
89+
}
90+
}
7491

7592
// add Pulsar Functions as MCP tools
76-
mcp.PulsarFunctionManagedMcpTools(mcpServer, false, configOpts.Features)
93+
// SSE is not support session-based tools, so we pass an fixed sessionId
94+
mcpServer.PulsarFunctionManagedMcpTools(configOpts.ReadOnly, configOpts.Features, "FIXED_SESSION_ID")
7795

7896
sseServer := server.NewSSEServer(
79-
mcpServer,
97+
mcpServer.MCPServer,
8098
server.WithStaticBasePath(configOpts.HTTPPath),
8199
server.WithSSEContextFunc(func(ctx context.Context, _ *http.Request) context.Context {
82-
return context.WithValue(ctx, common.OptionsKey, configOpts.Options)
100+
c := context.WithValue(ctx, common.OptionsKey, configOpts.Options)
101+
c = context2.WithKafkaSession(c, mcpServer.KafkaSession)
102+
c = context2.WithPulsarSession(c, mcpServer.PulsarSession)
103+
c = context2.WithSNCloudSession(c, mcpServer.SNCloudSession)
104+
return c
83105
}),
84106
)
85107

pkg/cmd/mcp/stdio.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,12 @@ func runStdioServer(configOpts *ServerOptions) error {
6565
// Create a new MCP server
6666
ctx = context.WithValue(ctx, common.OptionsKey, configOpts.Options)
6767
stdLogger := stdlog.New(logger.Writer(), "snmcp-server", 0)
68-
stdioServer := server.NewStdioServer(newMcpServer(configOpts, logger))
68+
mcpServer, err := newMcpServer(ctx, configOpts, logger)
69+
if err != nil {
70+
return fmt.Errorf("failed to create MCP server: %w", err)
71+
}
6972

73+
stdioServer := server.NewStdioServer(mcpServer.MCPServer)
7074
stdioServer.SetErrorLogger(stdLogger)
7175

7276
// Start listening for messages

0 commit comments

Comments
 (0)