You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## 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>
0 commit comments