Skip to content
Merged
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
14 changes: 14 additions & 0 deletions packages/core/src/mcp/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import {
capMcpOutput,
connectAllMcpServers,
connectMcpServer,
expandMcpResourceRefs,
Expand Down Expand Up @@ -442,6 +443,19 @@ describe('parseHelperOutput', () => {
});
});

describe('capMcpOutput', () => {
it('passes through output under the cap', () => {
expect(capMcpOutput('short', 100)).toBe('short');
});
it('truncates over-long output with a notice', () => {
const big = 'x'.repeat(120);
const out = capMcpOutput(big, 100);
expect(out.startsWith('x'.repeat(100))).toBe(true);
expect(out).toMatch(/20 characters truncated/);
expect(out).toMatch(/100-char cap/);
});
});

describe('parseResourceRefs', () => {
it('finds @server:scheme://path references', () => {
const refs = parseResourceRefs(
Expand Down
16 changes: 15 additions & 1 deletion packages/core/src/mcp/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,20 @@ interface FinishableTransport extends Transport {
finishAuth(code: string): Promise<void>;
}

/** Max characters of MCP tool output fed back to the model (keeps a runaway
* server response from blowing the context window). */
export const MCP_OUTPUT_CAP = 50_000;

/** Truncate over-long MCP output with a visible notice. Exported for testing. */
export function capMcpOutput(text: string, cap = MCP_OUTPUT_CAP): string {
if (text.length <= cap) return text;
const omitted = text.length - cap;
return (
text.slice(0, cap) +
`\n\n[… ${omitted} characters truncated — MCP output exceeded the ${cap}-char cap]`
);
}

/**
* Connect to one MCP server (stdio / http / sse). Returns a handle containing
* the registered tools (qualified as `mcp__<server>__<tool>`).
Expand Down Expand Up @@ -264,7 +278,7 @@ export async function connectMcpServer(
.map((c) => c.text ?? '')
.join('\n') || '';
return {
content: textParts || '(MCP tool returned no text content)',
content: textParts ? capMcpOutput(textParts) : '(MCP tool returned no text content)',
isError: result.isError === true,
data: { serverName, serverToolName: t.name },
};
Expand Down
Loading