Cherry pick MCP logging, instructions, and schema fixes to release/2.0#3512
Merged
anushakolan merged 6 commits intorelease/2.0from May 6, 2026
Merged
Cherry pick MCP logging, instructions, and schema fixes to release/2.0#3512anushakolan merged 6 commits intorelease/2.0from
anushakolan merged 6 commits intorelease/2.0from
Conversation
## Why make this change? Closes #3282 The issue is that runtime MCP server description exists in code (`McpRuntimeOptions.Description`) but was missing from the JSON schema, so valid config using `runtime.mcp.description` could fail schema validation. This change adds the missing schema entry, so config and schema stay aligned. ## What is this change? Added `runtime.mcp.description` to `schemas/dab.draft.schema.json` under the `mcp` runtime properties: - `type: "string"` - description clarifying it is exposed as the MCP `instructions` field in initialize response No runtime/CLI code changes were needed because support already exists in config model, converter, CLI configure option, and MCP server response wiring. ## How was this tested? - [ ] Integration Tests - [x] Unit Tests Ran: - `dotnet test src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj --filter "FullyQualifiedName~McpRuntimeOptionsSerializationTests" -v minimal` ## Sample Request(s) CLI example: ```bash dab configure --runtime.mcp.description "Use this MCP for product and inventory questions." ``` Config example: ```json { "runtime": { "mcp": { "enabled": true, "path": "/mcp", "description": "Use this MCP for product and inventory questions." } } } ```
…raft.schema.json. (#3424) ## Why make this change? Closes #3392. The JSON schema default for runtime.host.authentication.provider was set to AppService, while CLI help text and docs indicate the default should be Unauthenticated. This mismatch can confuse users and tooling. ## What is this change? - Updated the schema default in schemas/dab.draft.schema.json: - runtime.host.authentication.provider: AppService -> Unauthenticated - No runtime behavior changes were introduced beyond aligning the schema default value. ## How was this tested? - [ ] Integration Tests - [x] Unit Tests Ran: - dotnet test src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj --framework net8.0 --filter "FullyQualifiedName~CorsUnitTests.TestCorsConfigReadCorrectly" ## Sample Request(s) CLI example: - dab configure --runtime.host.authentication.provider AppService - This demonstrates overriding the default. Config example: - Omit runtime.host.authentication.provider from config. - Schema default resolves it to Unauthenticated. Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
…#3423) ## Why make this change? Closes #3283 `runtime.mcp.description` was configured, but MCP HTTP/SSE initialize did not return it as `instructions`. This made the engine behavior inconsistent with expected MCP initialization output. Related discussion: #3282 ## What is this change? - Wired runtime MCP description into MCP server options for HTTP/SSE initialization: - `runtime.mcp.description` -> `ServerInstructions` - Files updated: - `src/Azure.DataApiBuilder.Mcp/Core/McpServiceCollectionExtensions.cs` - `src/Azure.DataApiBuilder.Mcp/Core/McpServerConfiguration.cs` - Added/updated regression coverage for initialize response instructions: - `src/Service.Tests/Configuration/ConfigurationTests.cs` - Test: `TestMcpInitializeIncludesInstructionsFromRuntimeDescription` How the bug was simulated: - Reverted the MCP wiring changes and called MCP `initialize`; `result.instructions` was missing. How it was verified after fix: - Re-applied the wiring, called MCP `initialize` again, and confirmed `result.instructions` is present. ## How was this tested? - [x] Integration Tests - [ ] Unit Tests Ran: - `dotnet test src/Service.Tests/Azure.DataApiBuilder.Service.Tests.csproj --filter "FullyQualifiedName~ConfigurationTests.TestMcpInitializeIncludesInstructionsFromRuntimeDescription" -v minimal` ## Sample Request(s) MCP initialize request (HTTP): ```bash curl -i -X POST http://localhost:5000/mcp \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc":"2.0", "id":1, "method":"initialize", "params":{ "protocolVersion":"2025-03-26", "capabilities":{}, "clientInfo":{"name":"manual-test","version":"1.0.0"} } }' ``` Expected response snippet after fix: ```json { "result": { "instructions": "Use SQL tools to query the database." } } ```
…label on startup (#3307) ## Why make this change? Closes #3269 ## What is this change? Align the CLI logger labels with the labels used in ASP.Net Core. Downgraded internal plumbing message from `Information` to `Debug` Add a test case to cover the changed behavior. ## How was this tested? Added a test case to validate the new behavior.
## Why make this change? Closes #3274 - MCP Server returns "Method not found: logging/setLevel" error when clients send the standard MCP logging/setLevel request. Closes #3275 - Control output in MCP stdio mode (default to `LogLevel.None`, redirect/suppress console output). ## What is this change? ### MCP `logging/setLevel` Handler - Added handler for `logging/setLevel` JSON-RPC method in `McpStdioServer.cs` - Implemented `DynamicLogLevelProvider` with `ILogLevelController` interface to allow MCP to update log levels dynamically - Added `IsCliOverridden` and `IsConfigOverridden` properties to enforce precedence rules ### Log Level Precedence System **Precedence (highest to lowest):** 1. **CLI `--LogLevel` flag** - cannot be changed by MCP 2. **Config `runtime.telemetry.log-level`** - cannot be changed by MCP 3. **MCP `logging/setLevel`** - only works if neither CLI nor config set a level 4. Default (LogLevel.None for MCP stdio mode) If CLI or config set a level, MCP requests are accepted but silently ignored (no error returned per MCP spec). ### Early Config Reading for MCP Mode - Added `TryGetLogLevelFromConfig()` in `Program.cs` to read config file early (before host build) - This ensures config log level is detected before Console redirect decision - Console redirect for MCP stdio mode now respects config log level ### CLI Log Level Handling - Added `Utils.CliLogLevel` property to track the parsed `--LogLevel` value - CLI's `CustomLoggerProvider` now respects the `--LogLevel` value for its own logging ### Config Helpers - Added `HasExplicitLogLevel()` helper to `RuntimeConfig` to correctly detect when config actually pins a log level - This properly handles null values in telemetry section (null values don't count as explicit override) ## How was this tested? - [x] Unit Tests (`DynamicLogLevelProviderTests` - 5 tests) - [x] Manual Testing ### Manual Test 1: No override (MCP can change level) 1. Start MCP server without `--LogLevel` and without config `log-level` 2. MCP sends `logging/setLevel` with `level: info` 3. Result: Log level changes to info ### Manual Test 2: CLI override (MCP blocked) 1. Start MCP server with `--LogLevel Warning` 2. MCP sends `logging/setLevel` with `level: info` 3. Result: Log level stays at Warning, MCP request accepted silently ### Manual Test 3: Config override (MCP blocked) 1. Add `"telemetry": { "log-level": { "default": "Warning" } }` to config 2. Start MCP server without `--LogLevel` 3. MCP sends `logging/setLevel` with `level: info` 5. Result: Log level stays at Warning, MCP request accepted silently ### Manual Test 4: Config with null values (MCP can change level) 1. Add `"telemetry": { "log-level": { "default": null } }` to config 2. Start MCP server without `--LogLevel` 3. MCP sends `logging/setLevel` with `level: info` 4. Result: Log level changes to info (null values don't count as override) ## Sample Request(s) MCP client sends: ```json { "jsonrpc": "2.0", "id": 1, "method": "logging/setLevel", "params": { "level": "info" } } ``` Server responds with empty result (success per MCP spec) and updates log level if no CLI/config override is active. --------- Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This backport brings MCP initialization/schema fixes and MCP-focused logging improvements from main into the release/2.0 line, aiming to align runtime behavior, CLI logging, and JSON schema validation for MCP-related configuration.
Changes:
- Add MCP server
descriptionsupport in the JSON schema and wire it through to MCPinitializeinstructions(HTTP/SSE and stdio paths). - Introduce dynamic log-level control for MCP stdio via
logging/setLevel, including CLI/config precedence and cleaner stdio output behavior. - Align schema defaults and logging output labels with documented/expected defaults and ASP.NET Core conventions.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Service/Telemetry/DynamicLogLevelProvider.cs | Adds MCP log-level mapping and dynamic update path via ILogLevelController. |
| src/Service/Startup.cs | Downgrades response-compression message to Debug for less noisy startup logs. |
| src/Service/Program.cs | Initializes log level earlier, adds MCP stdio console redirection, and config-based log-level detection. |
| src/Service.Tests/UnitTests/DynamicLogLevelProviderTests.cs | Adds unit coverage for MCP logging/setLevel behavior and precedence. |
| src/Service.Tests/Configuration/ConfigurationTests.cs | Adds regression test ensuring MCP initialize includes instructions; extends MCP helpers to capture/parse response bodies (JSON/SSE). |
| src/Core/Telemetry/ILogLevelController.cs | Introduces an abstraction for runtime log-level control without tight coupling. |
| src/Core/Services/RequestValidator.cs | Fixes a garbled character in a comment (em dash). |
| src/Config/ObjectModel/RuntimeConfig.cs | Adds HasExplicitLogLevel() to detect when config truly pins a non-null log level. |
| src/Config/Converters/EntityCacheOptionsConverterFactory.cs | Fixes a garbled character in a comment (em dash). |
| src/Cli/Utils.cs | Adds flags/state used to suppress CLI stdout in MCP stdio mode and track CLI --LogLevel. |
| src/Cli/Program.cs | Adds early arg scanning so MCP/log-level flags affect logger creation. |
| src/Cli/CustomLoggerProvider.cs | Changes CLI log labels to ASP.NET Core abbreviations and routes MCP-stdio logs to stderr/suppresses output by default. |
| src/Cli/ConfigGenerator.cs | Only forwards --LogLevel to the engine when explicitly specified, enabling MCP dynamic changes otherwise. |
| src/Cli.Tests/CustomLoggerTests.cs | Adds tests for abbreviated CLI log labels. |
| src/Azure.DataApiBuilder.Mcp/Core/McpStdioServer.cs | Adds logging/setLevel JSON-RPC handler and removes stray debug stderr output; refines initialize payload. |
| src/Azure.DataApiBuilder.Mcp/Core/McpServiceCollectionExtensions.cs | Propagates runtime MCP description into server configuration. |
| src/Azure.DataApiBuilder.Mcp/Core/McpServerConfiguration.cs | Sets MCP server instructions (ServerInstructions) based on runtime description. |
| schemas/dab.draft.schema.json | Adds runtime.mcp.description and updates runtime.host.authentication.provider default to Unauthenticated. |
….15.3 (#3488) ## Why make this change? Bump `OpenTelemetry.Exporter.OpenTelemetryProtocol` to pick up patch fixes from 1.15.3. ## What is this change? - Updated `OpenTelemetry.Exporter.OpenTelemetryProtocol` from `1.13.0` → `1.15.3` in `src/Directory.Packages.props` (centrally managed versions) ## How was this tested? - [ ] Integration Tests - [ ] Unit Tests ## Sample Request(s) N/A — dependency version bump only. > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `www.nuget.org` > - Triggering command: `/home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/Azure/data-api-builder/settings/copilot/coding_agent) (admins only) > > </details> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com> Co-authored-by: Ruben Cerna <rcernaserna@microsoft.com>
souvikghosh04
approved these changes
May 6, 2026
Aniruddh25
approved these changes
May 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why make this change?
This backport ports a set of MCP-related and schema-related bug fixes from
maintorelease/2.0so the 2.0 release line includes:initializeinstructionsfield on the HTTP/SSE transport (was missing despiteruntime.mcp.descriptionbeing configured).runtime.mcp.description(was supported in code but missing fromdab.draft.schema.json, causing valid configs to fail validation).runtime.host.authentication.provideraligned with the documented/CLI default ofUnauthenticated(was incorrectlyAppService).logging/setLevelJSON-RPC method support, dynamic log-level updates, and clean stdout for MCP stdio mode.What is this change?
Cherry-picked PRs (chronological order on
main):dab.draft.schema.json#3424McpServerOptions.Instructionsin HTTPS/SSE mode #3423OpenTelemetry.Exporter.OpenTelemetryProtocolfrom 1.13.0 to 1.15.3 #3488 — required to unblock CI onrelease/2.0(fixes CVE-2026-42191 / GHSA-4625-4j76-fww9, whichdotnet format --verify-no-changespromotes to an error viaNU1902).How was this tested?
DynamicLogLevelProviderTests,TestMcpInitializeIncludesInstructionsFromRuntimeDescription,CustomLoggerTests,McpRuntimeOptionsSerializationTests).dotnet buildofsrc/Cli,src/Service, andsrc/Cli.Testson the cherry-pick branch — succeeded with 0 warnings, 0 errors.mainwas performed in each original PR; no additional manual verification was added for the backport.Sample Request(s)
N/A — these are bug fixes; no new public API.