Development Guide
March 7, 2026 · View on GitHub
This guide covers contributing to @gleanwork/mcp-server-tester, running tests, and building the library.
Table of Contents
Setup
Prerequisites
- Node.js 18 or higher
- npm or yarn
Installation
Clone the repository and install dependencies:
git clone https://github.com/gleanwork/mcp-server-tester.git
cd server-tester
npm install
Running Tests
The project includes a comprehensive test suite with both unit tests and integration tests.
Unit Tests (Vitest)
Unit tests cover core functionality:
# Run all unit tests
npm test
# Run in watch mode
npm run test:watch
Test Coverage:
- Configuration validation
- Dataset types and loading
- Expectations (exact, schema, textContains, regex, snapshot, judge)
- MCP client factory and fixtures
- LLM host simulation
- Judge implementations (OpenAI, Anthropic)
Integration Tests (Playwright)
Integration tests use a mock MCP server (5 tests):
# Run integration tests
npm run test:playwright
Test Coverage:
- MCP server connection and info
- Tool listing and conformance checks
- Eval dataset execution
- Error handling
Running All Tests
# Run both unit and integration tests
npm test && npm run test:playwright
Mock MCP Server
The integration tests use a mock server located at tests/mocks/simpleMCPServer.ts.
Available Tools:
echo- Echoes back the inputcalculate- Performs basic math operationsget_weather- Returns mock weather data
The mock server requires Zod schemas for MCP SDK compatibility.
Building
Build Commands
# Build library (ESM + CJS + .d.ts)
npm run build
# Build in watch mode
npm run dev
# Type check only (no build)
npm run typecheck
Build Output
The build produces:
dist/
├── index.js # ESM build
├── index.cjs # CommonJS build
└── index.d.ts # TypeScript declarations
Package Exports:
The package.json exports both ESM and CJS for maximum compatibility:
{
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
}
}
Code Quality
Linting
# Run ESLint
npm run lint
# Auto-fix issues
npm run lint:fix
Formatting
# Format with Prettier
npm run format
# Check formatting
npm run format:check
Pre-commit Checks
Before committing, ensure:
npm run typecheck # TypeScript validation
npm run lint # No lint errors
npm test # All tests pass
npm run build # Build succeeds
Project Structure
@gleanwork/mcp-server-tester/
├── src/
│ ├── config/ # MCPConfig types + Zod validation
│ ├── mcp/ # Client factory, fixtures, MCPFixtureApi
│ ├── evals/ # Dataset types, loader, runner, expectations
│ ├── judge/ # LLM-as-a-judge (OpenAI, Anthropic)
│ ├── spec/ # Protocol conformance checks
│ └── index.ts # Public API exports
├── tests/
│ ├── mocks/simpleMCPServer.ts # Mock server for integration tests
│ └── mcp-tests.spec.ts # Integration test suite
├── examples/ # Example projects
├── docs/ # Documentation
└── dist/ # Build output (generated)
Key Files
Public API:
src/index.ts- All exported functions and types
Fixtures:
src/fixtures/mcp.ts- Playwright fixture definitionssrc/mcp/fixtures/mcpFixture.ts- Fixture implementation
Configuration:
src/config/mcpConfig.ts- Transport configuration types and Zod validation schemas
Evaluations:
src/evals/datasetTypes.ts- Dataset and case typessrc/evals/evalRunner.ts- Dataset execution logicsrc/assertions/validators/- All validator implementations
Contributing
We welcome contributions! Here's how to get started:
Reporting Issues
- Check existing issues first
- Create a new issue with:
- Clear description
- Steps to reproduce
- Expected vs actual behavior
- Environment details (Node version, OS, etc.)
Submitting Pull Requests
-
Fork the repository
-
Create a feature branch
git checkout -b feature/your-feature-name -
Make your changes
- Follow existing code style
- Add tests for new functionality
- Update documentation as needed
-
Run quality checks
npm run typecheck npm run lint npm test npm run test:playwright npm run build -
Commit your changes
git commit -m "feat: add new feature"Use conventional commit format:
feat:- New featurefix:- Bug fixdocs:- Documentation changestest:- Test changesrefactor:- Code refactoringchore:- Build/tooling changes
-
Push and create PR
git push origin feature/your-feature-nameThen open a pull request on GitHub.
Code Style
Follow these conventions:
-
Function declarations over expressions
// ✓ Good export function createClient() {} // ✗ Avoid export const createClient = () => {}; -
Explicit null over short-circuit
// ✓ Good condition ? 'value' : null; // ✗ Avoid condition && 'value'; -
Descriptive type names
// ✓ Good (EvalDataset, MCPFixtureApi, Judge); // ✗ Avoid (Data, Api, Client); -
TypeScript strict mode
- No
anytypes - Prefer type safety
- Use proper null checks
- No
-
Async function style
- Keep
asynckeyword for consistency - Even if no
awaitcurrently used
- Keep
Adding Features
New Validator
- Create
src/assertions/validators/myValidator.tsreturningValidationResult - Export from
src/assertions/validators/index.ts - Add unit tests in
validators.test.ts - Update
docs/expectations.md
New LLM Judge Provider
- Add provider to
ProviderKindunion insrc/judge/judgeTypes.ts - Create
src/judge/myProviderJudge.tsimplementingJudge - Add case to
createJudge()switch insrc/judge/judgeClient.ts - Use environment variables for API keys
- Add tests
- Update
docs/expectations.md
New Transport Type
- Add to
MCPConfigdiscriminated union insrc/config/mcpConfig.ts - Update
createMCPClientForConfig()insrc/mcp/clientFactory.tswith SDK transport class - Update type guards and Zod schema in
src/config/mcpConfig.ts - Add tests
- Update
docs/transports.md
Testing Guidelines
- Unit tests: Mock MCP interactions, test logic in isolation
- Integration tests: Use
simpleMCPServer.tsmock with real MCP SDK - Conformance tests: Validate against MCP protocol spec
- Never skip tests without marking them explicitly (
test.skip())
Documentation
When adding features:
- Update relevant docs in
docs/ - Add JSDoc comments to public APIs
- Include code examples
- Update
CHANGELOG.md(if maintaining one)
Release Process
See RELEASE.md for the release process using release-it.
Getting Help
- Documentation: Check
docs/directory - Examples: See
examples/directory - Issues: GitHub Issues
License
MIT - See LICENSE file for details