Skip to content
Merged
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
5 changes: 4 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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}`).

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down
18 changes: 8 additions & 10 deletions internal/swmcp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
}
}
2 changes: 2 additions & 0 deletions internal/swmcp/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion internal/swmcp/sse.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
)
Expand Down
2 changes: 1 addition & 1 deletion internal/swmcp/stdio.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion internal/swmcp/streamable.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand Down
Loading