Skip to content

Commit c9dd4b8

Browse files
committed
add docs
1 parent 038ecf6 commit c9dd4b8

File tree

6 files changed

+235
-9
lines changed

6 files changed

+235
-9
lines changed

README.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# StreamNative MCP Server
2+
3+
A Model Context Protocol (MCP) server for integrating AI agents with StreamNative Cloud resources and Apache Pulsar/Kafka messaging systems.
4+
5+
## Overview
6+
7+
StreamNative MCP Server provides a standard interface for LLMs (Large Language Models) and AI agents to interact with StreamNative Cloud services, Apache Pulsar, and Apache Kafka. This implementation follows the [Model Context Protocol](https://modelcontextprotocol.io/introduction) specification, enabling AI applications to access messaging services through a standardized interface.
8+
9+
## Features
10+
11+
- **StreamNative Cloud Integration**:
12+
- Connect to StreamNative Cloud resources with authentication
13+
- Switch to clusters available in your organization
14+
- Describe the status of clusters resources
15+
- **Apache Pulsar Support**: Interact with Pulsar resources including:
16+
- Pulsar Admin operations (topics, namespaces, tenants, schemas, etc.)
17+
- Pulsar Client operations (producers, consumers)
18+
- Functions, Sources, and Sinks management
19+
- **Apache Kafka Support**: Interact with Kafka resources including:
20+
- Kafka Admin operations (topics, partitions, consumer groups)
21+
- Schema Registry operations
22+
- Kafka Connect operations
23+
- Kafka Client operations (producers, consumers)
24+
- **Multiple Connection Options**:
25+
- Connect to StreamNative Cloud with service account authentication
26+
- Connect directly to external Pulsar clusters
27+
- Connect directly to external Kafka clusters
28+
29+
## Installation
30+
31+
```bash
32+
# Clone the repository
33+
git clone https://github.com/streamnative/streamnative-mcp-server.git
34+
cd streamnative-mcp-server
35+
36+
go mod tidy
37+
go mod download
38+
39+
# Build the binary
40+
make
41+
```
42+
43+
## Usage
44+
45+
### Prerequisites
46+
47+
If you want to access to your StreamNative Cloud, you will need to have following resources ready:
48+
49+
1. Access to [StreamNative Cloud](https://console.streamnative.cloud/?defaultMethod=signup).
50+
2. StreamNative Cloud Organization
51+
3. StreamNative Cloud instance and cluster
52+
4. Service Account with admin role
53+
5. Download the Service Account Key file
54+
55+
### Start the MCP Server
56+
57+
```bash
58+
# Start MCP server with StreamNative Cloud authentication
59+
snmcp stdio --organization my-org --key-file /path/to/key-file.json
60+
61+
# Start MCP server with external Kafka
62+
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
63+
64+
# Start MCP server with external Pulsar
65+
snmcp stdio --use-external-pulsar --pulsar-web-service-url http://pulsar.example.com:8080
66+
bin/snmcp stdio --use-external-pulsar --pulsar-web-service-url http://pulsar.example.com:8080 --pulsar-token "xxx"
67+
```
68+
69+
### Command-line Options
70+
71+
```
72+
Usage:
73+
snmcp [command]
74+
75+
Available Commands:
76+
stdio Start stdio server
77+
help Help about any command
78+
79+
Flags:
80+
--audience string The audience identifier for the API server (default "https://api.streamnative.cloud")
81+
--client-id string The client ID to use for authorization grants (default "AJYEdHWi9EFekEaUXkPWA2MqQ3lq1NrI")
82+
--config-dir string If present, the config directory to use
83+
--enable-command-logging When enabled, the server will log all command requests and responses to the log file
84+
--features strings Features to enable, defaults to `all`
85+
-h, --help help for snmcp
86+
--issuer string The OAuth 2.0 issuer endpoint (default "https://auth.streamnative.cloud/")
87+
--kafka-auth-mechanism string The auth mechanism to use for Kafka
88+
--kafka-auth-pass string The auth password to use for Kafka
89+
--kafka-auth-type string The auth type to use for Kafka
90+
--kafka-auth-user string The auth user to use for Kafka
91+
--kafka-bootstrap-servers string The bootstrap servers to use for Kafka
92+
--kafka-ca-file string The CA file to use for Kafka
93+
--kafka-client-cert-file string The client certificate file to use for Kafka
94+
--kafka-client-key-file string The client key file to use for Kafka
95+
--kafka-schema-registry-auth-pass string The auth password to use for the schema registry
96+
--kafka-schema-registry-auth-user string The auth user to use for the schema registry
97+
--kafka-schema-registry-bearer-token string The bearer token to use for the schema registry
98+
--kafka-schema-registry-url string The schema registry URL to use for Kafka
99+
--key-file string The key file to use for authentication to StreamNative Cloud
100+
--log-file string Path to log file
101+
--organization string The organization to use for the API server
102+
--proxy-location string The proxy location to use for the API server (default "https://proxy.streamnative.cloud")
103+
--pulsar-auth-params string The auth params to use for Pulsar
104+
--pulsar-auth-plugin string The auth plugin to use for Pulsar
105+
--pulsar-token string The token to use for Pulsar
106+
--pulsar-cluster string The default cluster to use for the API server
107+
--pulsar-instance string The default instance to use for the API server
108+
--pulsar-tls-allow-insecure-connection The TLS allow insecure connection to use for Pulsar
109+
--pulsar-tls-cert-file string The TLS cert file to use for Pulsar
110+
--pulsar-tls-enable-hostname-verification The TLS enable hostname verification to use for Pulsar (default true)
111+
--pulsar-tls-key-file string The TLS key file to use for Pulsar
112+
--pulsar-tls-trust-certs-file-path string The TLS trust certs file path to use for Pulsar
113+
--pulsar-web-service-url string The web service URL to use for Pulsar
114+
-r, --read-only Read-only mode
115+
--server string The server to connect to (default "https://api.streamnative.cloud")
116+
--use-external-kafka Use external Kafka
117+
--use-external-pulsar Use external Pulsar
118+
-v, --version version for snmcp
119+
```
120+
121+
## Tool Configuration
122+
123+
The StreamNative MCP Server supports enabling or disabling specific groups of functionalities via the `--features` flag. This allows you to control which MCP tools are available to your AI tools. Enabling only the toolsets that you need can help the LLM with tool choice and reduce the context size.
124+
125+
### Available Features
126+
127+
The following sets of tools are available (all available by default on StreamNative Cloud)
128+
129+
| Features | Description |
130+
| ------|-------|
131+
| `all` | All tools, including StreamNative Cloud tools, Pulsar tools and Kafka tools |
132+
| `all-pulsar` | All Pulsar admin and Pulsar client tools |
133+
| `all-kafka` | All Kafka admin and Kafka client tools |
134+
| `pulsar-admin` | Pulsar administrative operations (including all `pulsar-admin-*`) |
135+
| `pulsar-client` | Pulsar client operations (produce and consume messages) |
136+
| `pulsar-admin-brokers` | Manage Pulsar brokers |
137+
| `pulsar-admin-broker-stats` | Access Pulsar broker statistics |
138+
| `pulsar-admin-clusters` | Manage Pulsar clusters |
139+
| `pulsar-admin-functions-worker` | Manage Pulsar Function workers |
140+
| `pulsar-admin-namespaces` | Manage Pulsar namespaces |
141+
| `pulsar-admin-namespace-policy` | Configure Pulsar namespace policies |
142+
| `pulsar-admin-isolation-policy` | Manage namespace isolation policies |
143+
| `pulsar-admin-packages` | Manage Pulsar packages |
144+
| `pulsar-admin-resource-quotas` | Configure resource quotas |
145+
| `pulsar-admin-schemas` | Manage Pulsar schemas |
146+
| `pulsar-admin-subscriptions` | Manage Pulsar subscriptions |
147+
| `pulsar-admin-tenants` | Manage Pulsar tenants |
148+
| `pulsar-admin-topics` | Manage Pulsar topics |
149+
| `pulsar-admin-sinks` | Manage Pulsar IO sinks |
150+
| `pulsar-admin-functions` | Manage Pulsar Functions |
151+
| `pulsar-admin-sources` | Manage Pulsar IO sources |
152+
| `pulsar-admin-topic-policy` | Configure Pulsar topic policies |
153+
| `kafka-admin` | Kafka administrative operations (including all `kafka-admin-*`) |
154+
| `kafka-client` | Kafka client operations (produce and consume messages) |
155+
| `kafka-admin-topics` | Manage Kafka partitions |
156+
| `kafka-admin-partitions` | Manage Kafka partitions |
157+
| `kafka-admin-groups` | Manage Kafka consumer groups |
158+
| `kafka-admin-schema-registry` | Interact with Kafka Schema Registry |
159+
| `kafka-admin-connect` | Manage Kafka Connect connectors |
160+
| `streamnative-cloud` | Manage the context of StreamNative Cloud |
161+
162+
### Usage Examples
163+
164+
To enable only specific feature sets:
165+
166+
```bash
167+
# Enable only Pulsar client features
168+
snmcp stdio --organization my-org --key-file /path/to/key-file.json --features pulsar-client
169+
```
170+
171+
## Integration with MCP Clients
172+
173+
This server can be used with any MCP-compatible client, such as:
174+
175+
- Claude Desktop
176+
- Other AI assistants supporting the MCP protocol
177+
- Custom applications built with MCP client libraries
178+
179+
### Usage with Claude Desktop
180+
181+
```json
182+
{
183+
"mcpServers": {
184+
"github": {
185+
"command": "snmcp",
186+
"args": [
187+
"stdio",
188+
"--organization",
189+
"my-org",
190+
"--key-file",
191+
"/path/to/key-file.json"
192+
],
193+
}
194+
}
195+
}
196+
```
197+
198+
## About Model Context Protocol (MCP)
199+
200+
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to LLMs. MCP helps build agents and complex workflows on top of LLMs by providing:
201+
202+
- A growing list of pre-built integrations that your LLM can directly plug into
203+
- The flexibility to switch between LLM providers and vendors
204+
- Best practices for securing your data within your infrastructure
205+
206+
For more information, visit [modelcontextprotocol.io](https://modelcontextprotocol.io/introduction).
207+
208+
## License
209+
210+
Copyright (c) 2025 StreamNative, Inc. All Rights Reserved.

pkg/cmd/mcp/mcp.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package mcp
44

55
import (
6+
"slices"
67
"time"
78

89
"github.com/pkg/errors"
@@ -67,14 +68,24 @@ func (o *ServerOptions) Complete() error {
6768
return errors.Wrap(err, "failed to set StreamNative Cloud context")
6869
}
6970
}
70-
}
7171

72-
// If the external Kafka is provided, enable kafka only mode
73-
if snConfig.ExternalKafka != nil {
72+
if len(o.Features) != 0 {
73+
requiredFeatures := []mcp.McpFeature{
74+
mcp.FeatureStreamNativeCloud,
75+
}
76+
for _, feature := range requiredFeatures {
77+
if !slices.Contains(o.Features, string(feature)) {
78+
o.Features = append(o.Features, string(feature))
79+
}
80+
}
81+
} else {
82+
o.Features = []string{string(mcp.FeatureAll)}
83+
}
84+
} else if snConfig.ExternalKafka != nil {
7485
if len(o.Features) != 0 {
7586
return errors.New("kafka-only mode does not support additional features")
7687
}
77-
o.Features = []string{"kafka-client", "kafka-admin", "kafka-admin-schema-registry"}
88+
o.Features = []string{string(mcp.FeatureKafkaClient), string(mcp.FeatureKafkaAdmin), string(mcp.FeatureKafkaAdminSchemaRegistry)}
7889
err := kafka.NewCurrentKafkaContext(kafka.KafkaContext{
7990
BootstrapServers: snConfig.ExternalKafka.BootstrapServers,
8091
AuthType: snConfig.ExternalKafka.AuthType,
@@ -97,11 +108,12 @@ func (o *ServerOptions) Complete() error {
97108
if len(o.Features) != 0 {
98109
return errors.New("pulsar-only mode does not support additional features")
99110
}
100-
o.Features = []string{"pulsar-admin", "pulsar-client"}
111+
o.Features = []string{string(mcp.FeatureAllPulsar)}
101112
err := pulsar.NewCurrentPulsarContext(pulsar.PulsarContext{
102113
WebServiceURL: snConfig.ExternalPulsar.WebServiceURL,
103114
AuthPlugin: snConfig.ExternalPulsar.AuthPlugin,
104115
AuthParams: snConfig.ExternalPulsar.AuthParams,
116+
Token: snConfig.ExternalPulsar.Token,
105117
TLSAllowInsecureConnection: snConfig.ExternalPulsar.TLSAllowInsecureConnection,
106118
TLSEnableHostnameVerification: snConfig.ExternalPulsar.TLSEnableHostnameVerification,
107119
TLSTrustCertsFilePath: snConfig.ExternalPulsar.TLSTrustCertsFilePath,

pkg/cmd/mcp/stdio.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ func newStdioServer(configOpts *ServerOptions, logrusLogger *logrus.Logger) *ser
125125
server.WithLogging())
126126

127127
mcp.RegisterPrompts(s)
128-
129128
mcp.RegisterContextTools(s, configOpts.Features)
130129
} else if snConfig.ExternalKafka != nil {
131130
s = server.NewMCPServer(

pkg/config/external_pulsar.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package config
22

33
type ExternalPulsar struct {
44
WebServiceURL string
5+
Token string
56
AuthPlugin string
67
AuthParams string
78
TLSAllowInsecureConnection bool

pkg/config/options.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ func (o *Options) AddFlags(cmd *cobra.Command) {
8989
"The auth user to use for Kafka")
9090
cmd.PersistentFlags().StringVar(&o.Kafka.AuthPass, "kafka-auth-pass", "",
9191
"The auth password to use for Kafka")
92+
cmd.PersistentFlags().BoolVar(&o.Kafka.UseTLS, "kafka-use-tls", false,
93+
"Use TLS for Kafka")
9294
cmd.PersistentFlags().StringVar(&o.Kafka.ClientKeyFile, "kafka-client-key-file", "",
9395
"The client key file to use for Kafka")
9496
cmd.PersistentFlags().StringVar(&o.Kafka.ClientCertFile, "kafka-client-cert-file", "",
@@ -117,9 +119,11 @@ func (o *Options) AddFlags(cmd *cobra.Command) {
117119
"The TLS cert file to use for Pulsar")
118120
cmd.PersistentFlags().StringVar(&o.Pulsar.TLSKeyFile, "pulsar-tls-key-file", "",
119121
"The TLS key file to use for Pulsar")
122+
cmd.PersistentFlags().StringVar(&o.Pulsar.Token, "pulsar-token", "",
123+
"The token to use for Pulsar")
120124

121125
cmd.MarkFlagsMutuallyExclusive("key-file", "use-external-kafka", "use-external-pulsar")
122-
cmd.MarkFlagsRequiredTogether("pulsar-cluster", "pulsar-instance", "key-file")
126+
cmd.MarkFlagsRequiredTogether("pulsar-cluster", "pulsar-instance")
123127
cmd.MarkFlagsRequiredTogether("use-external-kafka", "kafka-bootstrap-servers")
124128
cmd.MarkFlagsRequiredTogether("use-external-pulsar", "pulsar-web-service-url")
125129
o.AuthOptions.AddFlags(cmd)

pkg/pulsar/connection.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (pc *PulsarContext) SetPulsarContext() error {
6666

6767
authProvider, err := pulsar.NewAuthentication(pc.AuthPlugin, pc.AuthParams)
6868
if err != nil {
69-
return err
69+
return fmt.Errorf("failed to create authentication provider: %w", err)
7070
}
7171
CurrentPulsarClientOptions = pulsar.ClientOptions{
7272
URL: pc.WebServiceURL,
@@ -81,7 +81,7 @@ func (pc *PulsarContext) SetPulsarContext() error {
8181

8282
Client, err = pulsar.NewClient(CurrentPulsarClientOptions)
8383
if err != nil {
84-
return err
84+
return fmt.Errorf("failed to create pulsar client: %w", err)
8585
}
8686

8787
return nil

0 commit comments

Comments
 (0)