-
Notifications
You must be signed in to change notification settings - Fork 299
Implementation of Custom Tool in MCP #3048
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
base: main
Are you sure you want to change the base?
Conversation
- Add EntityMcpOptions class with custom-tool and dml-tools properties - Add JSON converter supporting boolean and object formats - Add CLI support for --mcp.dml-tools and --mcp.custom-tool flags - Add schema validation restricting custom-tool to stored procedures - Entity.Mcp property is optional (default null) to avoid test cascade Only 9 files changed in this minimal implementation.
- Update EntityMcpOptions documentation to clarify custom-tool behavior in boolean mode - Replace if-else with switch-case in converter for better extensibility - Remove unnecessary null writes in serializer - Change CustomToolEnabled and DmlToolEnabled from nullable to non-nullable bool - Fix boolean shorthand deserialization to not mark custom-tool as user-provided - Add consistent else block in constructor for symmetry All 530 tests passing. Functionality verified with manual testing.
…/Azure/data-api-builder into Usr/sogh/entity-level-mcp-config
…/Azure/data-api-builder into Usr/sogh/entity-level-mcp-config
|
/azp run |
|
Azure Pipelines successfully started running 6 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces dynamic custom MCP tool support, allowing stored procedures configured with "custom-tool" enabled to be automatically exposed as dedicated MCP tools. The implementation adds a factory pattern for generating tools from configuration and integrates them into the service registration pipeline.
Changes:
- Added
DynamicCustomToolclass to dynamically generate MCP tools from stored procedure configurations - Implemented
CustomMcpToolFactoryto scan runtime configuration and create custom tools - Updated service registration in
McpServiceCollectionExtensionsto exclude dynamic tools from auto-discovery and register custom tools from configuration
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 14 comments.
| File | Description |
|---|---|
| src/Azure.DataApiBuilder.Mcp/Core/McpServiceCollectionExtensions.cs | Added RegisterCustomTools method and modified auto-discovery to exclude DynamicCustomTool |
| src/Azure.DataApiBuilder.Mcp/Core/DynamicCustomTool.cs | New class implementing IMcpTool for dynamically generated stored procedure tools |
| src/Azure.DataApiBuilder.Mcp/Core/CustomMcpToolFactory.cs | New factory class for creating custom tools from runtime configuration |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
/azp run |
|
Azure Pipelines successfully started running 6 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 6 pipeline(s). |
| /// <summary> | ||
| /// Executes the stored procedure represented by this custom tool. | ||
| /// </summary> | ||
| public async Task<CallToolResult> ExecuteAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Please add explicit OpenTelemetry tracing for custom stored-procedure MCP tools.
Scope: DynamicCustomTool.ExecuteAsync(...)
Requirements:
- Create an
Activity/span around each tool invocation (e.g., span namemcp.tool.callordab.mcp.custom_tool.execute). - Add span attributes/tags at minimum:
mcp.tool.name= tool namedab.entity= entity alias/namedab.operation=executedb.procedure(or equivalent) = stored procedure name / db object (schema-qualified if available)
- Record outcome on the span:
- mark success vs failure (
ActivityStatusCode.Ok/Error) - on exceptions, record the exception on the span and include an error message/code where available.
- mark success vs failure (
Notes:
- Logging via
ILoggeris not sufficient; the tool should emit tracing spans directly. - Ensure spans are created for both success and failure paths (including auth/validation failures).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PLEASE TREAT TELEMETRY AS A BASE REQUIREMENT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please implement OpenTelemetry tracing for MCP tool execution centrally to avoid duplicating instrumentation in every tool.
Goal: Every MCP tools/call invocation (built-in DML tools and dynamic custom stored-proc tools) emits a consistent span.
General idea:
- Add instrumentation in the MCP dispatcher / tool execution entry point (the code path that resolves the tool by name and invokes
IMcpTool.ExecuteAsync). - Start an
Activityspan for each tool call (e.g.,mcp.tool.call/dab.mcp.tool.execute) and ensure it wraps the entire execution including auth/validation and query execution. - Apply standard tags (e.g.,
mcp.tool.name,dab.entitywhen applicable,dab.operation,db.procedurewhen applicable). - Set span status to Ok/Error and record exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree on this - but we can add it in a separate subsequent PR - for easier PR review and merge process.
Why make this change?
What is this change?
This pull request introduces a new system for dynamically generating and registering custom MCP tools based on stored procedure entity configurations in the runtime configuration. The main changes are the implementation of the
DynamicCustomToolclass, a factory to create these tools from configuration, and the necessary service registration logic to ensure these custom tools are available at runtime.Dynamic custom MCP tool support:
DynamicCustomToolclass, which implementsIMcpTooland provides logic for generating tool metadata, validating configuration, handling authorization, executing the underlying stored procedure, and formatting the response. This enables each stored procedure entity withcustom-toolenabled to be exposed as a dedicated MCP tool.CustomMcpToolFactoryclass, which scans the runtime configuration for stored procedure entities marked withcustom-toolenabled and creates correspondingDynamicCustomToolinstances.Dependency injection and service registration:
AddDabMcpServer) to register custom tools generated from configuration by calling a newRegisterCustomToolsmethod after auto-discovering static tools.RegisterAllMcpToolsmethod to excludeDynamicCustomToolfrom auto-discovery (since these are created dynamically per configuration) and added theRegisterCustomToolsmethod to register each generated custom tool as a singleton service.How was this tested?
Sample Request(s)
Error Scenarios
6. Missing Required Parameter
Edge Cases
9. SQL Injection Attempt