import type { Tool } from "@modelcontextprotocol/sdk/types.js";
import { handleListTools } from "../listTools";
import { handleCallTool } from "../callTool";
import { handleListResources } from "../listResources";
import { handleListPrompts } from "../listPrompts";
import { handleGetPrompt } from "../getPrompt";
import { handleReadResource } from "../readResource";
describe("server handlers", () => {
it("lists tools", async () => {
const handler = handleListTools();
const result = await handler({} as never);
expect(result.tools.map((tool: Tool) => tool.name)).toEqual(["readme_summary", "readme_from_git"]);
});
it("lists resources", async () => {
const handler = handleListResources();
const result = await handler({} as never);
expect(result).toEqual({
resources: [
{
uri: "readme://local/current",
name: "Current Directory README",
mimeType: "text/markdown",
},
],
});
});
it("lists prompts", async () => {
const handler = handleListPrompts();
const result = await handler({} as never);
expect(result).toEqual({
prompts: [
{
name: "analyze_readme",
description: "Analyze a README for completeness",
arguments: [{ name: "repo_url", description: "Git repository URL", required: true }],
},
],
});
});
it("summarizes a local README via readme_summary", async () => {
const readFile = jest.fn(async () => "Hello world\n\n# Usage\n\nMore details.");
const handler = handleCallTool({ readFile });
const result = await handler({
params: { name: "readme_summary", arguments: { path: "." } },
} as never);
expect(readFile).toHaveBeenCalledWith(expect.stringMatching(/README\.md$/), "utf8");
const first = result.content[0];
if (first.type !== "text") {
throw new Error("Expected text content");
}
const parsed = JSON.parse(first.text);
expect(parsed.summary).toBe("Hello world");
expect(parsed.key_facts).toEqual(["Usage"]);
});
it("summarizes a remote README via readme_from_git", async () => {
const getReadmeFromGitRepo = jest.fn(async () => "Remote intro\n\n## Install");
const handler = handleCallTool({ getReadmeFromGitRepo });
const result = await handler({
params: { name: "readme_from_git", arguments: { repo_url: "https://example.com/a/b" } },
} as never);
expect(getReadmeFromGitRepo).toHaveBeenCalledWith("https://example.com/a/b");
const first = result.content[0];
if (first.type !== "text") {
throw new Error("Expected text content");
}
const parsed = JSON.parse(first.text);
expect(parsed.summary).toBe("Remote intro");
expect(parsed.key_facts).toEqual(["Install"]);
});
it("throws when an unknown tool is requested", async () => {
const handler = handleCallTool();
await expect(
handler({ params: { name: "unknown_tool", arguments: {} } } as never)
).rejects.toThrow("Unknown tool: unknown_tool");
});
it("throws when a required dependency is missing", () => {
expect(() => handleCallTool({ readFile: undefined })).toThrow(
"Missing required dependency: readFile"
);
});
it("returns the analyze_readme prompt", async () => {
const getReadmeFromGitRepo = jest.fn(async () => "README content");
const handler = handleGetPrompt({ getReadmeFromGitRepo });
const result = await handler({
params: { name: "analyze_readme", arguments: { repo_url: "https://example.com/a/b" } },
} as never);
expect(getReadmeFromGitRepo).toHaveBeenCalledWith("https://example.com/a/b");
const content = result.messages[0].content;
expect(content.type).toBe("text");
if (content.type !== "text") {
throw new Error("Expected text content");
}
expect(content.text).toContain("README content");
});
it("throws when an unknown prompt is requested", async () => {
const handler = handleGetPrompt();
await expect(handler({ params: { name: "unknown", arguments: {} } } as never)).rejects.toThrow(
"Unknown prompt: unknown"
);
});
it("returns README content for the current directory resource", async () => {
const readFile = jest.fn(async () => "# Title\n\nContent");
const handler = handleReadResource({ readFile });
const result = await handler({ params: { uri: "readme://local/current" } } as never);
expect(readFile).toHaveBeenCalledWith(expect.stringMatching(/README\.md$/), "utf8");
expect(result).toEqual({
contents: [
{
uri: "readme://local/current",
mimeType: "text/markdown",
text: "# Title\n\nContent",
},
],
});
});
it("throws for unknown resources", async () => {
const handler = handleReadResource();
await expect(handler({ params: { uri: "readme://local/other" } } as never)).rejects.toThrow(
"Unknown resource: readme://local/other"
);
});
it("throws when readFile dependency is missing", () => {
expect(() => handleReadResource({ readFile: undefined })).toThrow(
"Missing required dependency: readFile"
);
});
});