MCP
Patchrooms exposes a Model Context Protocol endpoint so an AI agent (Claude, Cursor, and others) can list, read, file, and triage the feedback reports for a project. It is the same data you see in the dashboard, served as JSON-RPC over a single HTTP endpoint.
Endpoint
Section titled “Endpoint”POST https://room.patchrooms.com/mcpThe endpoint speaks JSON-RPC 2.0. Send method, params, and an id in the
request body; the response echoes the id.
Authentication
Section titled “Authentication”Authenticate with a secret API key (prefix pr_sk_) created in the dashboard,
sent as a Bearer token:
Authorization: Bearer pr_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxThe project is resolved from the key — there is no project id in the URL. The
key must carry the feedback:read scope for list_reports / get_report, or
the endpoint returns 403. set_status additionally requires feedback:write.
Create the key
Section titled “Create the key”In the dashboard, open the project → Integrations → API keys → Create, and pick the scopes the agent needs:
feedback:read—list_reportsandget_report.feedback:write— additionally allowsset_status(triage).channel:read/channel:write— read or manage channels (REST API).project:read/project:write— read or configure the project (REST API).apikey:write— mint and revoke keys (REST API).*— wildcard, satisfies any scope. Reserved for short-lived setup tokens minted in the dashboard; it cannot be minted via the API itself.
The pr_sk_… value is shown only once at creation. Store it in an environment
variable (e.g. PATCHROOMS_API_KEY) or your agent’s credential store. Keys may
carry an optional TTL — used for setup tokens, which expire and are revoked after
provisioning (see Agent self-setup).
Connect a coding agent
Section titled “Connect a coding agent”Point your agent’s MCP client at the endpoint with the key as a Bearer header, read from the environment — never hard-code or commit it.
Claude Code — register the server (project scope writes .mcp.json):
claude mcp add --transport http patchrooms https://room.patchrooms.com/mcp \ --header "Authorization: Bearer $PATCHROOMS_API_KEY" --scope project…or write .mcp.json yourself, keeping the key in an env var:
{ "mcpServers": { "patchrooms": { "type": "http", "url": "https://room.patchrooms.com/mcp", "headers": { "Authorization": "Bearer ${PATCHROOMS_API_KEY}" } } }}${PATCHROOMS_API_KEY} is expanded from the shell that launched Claude Code, so
export it before starting a session. Cursor, Windsurf, and other MCP clients
take the same URL + Bearer header in their own config.
On first use, call introduce with your agent’s name (and owner,
if known) — it’s a one-line call and every report you file or view afterward
carries that name instead of the raw key name.
No MCP client? The JSON-RPC tools/call POST shown below works from curl
or any script — read the key from the environment and hit the endpoint directly.
Connect claude.ai / Cowork (OAuth)
Section titled “Connect claude.ai / Cowork (OAuth)”Custom connectors on claude.ai cannot send a custom header — they authenticate via OAuth instead. No API key needed; add a connector with just the URL:
Settings → Connectors → Add custom connector → https://room.patchrooms.com/mcp
Claude discovers the OAuth endpoints automatically and opens a Patchrooms consent page. Sign in with your Patchrooms account (if you aren’t already), pick what to share — a single project, or All projects of an organization — plus the access level (read-only, or read + triage), and click Authorize. That’s it.
With an org-wide grant, list_reports spans every project in the organization
(each item carries a project name), and get_report / set_status accept
reports from any of them. Org-wide keys work on the MCP endpoint; the
REST API still requires a per-project key.
Behind the scenes a dedicated API key named OAuth: <client> is minted for the
connector, scoped to exactly what you picked. It shows up under
Integrations → API keys like any other key — revoke it there at any time to
disconnect the client. Reconnecting the connector just walks the same flow and
mints a fresh key.
Any other OAuth-capable MCP client (MCP Inspector and others) connects the same way: point it at the endpoint URL and it will walk the same flow.
The server advertises seven tools via tools/list.
introduce
Section titled “introduce”Introduces the calling agent — call this once, before the other tools. It labels the API key so reports the agent files or reads get attributed to it by name, instead of the raw key name.
| Argument | Type | Description |
|---|---|---|
agentName | string | Required. How to label this agent, e.g. "Claude (health-os)". |
owner | string | Who this agent belongs to, e.g. a user or team name. |
Optional — nothing blocks the other tools if you skip it, but reports and views fall back to the API key’s own name instead of an agent-chosen label.
list_reports
Section titled “list_reports”Lists feedback reports for the project, newest first, in a compact form. Every report returned is marked viewed by the calling agent (fire-and-forget, never blocks the response) — see Read tracking.
| Argument | Type | Description |
|---|---|---|
status | string | Filter by report status. |
channelKey | string | Filter by channel key. |
artifactId | string | Filter by artifact id. |
limit | number | Max results. Defaults to 50, capped at 200. |
All arguments are optional.
get_report
Section titled “get_report”Returns a single report rendered as Markdown, with its screenshots inlined as
image content the agent can look at directly — up to 6 images, capped at 8 MB
in total, no separate download step. Marks the report viewed by the calling
agent, same as list_reports.
| Argument | Type | Description |
|---|---|---|
id | string | Report id. Required. |
create_report
Section titled “create_report”Files a new feedback report — for agents that spot issues themselves (a failed
check, a broken widget, an API defect). The report is marked as submitted via
MCP (context.extra.via = 'mcp'). Requires the feedback:write scope.
| Argument | Type | Description |
|---|---|---|
message | string | Report body, plain text or Markdown. Required. |
channelKey | string | Channel key. Defaults to the project’s default channel. |
url | string | Page or resource the report is about. |
author | string | Freeform note on who’s filing this, stored in context.extra. Doesn’t affect the report’s structured author — that’s always agent:<key>, labelled from introduce. |
project | string | Project id, key, slug, or name. Required for org-wide keys. |
create_room
Section titled “create_room”Starts (or resumes) a room for an artifact/task you’re working on — idempotent
upsert by artifact_id, safe to call every time you begin work, before any
report exists. Requires the feedback:write scope.
| Argument | Type | Description |
|---|---|---|
artifact_id | string | Required. Stable id for the artifact/task — reports and future create_room calls group under this. |
title | string | Human-readable room title. |
goal | string | What you’re trying to accomplish in this room. |
project | string | Project id, key, slug, or name. Required for org-wide keys. |
set_status
Section titled “set_status”Triages a report by setting its status. Requires the feedback:write scope.
| Argument | Type | Description |
|---|---|---|
id | string | Report id. Required. |
status | string | One of new, triaged, in-progress, fixed, verified, canceled. Required. |
Set fixed once the change is made; verified means a human confirmed it
works, so leave that one to them unless you’re asked otherwise.
add_comment
Section titled “add_comment”Replies in a report’s comment thread — progress updates, questions, or an
explanation of a fix on a report the agent is already working. Requires the
feedback:write scope.
Comments land as drafts by default. A draft is visible only in the
dashboard, where a human reads it and either publishes it as the agent, edits
the text first, or publishes it under their own name. Nothing reaches the
thread until they do. Pass draft: false to post straight to the thread —
appropriate in an unattended loop with no human review step, or when the
person asked for it explicitly.
| Argument | Type | Description |
|---|---|---|
report_id | string | Report id. Required. |
text | string | Comment body, plain text or Markdown. Required. |
draft | boolean | Defaults to true (hold for human approval). false publishes immediately. |
kind | string | Optional label for triage: fix, question, options, deferral, techdebt. |
kind is what makes a batch of replies skimmable — a human can filter to
every question blocking the agent instead of reading each comment. Use fix
for a change already made, question when an answer is needed to proceed,
options when presenting alternatives with tradeoffs, deferral when
proposing to postpone with a reason, techdebt when explaining why something
is expensive because of existing debt.
Example
Section titled “Example”List the most recent reports:
curl -s https://room.patchrooms.com/mcp \ -H "Authorization: Bearer pr_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "list_reports", "arguments": { "limit": 2 } } }'The result is a tool-call envelope whose text content is a JSON array of reports:
{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "[\n {\n \"id\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n \"shortId\": \"9c0d\",\n \"title\": \"Checkout button misaligned on mobile\",\n \"status\": \"open\",\n \"channelKey\": \"bug\",\n \"url\": \"https://app.example.com/checkout\",\n \"artifactId\": null,\n \"createdAt\": \"2026-06-03T09:14:22.000Z\"\n }\n]" } ] }}Fetch one report as Markdown:
curl -s https://room.patchrooms.com/mcp \ -H "Authorization: Bearer pr_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_report", "arguments": { "id": "665f1a2b3c4d5e6f7a8b9c0d" } } }'The result content is the report rendered as a Markdown string. A report id
that is malformed, or that does not belong to your project, returns a tool
result with isError: true.
Protocol notes
Section titled “Protocol notes”initializereturns protocol version2024-11-05and advertises tool support.tools/listreturns the seven tools above.tools/callruns a tool. An unknown tool or method returns a JSON-RPC error with code-32601.