Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/acp-mcp-optional-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Fix ACP MCP server conversion when optional headers or environment variables are omitted.
8 changes: 4 additions & 4 deletions packages/acp-adapter/src/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,17 @@ function acpMcpServerToConfig(
}

function headersArrayToRecord(
headers: ReadonlyArray<{ readonly name: string; readonly value: string }>,
headers: ReadonlyArray<{ readonly name: string; readonly value: string }> | undefined,
): Record<string, string> {
const out: Record<string, string> = {};
for (const h of headers) out[h.name] = h.value;
for (const h of headers ?? []) out[h.name] = h.value;
return out;
}

function envArrayToRecord(
env: ReadonlyArray<{ readonly name: string; readonly value: string }>,
env: ReadonlyArray<{ readonly name: string; readonly value: string }> | undefined,
): Record<string, string> {
const out: Record<string, string> = {};
for (const e of env) out[e.name] = e.value;
for (const e of env ?? []) out[e.name] = e.value;
return out;
}
47 changes: 47 additions & 0 deletions packages/acp-adapter/test/mcp-forward.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,34 @@ describe('acpMcpServersToConfigs', () => {
expect(warnSpy).not.toHaveBeenCalled();
});

it('converts HTTP and SSE servers without headers', () => {
const out = acpMcpServersToConfigs([
{
type: 'http',
name: 'docs',
url: 'https://mcp.example.com',
} as unknown as McpServer,
{
type: 'sse',
name: 'events',
url: 'https://stream.example.com',
} as unknown as McpServer,
]);
expect(out).toEqual({
docs: {
transport: 'http',
url: 'https://mcp.example.com',
headers: {},
},
events: {
transport: 'sse',
url: 'https://stream.example.com',
headers: {},
},
});
expect(warnSpy).not.toHaveBeenCalled();
});

it('converts a stdio server with args + env to a Record keyed by name', () => {
const out = acpMcpServersToConfigs([
stdioServer(
Expand All @@ -192,6 +220,25 @@ describe('acpMcpServersToConfigs', () => {
expect(warnSpy).not.toHaveBeenCalled();
});

it('converts a stdio server without env', () => {
const out = acpMcpServersToConfigs([
{
name: 'fs',
command: '/usr/local/bin/mcp-fs',
args: ['--root', '/tmp'],
} as unknown as McpServer,
]);
expect(out).toEqual({
fs: {
transport: 'stdio',
command: '/usr/local/bin/mcp-fs',
args: ['--root', '/tmp'],
env: {},
},
});
expect(warnSpy).not.toHaveBeenCalled();
});

it('converts an SSE server with headers to a Record keyed by name', () => {
const out = acpMcpServersToConfigs([
sseServer('events', 'https://stream.example.com', [{ name: 'X-K', value: 'V' }]),
Expand Down