Skip to content
MCP Test Kitchen homePowered by Cakewalk

Tutorial

How to use the MCP Test Kitchen

Before you start

Before you start

You need two things: a client that can take a URL and an Authorization header, and a Google or GitHub account.

This walkthrough uses the hosted Test Kitchen, so you do not need to change your client's code, install anything or run a server.

If you would rather run your own copy, the server is open source under the MIT License. Start it with the Docker quick start in its README, add a Google or GitHub OAuth app for the console sign-in, then follow the same steps against http://localhost:5094/mcp.

Nine steps

From signing in to reading a failure

  1. Open the console and sign in

    Sign in with Google or GitHub. Signing in mints a personal access token, and the server uses that token to know which traffic is yours and which scenario you picked. Without it there is no way to tell your requests from anyone else's.

  2. Copy your access token

    The console shows it once you are in. Copy it now. You paste it into your client config in step 4.

  3. Pick Baseline (success) first

    Open the Scenarios panel, Tools tab, select Baseline (success) and hit Save.

    Do this before you test any failure. Baseline answers normally. If your client cannot complete a call against Baseline, the problem is your config, not your error handling, so you want to know that before you start reading failure logs.

    One scenario is active at a time, and it applies to your next connection rather than the current one.

  4. Point your client at the endpoint

    Add the server to your client's MCP config, with the token in the Authorization header.

    {
      "mcpServers": {
        "mcp-test-kitchen": {
          "url": "https://mcp-test-kitchen.cakewalk.security/mcp",
          "headers": { "Authorization": "Bearer <your-token>" }
        }
      }
    }

    If you have no client to point at it yet, the console generates a working TypeScript client already wired to the endpoint.

  5. Run a real task

    Run something you would actually run against a healthy server, not a synthetic ping. You are testing the path your client really takes, including whatever your agent does with the result it gets back.

  6. Read the log

    The Messages panel fills up as requests arrive. One row per request: time, method, phase, status, duration, the active scenario and the protocol revision it declared. Open a row for the rest: request id, status code, whether it cancelled and the headers.

    The revision column is worth a look on its own. Your client sends whatever its SDK defaults to, which is not always what you configured. That decides which path runs.

    Against Baseline you should see clean rows. That is your control.

  7. Now break something

    Switch to Tool error (isError). Use Customize to set which call the failure lands on, Save, then reconnect your client.

    { "errorMessage": "Lease expired", "onInvocation": 2 }

    Use 2, not 1. A failure on every call gets noticed immediately. The one that costs you arrives after things already worked: the first call comes back clean, and the second carries isError inside a successful response.

  8. Look at what your client did, not at the log

    The log tells you what the server sent. It cannot tell you what your client did next, and that is the part you are testing.

    You already know the second call carried isError, because you configured it. So the question is whether an answer still reached your user. If it did, your client passed a failed result upward as content. That is a result-handling fix in your code.

    Both rows will read status 200. The transport cannot tell a failed tool result from a successful one, so nothing watching status codes would have caught this.

  9. Fix it, then run the same scenario again

    Same scenario, same parameters. The second log is your proof.

Reference

Which scenario to use when

  • Baseline (success). Your control case. Confirm the connection before testing anything else. It also takes an optional delay, if you want to see how your client handles a slow server.
  • Tool error (isError). A failure hidden inside a successful response. Start here. It is the one clients get wrong most often.
  • JSON-RPC error. HTTP 200 with an error object in the body, on the call you name.
  • HTTP transport error. A configured sequence of status codes across successive requests, so the failure sits below MCP.
  • Elicitation approval. Calls elicitation, so you can check your client prompts a person before continuing.
  • C# SDK v2 backward compatibility. Whether your client handles the new revision's multi round-trip requests or falls back to the older path.

Resources and prompts sit on their own tabs. They are always on and need no scenario configuration, and each ships a valid and an invalid variant, so you can check how your client handles both without touching the Tools tab.

Scope

What this will not do

  • It will not tell you whether your client is correct, only what your client did. For correctness, run the official conformance suite. The two do not overlap.
  • It does not test your server.
  • The transport is stateless, so the server cannot hold state across a live connection. Stateful paths are out of scope.

Housekeeping

Housekeeping

Records are deleted after seven days, so pull anything you want to keep into your own tracker.

If you want it gone sooner, the console has an ERASE EVERYTHING button. It deletes your observations, your saved scenario, your MCP access token and your live sessions, signs you out and cannot be undone. There is also a feedback box in the console if you want to tell us what to break next.

What the server keeps has the full record of what is stored and for how long.

Start testing