@stabula/mcp
v0.2.1
Published
Model Context Protocol server for Stabula: build, run and read no-code API performance tests from an AI agent.
Maintainers
Readme
@stabula/mcp
The Stabula MCP server. It gives an AI agent the same workspace a person has in the Studio: list what is there, add requests and scenarios, start a run, wait for it, and read the report.
Stabula runs no-code API performance tests. A request is one endpoint with its assertions; a scenario is an ordered set of steps run as one journey. Running spends the workspace's monthly VU-minutes.
The same thing written for people rather than for a terminal: https://stabula.app/mcp.
Install
You need a workspace API token: in Stabula, Settings > API tokens > New token. The token decides which workspace the agent works in, and it is shown only once.
Every plan can use it, including the free one — a run spends VU-minutes whichever way it was started, and that is what the plans meter. Free comes with 60 VU-minutes a month, which is enough to try this.
STABULA_URL can be left out; it defaults to https://studio.stabula.app. Set
it only to point at another installation.
Claude Code
claude mcp add stabula \
--env STABULA_API_TOKEN=stb_your_token \
--env STABULA_URL=https://studio.stabula.app \
-- npx -y @stabula/mcpClaude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"stabula": {
"command": "npx",
"args": ["-y", "@stabula/mcp"],
"env": {
"STABULA_API_TOKEN": "stb_your_token",
"STABULA_URL": "https://studio.stabula.app"
}
}
}
}Cursor (.cursor/mcp.json) takes the same object.
| Variable | Meaning |
| --- | --- |
| STABULA_API_TOKEN | Required. The workspace token, stb_…. |
| STABULA_URL | The Stabula app origin. Defaults to https://studio.stabula.app; use http://localhost:3005 against a development server. |
| STABULA_TIMEOUT_MS | How long to wait for one API call. Default 30000. |
What it can do
Reading: list_requests, get_request, list_scenarios, list_runs,
get_run, get_run_logs, get_usage.
Building: create_request, update_request, create_scenario, add_step,
update_step, reorder_steps, import_spec (an OpenAPI 3 document or a
Postman v2.1 collection, by URL or pasted text; it previews first and only
creates when called again with confirm: true).
Running: test_connection (one request, no run, no VU-minutes),
run_test, wait_for_run, pin_baseline, share_report.
Resources: stabula://workspace is the workspace as JSON (plan, usage,
groups, requests, scenarios, recent runs); stabula://runs/{id}/report is one
run as markdown, for the agent to quote.
A typical exchange: "Load test POST https://api.example.com/orders with 50
users for 5 minutes and tell me if p95 stays under 300 ms." The agent creates
the request with max_p95_ms: 300, runs it, waits, and answers from the report.
Signed-in journeys
Most things worth load testing happen after a login, and a step often needs
something the step before it created. Two fields on add_step cover it:
capturespulls a value out of a step's response —{ name: "token", source: "json", path: "data.access_token" }— and any later step uses it as{{token}}in its URL, headers, query values or body.run_once: truemarks the sign-in step. It runs once per simulated user rather than on every iteration, and that user stops if it fails or the capture comes back empty.
"Import my Swagger, then load test signing in, adding an item to an order and removing it again."
// add_step — the sign-in, once per user
{ "scenario_id": 3, "name": "Sign in", "method": "POST",
"url": "https://api.example.com/login", "body_type": "json",
"body_raw": "{\"email\":\"[email protected]\",\"password\":\"…\"}",
"run_once": true,
"captures": [{ "name": "token", "source": "json", "path": "data.access_token" }] }
// add_step — creates the item, and remembers which one
{ "scenario_id": 3, "name": "Add item", "method": "POST",
"url": "https://api.example.com/orders/{{order_id}}/items",
"headers": { "Authorization": "Bearer {{token}}" },
"captures": [{ "name": "item_id", "source": "json", "path": "data.id" }] }
// add_step — removes the one this iteration added
{ "scenario_id": 3, "name": "Remove item", "method": "DELETE",
"url": "https://api.example.com/orders/{{order_id}}/items/{{item_id}}",
"headers": { "Authorization": "Bearer {{token}}" }, "expected_status": 204 }Two things worth knowing before this runs against anything real. Every
iteration adds and removes, so the test writes to whatever it is pointed at —
use a staging environment. And a {{name}} nothing captured is sent as
written, not blank: a broken run shows the placeholder in the failing URL
instead of hiding it.
Rules it works under
- The token is the boundary. Everything happens inside that workspace, as the person who created the token. Account, billing, team, and token endpoints refuse token authentication, so the agent cannot touch them.
- Plan limits apply exactly as in the Studio. Users, VU-minutes, concurrent runs, and gated test types are enforced by the API; a refusal comes back as a sentence naming the limit.
- Runs are tagged. Anything started this way carries
origin: apiand shows a CI tag in Results, so a person can tell agent runs from their own. - Secrets do not come back. Auth values can be sent when creating a request and are stored encrypted; no tool ever returns them, and file bodies are reported by name and size only.
- Rate limits are the API's own: 300 requests a minute per IP, with tighter caps on sign-in and account endpoints the server never calls.
Development
npm install
npm test # tools end to end against a faked API
npm run typecheck # regenerates types from packages/contracts/openapi.yaml
npm run build # dist/index.js, the stdio entry pointThe response types come from packages/contracts/openapi.yaml, so a change to
the API that this server has not caught up with fails the typecheck.
Point it at a development server with STABULA_URL=http://localhost:3005 and a
token minted in that installation.
Licence
This package — the MCP server that talks to Stabula — is MIT licensed, so you can read it, fork it, vendor it, or take it apart to see what it sends.
Stabula itself, the service it talks to, is not open source. The token you give this server is what pays for the work: running a test spends your workspace's VU-minutes.
