Skip to content

Commit 82d0dd3

Browse files
author
Griffin Evans
committed
Add better error message for stdio mcp connection failure
1 parent c06be30 commit 82d0dd3

2 files changed

Lines changed: 41 additions & 8 deletions

File tree

packages/plugins/mcp/src/sdk/connection.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,19 +177,25 @@ const connectionFromClient = (client: Client): McpConnection => ({
177177
close: () => client.close(),
178178
});
179179

180-
const connectionFailure = (
181-
transport: string,
182-
message: string,
183-
cause: unknown,
184-
): McpConnectionError | McpOAuthReauthorizationRequired => {
185-
if (Predicate.isTagged(cause, "McpOAuthReauthorizationRequired")) {
180+
const connectionFailure = (input: {
181+
readonly transport: string;
182+
readonly message: string;
183+
readonly cause: unknown;
184+
readonly command?: string;
185+
}): McpConnectionError | McpOAuthReauthorizationRequired => {
186+
if (Predicate.isTagged(input.cause, "McpOAuthReauthorizationRequired")) {
186187
return new McpOAuthReauthorizationRequired({ message: "MCP OAuth re-authorization required" });
187188
}
188-
return new McpConnectionError({ transport, message });
189+
const message =
190+
input.transport === "stdio" && input.command !== undefined
191+
? `Could not connect to stdio MCP server using "${input.command}"`
192+
: input.message;
193+
return new McpConnectionError({ transport: input.transport, message });
189194
};
190195

191196
const connectClient = (input: {
192197
transport: string;
198+
command?: string;
193199
createTransport: () => Parameters<Client["connect"]>[0];
194200
}): Effect.Effect<McpConnection, McpConnectionError | McpOAuthReauthorizationRequired> =>
195201
Effect.gen(function* () {
@@ -199,7 +205,12 @@ const connectClient = (input: {
199205
yield* Effect.tryPromise({
200206
try: () => client.connect(transportInstance),
201207
catch: (cause) =>
202-
connectionFailure(input.transport, `Failed connecting via ${input.transport}`, cause),
208+
connectionFailure({
209+
transport: input.transport,
210+
command: input.command,
211+
message: `Failed connecting via ${input.transport}`,
212+
cause,
213+
}),
203214
}).pipe(
204215
Effect.withSpan("plugin.mcp.connection.handshake", {
205216
attributes: { "plugin.mcp.transport": input.transport },
@@ -239,6 +250,7 @@ export const createMcpConnector = (input: ConnectorInput): McpConnector => {
239250

240251
return yield* connectClient({
241252
transport: "stdio",
253+
command: [command, ...(input.args ?? [])].join(" "),
242254
createTransport: () =>
243255
createStdioTransport({
244256
command,

packages/plugins/mcp/src/sdk/plugin.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,22 @@ describe("mcpPlugin", () => {
366366
}),
367367
);
368368

369+
it.effect("reports a clear stdio startup failure message", () =>
370+
Effect.gen(function* () {
371+
const error = yield* createMcpConnector({
372+
transport: "stdio",
373+
command: "__executor_missing_stdio_command__",
374+
args: ["--flag"],
375+
}).pipe(Effect.flip);
376+
377+
expect(error).toMatchObject({
378+
_tag: "McpConnectionError",
379+
message:
380+
'Could not connect to stdio MCP server using "__executor_missing_stdio_command__ --flag"',
381+
});
382+
}),
383+
);
384+
369385
it.effect("integration catalog has no configured MCP integrations initially", () =>
370386
Effect.gen(function* () {
371387
const executor = yield* createExecutor(makeTestConfig({ plugins: [mcpPlugin()] as const }));
@@ -615,6 +631,11 @@ describe("mcpPlugin", () => {
615631
}),
616632
);
617633
expect(Result.isFailure(result)).toBe(true);
634+
const failure = Result.isFailure(result) ? result.failure : null;
635+
expect(failure).toMatchObject({
636+
_tag: "McpToolDiscoveryError",
637+
message: `Failed connecting to MCP server: Could not connect to stdio MCP server using "${Path.join(fixture.dir, "missing-command")}"`,
638+
});
618639

619640
const integration = yield* executor.mcp.getServer("stdio_invalid");
620641
expect(integration?.config).toMatchObject({

0 commit comments

Comments
 (0)