The pattern that makes this category worth it
Set up through the API, act through the UI, assert against the database. Postman
creates the order in one call instead of six screens of clicking. Playwright performs the one
interaction you're actually testing. The database confirms the row landed with the right tenant id,
status, and audit entry. Each layer does what it's best at, and no layer is grading its own homework.
11
Postman MCP
Collections, environments, specs and mock servers, driven
from the agent — with the option of a minimal read-only toolset.
Official · Postman
Remote or local
API key / OAuth
Core stack
Why a tester should care
Two distinct jobs, and it's worth separating them because they have different value profiles.
Job one: API testing proper. Generate a collection from an OpenAPI spec, add
contract assertions to every request, and find the endpoints where the implementation drifted from
the documentation. That drift is a defect class most teams never systematically test for, because
doing it by hand across 80 endpoints is nobody's idea of a good week.
Job two: state setup for UI tests. Less glamorous, more valuable day to day. Reaching
"user with a pending refund on an order older than 30 days" through the UI takes six screens and
ninety seconds; through the API it takes one call and 200 ms. Multiply by every test in your
suite and it's the difference between a suite that runs in four minutes and one that runs in forty.
| Group | Representative tools | Notes |
| Discovery | getWorkspaces, getCollections, getCollection, searchPostmanElements | Safe. Where every session should start. |
| Authoring | createCollection, createCollectionRequest, updateCollectionRequest, putCollection | putCollection replaces the whole collection — highest-risk tool here |
| Environments | getEnvironments, createEnvironment, putEnvironment | Where the secrets live. Be careful what gets echoed into chat. |
| Specs | createSpec, getSpecDefinition, generateCollectionFromSpec, syncCollectionWithSpec | Spec-first contract testing lives here |
| Mocks | createMock, getMocks, publishMock | Test the frontend against an unbuilt backend |
Wire it up
Postman offers a hosted remote server (recommended — nothing to install, OAuth-based) and a local
npm package for air-gapped or proxy-constrained setups.
shell — remote, minimal toolset
claude mcp add --transport http postman https://mcp.postman.com/minimal
mcp config — local package with API key
{
"mcpServers": {
"postman": {
"command": "npx",
"args": ["-y", "@postman/mcp-server", "--region", "us"],
"env": {
"POSTMAN_API_KEY": "${POSTMAN_API_KEY}"
}
}
}
}
Use the minimal toolset first
The full toolset exposes a large number of tools, which is a lot of context spent on capabilities
you probably aren't using. The minimal set covers the common read and run paths. Start minimal, and
only move to full when you hit something you genuinely need.
Workflows
1 · Contract drift detection
Compare the "Payments API" collection against the OpenAPI spec in the same workspace.
List: endpoints in the spec with no request in the collection, requests whose parameters don't match
the spec, and response examples that violate the declared schema.
This is the single highest-value prompt in this guide. It finds real defects, it takes seconds, and
almost nobody does it manually.
2 · Negative-test generation
For every request in the "Orders" collection, add tests for: missing required fields,
wrong types, boundary values on numeric fields, expired auth token, and another tenant's resource id.
Show me the test scripts before saving.
Authorisation bypass — "another tenant's resource id" — is where multi-tenant products break, and
it's the case human testers skip most often because it's tedious to set up.
3 · State setup for the UI suite
Using the "Test Fixtures" collection against the staging environment, create a user
with a pending refund on an order older than 30 days. Return the user id and credentials as JSON so
I can feed them into the Playwright test.
4 · Mock-first frontend testing
Create a mock server from the Payments spec with examples for 200, 402, 429 and 500.
Give me the mock URL so I can point the staging frontend at it and test the error states properly.
Error-state UI is chronically under-tested because triggering a real 429 is hard. A mock makes it
trivial, and error states are where users actually get stuck.
Gotchas
- Shared workspaces mean shared consequences.
putCollection overwrites.
Have the agent work in a personal workspace and promote deliberately.
- Secrets in environments. Ask for an environment's contents and you may get an API
key printed into the transcript. Use secret-type variables and avoid dumping environments wholesale.
- Collection ≠ execution. The MCP server manages Postman resources; running a
collection in CI is still Newman or Postman CLI. Don't assume "run the collection" means what you
think it means — check what your chosen setup actually executes.
- Generated tests over-assert on the happy path. Status 200 and a schema check is a
starting point, not a test. Push for business-rule assertions.
Verdict
Core stack. Contract-drift detection alone pays for it, and the state-setup role quietly makes your
entire UI suite faster and less flaky.
12
k6 MCP
Generate and execute Grafana k6 load scripts from natural
language, then read the thresholds back.
k6 CLI required
Can DoS your own environment
Status check
k6 itself is Grafana's, open source and very much maintained. The MCP servers that wrap it
are community projects — thin shells around k6 run. Grafana also publishes
xk6-mcp, which is the reverse idea: a k6 extension for load-testing MCP servers
themselves. Useful, and not what this section is about — don't install it expecting a load-testing
MCP server.
Why a tester should care
The barrier to performance testing was never the tooling — k6 scripts are ordinary JavaScript. It
was that writing a realistic load profile means thinking about ramp shapes, think time, correlation
of dynamic tokens, and threshold definitions, and most teams give up and run 100 flat VUs against
one endpoint, which measures nothing useful.
An agent that can draft "ramp to 200 VUs over 5 minutes, hold 10, ramp down, with p(95) under 800ms
and error rate under 1%" from a sentence removes that barrier. Whether the resulting numbers mean
anything still depends entirely on whether your load model resembles reality — and that judgement
stays yours.
Minimal by nature. Typically execute_k6_test (script path, duration, VUs) and
execute_k6_test_with_options (arbitrary CLI flags), sometimes plus a script-generation
helper. The real surface is k6 itself: stages, thresholds, checks, scenarios, and the metrics output.
Wire it up
shell — install k6 first
winget install k6 --source winget
k6 version
mcp config
{
"mcpServers": {
"k6": {
"command": "uvx",
"args": ["k6-mcp-server"],
"env": {
"K6_BIN": "k6",
"K6_SCRIPTS_DIR": "./perf"
}
}
}
}
Environment isolation is not optional
This is the one server in this guide that can cause a production outage by doing exactly what it
was told. Three rails, all of them configuration rather than prompting:
- Base URL comes from an environment variable that only ever points at a load-test
environment. Never let the agent type a hostname.
- Cap VUs and duration in the script template, not in the prompt.
- Run from a host that has no network route to production. If the packet can't leave, no prompt
can send it.
Workflows
1 · Draft the load profile from a requirement
Write a k6 script for the checkout flow: browse → add to cart → checkout, with 3–8
seconds think time between steps. Ramp 0→200 VUs over 5 minutes, hold 10 minutes, ramp down over 2.
Thresholds: p(95) under 800ms, error rate under 1%, checkout success rate above 99%. Target
__ENV.BASE_URL. Save it, don't run it yet.
"Save it, don't run it" should be your default with this server, every time, without exception.
2 · Review before execute
Show me the script. Confirm the target host resolves from BASE_URL only, the peak VU
count, total request estimate, and roughly what that costs the target in requests per second.
3 · Interpret the results
Run it against the perf environment. Then tell me which thresholds failed, where in
the ramp latency started degrading, and whether the failures cluster on a particular endpoint or
appear across the board.
"Where in the ramp did it degrade" is the question that distinguishes a capacity limit from a leak.
Degradation at a fixed VU count is saturation; degradation over time at constant load is a leak.
4 · Regression comparison
Compare this run's summary to perf/baseline-4.1.json. Report p(95), p(99)
and error-rate deltas per endpoint, and flag anything more than 15% worse.
Gotchas
- Generated scripts miss correlation. Agents happily hardcode a session token from an
example. Real load tests must extract tokens, ids, and CSRF values from responses. Review for this
specifically — it's the most common defect in generated k6 code.
- Think time gets forgotten. Without
sleep(), 200 VUs generate load no
real population of 200 users ever would, and your results are meaningless.
- Local runs are load-generator-bound. Your laptop is not a load generator. Past a few
hundred VUs you're measuring your own machine.
- Long runs block. A 30-minute soak inside a conversation is awkward. Run those in CI
and have the agent read the output afterwards.
Verdict
Excellent for lowering the barrier to writing performance tests; dangerous if the environment
isolation is sloppy. Adopt with hard configuration limits and a strict draft-then-run habit.
13
Supabase / Postgres MCP
The independent oracle. Verify state, seed fixtures, check
migrations, and inspect logs — read-only unless you have a very good reason.
Official · Supabase
PAT / connection string
Critical without --read-only
Core stack
Why a tester should care
Almost every weak UI test has the same flaw: it asserts on what the UI says happened rather than on
what happened. The UI can show "Saved" while the write silently failed, landed in the wrong tenant,
or skipped the audit trail. Database access gives your tests an oracle the application didn't
produce — the single biggest quality upgrade available to a functional suite.
For Supabase specifically there is a second, sharper use: Row Level Security verification.
RLS policies are security controls expressed as SQL, they're easy to get subtly wrong, and the failure
mode is cross-tenant data exposure. Being able to ask "which tables have RLS disabled" and to run the
same query as two different roles is a security test you can run in a sentence.
| Group | Representative tools | QA use |
| Schema | list_tables, list_extensions, list_migrations | Understand structure; confirm a migration actually applied |
| Query | execute_sql | The workhorse. Read-only mode makes it safe. |
| Advisors | get_advisors | Security and performance findings — including missing RLS |
| Logs | query_logs | API, auth, and Postgres logs — correlate a UI failure to a server error |
| Branches | create_branch, merge_branch, reset_branch | Ephemeral test databases per feature branch |
| Migrations | apply_migration | Write. Not something a test agent should have. |
Wire it up
mcp config — Supabase, scoped and read-only
{
"mcpServers": {
"supabase": {
"command": "npx",
"args": [
"-y", "@supabase/mcp-server-supabase@latest",
"--read-only",
"--project-ref=<staging-project-ref>"
],
"env": {
"SUPABASE_ACCESS_TOKEN": "${SUPABASE_ACCESS_TOKEN}"
}
}
}
}
Both flags matter and they do different jobs. --read-only means no tool call can mutate
data. --project-ref pins the server to one project, so a confused agent cannot reach
your production instance even if it names it. Set both.
For plain Postgres, use a dedicated read-only role rather than trusting a flag:
sql — create the role your MCP server connects as
CREATE ROLE qa_agent_ro LOGIN PASSWORD '<strong-password>';
GRANT CONNECT ON DATABASE app_staging TO qa_agent_ro;
GRANT USAGE ON SCHEMA public TO qa_agent_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO qa_agent_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO qa_agent_ro;
Why the role beats the flag
A --read-only flag is enforced by the MCP server — software you didn't write. A
SELECT-only Postgres role is enforced by the database. If the server has a bug, or you
typo the flag, or a future version changes its meaning, the database still says no. Defence in depth
costs you five minutes here.
Never point this at production
Even read-only. A SELECT * on a customer table pulls real personal data into a model's
context window, which is a data-protection incident regardless of intent. Staging and test data only.
Workflows
1 · Verify what the UI claimed
I just submitted a refund for order ORD-88213 through the UI. Check the
refunds, orders and audit_log tables: is there exactly one refund
row, is the order status refund_pending, and does the audit log have a matching entry with
the right actor?
Three assertions the UI cannot fake. This is what a real functional test looks like.
2 · Multi-tenant isolation
List every table without RLS enabled. For each with a tenant_id column,
show me the policies. Are there any where a user from tenant A could read tenant B's rows?
3 · Migration verification
Migration 20260813_add_refund_reason just deployed to staging. Confirm the
column exists with the right type and nullability, check whether existing rows were backfilled, and
tell me if any index the migration was supposed to create is missing.
4 · Test-data reconnaissance
I need a user with an active subscription, at least 3 completed orders, and no
payment method on file. Find one in staging, or tell me exactly what's missing so I can construct it.
5 · Correlate a UI failure with a server error
The checkout failed at 14:32 UTC. Query the API and Postgres logs for that window and
show me errors related to the orders or payments path.
Gotchas
- Query results land in the context window.
SELECT * on a big table is
both a context problem and a privacy problem. Always constrain columns and add a LIMIT.
- PII discipline. Even in staging, if the data is a production copy it is production
data. Ask for aggregates and shapes, not raw customer rows.
- The reference Postgres MCP server was archived. Several community successors exist
with different feature sets. Verify maintenance before trusting one with a connection string.
- Testing through the database creates coupling. Assertions on internal schema break
when the schema legitimately changes. Assert on the columns that encode business meaning, not on
every field.
- Don't let it write fixtures into shared environments. If it needs to seed, give it
a branch or an ephemeral database, not the team's staging instance.
Verdict
Core stack, with the read-only role in place before the first query. The independent oracle is the
thing that turns agent-driven UI testing from theatre into testing.
14
Fetch MCP
Retrieve a URL and hand the content to the model as markdown.
Small, useful, and frequently expected to be something it isn't.
MCP reference server
uvx mcp-server-fetch
SSRF-adjacent
What it actually does
Set the expectation correctly and this server is useful; set it wrongly and you'll be frustrated for
an hour. The reference Fetch server retrieves a URL and converts HTML to markdown for the model to
read. It is a content retrieval tool, not an HTTP client. It does not give you
arbitrary methods, custom auth headers, or response-time assertions.
For real API testing use Postman MCP, or have the agent write a script. Use Fetch for what it's good
at: pulling documentation, changelogs, spec pages, or a status endpoint's JSON into context so the
agent can reason about it.
One tool: fetch, taking a URL, an optional max_length, a
start_index for paging through long documents, and a raw flag to skip
markdown conversion. That's the whole thing.
Wire it up
mcp config
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch", "--user-agent", "qa-agent/1.0"]
}
}
}
Requires uv. There is a --ignore-robots-txt flag; leave it off.
The SSRF footnote
A tool that fetches any URL the model chooses, running on a machine inside your network, is a
server-side request forgery primitive. If a page the agent read contains a link to
http://169.254.169.254/ or an internal admin host, it may follow it. On a developer
laptop this is low risk; on a CI runner with cloud metadata access it is not. Run it where it can't
reach anything interesting, and remember that anything it fetches is untrusted data, never
instructions.
Workflows
1 · Read the docs the agent needs
Fetch the changelog at https://api.example.com/docs/changelog and list
breaking changes since v3.2 that would affect our Postman collection.
2 · Health-check sweep
Fetch the /health endpoint for each of our six staging services and tell
me which report degraded dependencies.
3 · Pull a spec into context
Fetch the OpenAPI spec at that URL and list every endpoint with no documented error
responses — those are the ones our tests are probably missing.
Gotchas
- Not an HTTP client. No POST bodies, no custom auth headers, no timing assertions.
- JS-rendered pages come back empty. Use Playwright or Puppeteer for SPAs.
- Content is untrusted. A fetched page saying "ignore previous instructions" is an
injection attempt, and a fetch tool is the cheapest possible delivery mechanism for one.
- Long documents truncate. Use
start_index to page rather than assuming
you got everything.
Verdict
Nice to have, not core. Many clients already have built-in web fetching that covers the same ground —
check before adding a server for it. If you do add it, run it somewhere it can't reach your internal
network.
Wiring Postman + Playwright + Supabase together
The three-layer test is the reason to adopt this category. Here it is as one flow:
- Arrange — Postman. Call the fixtures collection to create exactly the state the test
needs. Capture the ids it returns. Fast, deterministic, no UI involved.
- Act — Playwright. Log in with that user, navigate directly to the relevant screen,
perform the one interaction under test. Nothing else — every extra step is a chance to fail for an
unrelated reason.
- Assert (UI) — Playwright. Check what the user is told: the confirmation, the updated
total, the new row in the table.
- Assert (truth) — Supabase. Check what actually happened: the row, its status, the
audit entry, the tenant id. This is the assertion that catches the bug the UI hides.
- Evidence — trace + query results. Playwright trace plus the SQL output is a defect
report a developer can act on without asking you a single follow-up question.
Using the Test Fixtures collection, create a user with a pending refund. Then with
Playwright, log in as that user on staging and approve the refund from the admin panel. Assert the UI
shows "Refund approved". Then query staging: confirm the refund row moved to approved, the
order total is unchanged, and there's an audit entry with the admin's id. Report each assertion
separately and save the trace.
Full end-to-end evidence pipeline, including CI integration, is in the
playbooks.