-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fine-grained control over parameter (de)serialization #216
Comments
You can derive from McpServerTool and then just add an instance of your class as an McpServerTool to DI; it'll be picked up and automatically served. Deriving from McpServerTool involves effectively just providing a name, description, schema, and invoke method, so it does provide direct control over how tool parameters are handled. If you only want to customize aspects of it, but still want to use the core logic, you can create a tool using McpServerTool.Create, giving it your delegate or method, and then wrap the resulting McpServerTool in a DelegatingMcpServerTool, where you derive from that type instead of from McpServerTool, and just override the portions that you want and delegate to the existing implementation for the rest. Or as another middle ground, you can pass an arbitrary AIFunction to McpServerTool.Create, and use AIFunctionFactory.Create to create your AIFunction, using AIFunctionFactoryOptions to control how parameters are serialized. Do none of those options meet your needs? If not, can you elaborate on exactly what you'd be hoping for? |
As an aside, you generally want to carefully consider whether to use complex tool parameters at all. Models tend to perform better with simpler tool signatures, where all parameters are simple types. If you have existing services you want to expose as tools, I would recommend doing evaluations (either with API-based pipelines or a library such as In addition to what @stephentoub mentioned above you can also just wrap your tool explicitly in a Facade-style pattern, which I think actually is a strong design as it means your MCP Server tools aren't tightly coupled to your existing service interface. It also doesn't require deriving from McpServerTool - you simply write a Facade for which each service which uses the SDK attributes and maps to the underlying service. Then you can have breaking changes in your service contract without implicitly changing your tool signatures - which might break Clients that have Server-specific instructions and examples in their system prompt. More importantly it also allows you to keep the LLM-facing Description attributes separate from your existing service code. And Descriptions are very important for tool calling quality. |
@stephentoub @PederHP Thanks! Both your comments give insight into alternative solutions. I think one of these will fit my use case. Keep up the good work! |
Is your feature request related to a problem? Please describe.
When using the SDK to add MCP capabilities to existing .NET core applications, it would be benificial to control how Tool parameters are serialized and deserialized from/to JSON.
This is espcially true if you want to reuse existing service methods and the tool parameters (= method arguments) are of a complex type with existing serialization/desarialization mechanisms that are already used in the application
Describe the solution you'd like
There could be an extention point that allows the developer to tap in to do the (de) serializion between the MCPServer revieving a request and passing it on to the Tool.
Describe alternatives you've considered
The text was updated successfully, but these errors were encountered: