This document explains how to run and maintain the end-to-end tests for the Claude Code MCP server.
The e2e tests are designed to validate the Claude Code MCP server's functionality in real-world scenarios. Since the Claude CLI requires authentication and isn't easily installable in automated environments, the tests use a mock Claude CLI for automated testing and provide optional integration tests for local development.
The e2e tests are organized into several files:
src/__tests__/e2e.test.ts- Main e2e test suite with mock Claude CLIsrc/__tests__/edge-cases.test.ts- Edge case and error handling testssrc/__tests__/utils/mcp-client.ts- Mock MCP client for testingsrc/__tests__/utils/claude-mock.ts- Mock Claude CLI implementation
# Install dependencies
npm install
# Build the project
npm run build
# Run all tests (unit + e2e)
npm test
# Run only e2e tests with mocks
npm run test:e2e
# Run unit tests only
npm run test:unitWhen Claude CLI is installed locally, you can run the full integration tests:
# Run all tests including integration tests
npm run test:e2e:localThe integration tests are marked with .skip() by default and will only run when you have Claude CLI installed and authenticated.
Use test:live for release-time checks against real installed AI CLIs. By default this suite runs the built dist/bin/ai-cli.js command and verifies the real run -> ps -> peek -> wait -> result -> cleanup flow, including persisted exit-status.json. It can also exercise the built MCP server surface.
Live E2E is opt-in and is not part of normal npm test:
# Shows the opt-in guard and does not call external CLIs
npm run test:live
# Default live backends: claude,codex
ACM_LIVE_E2E=1 npm run test:live
# Choose exact backends
ACM_LIVE_E2E=1 ACM_LIVE_E2E_AGENTS=claude,codex npm run test:live
# Full release-time coverage
ACM_LIVE_E2E=1 ACM_LIVE_E2E_AGENTS=all npm run test:live
# Include both ai-cli and MCP server surfaces
ACM_LIVE_E2E=1 ACM_LIVE_E2E_SURFACE=all ACM_LIVE_E2E_AGENTS=claude,codex npm run test:liveUseful environment variables:
ACM_LIVE_E2E_AGENTS: comma-separatedclaude,codex,gemini,forge,opencode, orall. Defaults toclaude,codex.ACM_LIVE_E2E_SURFACE:cli,mcp, orall. Defaults tocli.ACM_LIVE_E2E_TIMEOUT_SECONDS: timeout passed toai-cli wait. Defaults to240.ACM_LIVE_E2E_COMMAND_TIMEOUT_MS: process/request timeout used by the live test harness. Defaults toACM_LIVE_E2E_TIMEOUT_SECONDS + 60s.ACM_LIVE_E2E_TOKEN: expected token in the model response. Defaults toACM_LIVE_E2E_OK.ACM_LIVE_E2E_ASSERT_TOKEN=0: disables response-token assertion if a provider adds unavoidable formatting.ACM_LIVE_E2E_<AGENT>_MODEL: override a default model, for exampleACM_LIVE_E2E_CODEX_MODEL=gpt-5.6-sol. The default Codex value isgpt-5.4.
Keep this suite out of mandatory CI unless the runner has authenticated CLI sessions, network access, and an acceptable cost budget.
- Tool registration and discovery
- Simple prompt execution
- Error handling
- Default working directory behavior
- Custom working directory support
- Non-existent directory handling
- Permission errors
- Input validation (missing/invalid parameters)
- Special characters in prompts
- Concurrent request handling
- Large prompt handling
- Path traversal prevention
- File creation with real Claude CLI
- Git operations
- Complex multi-step workflows
The tests use a mock Claude CLI that simulates basic Claude behavior. The mock:
- Creates a fake executable at
~/.claude/local/claude - Responds to basic commands based on prompt patterns
- Simulates errors for testing error handling
The mock is automatically set up before tests run and cleaned up afterwards.
When adding new e2e tests:
- Use the
MCPTestClientfor communicating with the server - Set up test directories in
beforeEachand clean up inafterEach - Use descriptive test names that explain the scenario
- Add appropriate assertions for both success and failure cases
Example:
it('should handle complex file operations', async () => {
const response = await client.callTool('claude_code', {
prompt: 'Create multiple files and organize them',
workFolder: testDir,
});
expect(response).toBeTruthy();
// Add specific assertions about the result
});To debug e2e tests:
- Enable debug mode by setting
MCP_CLAUDE_DEBUG=true - Add console.log statements in test code
- Use the VSCode debugger with the test runner
- Check server stderr output for debug logs
The e2e tests are designed to run in CI environments without Claude CLI:
- Mock tests run automatically in CI
- Integration tests are skipped unless explicitly enabled
- Tests use temporary directories to avoid conflicts
- All tests clean up after themselves
- Increase timeout in
vitest.config.e2e.ts - Check if the mock Claude CLI is set up correctly
- Verify the server is building properly
- Ensure the mock setup runs in
beforeAll - Check file permissions on the mock executable
- Verify the mock path matches the server's expectations
- Ensure Claude CLI is installed and authenticated
- Check that you're running the local test command
- Verify Claude CLI is accessible in your PATH
- Add performance benchmarking tests
- Implement stress testing scenarios
- Add tests for specific Claude Code features
- Create visual regression tests for output formatting