Skip to main content
Glama
README.md
# 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

```bash
npm install
```

### 2. Set Up Test Environment

The server needs Jest and related tools installed in a separate test environment directory:

```bash
npm run setup:test-env
```

This creates a `test-env/` directory with Jest, ts-jest, and TypeScript installed.

### 3. Build the Server

```bash
npm run build
```

## Usage

### Running the Server Directly

```bash
npm start
```

### Testing with MCP Inspector

For interactive testing and debugging:

```bash
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 workspace
- `timeoutMs` (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:**

```json
{
  "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 ID
- `configUpdates` (object): Jest config properties to merge

**Example:**

```json
{
  "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 workspace
- `status` (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 clean
- `olderThanHours` (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:**

```json
{
  "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:**

```json
{
  "limit": 20,
  "sortBy": "created"
}
```

### 8. `update-implementation`

Update an implementation file in an existing workspace and optionally run tests.

**Input:**

- `workspaceId` (string): Workspace ID
- `implementationFile` (object):
  - `name` (string): File name to update
  - `content` (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:**

```json
{
  "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 ID
- `testFile` (object):
  - `name` (string): Test file name
  - `content` (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:**

```json
{
  "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 ID
- `testNamePattern` (optional): Regex pattern to match test names (Jest -t flag)
- `testPathPattern` (optional): File path pattern for specific test files
- `timeoutMs` (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:**

```json
{
  "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`

```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

```bash
npm run build
```

### Testing Tools

Use the MCP Inspector for interactive testing:

```bash
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:

```bash
npm run setup:test-env
```

### Test execution fails

1. Check that files are valid TypeScript/JavaScript
2. Verify test file uses Jest syntax
3. Check timeout settings (increase if needed)
4. Inspect workspace with `get-test-workspace` tool

### Workspace not found

Workspaces may have been cleaned up due to retention policy. Check:

- `TDD_MCP_WORKSPACE_RETENTION_HOURS` setting
- Use `list-test-history` to 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

TDQS

A4.1/5.0

Scored across 10 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: adding test files, cleaning workspaces, retrieving details, listing, running tests, updating implementation or config. The only potential overlap is between run-test and run-specific-tests, but their descriptions clarify one is for initial execution and the other for subset runs.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with hyphens (e.g., add-test-file, list-workspaces, update-jest-config). The naming is predictable and uniform.

Tool Count5/5

10 tools appropriately cover the TDD workspace lifecycle: creating, listing, running tests, updating code, configuring Jest, and cleaning. This is a well-scoped set without unnecessary tools.

Completeness4/5

The tools cover the main TDD workflow well, including adding tests, updating implementation, running tests, viewing history, and managing workspaces. A minor gap is the lack of a tool to delete individual test files from a workspace, but the overall surface is comprehensive.

Maintenance

ActivityInactive
ResponsivenessNo issues