chore(mcp): check MCP error code over brittle string match (#25381)

This commit is contained in:
Jack Wotherspoon
2026-04-14 13:24:21 -04:00
committed by GitHub
parent 1bb41262b0
commit 212edf31ed
2 changed files with 31 additions and 7 deletions

View File

@@ -20,6 +20,8 @@ import { MCPOAuthTokenStorage } from '../mcp/oauth-token-storage.js';
import { OAuthUtils } from '../mcp/oauth-utils.js';
import type { PromptRegistry } from '../prompts/prompt-registry.js';
import {
ErrorCode,
McpError,
PromptListChangedNotificationSchema,
ResourceListChangedNotificationSchema,
ToolListChangedNotificationSchema,
@@ -35,6 +37,7 @@ import {
isEnabled,
McpClient,
populateMcpServerCommand,
discoverPrompts,
type McpContext,
} from './mcp-client.js';
import type { ToolRegistry } from './tool-registry.js';
@@ -320,6 +323,25 @@ describe('mcp-client', () => {
);
});
it('should return empty array for discoverPrompts on MethodNotFound error without diagnostic', async () => {
const mockedClient = {
getServerCapabilities: vi.fn().mockReturnValue({ prompts: {} }),
listPrompts: vi
.fn()
.mockRejectedValue(
new McpError(ErrorCode.MethodNotFound, 'Method not supported'),
),
};
const result = await discoverPrompts(
'test-server',
mockedClient as unknown as ClientLib.Client,
MOCK_CONTEXT,
);
expect(result).toEqual([]);
// MethodNotFound errors should be silently ignored regardless of message text
expect(MOCK_CONTEXT.emitMcpDiagnostic).not.toHaveBeenCalled();
});
it('should not discover tools if server does not support them', async () => {
const mockedClient = {
connect: vi.fn(),

View File

@@ -27,6 +27,8 @@ import {
ReadResourceResultSchema,
ResourceListChangedNotificationSchema,
ToolListChangedNotificationSchema,
ErrorCode,
McpError,
PromptListChangedNotificationSchema,
ProgressNotificationSchema,
type GetPromptResult,
@@ -1250,6 +1252,10 @@ export async function connectAndDiscover(
}
}
function isMcpMethodNotFoundError(error: unknown): boolean {
return error instanceof McpError && error.code === ErrorCode.MethodNotFound;
}
/**
* Discovers and sanitizes tools from a connected MCP client.
* It retrieves function declarations from the client, filters out disabled tools,
@@ -1329,10 +1335,7 @@ export async function discoverTools(
}
return discoveredTools;
} catch (error) {
if (
error instanceof Error &&
!error.message?.includes('Method not found')
) {
if (!isMcpMethodNotFoundError(error)) {
cliConfig.emitMcpDiagnostic(
'error',
`Error discovering tools from ${mcpServerName}: ${getErrorMessage(
@@ -1456,8 +1459,7 @@ export async function discoverPrompts(
),
}));
} catch (error) {
// It's okay if the method is not found, which is a common case.
if (error instanceof Error && error.message?.includes('Method not found')) {
if (isMcpMethodNotFoundError(error)) {
return [];
}
cliConfig.emitMcpDiagnostic(
@@ -1505,7 +1507,7 @@ async function listResources(
cursor = response.nextCursor ?? undefined;
} while (cursor);
} catch (error) {
if (error instanceof Error && error.message?.includes('Method not found')) {
if (isMcpMethodNotFoundError(error)) {
return [];
}
cliConfig.emitMcpDiagnostic(