Skip to content

Server notifications are not sent out in stateless mode #387

@ln-12

Description

@ln-12

Describe the bug
With #307 the Stateless flag was introduced. The documentation for the flag says that Server->Client notifications may reach the client if they are made in the context of an incoming request. However, I cannot get them to work again after the update to 0.3.0 of this library.

I explicitly set the logging level to debug in the inspector:
Image

The state update also reaches the server:
Image

But if I look at the stored logLevel when sending a notification, it is empty:
Image

So I think the state is not correctly handled in stateless mode. Or am I missing something?

To Reproduce
Minimal example:

package main

import (
	"context"
	"flag"
	"log"
	"net/http"
	"os"

	"github.com/modelcontextprotocol/go-sdk/mcp"
)

var httpAddr = flag.String("http", "", "if set, use streamable HTTP at this address, instead of stdin/stdout")

func main() {
	flag.Parse()

	server := mcp.NewServer(&mcp.Implementation{Name: "everything"}, nil)

	mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, contentTool)

	if *httpAddr != "" {
		handler := mcp.NewStreamableHTTPHandler(
			func(*http.Request) *mcp.Server {
				return server
			}, &mcp.StreamableHTTPOptions{Stateless: true},
		)
		log.Printf("MCP handler listening at %s", *httpAddr)
		http.ListenAndServe(*httpAddr, handler)
	} else {
		t := &mcp.LoggingTransport{Transport: &mcp.StdioTransport{}, Writer: os.Stderr}
		if err := server.Run(context.Background(), t); err != nil {
			log.Printf("Server failed: %v", err)
		}
	}
}

type args struct {
	SomeString string `json:"someString" jsonschema:"A random string"`
}

func contentTool(ctx context.Context, req *mcp.CallToolRequest, args args) (*mcp.CallToolResult, any, error) {
	req.Session.Log(ctx, &mcp.LoggingMessageParams{Logger: "logger", Level: "debug", Data: "Some data"})

	return &mcp.CallToolResult{
		Content: []mcp.Content{
			&mcp.TextContent{Text: "Something"},
		},
	}, nil, nil
}

Steps to reproduce the behavior:

  1. Run the code above
  2. Connect to the server and set logging level to debug
  3. Perform a request

Expected behavior
The example above should work as the notification is sent in the context of the incoming request.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions