| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .. | ||
| helpers | ||
| app-info.test.ts | ||
| cli.test.ts | ||
| cliOAuth.test.ts | ||
| e2e.test.ts | ||
| emit-result.test.ts | ||
| error-handler.test.ts | ||
| format-json.test.ts | ||
| headers.test.ts | ||
| metadata.test.ts | ||
| methods.test.ts | ||
| oauth-interactive.test.ts | ||
| oauth-runner.test.ts | ||
| programmatic-ergonomics.test.ts | ||
| README.md | ||
| stored-auth.test.ts | ||
| tools.test.ts | ||
CLI Tests
Running Tests
# Run all tests (pretest builds test-servers + the CLI binary)
npm test
# Run all tests under the per-file coverage gate
npm run test:coverage
# Run in watch mode (useful for test file changes)
npm run test:watch
# Run specific test file
npm run test:cli # cli.test.ts
npm run test:cli-tools # tools.test.ts
npm run test:cli-headers # headers.test.ts
npm run test:cli-metadata # metadata.test.ts
npx vitest run oauth-interactive.test.ts cliOAuth.test.ts # OAuth interactive smoke parity
How the CLI is exercised
Most tests run the CLI in-process: helpers/cli-runner.ts imports runCli()
from ../src/cli.ts and invokes it directly, capturing process.stdout/stderr
and mapping thrown errors to an exit code. This is what lets vitest's v8 coverage
instrument clients/cli/src (#1484). Because commander uses .exitOverride(),
a parse/usage error throws instead of calling process.exit and tearing down the
worker.
e2e.test.ts is the deliberately thin out-of-process layer: it spawns the
built build/index.js as a real subprocess to cover the shebang, the
index.ts isMain bootstrap, and the actual process.exit codes — the only
parts the in-process runner can't reach. (scripts/smoke-cli.mjs at the repo
root provides a further end-to-end check of the binary.)
Test Files
cli.test.ts- Basic CLI functionality: CLI mode, environment variables, config files, resources, prompts, logging, transport typestools.test.ts- Tool-related tests: Tool discovery, JSON argument parsing, error handling, promptsheaders.test.ts- Header parsing and validationmetadata.test.ts- Metadata functionality: General metadata, tool-specific metadata, parsing, merging, validationmethods.test.ts- Method/option-validation paths not covered elsewhere (resource templates, missing/invalid options, the--target separator)error-handler.test.ts- The binary'shandleErrorerror sink, exercised in-process withprocess.exitstubbedoauth-runner.test.ts- OAuth flag wiring (--client-config,--callback-url, CIMD overrides)cliOAuth.test.ts- Unit tests forcliOAuth.ts(step-up confirm, helper wiring, retry)oauth-interactive.test.ts- Integration smoke parity for CLI interactive OAuth: connect-time callback server + step-up y/N against composableTestServerHttp(auto-completes authorize URL programmatically; not a subprocess binary e2e)e2e.test.ts- Out-of-process spawn of the built binary (exit codes + boot; no OAuth)
Helpers
The helpers/ directory contains shared utilities:
cli-runner.ts- InvokesrunCli()in-process and captures stdout/stderr + exit codeassertions.ts- Custom assertion helpers for CLI output validationfixtures.ts- Test config/catalog file generators and temporary directory management
HTTP/SSE test servers (for transport tests) come from the
@modelcontextprotocol/inspector-test-server package (createTestServerHttp),
and the bundled stdio server is launched via getTestMcpServerCommand().
Notes
- Test files run in separate forked processes (
pool: 'forks'), so the in-process runner'sprocess.std*.writepatching never overlaps across files; tests within a file run sequentially - Config files use
crypto.randomUUID()for uniqueness - HTTP/SSE servers use dynamic port allocation to avoid conflicts
- Coverage is enforced per-file (lines ≥ 90, statements ≥ 85, functions ≥ 80,
branches ≥ 50).
src/index.ts(the binary bootstrap) is excluded because it only runs in the spawned binary, which coverage can't instrument - All tests use the built-in MCP test servers — no external/registry dependencies