Skip to main content
Glama
mcp-server.test.ts8.94 kB
/** * Integration tests using MCP client to call the MCP server * Tests both count_files and switch examples via MCP protocol */ import { describe, it, before, after } from "node:test"; import { strict as assert } from "node:assert"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; import { join } from "node:path"; import { fileURLToPath } from "node:url"; import { dirname } from "node:path"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const projectRoot = join(__dirname, ".."); function createClient(configPath: string): { client: Client; transport: StdioClientTransport } { const transport = new StdioClientTransport({ command: "tsx", args: [join(projectRoot, "src", "main.ts"), "-c", configPath], }); const client = new Client( { name: "mcpgraph-test-client", version: "1.0.0", }, { capabilities: {}, } ); return { client, transport }; } describe("MCP server integration", () => { describe("count_files example", () => { let client: Client; let transport: StdioClientTransport; before(async () => { const configPath = join(projectRoot, "examples", "count_files.yaml"); const clientData = createClient(configPath); client = clientData.client; transport = clientData.transport; await client.connect(transport); }); after(async () => { await client.close(); }); it("should list available tools", async () => { const result = await client.listTools(); assert(result !== undefined, "Result should be defined"); assert(result.tools !== undefined, "Result should have tools"); assert(Array.isArray(result.tools), "Tools should be an array"); assert(result.tools.length > 0, "Should have at least one tool"); const countFilesTool = result.tools.find((t) => t.name === "count_files"); assert(countFilesTool !== undefined, "Should have count_files tool"); assert(countFilesTool.description !== undefined, "Tool should have description"); }); it("should count files in the test directory via MCP client", async () => { const testDir = join(projectRoot, "tests", "files"); const result = await client.callTool({ name: "count_files", arguments: { directory: testDir, }, }); assert(result !== undefined, "Result should be defined"); assert(!result.isError, "Result should not be an error"); assert(result.content !== undefined, "Result should have content"); assert(Array.isArray(result.content), "Content should be an array"); assert(result.content.length > 0, "Content should have at least one item"); const textContent = result.content.find((c) => c.type === "text"); assert(textContent !== undefined, "Should have text content"); assert("text" in textContent, "Text content should have text property"); const parsed = JSON.parse(textContent.text as string); assert(parsed !== undefined, "Parsed result should be defined"); assert(typeof parsed === "object", "Parsed result should be an object"); assert("count" in parsed, "Result should have count property"); assert(typeof parsed.count === "number", "Count should be a number"); assert(parsed.count > 0, "Count should be greater than 0"); // Verify structuredContent is present and matches the parsed content assert(result.structuredContent !== undefined, "Result should have structuredContent"); assert(result.structuredContent !== null, "structuredContent should not be null"); assert(typeof result.structuredContent === "object", "structuredContent should be an object"); const structuredContent = result.structuredContent as Record<string, unknown>; assert("count" in structuredContent, "structuredContent should have count property"); assert(typeof structuredContent.count === "number", "structuredContent count should be a number"); assert(structuredContent.count === parsed.count, "structuredContent count should match parsed count"); }); }); describe("switch example", () => { let client: Client; let transport: StdioClientTransport; before(async () => { const configPath = join(projectRoot, "examples", "switch_example.yaml"); const clientData = createClient(configPath); client = clientData.client; transport = clientData.transport; await client.connect(transport); }); after(async () => { await client.close(); }); it("should list available tools", async () => { const result = await client.listTools(); assert(result !== undefined, "Result should be defined"); assert(result.tools !== undefined, "Result should have tools"); assert(Array.isArray(result.tools), "Tools should be an array"); assert(result.tools.length > 0, "Should have at least one tool"); const switchTool = result.tools.find((t) => t.name === "test_switch"); assert(switchTool !== undefined, "Should have test_switch tool"); assert(switchTool.description !== undefined, "Tool should have description"); }); it("should route to high_path when value is greater than 10", async () => { const result = await client.callTool({ name: "test_switch", arguments: { value: 15, }, }); assert(result !== undefined, "Result should be defined"); assert(!result.isError, "Result should not be an error"); assert(result.content !== undefined, "Result should have content"); assert(Array.isArray(result.content), "Content should be an array"); const textContent = result.content.find((c) => c.type === "text"); assert(textContent !== undefined, "Should have text content"); const parsed = JSON.parse((textContent as { text: string }).text); assert(parsed.result === "high", `Expected "high", got "${parsed.result}"`); // Verify structuredContent assert(result.structuredContent !== undefined, "Result should have structuredContent"); const structuredContent = result.structuredContent as Record<string, unknown>; assert(structuredContent.result === "high", "structuredContent should match"); }); it("should route to low_path when value is between 1 and 10", async () => { const result = await client.callTool({ name: "test_switch", arguments: { value: 5, }, }); assert(result !== undefined, "Result should be defined"); assert(!result.isError, "Result should not be an error"); assert(result.content !== undefined, "Result should have content"); assert(Array.isArray(result.content), "Content should be an array"); const textContent = result.content.find((c) => c.type === "text"); assert(textContent !== undefined, "Should have text content"); const parsed = JSON.parse((textContent as { text: string }).text); assert(parsed.result === "low", `Expected "low", got "${parsed.result}"`); }); it("should route to zero_path (default) when value is zero", async () => { const result = await client.callTool({ name: "test_switch", arguments: { value: 0, }, }); assert(result !== undefined, "Result should be defined"); assert(!result.isError, "Result should not be an error"); assert(result.content !== undefined, "Result should have content"); assert(Array.isArray(result.content), "Content should be an array"); const textContent = result.content.find((c) => c.type === "text"); assert(textContent !== undefined, "Should have text content"); const parsed = JSON.parse((textContent as { text: string }).text); assert(parsed.result === "zero_or_negative", `Expected "zero_or_negative", got "${parsed.result}"`); }); it("should route to zero_path (default) when value is negative", async () => { const result = await client.callTool({ name: "test_switch", arguments: { value: -5, }, }); assert(result !== undefined, "Result should be defined"); assert(!result.isError, "Result should not be an error"); assert(result.content !== undefined, "Result should have content"); assert(Array.isArray(result.content), "Content should be an array"); const textContent = result.content.find((c) => c.type === "text"); assert(textContent !== undefined, "Should have text content"); const parsed = JSON.parse((textContent as { text: string }).text); assert(parsed.result === "zero_or_negative", `Expected "zero_or_negative", got "${parsed.result}"`); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TeamSparkAI/mcpGraph'

If you have feedback or need assistance with the MCP directory API, please join our Discord server