Skip to main content
Use direct calls for application logic and server calls for validation, result conversion, diagnostics, and authorization. A passing direct handler test does not establish the public MCP contract.

Direct handler test

Save this as src/test.ts in the modular tutorial project. The next block continues the same file. Inputs here are already the handler’s parsed values. Direct calls bypass parsing, output validation, authorization, and MCP conversion.

Test the server boundary

Compile and run the test with npx tsc -p tsconfig.json and node dist/test.js. For your own tools, also assert text blocks, send invalid input and check that the handler is not invoked, and test output failures. Check that unexpected failures remain generic and reach private onError details. Use the actual legacy envelope when checking the older revision rather than only changing a version label.

Override services

Providers support typed replacements without mutating the original definition:
Here database is your provider and fakeDatabase implements its inferred contract. Concurrent accessor calls should share one value per context; fresh contexts should not share request caches. The context guide includes a complete example.

Transport and auth tests

Test stdio through a real child process to catch stdout pollution, framing, EOF, and cancellation. Test HTTP through its adapter/listener to cover hosts, headers, body limits, metadata routes, authorization ordering, and disconnects. server.handle() alone does not exercise those HTTP boundaries. For protected direct tests, obtain a scope with authorize(), pass it to handle(), and dispose it in finally. Stub trusted signing keys or token-verification responses rather than requiring live secrets in ordinary tests. Keep live login interoperability checks separate and record client/runtime versions.