smithery.ai

mcp-testing

MCP Testing Strategies with Vitest, Inspector, and Integration Tests

First seen Mar 19, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,277 B
  • docs SUMMARY.md 87 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

MCP Testing Skill

Modern testing strategies for Model Context Protocol (MCP) servers developed in VS Code using TypeScript, Bun, and Vitest.

Unit Testing with Vitest & In-Memory Transport

Setup Minimal Test Environment

import { describe, it, expect, beforeEach } from "vitest";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { InMemoryTransport } from "@modelcontextprotocol/sdk/testing/inMemoryTransport.js";
import { RaindropMCPService } from "../src/services/raindropmcp.service.js";

describe("RaindropMCPService Tools", () => {
  let service: RaindropMCPService;
  let transport: InMemoryTransport;
  let client: Client;

  beforeEach(async () => {
    service = new RaindropMCPService();
    transport = new InMemoryTransport(service.getServer());
    client = new Client(
      {
        name: "test-client",
        version: "1.0.0",
      },
      { capabilities: {} },
    );
    await client.connect(transport);
  });

  it("should list available tools", async () => {
    const tools = await client.listTools();
    expect(tools.tools.length).toBeGreaterThan(0);
    expect(tools.tools.map((t) => t.name)).toContain("collection_list");
  });

  it("should call a tool with valid input", async () => {
    const result = await client.callTool({
      name: "collection_list",
      arguments: {},
    });
    expect(result).toBeDefined();
    expect(result.content).toBeDefined();
  });
});

Key Testing Patterns

  1. In-Memory Transport: Use for unit tests—no subprocess overhead, direct method invocation
  2. Server Capabilities: Verify manifest before running tool tests
  3. Mock Context: Provide mock RaindropService for isolated tool testing
  4. Error Handling: Test both success and error paths with Zod validation

Integration Testing with MCP Inspector

Launch Inspector in VS Code

  1. Terminal > Run Task > "Debug HTTP Server with Inspector" (or STDIO variant)

- Opens Inspector at http://localhost:3000 (or via auto-opened browser) - Live tool/resource exploration with bidirectional message capture

  1. Manual Inspection Flow:

- Call diagnostics tool → view server version and enabled tools - Call collection_list → see resource links to collections - Read collection resources by URI → validate dynamic resource handling - Test tool inputs directly with Inspector's form interface

  1. Record & Replay:

- Inspector logs all requests/responses - Copy test cases directly into Vitest from Inspector logs - Validate against snapshot tests

Snapshot Testing for Tool Schemas

import { describe, it, expect } from "vitest";
import { RaindropMCPService } from "../src/services/raindropmcp.service.js";

describe("Tool Schema Snapshots", () => {
  let service: RaindropMCPService;

  beforeEach(() => {
    service = new RaindropMCPService();
  });

  it("should maintain consistent tool schemas", async () => {
    const tools = await service.listTools();
    expect(tools).toMatchSnapshot();
  });
});

Why Snapshot Testing?

  • Catches unintended schema changes (breaking for LLM clients)
  • Auto-generates golden files for schema validation
  • Reduces boilerplate when verifying complex schemas

Running Tests in VS Code

Run Tests with Coverage

bun run test:coverage

Generates coverage reports showing:

  • Line & branch coverage for tools
  • Uncovered error paths
  • Integration test coverage vs unit test coverage

Watch Mode During Development

bun test --watch
  • Re-runs tests on file changes
  • Ideal for TDD workflows
  • Vitest provides formatted output in terminal

Load & Performance Testing

Stress Test Tools with Concurrency

it("should handle concurrent tool calls", async () => {
  const promises = Array.from({ length: 10 }, () =>
    client.callTool({
      name: "collection_list",
      arguments: {},
    }),
  );

  const results = await Promise.all(promises);
  expect(results).toHaveLength(10);
  expect(results.every((r) => r.content)).toBe(true);
});

Measure Tool Latency

it("should respond within acceptable latency", async () => {
  const start = performance.now();
  await client.callTool({
    name: "bookmark_search",
    arguments: { search: "test" },
  });
  const duration = performance.now() - start;

  expect(duration).toBeLessThan(5000); // 5s timeout for API calls
});

Resource Testing

Test Dynamic Resource Resolution

it("should fetch and validate collection resources", async () => {
  const resources = await client.listResources();
  const collectionPattern = resources.resources.find((r) =>
    r.uri.includes("mcp://collection/"),
  );

  expect(collectionPattern).toBeDefined();

  // Read a specific collection
  const resourceData = await client.readResource({
    uri: "mcp://collection/12345",
  });

  expect(resourceData).toBeDefined();
  expect(Array.isArray(resourceData)).toBe(true);
  expect(resourceData[0].text).toBeDefined();
});

Test Error Conditions

it("should handle invalid resource URIs gracefully", async () => {
  expect(async () => {
    await client.readResource({ uri: "mcp://invalid/xyz" });
  }).rejects.toThrow();
});

Recommended Dev Dependencies

Testing & Quality

{
  "devDependencies": {
    "vitest": "^4.0.0",
    "@vitest/coverage-v8": "^1.0.0",
    "@vitest/ui": "^1.0.0",
    "happy-dom": "^13.0.0"
  }
}

Code Quality & Linting

{
  "devDependencies": {
    "eslint": "^9.0.0",
    "@typescript-eslint/eslint-plugin": "^8.0.0",
    "@typescript-eslint/parser": "^8.0.0",
    "eslint-config-prettier": "^9.0.0",
    "prettier": "^3.0.0"
  }
}

Debugging & Inspection

{
  "devDependencies": {
    "@modelcontextprotocol/inspector": "^1.0.0"
  }
}

References