A tool call can return valid JSON while accessing the wrong tenant or repeating a write after a timeout.
MCP server testing verifies the contract between an MCP client, a server, and the systems its tools access. A successful connection proves little about permissions, result correctness, or recovery after an interrupted write. Valid JSON can still describe an unauthorized operation.
This guide uses the Model Context Protocol revision 2026-07-28, current in the official documentation reviewed on October 12, 2026. It also identifies compatibility tests for the earlier 2025-11-25 revision. The official versioning guidance establishes the current version. Examples below are hypothetical engineering scenarios, not reported experiments.
Define the MCP protocol contract before testing
Pin versions and supported capabilities
Record the server build, SDK release, protocol revision, transport, client version, and enabled extensions with every run. A dependency upgrade can change protocol messages even when application code stays unchanged. Keep separate expectations for each supported combination.
In 2026-07-28, requests carry their protocol version in metadata rather than negotiating it through an initialization handshake. Servers implement server/discover; clients can use it to inspect supported versions and capabilities. An unsupported version produces an UnsupportedProtocolVersionError. The versioning specification defines these rules and compatibility behavior.
Test missing metadata, unsupported versions, and unavailable capabilities using a protocol harness. Require an explicit compatibility result rather than silently accepting a different contract. Client identity and capability claims describe the request; they do not authenticate its caller.
Keep legacy initialization tests separate
For 2025-11-25 support, verify initialize, the negotiated version and capabilities, and notifications/initialized before normal operation. Test incompatible responses and features that were not negotiated. These are legacy lifecycle requirements, not the modern startup sequence. Label fixtures by revision so a legacy success cannot satisfy a modern test accidentally.
Build a repeatable MCP server testing workflow

Explore locally with MCP Inspector
The MCP Inspector provides browser, CLI, and terminal interfaces for inspecting servers. Start with a reviewed local build or isolated staging endpoint. Inspect the tool catalog, make a permitted read, and examine the request and response before automating assertions.
Install a trusted, pinned Inspector release compatible with the chosen protocol and runtime. Pin the server package too. Do not copy an unreviewed package launcher from a tool description. A stdio server is executable code, and launching it grants the process the authority of its environment.
Keep Inspector access local, retain its authentication protections, and use disposable credentials. The Inspector security documentation explains its backend and secret storage boundaries. Redact captured credentials before attaching debugging evidence to a report.
Turn observations into test cases
Each case needs a starting fixture, authenticated principal, protocol revision, tool name, input, expected result category, and expected backend state. Record what must remain absent as well as what should happen.
In a hypothetical case, a read tool receives a synthetic project identifier. Assert the expected project fields and that no unrelated record appears. For a denied write, inspect the database and mock outbound queue to establish that nothing changed. That server-side assertion catches failures hidden by a reassuring error message.
Validate tool schemas and error behavior
Test the published contract against implementation
Capture tools/list and review names, tool description text, parameters, and tool schemas as a versioned artifact. Check pagination for omissions and duplicates, then compare catalog changes with the intended release. Make schema changes reviewable instead of automatically updating snapshots.
The MCP tools specification defines inputSchema and optional outputSchema, with structured results required to conform to a declared output schema. It also distinguishes protocol errors from execution failures returned with isError set to true.
Generate boundary cases from the actual contract. Cover missing required input, wrong types, empty strings, unknown enum values, nested objects, and values immediately outside accepted limits. Test unknown properties according to the schema's policy; do not assume every schema rejects them. Pair each rejected input with a valid neighboring value to detect overly broad validation.
Assert the right error layer
An unknown tool or malformed call envelope belongs to the protocol error path. Input validation and business failures inside a tool belong to the execution error path. Assert the JSON-RPC envelope and isError independently of HTTP status. A transport success does not mean the tool succeeded.
In a hypothetical reservation tool, a negative quantity should produce actionable validation feedback without creating a reservation. An unknown tool name should produce a protocol error. Neither response should expose stack traces, credentials, or private records. Add a test for schema valid input that violates a business rule, such as requesting an unavailable synthetic item.
Test authentication for HTTP and authority for stdio
Verify protected HTTP requests
The MCP authorization specification describes OAuth for HTTP transports when authorization is supported. It directs stdio implementations toward environment credentials instead. OAuth is not a universal requirement for every MCP server.
For protected HTTP deployments, test missing, expired, invalid, and wrong audience tokens, plus valid tokens lacking required permissions. Verify the documented 401 and 403 behavior and discovery challenges. Exercise the real validation mechanism, including signature verification or token introspection as applicable. A fabricated principal injected after authentication cannot test the authentication boundary.
The MCP security guidance prohibits token passthrough and describes confused deputy risks. Assert that downstream credentials are acquired through the intended integration rather than forwarding an incoming token issued for another service.
Constrain local process access
For stdio, inspect environment inheritance, filesystem access, subprocess permissions, and outbound network authority. Give the fixture only the credentials and directories it needs. Test attempts to access an adjacent synthetic directory and verify denial at the operating system or application boundary.
The stdio binding reserves stdout for MCP messages and allows logging on stderr. Include a startup test that catches banners or debug output corrupting the message stream. Confirm cleanup after process exit and restart.
Enforce MCP security across trust boundaries
Authorize every object access
Authentication establishes identity; each tool still needs authorization for the requested object and action. Derive tenant membership from trusted server context. Treat tenant identifiers in arguments as selectors that require checks, never as evidence of permission.
In a hypothetical two tenant fixture, both tenants have a project with a similar name. Call the read and write tools as tenant A using tenant B's identifier. Assert no returned private fields, no writes, no queued work, and no unauthorized data in logs or caches. Repeat after permission revocation and under concurrent requests.
Check handles and resource links through the same policy. Possessing an identifier should not grant access. Test cache reuse after switching principals, not only fresh requests, because stale authorized results can become unauthorized disclosures.
Treat annotations and content as untrusted
Tool annotations are hints, not enforcement. The protocol security principles identify descriptions such as annotations as untrusted unless obtained from a trusted server. A readOnlyHint or idempotentHint cannot establish that implementation behavior is safe.
Build defensive tool poisoning cases with harmless synthetic markers. In a hypothetical fixture, a tool description or retrieved result asks the host to send marker TEST_ONLY_CANARY to a mock sink. The expected outcome is no unauthorized outbound request. Inspect the mock sink and invocation trace, not merely the assistant's final wording. These cases assess a defense against a specified attack, not universal prompt injection resistance.
Test retries cancellation and resource bounds
Verify recovery against durable state
A lost response leaves a caller uncertain whether an operation committed. Do not assume an MCP tool is idempotent because its name sounds repeatable. Define the application's replay contract, then test it with an isolated backend and fault injection around the commit point.
In a hypothetical draft creation tool with documented idempotency keys, drop the response after persistence and retry with the same key. Assert one draft and a consistent result. Reuse the key with different arguments and expect the documented conflict behavior. Scope keys to the authorized caller. Without such a contract, require state reconciliation or user review before replaying a consequential write.
Distinguish stopping work from undoing work
The 2026-07-28 cancellation rules use a cancellation notification for stdio and closure of the SSE response stream for Streamable HTTP. They also call for maximum timeouts despite progress updates. Keep legacy cancellation cases tied to their own revision.
Cancellation does not roll back an external effect already committed. Inject cancellation before work starts, during a dependency wait, and after a synthetic commit. Assert worker cleanup and durable state separately. Make the client explain an uncertain outcome instead of falsely promising that a cancelled request changed nothing.
Bound request size, result size, concurrency, queue depth, and dependency time. Test oversized payloads, excessive pagination, slow dependencies, and repeated failures at controlled limits. Record rejection behavior and verify recovery after load stops. Keep these tests isolated from production and use mock external services.
Automate MCP server tests with deterministic evidence
Build a focused CI test suite
Use unit tests for domain validation and permission decisions, then protocol tests against the actual server adapter. Control clocks, random identifiers, fixtures, and dependency responses. Keep smoke tests cheap and safe to repeat. A passing process exit is insufficient when the payload reports a tool error.
Assert the result schema, meaningful field values, error category, and backend effects. Include negative controls that deliberately break a mock permission check or return malformed output. The suite should fail for the intended reason; otherwise its apparent coverage is questionable.
Store sanitized request identifiers, version information, and assertion failures as restricted CI artifacts. Establish product specific budgets and fail releases on critical authorization violations. Review approved contract changes with their fixtures rather than suppressing failures through broad snapshot replacement.
Exercise the MCP client used by the product
Inspector success does not establish compatibility with every host. Repeat critical cases through the actual MCP client versions you support, including discovery, consent, tool errors, cancellation, and reconnect behavior.
For modern HTTP, test JSON and SSE response handling and header consistency. The Streamable HTTP specification requires matching protocol version metadata and headers, validates Origin, and removes legacy protocol sessions. Exercise deployment proxies too, because buffering or header rewriting can change observed behavior.
For client side security, confirm that a denied action remains denied even if the model selects it. Measure agent task performance separately with the AI agent testing guide. Use the RAG evaluation guide for retrieval and answer support. Neither score substitutes for protocol and backend assertions. The API rate limit testing guide covers broader service recovery checks.
Review the visible integration with human feedback
Create a BetaRoast feedback round using synthetic accounts and a permitted staging integration. Ask people to interpret the tool approval, recognize a failure, and describe the next safe action when an outcome is uncertain.
BetaRoast can support human feedback on clarity and usability. Engineering owners remain responsible for MCP conformance, authentication, tenant isolation, and security testing. Keep those evidence streams distinct so a pleasant interface cannot conceal a failing access check.
Frequently asked questions
What is MCP server testing?
It verifies protocol compatibility, tool inputs and results, authorization boundaries, backend effects, and failure recovery. It also checks the actual client integration. Agent answer quality needs a separate evaluation.
How do I test an MCP server with MCP Inspector?
Use a trusted pinned Inspector release with a reviewed local server or isolated endpoint. Inspect the catalog and call safe fixture tools, then turn observations into repeatable assertions. Never supply production credentials to an unfamiliar package.
Does every MCP server need OAuth?
No. The MCP authorization framework addresses HTTP transports when supported. Local stdio servers typically obtain credentials from their environment and need constrained process authority. Every deployment still needs an appropriate access policy.
What should MCP server tests assert in CI?
Assert the selected protocol contract, result schemas and values, correct error layers, denied access, bounded execution, and durable backend effects. Use deterministic fixtures and verify replay behavior explicitly rather than assuming retries are safe.
Pin the MCP protocol contract, test tool behavior against backend state, and enforce authorization independently of descriptions and model decisions. Use trusted Inspector tooling for exploration, deterministic automation for release checks, and the actual client for integration coverage. BetaRoast can support human feedback on the visible experience; protocol conformance and security verification remain engineering responsibilities.

