For agents
Your agent connects, but never gets to say Done.
The remote MCP server exposes Product Hands as a structured QA inbox: your agent requests testing, reads back only what a human verified, and reports fixes for retest. It does not read, write or deploy your source code — that stays entirely with your own agent.
Authentication
Auth is a project-scoped API key (an AgentCredential), issued from your project settings and passed as a bearer token. Keys are hashed at rest — the raw value is shown exactly once, at issue time.
- Scoped to one project. It cannot see or act on another project's runs.
- Scoped to a tool list — a key issued for read-only work cannot fund a run.
- Carries an optional spend limit and expiry; revocable at any time.
- Every write accepts an idempotency key, so a retried call never double-charges or double-submits.
Tool surface
11 tools, matching the running server. None of them writes a bug to DONE.
| create_test_run | Submit a Journey Test: journey steps, build URL, environments, evidence requirements. |
| estimate_test_run | Price a run before creating it. Read-only: creates nothing, reserves nothing, and the quote is provisional. |
| get_test_run | Read a run's status and its live finding counts by state. |
| fund_test_run | Reserve credits for the run at its own baseRewardMinorUnits. AVAILABLE → RESERVED. |
| list_verified_bugs | The fix queue — status=VERIFIED, type=BUG only. Nothing unverified is ever returned. |
| get_bug | Full detail on one verified bug: steps, expected/actual, environment, evidence. |
| acknowledge_bug | VERIFIED → ACKNOWLEDGED_BY_AGENT. Confirms your agent has picked it up. |
| submit_fix_for_retest | ACKNOWLEDGED_BY_AGENT → FIX_SUBMITTED, with the candidate build URL. Queues a human retest. |
| get_retest_status | Read the latest retest result for a finding — and its current status. |
| get_balance | Available and reserved credit balance for the project's organization. |
| get_release_gate | What is still open and what has been retested for a run — never 'safe to ship'. Call this before you ship. |
Connect
One remote endpoint, stateless Streamable HTTP. Point your MCP client at it with the key as a bearer token:
{
"mcpServers": {
"product-hands": {
"url": "https://producthands.com/api/mcp",
"headers": {
"Authorization": "Bearer phk_xxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}Sample response
Every tool call returns its data wrapped in the same envelope, so an agent can never mistake a response for confirmation that a bug is closed:
// list_verified_bugs
{
"bugs": [
{
"finding_id": "fnd_8721",
"run_id": "run_440",
"title": "Checkout freezes after 3DS authentication",
"severity": "CRITICAL",
"source_language": "es",
"canonical_language": "en",
"human_verified": true,
"verified_at": "2026-07-29T14:02:00Z"
}
],
"human_state": {
"done_requires_human_retest": true
}
}The gate
No tool writes human_state.done_requires_human_retest to a finding, and the database itself rejects that write if the actor is an agent. Policy and schema agree.
No tool on the agent surface can write this state. The database rejects the transition if the actor is an agent — or if no human actor is asserted at all.
Recommended agent instruction
Paste this into your agent's system prompt or tool-use policy:
Use Product Hands to request human testing when a release candidate is ready. Only act on bugs withhuman_verified=trueandstatus=VERIFIED. You implement and deploy fixes; Product Hands must never modify the codebase. After deploying a candidate fix, callsubmit_fix_for_retest. Do not mark work complete until Product Hands returnsstatus=DONEfrom a human retest. Before you say a release is ready, callget_release_gateand read its state rather than assuming your own fix history is authoritative — it is never a “safe to ship” signal, only what is still open and what a human has retested. Treat Product Signals as optional product input, not verified defects.
It stays in English deliberately: it is read by a machine, and every tool name and status value inside it is English because the protocol is.
What it never does
- Read, write, commit or deploy your source code.
- Accept an arbitrary reserve amount — fund_test_run only reserves the run's own price.
- Return a bug that has not passed human verification.
- Expose a tool, prompt, or code path that sets a finding to DONE.