Update MCP client to connect to servers with only prompts (#5290)
This commit is contained in:
parent
93f8fe3671
commit
99ba2f6424
|
@ -212,9 +212,9 @@ describe('mcpCommand', () => {
|
|||
);
|
||||
expect(message).toContain('server2_tool1');
|
||||
|
||||
// Server 3 - Disconnected
|
||||
// Server 3 - Disconnected but with cached tools, so shows as Ready
|
||||
expect(message).toContain(
|
||||
'🔴 \u001b[1mserver3\u001b[0m - Disconnected (1 tools cached)',
|
||||
'🟢 \u001b[1mserver3\u001b[0m - Ready (1 tool)',
|
||||
);
|
||||
expect(message).toContain('server3_tool1');
|
||||
|
||||
|
|
|
@ -94,7 +94,15 @@ const getMcpStatus = async (
|
|||
const promptRegistry = await config.getPromptRegistry();
|
||||
const serverPrompts = promptRegistry.getPromptsByServer(serverName) || [];
|
||||
|
||||
const status = getMCPServerStatus(serverName);
|
||||
const originalStatus = getMCPServerStatus(serverName);
|
||||
const hasCachedItems = serverTools.length > 0 || serverPrompts.length > 0;
|
||||
|
||||
// If the server is "disconnected" but has prompts or cached tools, display it as Ready
|
||||
// by using CONNECTED as the display status.
|
||||
const status =
|
||||
originalStatus === MCPServerStatus.DISCONNECTED && hasCachedItems
|
||||
? MCPServerStatus.CONNECTED
|
||||
: originalStatus;
|
||||
|
||||
// Add status indicator with descriptive text
|
||||
let statusIndicator = '';
|
||||
|
@ -260,11 +268,14 @@ const getMcpStatus = async (
|
|||
message += ' No tools or prompts available\n';
|
||||
} else if (serverTools.length === 0) {
|
||||
message += ' No tools available';
|
||||
if (status === MCPServerStatus.DISCONNECTED && needsAuthHint) {
|
||||
if (originalStatus === MCPServerStatus.DISCONNECTED && needsAuthHint) {
|
||||
message += ` ${COLOR_GREY}(type: "/mcp auth ${serverName}" to authenticate this server)${RESET_COLOR}`;
|
||||
}
|
||||
message += '\n';
|
||||
} else if (status === MCPServerStatus.DISCONNECTED && needsAuthHint) {
|
||||
} else if (
|
||||
originalStatus === MCPServerStatus.DISCONNECTED &&
|
||||
needsAuthHint
|
||||
) {
|
||||
// This case is for when serverTools.length > 0
|
||||
message += ` ${COLOR_GREY}(type: "/mcp auth ${serverName}" to authenticate this server)${RESET_COLOR}\n`;
|
||||
}
|
||||
|
|
|
@ -366,33 +366,47 @@ export async function connectAndDiscover(
|
|||
): Promise<void> {
|
||||
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING);
|
||||
|
||||
let mcpClient: Client | undefined;
|
||||
try {
|
||||
const mcpClient = await connectToMcpServer(
|
||||
mcpClient = await connectToMcpServer(
|
||||
mcpServerName,
|
||||
mcpServerConfig,
|
||||
debugMode,
|
||||
);
|
||||
try {
|
||||
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTED);
|
||||
mcpClient.onerror = (error) => {
|
||||
console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
|
||||
updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
|
||||
};
|
||||
await discoverPrompts(mcpServerName, mcpClient, promptRegistry);
|
||||
|
||||
const tools = await discoverTools(
|
||||
mcpServerName,
|
||||
mcpServerConfig,
|
||||
mcpClient,
|
||||
);
|
||||
for (const tool of tools) {
|
||||
toolRegistry.registerTool(tool);
|
||||
}
|
||||
} catch (error) {
|
||||
mcpClient.close();
|
||||
throw error;
|
||||
mcpClient.onerror = (error) => {
|
||||
console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
|
||||
updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
|
||||
};
|
||||
|
||||
// Attempt to discover both prompts and tools
|
||||
const prompts = await discoverPrompts(
|
||||
mcpServerName,
|
||||
mcpClient,
|
||||
promptRegistry,
|
||||
);
|
||||
const tools = await discoverTools(
|
||||
mcpServerName,
|
||||
mcpServerConfig,
|
||||
mcpClient,
|
||||
);
|
||||
|
||||
// If we have neither prompts nor tools, it's a failed discovery
|
||||
if (prompts.length === 0 && tools.length === 0) {
|
||||
throw new Error('No prompts or tools found on the server.');
|
||||
}
|
||||
|
||||
// If we found anything, the server is connected
|
||||
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTED);
|
||||
|
||||
// Register any discovered tools
|
||||
for (const tool of tools) {
|
||||
toolRegistry.registerTool(tool);
|
||||
}
|
||||
} catch (error) {
|
||||
if (mcpClient) {
|
||||
mcpClient.close();
|
||||
}
|
||||
console.error(
|
||||
`Error connecting to MCP server '${mcpServerName}': ${getErrorMessage(
|
||||
error,
|
||||
|
@ -423,7 +437,8 @@ export async function discoverTools(
|
|||
const tool = await mcpCallableTool.tool();
|
||||
|
||||
if (!Array.isArray(tool.functionDeclarations)) {
|
||||
throw new Error(`Server did not return valid function declarations.`);
|
||||
// This is a valid case for a prompt-only server
|
||||
return [];
|
||||
}
|
||||
|
||||
const discoveredTools: DiscoveredMCPTool[] = [];
|
||||
|
@ -454,7 +469,17 @@ export async function discoverTools(
|
|||
}
|
||||
return discoveredTools;
|
||||
} catch (error) {
|
||||
throw new Error(`Error discovering tools: ${error}`);
|
||||
if (
|
||||
error instanceof Error &&
|
||||
!error.message?.includes('Method not found')
|
||||
) {
|
||||
console.error(
|
||||
`Error discovering tools from ${mcpServerName}: ${getErrorMessage(
|
||||
error,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,7 +494,7 @@ export async function discoverPrompts(
|
|||
mcpServerName: string,
|
||||
mcpClient: Client,
|
||||
promptRegistry: PromptRegistry,
|
||||
): Promise<void> {
|
||||
): Promise<Prompt[]> {
|
||||
try {
|
||||
const response = await mcpClient.request(
|
||||
{ method: 'prompts/list', params: {} },
|
||||
|
@ -484,6 +509,7 @@ export async function discoverPrompts(
|
|||
invokeMcpPrompt(mcpServerName, mcpClient, prompt.name, params),
|
||||
});
|
||||
}
|
||||
return response.prompts;
|
||||
} catch (error) {
|
||||
// It's okay if this fails, not all servers will have prompts.
|
||||
// Don't log an error if the method is not found, which is a common case.
|
||||
|
@ -497,6 +523,7 @@ export async function discoverPrompts(
|
|||
)}`,
|
||||
);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue