Skip to content

[MCP] Fix for inconsistent MCP enabled check#3303

Draft
souvikghosh04 wants to merge 1 commit intomainfrom
Usr/sogh/mcpenabledfix
Draft

[MCP] Fix for inconsistent MCP enabled check#3303
souvikghosh04 wants to merge 1 commit intomainfrom
Usr/sogh/mcpenabledfix

Conversation

@souvikghosh04
Copy link
Contributor

@souvikghosh04 souvikghosh04 commented Mar 23, 2026

Why make this change?

MCP endpoint returns 404 when the mcp config block is omitted, despite mcp.enabled defaulting to true across schema, CLI, and model layers.

What is this change?

McpEndpointRouteBuilderExtensions.TryGetMcpOptions: Falls back to new McpRuntimeOptions() when Runtime.Mcp is null, so the /mcp endpoint is registered by default.
RestService.GetRouteAfterPathBase: Guards the GlobalMcpEndpointDisabled exception with an IsMcpEnabled check so MCP path requests are not unconditionally rejected.

How was this tested?

  • Integration Tests
  • Unit Tests

Sample Request(s)

/mcp
/health

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes inconsistent MCP enablement behavior so the /mcp endpoint is registered by default when the runtime.mcp block is omitted, aligning runtime behavior with mcp.enabled defaulting to true in config/model layers (closes #3284).

Changes:

  • Default MCP options resolution now falls back to new McpRuntimeOptions() when runtime.mcp is absent, enabling endpoint registration by default.
  • REST routing guard now throws GlobalMcpEndpointDisabled only when MCP is actually disabled.
  • Added unit tests covering MCP enabled/disabled routing guard behavior and config defaulting of IsMcpEnabled / McpPath.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/Azure.DataApiBuilder.Mcp/Core/McpEndpointRouteBuilderExtensions.cs Ensures MCP endpoints are mapped by default when runtime.mcp is omitted.
src/Core/Services/RestService.cs Gates the MCP-disabled 404 guard behind IsMcpEnabled.
src/Service.Tests/UnitTests/RestServiceUnitTests.cs Adds unit tests for MCP path guard behavior in GetRouteAfterPathBase.
src/Service.Tests/Configuration/McpRuntimeOptionsSerializationTests.cs Adds tests verifying IsMcpEnabled/McpPath defaults when runtime/mcp blocks are omitted.

Comment on lines +53 to 55
mcpOptions = runtimeConfig?.Runtime?.Mcp ?? new McpRuntimeOptions();
return mcpOptions != null;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryGetMcpOptions now returns a default new McpRuntimeOptions() even when the config has no runtime.mcp block, so the method name/XML docs ("found") and the return mcpOptions != null; are misleading/redundant (it will always be true after the assignment). Consider updating the docs/return semantics and simplifying the null checks in MapDabMcp accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +53 to 54
mcpOptions = runtimeConfig?.Runtime?.Mcp ?? new McpRuntimeOptions();
return mcpOptions != null;
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change makes MCP map by default when runtime.mcp is absent, but there’s no test exercising actual endpoint registration (e.g., a TestServer request to /mcp with a config omitting runtime/mcp). Adding an integration test would prevent regressions of #3284.

Suggested change
mcpOptions = runtimeConfig?.Runtime?.Mcp ?? new McpRuntimeOptions();
return mcpOptions != null;
McpRuntimeOptions? configuredOptions = runtimeConfig.Runtime?.Mcp;
if (configuredOptions is null)
{
return false;
}
mcpOptions = configuredOptions;
return true;

Copilot uses AI. Check for mistakes.
Comment on lines +413 to +414
if (route.Equals(_runtimeConfigProvider.GetConfig().McpPath.Substring(1))
&& !_runtimeConfigProvider.GetConfig().IsMcpEnabled)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetRouteAfterPathBase calls _runtimeConfigProvider.GetConfig() three times and recomputes McpPath.Substring(1) on the hot path for every request. Consider storing the config (and the trimmed MCP route segment) in locals to avoid repeated config access and string operations.

Copilot uses AI. Check for mistakes.
queryManagerFactory.Setup(x => x.GetQueryBuilder(It.IsAny<DatabaseType>())).Returns(queryBuilder);
queryManagerFactory.Setup(x => x.GetQueryExecutor(It.IsAny<DatabaseType>())).Returns(queryExecutor);

Mock<ISqlMetadataProvider> sqlMetadataProvider = new();
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InitializeTestWithMcpConfig duplicates most of InitializeTestWithEntityPaths and introduces additional unused locals (e.g., sqlMetadataProvider). Consider reusing the existing initializer and/or removing unused locals to keep the test setup smaller and easier to maintain.

Suggested change
Mock<ISqlMetadataProvider> sqlMetadataProvider = new();

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

[Bug]: mcp.enabled defaults are not working

2 participants