Skip to content

Support building stateful MCP servers #425

Open
@AArnott

Description

@AArnott

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.

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions