mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 03:30:40 +00:00
fix(core): show clear error when MCP server cwd does not exist (#3192)
* fix(core): show clear error when MCP server cwd does not exist Validate that the configured cwd directory exists before spawning the MCP server process. Previously, a non-existent cwd caused Node.js to emit "spawn <cmd> ENOENT" — indistinguishable from the command binary being missing. Now throws a descriptive error naming the server and the missing path. Fixes #3163 * test(core): add test for MCP stdio transport without cwd
This commit is contained in:
parent
9a889dc614
commit
9cdf7bd7c8
2 changed files with 52 additions and 0 deletions
|
|
@ -23,6 +23,11 @@ import {
|
|||
} from './mcp-client.js';
|
||||
import type { ToolRegistry } from './tool-registry.js';
|
||||
|
||||
const mockExistsSync = vi.hoisted(() => vi.fn(() => true));
|
||||
|
||||
vi.mock('node:fs', () => ({
|
||||
existsSync: mockExistsSync,
|
||||
}));
|
||||
vi.mock('@modelcontextprotocol/sdk/client/stdio.js');
|
||||
vi.mock('@modelcontextprotocol/sdk/client/index.js');
|
||||
vi.mock('@google/genai');
|
||||
|
|
@ -289,6 +294,46 @@ describe('mcp-client', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should connect via command without cwd', async () => {
|
||||
const mockedTransport = vi
|
||||
.spyOn(SdkClientStdioLib, 'StdioClientTransport')
|
||||
.mockReturnValue({} as SdkClientStdioLib.StdioClientTransport);
|
||||
|
||||
await createTransport(
|
||||
'test-server',
|
||||
{
|
||||
command: 'test-command',
|
||||
args: ['--foo', 'bar'],
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
expect(mockedTransport).toHaveBeenCalledWith({
|
||||
command: 'test-command',
|
||||
args: ['--foo', 'bar'],
|
||||
cwd: undefined,
|
||||
env: expect.any(Object),
|
||||
stderr: 'pipe',
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw if cwd does not exist', async () => {
|
||||
mockExistsSync.mockReturnValueOnce(false);
|
||||
|
||||
await expect(
|
||||
createTransport(
|
||||
'test-server',
|
||||
{
|
||||
command: 'test-command',
|
||||
cwd: '/nonexistent/path',
|
||||
},
|
||||
false,
|
||||
),
|
||||
).rejects.toThrow(
|
||||
"MCP server 'test-server': configured cwd does not exist: /nonexistent/path",
|
||||
);
|
||||
});
|
||||
|
||||
describe('useGoogleCredentialProvider', () => {
|
||||
it('should use GoogleCredentialProvider when specified', async () => {
|
||||
const transport = await createTransport(
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import { SdkControlClientTransport } from './sdk-control-client-transport.js';
|
|||
|
||||
import type { FunctionDeclaration } from '@google/genai';
|
||||
import { mcpToTool } from '@google/genai';
|
||||
import { existsSync } from 'node:fs';
|
||||
import { basename } from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { MCPOAuthProvider } from '../mcp/oauth-provider.js';
|
||||
|
|
@ -1402,6 +1403,12 @@ export async function createTransport(
|
|||
}
|
||||
|
||||
if (mcpServerConfig.command) {
|
||||
if (mcpServerConfig.cwd && !existsSync(mcpServerConfig.cwd)) {
|
||||
throw new Error(
|
||||
`MCP server '${mcpServerName}': configured cwd does not exist: ${mcpServerConfig.cwd}`,
|
||||
);
|
||||
}
|
||||
|
||||
const transport = new StdioClientTransport({
|
||||
command: mcpServerConfig.command,
|
||||
args: mcpServerConfig.args || [],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue