Skip to content

Expose (to Client) and Subscribe (at Server) on call tool event without a real C# method at Server #298

@IvanMurzak

Description

@IvanMurzak

Is your feature request related to a problem? Please describe.

I am working on Unity-MCP project. Unity Engine is a dedicated app which doesn't have exposed API for external access. The only one way to connect MCP server with Unity is to create a Plugin and integrate it into Unity. Then, via TCP connection with MCP Server they can talk to each other. The code which is responsible for taking resources or running a tool should be in Unity as part of the Plugin. Unfortunately because of the current csharp-sdk limitation, a function for a tool should also be duplicated in the MCP server, and then connected with the same function in Plugin. Which forces to produce code duplication and unnecessary complexity in communication between apps.

Also, Plugin (package) is a read-only subject in Unity. Which doesn't let people to add custom tools in their projects. Unity Engine is designed to recompile Domain each time as only any C# file is changed. And the source code of the game is often used as "tools" for game development in Unity Editor. Which makes a lot of sense to expose the ability for developers to let them to add custom tools outside of read-only package.

csharp-sdk had an API for dynamic add of a method, but that should be a real method with arguments in C# code. Which doesn't help to avoid code duplication. And doesn't let to add 'tools' outside of read-only area in a Unity project.

Describe the solution you'd like

Yes, there is a solution which I already implemented and tested in Unity-MCP. Would be awesome to have it in csharp-sdk. It has some mind-shift in comparison to what I heard in talks at the repository. So please be patient in reading the explanation. Because that is truly seamless and intuitive way for people who would like to integrate MCP into a third-party app, or even natively into their own app or game.

Let's determine few entities...

  • Client - such a chat for a user
  • Server - (in this case) it is data transmitter between Client and Plugin
  • Plugin - it is tool executor, resource loader, tools list provider, prompt provider to the Server
  • Target - Unity Editor, a game, any software such as Blender, Photoshop, 3DS Max etc.

Image

I have a strong feeling that majority of community is pushing the MCP Server as the core of this architecture. It works well only when the "Target" has explicit API. If that is not - "Plugin" is required. is a web service. But if that is a local app such as Blender or a Photoshop, and the app doesn't have an API, the only solution is to develop a Plugin.

The Plugin is the core in this concept. Server is only a data router and connector.

Plugin's responsibilities:

  • expose capabilities (tools, resources, prompts) and updates to Server
  • provide prompts and updates
  • provide resources and updates
  • provide tools and updates
  • notify Server about internal events if needed
  • constantly reconnecting to a Server if connection lost

Server's responsibilities:

  • forward Plugin capabilities (tools, resources, prompts) and updates to Client
  • forward Client requests to Plugin
  • on top of Plugin capabilities provide it's own capabilities (needed for the specific category of tools, for example when the Target and Plugin should be restarted by a command from Client.
  • constantly reconnecting to Plugin if connection lost

Ideal solution 💖

  1. csharp-sdk may support "Plugin" mode. It is similar to existed csharp-sdk architecture which supports Client and Server modes, that is another Plugin mode. It would require to have TCP connection between Server and Plugin.
  2. Plugin mode supports the same style of method binding like csharp-sdk works for a Server already with attributes.
  3. Plugin automatically shares and updates current capabilities with Server via TCP connection.
  4. Plugin is independent from Server and may life without connection. There is nothing to do with that, it just waits for connection with Server

By the way, I already implemented it all in Unity-MCP. Thinking about making a NuGet package from it. Any feedback is appreciated. Also, I understand that the Plugin concept is a bit out of the scope for the csharp-sdk for MCP. That is why I have the Minimal solution, which is really required such as a last jigsaw in the puzzle.

Minimal solution ⭐

  1. Allow to override routing in the Server mode and providing response to a Client.

I assume it should already work, but it doesn't or I didn't understand how exactly it is designed in the current implementation. There is a concept of "Handlers" in cshapr-sdk which could be triggered, but the response from the handler is ignored (not passed to a Client). Also, there is no way to add a tool on a fly in the handler callback. Because csharp-sdk expose only registered tools. Even if I have a tool csharp-sdk doesn't let me to add without explicit method. So even if to add tool a the custom router using the Handler, it won't be exposed to a Client and Client would never call it. That is why there is the next point.

  1. Allow to register a tool without a real C# method. Using JsonSchema for describing input arguments and result value is ideal.

This is already implemented in the Handler concept. You are using JsonSchema for describing arguments. Just please make the same ability for registering a tool.

That is it, only two things in the minimal solution. Both of them already exist in the project, just need to connect them together.

Minimal solution 2 ⭐⭐⭐

  1. To have IMcpServer.NotifyTooListChanged method. It would request list of tools using the handler that were added earlier using .WithListToolsHandler.
public class McpServer : IMcpServer
{
    public void NotifyToolListChanged()
    {
        // 1. request list of tools from handler
        // 2. notify Client about changes
    }
    // ...
}
public interface IMcpServer
{
    void NotifyToolListChanged();
    // ...
}

It feels like the Minimal solution 2 is even simpler for both group of developers: csharp-sdk developers and MCP server developers. We (MCP server devs) don't need to worry about about managing the tools reactive collection. The list of tools already exposed using the handler. There is not much sense for doing that in two places.

Metadata

Metadata

Assignees

No one assigned

    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