MCP server

Run a load test from the assistant you already have open

Stabula speaks the Model Context Protocol. Point Claude, Claude Code or Cursor at your workspace and it can read your API specification, build the journey, run it, and tell you what happened — without you leaving the conversation.

@stabula/mcp 0.2.1 · MIT licensed · on npm

What this is for

The slow part of performance testing is rarely the test. It is writing down what your API does — every endpoint, every header, the order the calls happen in, the token that has to be carried between them. You have already described most of that somewhere: an OpenAPI document, a Postman collection, or the code itself.

An assistant connected to Stabula can read that description and turn it into a test. You say what you want measured; it builds the requests, wires the journey together, starts the run against Stabula's own runners, and reads the report back to you in sentences. The run is a normal Stabula run — it shows up in the Studio, it counts against the same allowance, and a person can open it, change it, and run it again by hand.

Connecting it

You need a workspace API token: in Stabula, Settings › API tokens › New token. The token decides which workspace the assistant works in, and it is shown once. Every plan can use it, including Free — its 60 VU-minutes a month are enough to try this properly.

Claude Code

claude mcp add stabula \
  --env STABULA_API_TOKEN=stb_your_token \
  -- npx -y @stabula/mcp

Claude Desktop

In claude_desktop_config.json:

{
  "mcpServers": {
    "stabula": {
      "command": "npx",
      "args": ["-y", "@stabula/mcp"],
      "env": { "STABULA_API_TOKEN": "stb_your_token" }
    }
  }
}

Cursor

.cursor/mcp.json takes the same object. So does any other client that speaks MCP over stdio — nothing here is specific to one assistant.

Environment variables
Variable Meaning
STABULA_API_TOKENrequired Required. The workspace token, the one beginning stb_.
STABULA_URL The Stabula origin. Defaults to https://studio.stabula.app.
STABULA_TIMEOUT_MS How long to wait for one API call. Default 30000.

What to ask for

Three requests, in the order people tend to make them.

One endpoint, one question

Load test POST https://api.example.com/orders with 50 users for 5 minutes and tell me if p95 stays under 300 ms.

The assistant creates the request with max_p95_ms: 300, starts the run, waits for it, and answers from the report: whether the target was met, what the p95 actually was, and what the runner hit if anything failed.

A whole specification

Here's our Swagger file. Import the Orders endpoints, then smoke test each one so I know which are healthy.

import_spec reads an OpenAPI 3 document or a Postman v2.1 collection, from a URL or pasted text. It shows you what it would create before it creates anything — groups, requests, and any warnings about the document — and only writes when you say yes.

A journey that has to sign in

This is the one that matters, and the one that is tedious by hand. Most things worth load testing happen after a login, and a step usually needs something the step before it produced.

Build a scenario against staging: log in, add an item to an order, then remove it again. 20 users for 5 minutes.

Two fields carry the whole pattern, and the assistant sets them as it builds the steps:

  • A capture pulls a value out of a step's response — the token out of data.access_token, the id out of data.id — and every step after it can use that value as {{token}} or {{item_id}} in its URL, headers, query values or body.
  • Run once marks the sign-in. It runs once per simulated user rather than on every loop, which is what a real user does — signing in 40,000 times measures your login endpoint, not your checkout.

So the journey ends up as: sign in once and remember the token; add an item, sending that token and remembering the id that comes back; delete that id, with the same token. Each simulated user repeats the add-and-remove for the length of the run.

Point it at staging. A journey like this writes to whatever it is aimed at, and every iteration of every user adds and removes a real row. Stabula will not stop you running it against production — that is your call — but it should be a deliberate one.

What it can do

19 tools and two resources. The names are here because an assistant will announce them the first time it connects, and it is worth knowing which of them spend money.

Reading

  • list_requests — Every request in the workspace, grouped as the Studio tree has them.
  • get_request — One request or step in full: headers, query, body, assertions, captures.
  • list_scenarios — Every scenario with its ordered steps.
  • list_runs — Recent runs, newest first.
  • get_run — One run: status, metrics, which targets were met, what went wrong.
  • get_run_logs — The runner's own output for a run, cleaned of secrets.
  • get_usage — The plan, the VU-minutes used this month, and what is left.

Building

  • import_spec — An OpenAPI 3 document or a Postman v2.1 collection, by URL or pasted text. It previews first and creates only when called again with confirm.
  • create_request — Add a reusable request, with its assertions and load settings.
  • update_request — Change any field of a request.
  • create_scenario — A journey, optionally seeded from a whole request group.
  • add_step — A step: copied from a request, or written from scratch.
  • update_step — Change a step in place — a capture path, a header, an assertion.
  • reorder_steps — Put a scenario's steps in the order they should run.

Running

  • test_connection — One request, one response. No run is created and no VU-minutes are spent.
  • run_test — Start a run against a request, a step or a scenario.
  • wait_for_run — Poll until it finishes, then answer from the report.
  • pin_baseline — Make a run the baseline later runs are compared against.
  • share_report — A read-only link to one report.

Resources

  • stabula://workspace — The workspace as JSON: plan, usage, groups, requests, scenarios, recent runs.
  • stabula://runs/{id}/report — One run as markdown, for the assistant to quote back.

What it cannot do

The boundary is the token, and it is narrower than the assistant's enthusiasm.

  • One workspace. Everything happens inside the workspace the token belongs to, as the person who created it. Account, billing, team and token endpoints refuse token authentication altogether, so an assistant cannot change your plan, invite anyone, or mint itself another token.
  • Plan limits hold. Simulated users, VU-minutes, concurrent runs and gated test types are enforced by the API, not by the assistant's good manners. A refusal comes back as a sentence naming the limit, which the assistant will read out rather than work around.
  • Secrets do not come back. Auth values can be set when a request is built and are encrypted at rest; no tool returns them. A password sent into a request is not something the assistant can be talked into reading later.
  • Runs are labelled. Anything started this way carries origin: api and shows a CI tag in Results, so you can always tell which runs were yours and which were the assistant's.
  • It cannot run code on your machine. The server only calls the Stabula API. Tests execute in isolated containers on our infrastructure — how that is contained.

If you would rather read the code

The server is MIT licensed — about a thousand lines of TypeScript whose whole job is turning tool calls into HTTP requests. You can read exactly what it sends, fork it, or vendor it. Stabula itself, the service it talks to, is not open source; the token is what pays for the work.