# MCP Testing Strategy - Executive Summary
## Question Answered
**"Are there better frameworks for MCP testing than Vitest? What about helper libraries for automated testing?"**
### Short Answer
**No, Vitest is the official recommendation.** But here's what's better:
✅ **Keep:** Vitest + InMemoryTransport + MCP Inspector
⏳ **Add:** Supertest for HTTP endpoint testing (5-min install)
❌ **Skip:** Anything else (not yet mature in MCP ecosystem)
---
## The MCP Testing Reality (2024)
| Testing Need | Solution | Status | Your Project |
| -------------------- | ----------------------------------- | ---------------- | ---------------- |
| Unit testing tools | Vitest + mocks | Stable | ✅ Already using |
| Protocol testing | InMemoryTransport | Official | ✅ Already using |
| Manual validation | MCP Inspector | Official | ✅ Already using |
| HTTP testing | Supertest | Proven (Node.js) | ⏳ Add this |
| Advanced mocking | vitest-mock-extended | Optional | ❌ Skip for now |
| Performance testing | autocannon | Optional | ❌ Skip for now |
| MCP-specific helpers | None exist yet | N/A | N/A |
| v2 test config | @modelcontextprotocol/vitest-config | Pre-alpha | ⏳ Wait for v2 |
**Bottom line:** You already have the best setup. Supertest is the only worthwhile addition.
---
## Why No "MCP-Specific" Testing Framework?
1. **MCP is Protocol-Based** - Uses standard JSON-RPC, works with any HTTP client
2. **Framework Agnostic** - Works with Vitest, Jest, Mocha, etc.
3. **Young Ecosystem** - No community testing helpers yet (Anthropic focused on core SDK)
4. **Generic Tools Work Better** - InMemoryTransport is more elegant than custom helpers
**Expectation:** As MCP adoption grows (2025+), expect:
- @modelcontextprotocol/testing-utils (might materialize)
- Vitest plugin for MCP (low priority)
- Community testing helpers (possibly)
---
## What You Already Have (And Why It's Great)
### 1. Vitest
- ✅ Fastest test runner (Bun-native, ESM-first)
- ✅ Similar to Jest but modern
- ✅ Built for TypeScript
- ✅ Zero config with your setup
**Result:** Tests run in 10-100ms. Perfect.
### 2. InMemoryTransport
- ✅ Direct client/server connection (no network)
- ✅ Built into official SDK
- ✅ Deterministic, debuggable
- ✅ Tests real MCP protocol
**Result:** Can test all MCP operations without subprocess overhead.
### 3. MCP Inspector
- ✅ Official Anthropic tool
- ✅ Visual request/response inspection
- ✅ Schema browser
- ✅ Record & replay
**Result:** Perfect for interactive testing during development.
---
## What's Missing (And Why Supertest Helps)
### Current Gap: HTTP Testing
Your HTTP server (`src/server.ts`) handles:
- POST /mcp (JSON-RPC over HTTP)
- SSE /mcp (streaming responses)
- Custom Host header validation (DNS rebinding)
- Error handling
**InMemoryTransport tests the MCP protocol, NOT the HTTP layer.**
**Problem:** What if your HTTP request handler has a bug?
- Wrong status code
- Incorrect Host header validation
- SSE connection issues
- Middleware ordering
**Solution:** Supertest tests HTTP behavior directly:
```typescript
const res = await request(server)
.post("/mcp")
.set("Host", "evil.com") // Test Host validation
.send({
/* MCP request */
})
.expect(403); // Verify DNS rebinding works
```
**Install:** `bun add -D supertest @types/supertest` (30 seconds)
---
## Testing Pyramid for Raindrop MCP
```
/\
/ \ Integration (10%)
/ \ HTTP server responses
/------\
/ \ Contract (30%)
/ \ MCP protocol (InMemoryTransport)
/-----------\
/ \ Unit (60%)
/ \ Tool handlers, Raindrop API calls
/----------------\
```
### Unit Tests (60%) - You Have This ✓
```typescript
// tests/unit/tools/collections.test.ts
test('collection_list returns formatted data', async () => {
const mock = { getCollections: () => [...] };
const result = await handleCollectionList({}, { raindropService: mock });
expect(result).toBeDefined();
});
```
### Contract Tests (30%) - You Have This ✓
```typescript
// tests/integration/mcp.test.ts
test("MCP protocol returns tools", async () => {
const transport = new InMemoryTransport(service);
const client = new Client({}, {});
await client.connect(transport);
const tools = await client.listTools();
expect(tools.tools).toBeDefined();
});
```
### Integration Tests (10%) - **You Need This** ⏳
```typescript
// tests/integration/http-server.test.ts
test('POST /mcp responds with correct status', async () => {
const res = await request(server)
.post('/mcp')
.set('Host', 'localhost')
.send({...});
expect(res.status).toBe(200);
});
```
---
## Implementation Roadmap
### Phase 0 (Right Now) ✅
- Review existing tests (18/28 passing)
- Understand what's already covered
### Phase 1 (10 minutes) ⏳
```bash
bun add -D supertest @types/supertest
```
Add HTTP server tests (see `http-server-testing-supertest.md`)
### Phase 2 (Optional, 30 minutes)
- Expand InMemoryTransport coverage
- Add snapshot tests for tool schemas
- Document test patterns for future contributors
### Phase 3 (Wait for MCP v2)
- Adopt @modelcontextprotocol/vitest-config (when stable)
- Migrate to middleware components if beneficial
---
## File References
📄 **Detailed Guides Created:**
1. `.github/instructions/mcp-testing-frameworks.md` - Full analysis, best practices, examples
2. `.github/instructions/http-server-testing-supertest.md` - Implementation guide with code
3. This document - Executive summary
---
## Answers to Your Specific Questions
**Q: "Are there better frameworks for MCP testing than Vitest?"**
A: No. Vitest is the standard. Jest and Mocha are older, Playwright/Cypress are for UI. Vitest is correct.
**Q: "What about helper libraries for automated testing?"**
A:
- ✅ InMemoryTransport (official SDK) - Best for MCP protocol
- ✅ Supertest (proven Node.js library) - Best for HTTP layer
- ❌ mcp-cli, msw, etc. - Not designed for automated testing
- ❌ Custom MCP testing helpers - Don't exist yet (opportunity?)
**Q: "Are there any better frameworks for MCP testing?"**
A: No. MCP is too new. The ecosystem is:
- Official: MCP SDK (Vitest + InMemoryTransport)
- Manual: MCP Inspector
- Community: Barely exists
**What you should do:**
1. Keep Vitest (perfect choice)
2. Add Supertest (5-min install, solves HTTP testing gap)
3. Expand InMemoryTransport tests
4. Wait for MCP ecosystem to mature (2025+)
---
## Why This Is Actually Great News
**Most frameworks struggle because they over-engineer.**
You've got the simple, elegant solution:
- Vitest: Fast, minimal overhead, perfect for your async needs
- InMemoryTransport: Direct testing without network, designed for exactly this
- MCP Inspector: Visual tool for exploration and validation
Adding Supertest just closes the HTTP testing gap. Everything else is unnecessary.
---
## Next Steps
1. **Read** `.github/instructions/http-server-testing-supertest.md`
2. **Run** `bun add -D supertest @types/supertest`
3. **Create** test file for DNS rebinding protection
4. **Run** `bun test` to verify
5. **Commit** with your DNS rebinding changes
That's it. You're done upgrading your testing setup.
---
## Resources
- [MCP Testing Guide](https://modelcontextprotocol.io/docs/tools/debugging)
- [Vitest Docs](https://vitest.dev/)
- [Supertest Docs](https://github.com/visionmedia/supertest)
- [InMemoryTransport](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/packages/client/src/testing/inMemoryTransport.ts)
- [MCP Inspector](https://github.com/modelcontextprotocol/inspector)