fix: MCP proxy resilience — discovery cache, default liveness probes
Some checks failed
Some checks failed
Adds a per-server tools/list cache in McpRouter (positive + negative TTL) so a slow or dead upstream only stalls the first discovery call, not every subsequent client request. Invalidated on upstream add/remove. Health probes now apply a default liveness spec (tools/list via the real production path) to any RUNNING instance without an explicit healthCheck, so synthetic and real failures converge on the same signal. Includes supporting updates in mcpd-client, discovery, upstream/mcpd, seeder, and fulldeploy/release scripts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -107,4 +107,38 @@ describe('McpdUpstream', () => {
|
||||
const response = await upstream.send(request);
|
||||
expect(response.error).toEqual({ code: -32601, message: 'Tool not found' });
|
||||
});
|
||||
|
||||
it('routes */list methods through discoveryClient when provided', async () => {
|
||||
const mainClient = mockMcpdClient();
|
||||
const discoveryClient = mockMcpdClient(new Map([
|
||||
['srv-1:tools/list', { result: { tools: [] } }],
|
||||
['srv-1:resources/list', { result: { resources: [] } }],
|
||||
['srv-1:prompts/list', { result: { prompts: [] } }],
|
||||
]));
|
||||
|
||||
const upstream = new McpdUpstream('srv-1', 'slack', mainClient as any, undefined, discoveryClient as any);
|
||||
|
||||
await upstream.send({ jsonrpc: '2.0', id: '1', method: 'tools/list' });
|
||||
await upstream.send({ jsonrpc: '2.0', id: '2', method: 'resources/list' });
|
||||
await upstream.send({ jsonrpc: '2.0', id: '3', method: 'prompts/list' });
|
||||
|
||||
expect(discoveryClient.post).toHaveBeenCalledTimes(3);
|
||||
expect(mainClient.post).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('routes tools/call through mainClient even when discoveryClient is set', async () => {
|
||||
const mainClient = mockMcpdClient(new Map([
|
||||
['srv-1:tools/call', { result: { ok: true } }],
|
||||
]));
|
||||
const discoveryClient = mockMcpdClient();
|
||||
|
||||
const upstream = new McpdUpstream('srv-1', 'slack', mainClient as any, undefined, discoveryClient as any);
|
||||
await upstream.send({
|
||||
jsonrpc: '2.0', id: '1', method: 'tools/call',
|
||||
params: { name: 'noop', arguments: {} },
|
||||
});
|
||||
|
||||
expect(mainClient.post).toHaveBeenCalledTimes(1);
|
||||
expect(discoveryClient.post).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user