Description
Is your feature request related to a problem? Please describe.
Imagine an MCP server that keeps state for a particular client. Maybe it remembers things, or maybe it's performing long running analysis.
In such a case, it can be critical to have fields storing data for a particular MCP client.
It can also be critical for one of those fields to be an IMcpServer
that represents that connection with the client.
For local MCP servers using STDIO, there is exactly one client and static fields (though very gross) would suffice (but are very unfriendly to testing).
For HTTP/SSE MCP servers, of course there can be many clients, and many IMcpServer objects. But there's no good way for user code to create objects with fields that are associated with each individual server object.
Describe the solution you'd like
I'd like to define my server as an instance class with instance method for tools.
Instantiating the server should require an IMcpServer
thereby ensuring that every instance is bound to exactly one client.
Something like this:
[McpServerToolType]
public class EchoTool(IMcpServer server)
{
[McpServerTool(Name = "echo"), Description("Echoes the message back to the client.")]
public string Echo(string message) => $"{server.ClientInfo.Name}, you said {message}";
}
Now I can add fields and manage state more efficiently. For example I might keep a "roots" field, which I initialize on demand and then store. I would subscribe to notifications/roots/list_changed
to ensure that the field is always current without having to requery it on every need for the list.
This has the benefit of working equally well for HTTP and STDIO servers, so that statics are not required and therefore testability is high.
Describe alternatives you've considered
I suppose I could have a static ConditionalWeakTable<IMcpServer, MyFields> data
field on my static class, and index into it via an IMcpServer
that each tool takes as a parameter.