Signal
EN TR Sign in Start free
MCP Claude builds and runs your tests

A 200 response
is not a passing test.

Signal fires your API, chains the values it returns, then verifies what actually landed in Postgres, MySQL, Redis and Mongo.

Start free See a flow run
Postman import in one paste Encrypted database credentials CI exit codes + JUnit
signal · checkout api · staging
running live
Flow 7 steps · 2 DB
POST Create customer 201 · 412ms
POST {{baseUrl}}/v3/customers
CALL auth: get bearer token ok · 340ms
↳ sub-flow · shares variables
POST Start subscription 201 · 518ms
POST {{baseUrl}}/v3/subscriptions
WAIT Let the webhook land done
wait 1 500 ms
DB subscriptions row is active assert failed
postgres · SELECT … WHERE id = {{subId}}
DB ledger cache warmed skipped
redis · GET ledger:{{customerId}}
GET Invoice reflects the plan skipped
GET {{baseUrl}}/v3/invoices
Database assertion
SELECT status, plan_id, renews_at
FROM subscriptions
WHERE id = {{subId}}
 
-- 1 row · 64 ms
rowCount == 1 got 1
rows.0.status == "active" got "trialing"
rows.0.plan_id == {{planId}} skipped after failure
Caught it: the API said 201, the row said trialing.
The difference

Most tools stop at the response body.

That is where the interesting bugs start. A webhook that never fires, a ledger row that never lands, a cache that never invalidates — all of it returns 200.

Chain HTTP into SQL A value extracted from a response goes straight into WHERE id = {{subId}}.
Four connectors, one step type PostgreSQL, MySQL, Redis and MongoDB assertions live next to your HTTP steps.
Encrypted credentials Connection passwords are sealed with libsodium and never returned to the browser.
Waterfall
3 140 ms
POST Create customer 412 ms
CALL auth: token 340 ms
POST Start subscription 518 ms
WAIT Webhook window 1500 ms
DB subscriptions row 64 ms
DB ledger cache
GET Invoice check
PostgreSQL
SELECT
MySQL
SELECT
Redis
GET / EXISTS
MongoDB
find / count
What you get

A workbench, a flow engine and a scheduler — in one place.

Request workbench

Collections, folders, saved examples, variable highlighting and code generation. Import a Postman collection and keep working.

Collection v2.1Environments
Flows that chain

Extract a value, assert on it, feed it into the next step. Conditions, loops, retries and sub-flows called by reference.

extractassertsub-flow
Database assertions

rowCount, row values, Redis keys, Mongo documents — asserted in the same run as the request that caused them.

SQLRedisMongo
Suites and schedules

Group flows into suites, run a suite end to end, or let cron do it every fifteen minutes.

cronstopOnFailure
CI without glue code

One authenticated POST runs a flow and returns 422 on failure. Ask for JUnit XML and your pipeline renders it.

Bearer tokenJUnit XML
Built for teams

Companies, workspaces, members and API tokens — every resource scoped, including the MCP session.

workspacesroles
MCP SERVER

Describe the test. Claude wires it up.

A Streamable HTTP MCP endpoint inside the app, scoped to a single workspace by the same Bearer token. Nineteen tools, no separate Node process.

SCOPE whoami
READ list_flows · get_run · search_requests
BUILD create_flow · add_http_step · add_db_step
RUN run_flow · run_flow_async
claude mcp add --transport http signal https://signalapi.dev/mcp
you Hit the signup request, then check the subscriptions table has an active row for that user.
claude Found POST /v3/customers in Checkout v3. Creating flow "signup → subscription".
tool add_http_step · add_db_step · run_flow
claude Ran it: 6 of 7 passed. rows.0.status came back trialing, not active — want me to add a 2s wait before the check?
Triggers

Run it from wherever you already work.

One authenticated call runs a flow and answers with the verdict — 200 when it passes, 422 when it does not. Or let cron, your pipeline or Claude start it.

GitHub Actions GitLab CI cron schedules API tokens JUnit XML Claude MCP
bash
# in your pipeline — non-zero exit when a step fails
curl -fsS -X POST \
-H "Authorization: Bearer $TOKEN" \
signalapi.dev/api/v1/flows/$FLOW/run
 
# same call, JUnit XML your CI can render
curl -fsS -X POST \
-H "Authorization: Bearer $TOKEN" \
signalapi.dev/api/v1/flows/$FLOW/run?format=junit

Stop trusting the status code.

Create a workspace, import your Postman collection and watch the first flow verify itself against your database.

Start free See a flow run