Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ public Task<CallToolResult> ExecuteAsync(

List<Dictionary<string, object?>> entityList = new();

// Track how many stored procedures were filtered out because they're exposed as custom-tool-only.
// This helps provide a more specific error message when all entities are filtered.
int filteredCustomToolCount = 0;

if (runtimeConfig.Entities != null)
{
foreach (KeyValuePair<string, Entity> entityEntry in runtimeConfig.Entities)
Expand All @@ -155,6 +159,18 @@ public Task<CallToolResult> ExecuteAsync(
string entityName = entityEntry.Key;
Entity entity = entityEntry.Value;

// Filter out stored procedures when dml-tools is explicitly disabled (false).
// This applies regardless of custom-tool setting:
// - custom-tool: true, dml-tools: false → Filtered (appears only in tools/list)
// - custom-tool: false, dml-tools: false → Filtered (entity fully disabled for MCP)
// When dml-tools is true (or default), the entity appears in describe_entities.
if (entity.Source.Type == EntitySourceType.StoredProcedure &&
entity.Mcp?.DmlToolEnabled == false)
{
filteredCustomToolCount++;
continue;
}

if (!ShouldIncludeEntity(entityName, entityFilter))
{
continue;
Expand All @@ -177,6 +193,7 @@ public Task<CallToolResult> ExecuteAsync(

if (entityList.Count == 0)
{
// No entities matched the filter criteria
if (entityFilter != null && entityFilter.Count > 0)
{
return Task.FromResult(McpResponseBuilder.BuildErrorResult(
Expand All @@ -185,6 +202,20 @@ public Task<CallToolResult> ExecuteAsync(
$"No entities found matching the filter: {string.Join(", ", entityFilter)}",
logger));
}
// All entities were filtered because they're custom-tool-only - only return this specific error
// if ALL configured entities were filtered (not just some). This prevents misleading errors
// when entities fail to build for other reasons (e.g., exceptions in Build*EntityInfo).
else if (filteredCustomToolCount > 0 &&
runtimeConfig.Entities != null &&
filteredCustomToolCount == runtimeConfig.Entities.Entities.Count)
{
return Task.FromResult(McpResponseBuilder.BuildErrorResult(
toolName,
"AllEntitiesFilteredAsCustomTools",
$"All {filteredCustomToolCount} configured entities are stored procedures exposed as custom-tool-only (dml-tools: false). Custom tools appear in tools/list, not describe_entities. Use the tools/list endpoint to discover available custom tools.",
logger));
}
// Truly no entities configured in the runtime config, or entities failed to build for other reasons
else
{
return Task.FromResult(McpResponseBuilder.BuildErrorResult(
Expand Down
Loading