fix: STDIO transport stdout flush and MCP notification handling
- Wait for stdout.write callback before process.exit in STDIO transport to prevent truncation of large responses (e.g. grafana tools/list) - Handle MCP notification methods (notifications/initialized, etc.) in router instead of returning "Method not found" error - Use -p shorthand in config claude output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,7 +98,7 @@ export function createConfigCommand(deps?: Partial<ConfigCommandDeps>, apiDeps?:
|
|||||||
mcpServers: {
|
mcpServers: {
|
||||||
[opts.project]: {
|
[opts.project]: {
|
||||||
command: 'mcpctl',
|
command: 'mcpctl',
|
||||||
args: ['mcp', '--project', opts.project],
|
args: ['mcp', '-p', opts.project],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ describe('config claude', () => {
|
|||||||
const written = JSON.parse(readFileSync(outPath, 'utf-8'));
|
const written = JSON.parse(readFileSync(outPath, 'utf-8'));
|
||||||
expect(written.mcpServers['homeautomation']).toEqual({
|
expect(written.mcpServers['homeautomation']).toEqual({
|
||||||
command: 'mcpctl',
|
command: 'mcpctl',
|
||||||
args: ['mcp', '--project', 'homeautomation'],
|
args: ['mcp', '-p', 'homeautomation'],
|
||||||
});
|
});
|
||||||
expect(output.join('\n')).toContain('1 server(s)');
|
expect(output.join('\n')).toContain('1 server(s)');
|
||||||
});
|
});
|
||||||
@@ -60,7 +60,7 @@ describe('config claude', () => {
|
|||||||
const parsed = JSON.parse(output[0]);
|
const parsed = JSON.parse(output[0]);
|
||||||
expect(parsed.mcpServers['myproj']).toEqual({
|
expect(parsed.mcpServers['myproj']).toEqual({
|
||||||
command: 'mcpctl',
|
command: 'mcpctl',
|
||||||
args: ['mcp', '--project', 'myproj'],
|
args: ['mcp', '-p', 'myproj'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ describe('config claude', () => {
|
|||||||
expect(written.mcpServers['existing--server']).toBeDefined();
|
expect(written.mcpServers['existing--server']).toBeDefined();
|
||||||
expect(written.mcpServers['proj-1']).toEqual({
|
expect(written.mcpServers['proj-1']).toEqual({
|
||||||
command: 'mcpctl',
|
command: 'mcpctl',
|
||||||
args: ['mcp', '--project', 'proj-1'],
|
args: ['mcp', '-p', 'proj-1'],
|
||||||
});
|
});
|
||||||
expect(output.join('\n')).toContain('2 server(s)');
|
expect(output.join('\n')).toContain('2 server(s)');
|
||||||
});
|
});
|
||||||
@@ -96,7 +96,7 @@ describe('config claude', () => {
|
|||||||
const written = JSON.parse(readFileSync(outPath, 'utf-8'));
|
const written = JSON.parse(readFileSync(outPath, 'utf-8'));
|
||||||
expect(written.mcpServers['proj-1']).toEqual({
|
expect(written.mcpServers['proj-1']).toEqual({
|
||||||
command: 'mcpctl',
|
command: 'mcpctl',
|
||||||
args: ['mcp', '--project', 'proj-1'],
|
args: ['mcp', '-p', 'proj-1'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -61,9 +61,10 @@ proc.stdout.on('data', d => {
|
|||||||
const msg = JSON.parse(line);
|
const msg = JSON.parse(line);
|
||||||
if (msg.id === 2) {
|
if (msg.id === 2) {
|
||||||
responded = true;
|
responded = true;
|
||||||
process.stdout.write(JSON.stringify(msg));
|
process.stdout.write(JSON.stringify(msg), () => {
|
||||||
proc.kill();
|
proc.kill();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,6 +367,17 @@ export class McpRouter {
|
|||||||
case 'prompts/get':
|
case 'prompts/get':
|
||||||
return this.routeNamespacedCall(request, 'name', this.promptToServer);
|
return this.routeNamespacedCall(request, 'name', this.promptToServer);
|
||||||
|
|
||||||
|
// Handle MCP notifications (no response expected, but return empty result if called as request)
|
||||||
|
case 'notifications/initialized':
|
||||||
|
case 'notifications/cancelled':
|
||||||
|
case 'notifications/progress':
|
||||||
|
case 'notifications/roots/list_changed':
|
||||||
|
return {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
id: request.id,
|
||||||
|
result: {},
|
||||||
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
|
|||||||
Reference in New Issue
Block a user