Skip to content

Commit 676a079

Browse files
committed
harden: test resolveMcpInitializeInstructions override path
Extract instructions resolver from runMcpServer so CodeRabbit fix has regression coverage without stdio integration harness.
1 parent 7a2065f commit 676a079

2 files changed

Lines changed: 39 additions & 17 deletions

File tree

src/application/mcp-server.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ import { initCodemap } from "../runtime";
2424
import { installCodemapTestTeardown } from "../test-helpers/runtime-reset";
2525
import { assembleMcpInstructions } from "./agent-content";
2626
import { buildMcpInstructionsCodebaseMapAppendix } from "./context-engine";
27-
import { createMcpServer } from "./mcp-server";
27+
import {
28+
createMcpServer,
29+
resolveMcpInitializeInstructions,
30+
} from "./mcp-server";
2831
import { MCP_TOOL_NAMES } from "./mcp-tool-allowlist";
2932
import { MCP_TOOL_ANNOTATIONS } from "./mcp-tool-annotations";
3033

@@ -94,6 +97,20 @@ describe("MCP server — initialize instructions", () => {
9497
}
9598
});
9699

100+
it("resolveMcpInitializeInstructions honors caller-provided instructions", async () => {
101+
const custom = "custom-mcp-instructions\n";
102+
const resolved = await resolveMcpInitializeInstructions({
103+
instructions: custom,
104+
});
105+
expect(resolved).toBe(custom);
106+
});
107+
108+
it("resolveMcpInitializeInstructions assembles codebase map appendix by default", async () => {
109+
const resolved = await resolveMcpInitializeInstructions({});
110+
expect(resolved).toContain("map_id:");
111+
expect(resolved).toContain("Session start");
112+
});
113+
97114
it("can append codebase map block to initialize instructions", async () => {
98115
const db = openDb();
99116
let appendix: string;

src/application/mcp-server.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,26 @@ async function bootstrapForMcp(opts: ServerOpts): Promise<void> {
644644
configureResolver(getProjectRoot(), getTsconfigPath());
645645
}
646646

647+
/** Initialize `instructions` for `runMcpServer` — honors `opts.instructions` when set. */
648+
export async function resolveMcpInitializeInstructions(
649+
opts: Pick<ServerOpts, "instructions">,
650+
): Promise<string> {
651+
if (opts.instructions !== undefined) return opts.instructions;
652+
try {
653+
const { openDb, closeDb } = await import("../db");
654+
const db = openDb();
655+
try {
656+
return assembleMcpInstructions(
657+
buildMcpInstructionsCodebaseMapAppendix(db, getProjectRoot()),
658+
);
659+
} finally {
660+
closeDb(db, { readonly: true });
661+
}
662+
} catch {
663+
return assembleMcpInstructions();
664+
}
665+
}
666+
647667
/**
648668
* Starts the MCP server over stdio. Resolves on client disconnect
649669
* (`session-lifecycle.ts`). Logs to stderr per MCP convention.
@@ -681,22 +701,7 @@ export async function runMcpServer(opts: ServerOpts): Promise<void> {
681701
await watchSession.acquireClient();
682702
}
683703

684-
let instructions = opts.instructions;
685-
if (instructions === undefined) {
686-
try {
687-
const { openDb, closeDb } = await import("../db");
688-
const db = openDb();
689-
try {
690-
instructions = assembleMcpInstructions(
691-
buildMcpInstructionsCodebaseMapAppendix(db, getProjectRoot()),
692-
);
693-
} finally {
694-
closeDb(db, { readonly: true });
695-
}
696-
} catch {
697-
instructions = assembleMcpInstructions();
698-
}
699-
}
704+
const instructions = await resolveMcpInitializeInstructions(opts);
700705

701706
const server = createMcpServer({ ...opts, instructions });
702707
const transport = new StdioServerTransport();

0 commit comments

Comments
 (0)