Skip to content

Commit a43ce7a

Browse files
Copilotconnor4312
andauthored
mcp: forward log level changes to MCP servers
Fixes microsoft#256267 * Initial plan * Implement MCP server log level forwarding Co-authored-by: connor4312 <[email protected]> * Add tests for MCP server log level functionality Co-authored-by: connor4312 <[email protected]> * Move log level forwarding to McpServerRequestHandler and clean up imports Co-authored-by: connor4312 <[email protected]> * properly --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: connor4312 <[email protected]> Co-authored-by: Connor Peet <[email protected]>
1 parent 2ebd246 commit a43ce7a

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { equals } from '../../../../base/common/arrays.js';
7+
import { assertNever } from '../../../../base/common/assert.js';
78
import { DeferredPromise, IntervalTimer } from '../../../../base/common/async.js';
89
import { CancellationToken } from '../../../../base/common/cancellation.js';
910
import { CancellationError } from '../../../../base/common/errors.js';
@@ -122,6 +123,7 @@ export class McpServerRequestHandler extends Disposable {
122123
}, token);
123124

124125
mcp._serverInit = initialized;
126+
mcp._sendLogLevelToServer(opts.logger.getLevel());
125127

126128
mcp.sendNotification<MCP.InitializedNotification>({
127129
method: 'notifications/initialized'
@@ -166,6 +168,11 @@ export class McpServerRequestHandler extends Disposable {
166168
this.cancelAllRequests();
167169
}
168170
}));
171+
172+
// Listen for log level changes and forward them to the MCP server
173+
this._register(logger.onDidChangeLogLevel((logLevel) => {
174+
this._sendLogLevelToServer(logLevel);
175+
}));
169176
}
170177

171178
/**
@@ -440,6 +447,22 @@ export class McpServerRequestHandler extends Disposable {
440447
super.dispose();
441448
}
442449

450+
/**
451+
* Forwards log level changes to the MCP server if it supports logging
452+
*/
453+
private async _sendLogLevelToServer(logLevel: LogLevel): Promise<void> {
454+
try {
455+
// Only send if the server supports logging capabilities
456+
if (!this.capabilities.logging) {
457+
return;
458+
}
459+
460+
await this.setLevel({ level: mapLogLevelToMcp(logLevel) });
461+
} catch (error) {
462+
this.logger.error(`Failed to set MCP server log level: ${error}`);
463+
}
464+
}
465+
443466
/**
444467
* Send an initialize request
445468
*/
@@ -531,3 +554,26 @@ export class McpServerRequestHandler extends Disposable {
531554
return this.sendRequest<MCP.CompleteRequest, MCP.CompleteResult>({ method: 'completion/complete', params }, token);
532555
}
533556
}
557+
558+
559+
/**
560+
* Maps VSCode LogLevel to MCP LoggingLevel
561+
*/
562+
function mapLogLevelToMcp(logLevel: LogLevel): MCP.LoggingLevel {
563+
switch (logLevel) {
564+
case LogLevel.Trace:
565+
return 'debug'; // MCP doesn't have trace, use debug
566+
case LogLevel.Debug:
567+
return 'debug';
568+
case LogLevel.Info:
569+
return 'info';
570+
case LogLevel.Warning:
571+
return 'warning';
572+
case LogLevel.Error:
573+
return 'error';
574+
case LogLevel.Off:
575+
return 'emergency'; // MCP doesn't have off, use emergency
576+
default:
577+
return assertNever(logLevel); // Off and other levels are not supported
578+
}
579+
}

src/vs/workbench/contrib/mcp/test/common/mcpServerConnection.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { McpServerConnection } from '../../common/mcpServerConnection.js';
2121
import { McpCollectionDefinition, McpConnectionState, McpServerDefinition, McpServerTransportType } from '../../common/mcpTypes.js';
2222
import { TestMcpMessageTransport } from './mcpRegistryTypes.js';
2323
import { ConfigurationTarget } from '../../../../../platform/configuration/common/configuration.js';
24+
import { Event } from '../../../../../base/common/event.js';
2425

2526
class TestMcpHostDelegate extends Disposable implements IMcpHostDelegate {
2627
private readonly _transport: TestMcpMessageTransport;
@@ -288,6 +289,7 @@ suite('Workbench - MCP - ServerConnection', () => {
288289
delegate,
289290
serverDefinition.launch,
290291
{
292+
onDidChangeLogLevel: Event.None,
291293
getLevel: () => LogLevel.Debug,
292294
info: (message: string) => {
293295
loggedMessages.push(message);

0 commit comments

Comments
 (0)