This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch fix/session-stdio-only
in repository https://gitbox.apache.org/repos/asf/skywalking-mcp.git

commit 9a041a4d672f4541d8befbd76cfa12a86a939481
Author: Wu Sheng <[email protected]>
AuthorDate: Fri Mar 13 20:36:42 2026 +0800

    fix: restrict set_skywalking_url tool to stdio transport only
    
    Reverts the session-in-all-transports behavior from PR #29. The
    set_skywalking_url tool is now only registered for stdio mode, where
    single-client session semantics are well-defined. SSE and HTTP
    transports rely on per-request SW-URL headers and CLI flags instead,
    avoiding the shared-session issue where one client could override
    another's credentials.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 CLAUDE.md                    |  5 ++++-
 README.md                    |  2 +-
 internal/swmcp/server.go     | 18 ++++++++----------
 internal/swmcp/session.go    |  2 ++
 internal/swmcp/sse.go        |  2 +-
 internal/swmcp/stdio.go      |  2 +-
 internal/swmcp/streamable.go |  2 +-
 7 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 483758e..5de6db1 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -41,7 +41,10 @@ No unit tests exist yet. CI runs license checks, lint, and 
docker build.
 Three MCP transport modes as cobra subcommands: `stdio`, `sse`, `streamable`.
 
 The SkyWalking OAP URL is resolved in priority order:
-`set_skywalking_url` session tool > `--sw-url` flag > `SW-URL` HTTP header > 
`http://localhost:12800/graphql`
+- **stdio**: `set_skywalking_url` session tool > `--sw-url` flag > 
`http://localhost:12800/graphql`
+- **SSE/HTTP**: `SW-URL` HTTP header > `--sw-url` flag > 
`http://localhost:12800/graphql`
+
+The `set_skywalking_url` tool is only available in stdio mode (single client, 
well-defined session). SSE and HTTP transports use per-request headers instead.
 
 Basic auth is configured via `--sw-username` / `--sw-password` flags. Both 
flags (and the `set_skywalking_url` tool) support `${ENV_VAR}` syntax to 
resolve credentials from environment variables (e.g. `--sw-password 
${MY_SECRET}`).
 
diff --git a/README.md b/README.md
index 75701ef..5d9e8f5 100644
--- a/README.md
+++ b/README.md
@@ -110,7 +110,7 @@ SkyWalking MCP provides the following tools to query and 
analyze SkyWalking OAP
 
 | Category     | Tool Name                      | Description                  
                                                                     |
 
|--------------|--------------------------------|---------------------------------------------------------------------------------------------------|
-| **Session**  | `set_skywalking_url`           | Set the SkyWalking OAP 
server URL and optional basic auth credentials for the current session. 
Supports `${ENV_VAR}` syntax for credentials. |
+| **Session**  | `set_skywalking_url`           | Set the SkyWalking OAP 
server URL and optional basic auth credentials for the current session (stdio 
mode only). Supports `${ENV_VAR}` syntax for credentials. |
 | **Trace**    | `query_traces`                 | Query traces with 
multi-condition filtering (service, endpoint, state, tags, and time range via 
start/end/step). Supports `full`, `summary`, and `errors_only` views with 
performance insights. |
 | **Log**      | `query_logs`                   | Query logs with filters for 
service, instance, endpoint, trace ID, tags, and time range. Supports cold 
storage and pagination. |
 | **MQE**      | `execute_mqe_expression`       | Execute MQE (Metrics Query 
Expression) to query and calculate metrics data. Supports calculations, 
aggregations, TopN, trend analysis, and multiple result types. |
diff --git a/internal/swmcp/server.go b/internal/swmcp/server.go
index 6da1bf8..8b4a740 100644
--- a/internal/swmcp/server.go
+++ b/internal/swmcp/server.go
@@ -37,14 +37,18 @@ import (
 )
 
 // newMCPServer creates a new MCP server with all tools, resources, and 
