TDD MCP Server
A production-quality MCP (Model Context Protocol) server that enables AI agents to run Jest/TypeScript tests in isolated workspaces for Test-Driven Development (TDD) workflows.
Features
- ✅ Run Jest tests on TypeScript and JavaScript code in isolated workspaces
- ✅ Concurrent test execution with isolated workspace directories
- ✅ Detailed test results with pass/fail status, error messages, stack traces, and code coverage
- ✅ Test history tracking to review past test runs with full detail retrieval
- ✅ Dynamic Jest configuration updates for custom test settings
- ✅ Workspace inspection to view test files and configurations
- ✅ Workspace management with discovery, listing, and metadata viewing
- ✅ Incremental iteration - update implementation or add tests without re-uploading
- ✅ Focused testing - run specific tests by name or file pattern
- ✅ Automatic cleanup of old workspaces based on retention policy
Installation
1. Install Dependencies
npm install
2. Set Up Test Environment
The server needs Jest and related tools installed in a separate test environment directory:
npm run setup:test-env
This creates a test-env/ directory with Jest, ts-jest, and TypeScript installed.
3. Build the Server
npm run build
Usage
Running the Server Directly
npm start
Testing with MCP Inspector
For interactive testing and debugging:
npm run inspect
Then navigate to http://localhost:6274 in your browser.
Available Tools
1. run-test
Execute Jest tests on provided implementation and test files.
Input:
implementationFile(object):name(string): File name (e.g., "calculator.ts")content(string): Implementation code
testFile(object):name(string): Test file name (e.g., "calculator.test.ts")content(string): Test code
language(optional): "typescript" (default) or "javascript"workspaceId(optional): Reuse existing workspacetimeoutMs(optional): Test timeout in milliseconds (default: 60000)
Output:
- Test results with pass/fail status
- Individual test details with error messages and stack traces
- Code coverage metrics
- Workspace ID for future reference
Example:
{
"implementationFile": {
"name": "calculator.ts",
"content": "export function add(a: number, b: number): number { return a + b; }"
},
"testFile": {
"name": "calculator.test.ts",
"content": "import { add } from './calculator';\n\ntest('adds 1 + 2 to equal 3', () => {\n expect(add(1, 2)).toBe(3);\n});"
},
"language": "typescript"
}
2. update-jest-config
Update Jest configuration in a workspace.
Input:
workspaceId(string): Workspace IDconfigUpdates(object): Jest config properties to merge
Example:
{
"workspaceId": "abc123...",
"configUpdates": {
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
}
}
}
3. list-test-history
Retrieve past test runs with optional filters.
Input:
limit(optional): Max results (default: 10)workspaceId(optional): Filter by workspacestatus(optional): "passed" or "failed"
Output:
- Array of test run summaries
- Statistics (total runs, passed/failed counts, unique workspaces)
4. get-test-workspace
Inspect a workspace's contents and configuration.
Input:
workspaceId(string): Workspace ID
Output:
- Workspace metadata (creation date, language, file count)
- File contents
- Current Jest configuration
5. clean-workspace
Delete workspace(s) and associated history.
Input:
workspaceId(optional): Specific workspace to cleanolderThanHours(optional): Clean workspaces older than N hours
Output:
- Count of deleted workspaces and history entries
6. get-test-run-details
Retrieve complete details of a historical test run by history ID.
Input:
historyId(string): History ID from a previous test run
Output:
- Full test results with all details
- Error messages and stack traces
- Coverage data
- Timestamp and metadata
Example:
{
"historyId": "1706234567890-abc12345"
}
7. list-workspaces
List all available test workspaces with metadata.
Input:
limit(optional): Maximum workspaces to return (default: 50)sortBy(optional): "created" (default) or "fileCount"
Output:
- Array of workspaces with IDs, creation dates, languages, and file counts
Example:
{
"limit": 20,
"sortBy": "created"
}
8. update-implementation
Update an implementation file in an existing workspace and optionally run tests.
Input:
workspaceId(string): Workspace IDimplementationFile(object):name(string): File name to updatecontent(string): New implementation code
timeoutMs(optional): Test timeout (default: 60000)autoRunTests(optional): Run tests after update (default: true)
Output:
- Test results (if autoRunTests is true)
- Updated file name and workspace ID
Example:
{
"workspaceId": "abc123...",
"implementationFile": {
"name": "calculator.ts",
"content": "export function add(a: number, b: number): number { return a + b + 1; }"
},
"autoRunTests": true
}
Use Case: Efficient iteration during the refactor phase of TDD without re-uploading test files.
9. add-test-file
Add an additional test file to an existing workspace and optionally run all tests.
Input:
workspaceId(string): Workspace IDtestFile(object):name(string): Test file namecontent(string): Test code
timeoutMs(optional): Test timeout (default: 60000)autoRunTests(optional): Run all tests after adding (default: true)
Output:
- Test results for all tests in workspace (if autoRunTests is true)
- Added file name and workspace ID
Example:
{
"workspaceId": "abc123...",
"testFile": {
"name": "calculator.edge-cases.test.ts",
"content": "import { add } from './calculator';\n\ntest('handles negative numbers', () => {\n expect(add(-1, -2)).toBe(-3);\n});"
}
}
Use Case: Add edge case tests, integration tests, or additional test suites incrementally.
10. run-specific-tests
Run a subset of tests using Jest patterns for focused testing.
Input:
workspaceId(string): Workspace IDtestNamePattern(optional): Regex pattern to match test names (Jest -t flag)testPathPattern(optional): File path pattern for specific test filestimeoutMs(optional): Test timeout (default: 60000)
Note: At least one pattern (testNamePattern or testPathPattern) must be provided.
Output:
- Test results for matched tests only
- Applied filters
- Coverage data
Example:
{
"workspaceId": "abc123...",
"testNamePattern": "should multiply",
"timeoutMs": 30000
}
Use Case: Focused testing during debugging, running only failing tests, or testing specific functionality.
Configuration
Configure the server via environment variables:
| Variable | Default | Description |
|---|---|---|
TDD_MCP_BASE_DIR |
./test-env |
Base directory for test environment |
TDD_MCP_WORKSPACE_RETENTION_HOURS |
168 (7 days) |
How long to keep workspaces |
TDD_MCP_TEST_TIMEOUT_MS |
60000 |
Default test timeout |
TDD_MCP_MAX_HISTORY_ENTRIES |
1000 |
Maximum history entries to keep |
TDD_MCP_AUTO_CLEANUP_ON_START |
true |
Auto-clean old workspaces on startup |
MCP Client Configuration
Claude Desktop
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"tdd-mcp-server": {
"command": "npx",
"args": ["-y", "tsx", "G:/tdd-mcp/server.ts"],
"env": {
"TDD_MCP_BASE_DIR": "G:/tdd-mcp/test-env",
"TDD_MCP_WORKSPACE_RETENTION_HOURS": "168"
}
}
}
}
Note: Use absolute paths. Replace G:/tdd-mcp with your actual installation path.
Project Structure
tdd-mcp/
├── server.ts # MCP server entry point
├── src/
│ ├── config.ts # Configuration management
│ ├── logger.ts # Structured logging
│ ├── tool.ts # Abstract Tool base class
│ ├── workspace-manager.ts # Workspace creation & file management
│ ├── jest-config-manager.ts # Jest configuration handling
│ ├── test-runner.ts # Jest execution & result parsing
│ ├── test-history-manager.ts # Test history storage & queries
│ └── tools/
│ ├── run-test.ts # Main test execution tool
│ ├── update-jest-config.ts # Config update tool
│ ├── list-test-history.ts # History listing tool
│ ├── get-test-workspace.ts # Workspace inspection tool
├── clean-workspace.ts # Cleanup tool
├── get-test-run-details.ts # History details retrieval
├── list-workspaces.ts # Workspace discovery
├── update-implementation.ts # Implementation file updates
├── add-test-file.ts # Add test files incrementally
└── run-specific-tests.ts # Focused test execution
├── test-env/ # Jest installation directory
│ ├── node_modules/ # Jest & dependencies
│ ├── workspaces/ # Isolated test workspaces
│ └── history/ # Test run history
├── package.json
├── tsconfig.json
└── README.md
Development
Building
npm run build
Testing Tools
Use the MCP Inspector for interactive testing:
npm run inspect
Logging
All logs are written to stderr (MCP protocol requirement). The server uses structured logging with:
- Timestamps
- Color-coded levels (info, warn, error)
- Tool execution tracking
- Performance metrics
Troubleshooting
"Jest environment not initialized"
Run the setup command:
npm run setup:test-env
Test execution fails
- Check that files are valid TypeScript/JavaScript
- Verify test file uses Jest syntax
- Check timeout settings (increase if needed)
- Inspect workspace with
get-test-workspacetool
Workspace not found
Workspaces may have been cleaned up due to retention policy. Check:
TDD_MCP_WORKSPACE_RETENTION_HOURSsetting- Use
list-test-historyto see available workspaces
Security
- Path validation: All file operations validate paths to prevent directory traversal
- Workspace isolation: Each test run is isolated in its own directory
- No external dependencies: Tests run with provided code only (no npm install in workspaces)
- Timeout protection: Tests are killed if they exceed timeout
License
MIT
Contributing
Contributions welcome! Please follow the existing code style and architecture patterns.
Support
For issues or questions, please file a GitHub issue with:
- MCP server version
- Tool used and parameters
- Error messages (from stderr logs)
- Expected vs actual behavior