prompts registered.
-func newMCPServer() *server.MCPServer {
+// When stdio is true, session management tools (set_skywalking_url) are also 
registered,
+// since stdio has a single client and session semantics are well-defined.
+func newMCPServer(stdio bool) *server.MCPServer {
        s := server.NewMCPServer(
                "skywalking-mcp", "0.1.0",
                server.WithResourceCapabilities(true, true),
                server.WithPromptCapabilities(true),
                server.WithLogging(),
        )
-       AddSessionTools(s)
+       if stdio {
+               AddSessionTools(s)
+       }
        tools.AddTraceTools(s)
        tools.AddLogTools(s)
        tools.AddMQETools(s)
@@ -168,29 +172,23 @@ func EnhanceStdioContextFunc() server.StdioContextFunc {
 }
 
 // EnhanceSSEContextFunc returns a SSEContextFunc that enriches the context
-// with SkyWalking settings from SSE request headers and a per-session store.
+// with SkyWalking settings from SSE request headers and CLI-configured auth.
 func EnhanceSSEContextFunc() server.SSEContextFunc {
-       session := &Session{}
        return func(ctx context.Context, req *http.Request) context.Context {
-               ctx = WithSession(ctx, session)
                urlStr := urlFromHeaders(req)
                ctx = WithSkyWalkingURLAndInsecure(ctx, urlStr, false)
                ctx = withConfiguredAuth(ctx)
-               ctx = applySessionOverrides(ctx)
                return ctx
        }
 }
 
 // EnhanceHTTPContextFunc returns a HTTPContextFunc that enriches the context
-// with SkyWalking settings from HTTP request headers and a per-session store.
+// with SkyWalking settings from HTTP request headers and CLI-configured auth.
 func EnhanceHTTPContextFunc() server.HTTPContextFunc {
-       session := &Session{}
        return func(ctx context.Context, req *http.Request) context.Context {
-               ctx = WithSession(ctx, session)
                urlStr := urlFromHeaders(req)
                ctx = WithSkyWalkingURLAndInsecure(ctx, urlStr, false)
                ctx = withConfiguredAuth(ctx)
-               ctx = applySessionOverrides(ctx)
                return ctx
        }
 }
diff --git a/internal/swmcp/session.go b/internal/swmcp/session.go
index 847504a..5a684c1 100644
--- a/internal/swmcp/session.go
+++ b/internal/swmcp/session.go
@@ -112,11 +112,13 @@ func AddSessionTools(s *server.MCPServer) {
        tool := tools.NewTool(
                "set_skywalking_url",
                `Set the SkyWalking OAP server URL and optional basic auth 
credentials for this session.
+This tool is only available in stdio transport mode.
 
 This tool configures the connection to SkyWalking OAP for all subsequent tool 
calls in the current session.
 The URL and credentials persist for the lifetime of the session.
 
 Priority: session URL (set by this tool) > --sw-url flag > default 
(http://localhost:12800/graphql)
+For SSE/HTTP transports, use the SW-URL HTTP header or --sw-url flag instead.
 
 Credentials support raw values or environment variable references using 
${ENV_VAR} syntax.
 
diff --git a/internal/swmcp/sse.go b/internal/swmcp/sse.go
index 14365a9..1e9a04e 100644
--- a/internal/swmcp/sse.go
+++ b/internal/swmcp/sse.go
@@ -72,7 +72,7 @@ func runSSEServer(ctx context.Context, cfg 
*config.SSEServerConfig) error {
        }
 
        sseServer := server.NewSSEServer(
-               newMCPServer(),
+               newMCPServer(false),
                server.WithStaticBasePath(cfg.BasePath),
                server.WithSSEContextFunc(EnhanceSSEContextFunc()),
        )
diff --git a/internal/swmcp/stdio.go b/internal/swmcp/stdio.go
index 02abb4a..9dd58df 100644
--- a/internal/swmcp/stdio.go
+++ b/internal/swmcp/stdio.go
@@ -60,7 +60,7 @@ func runStdioServer(ctx context.Context, cfg 
*config.StdioServerConfig) error {
        ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
        defer stop()
 
-       stdioServer := server.NewStdioServer(newMCPServer())
+       stdioServer := server.NewStdioServer(newMCPServer(true))
 
        logger, err := initLogger(cfg.LogFilePath)
        if err != nil {
diff --git a/internal/swmcp/streamable.go b/internal/swmcp/streamable.go
index 0500352..8f41194 100644
--- a/internal/swmcp/streamable.go
+++ b/internal/swmcp/streamable.go
@@ -57,7 +57,7 @@ func NewStreamable() *cobra.Command {
 // runStreamableServer starts the Streamable server with the provided 
configuration.
 func runStreamableServer(cfg *config.StreamableServerConfig) error {
        httpServer := server.NewStreamableHTTPServer(
-               newMCPServer(),
+               newMCPServer(false),
                server.WithStateLess(true),
                server.WithLogger(log.StandardLogger()),
                server.WithHTTPContextFunc(EnhanceHTTPContextFunc()),

Reply via email to