You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: SETUP.md
+46Lines changed: 46 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -621,6 +621,52 @@ The key is **required for the feature but optional at boot**: the worker starts
621
621
622
622
> **Security warning.** The shipped `webhook-ticket-triage` template feeds external input (a support ticket body) straight through to an automatically opened pull request with **no human gate**. HMAC authenticates the **channel**, not the **content**: anyone who can file a ticket into a connected Zendesk or Sentry controls the agent's prompt, and therefore the PR it opens. Before pointing a real sender at this template, add a human-approval gate before the `open_pr` block, or treat the workflow as triage-and-notify only.
623
623
624
+
### Remote MCP — connect your agent
625
+
626
+
A deployment can expose an [MCP](https://modelcontextprotocol.io) endpoint so an external agent (Claude, or any MCP-capable client) can inspect this deployment's workflows, block catalog and run history, and — if you grant it the scope — author and dispatch workflows itself. It is off by default and entirely additive: nothing here is required for the bot to run.
627
+
628
+
| Variable | Value |
629
+
| --- | --- |
630
+
|`MCP_ENABLED`|`true` to turn the endpoint on. Defaults to `false`. |
631
+
|`MCP_ALLOW_PUBLIC_DCR`|`true` to let a connecting client register itself via OAuth Dynamic Client Registration, with no client pre-provisioned. Defaults to `false`. This is the path a customer engineer wiring up their own agent normally wants. |
632
+
633
+
```bash
634
+
vercel env add MCP_ENABLED production
635
+
vercel env add MCP_ALLOW_PUBLIC_DCR production
636
+
```
637
+
638
+
Redeploy after setting either variable.
639
+
640
+
**Connecting.** Point your agent's MCP client at:
641
+
642
+
```
643
+
https://<your-worker>.vercel.app/mcp
644
+
```
645
+
646
+
using the Streamable HTTP transport at protocol version `2025-11-25` (`2025-06-18` is also accepted). Authentication is standard MCP OAuth: an MCP-compliant client discovers the authorization requirements from the endpoint itself (`WWW-Authenticate`, then `.well-known/oauth-protected-resource` and `.well-known/oauth-authorization-server`), registers itself if `MCP_ALLOW_PUBLIC_DCR` is on, and opens a browser tab for the connecting person to log in and approve a consent screen — nothing is pasted or configured by hand. Approve only the scopes the agent actually needs:
647
+
648
+
| Scope | Grants |
649
+
| --- | --- |
650
+
|`mcp:read`| Read tickets, runs, workflows, prompts and the block catalog. Enough to inspect a deployment without changing anything. |
651
+
|`runs:dispatch`| Start a manual run, answer a run's clarification, cancel a run. |
652
+
|`workflows:write`| Author workflows: create a definition, save a draft graph, publish it live. |
653
+
|`prompts:write`| Edit the prompt library. |
654
+
|`tickets:write`| Comment on, transition, or create a ticket in the connected tracker. |
655
+
656
+
**Verifying the connection.** Ask the connected agent to call `system.capabilities` (confirms the handshake and reports the enabled tool domains) and then `blocks.list` (confirms it can read this deployment's block catalog — every block type the editor offers, with its input and output contract, so an authoring agent can compose a valid graph without guessing a field name and finding out from a `VALIDATION_FAILED`).
657
+
658
+
**A worked example: a loop and a branch together.**[`docs/example-workflows/loop-branch-workflow.json`](./docs/example-workflows/loop-branch-workflow.json) is a complete, valid workflow graph an agent can read for a concrete pattern rather than reasoning from the block catalog alone. Shape:
verdict --false--> loop(retry) --continue--> review_agent(fix) -> back to run_pre_pr_checks
666
+
```
667
+
668
+
`branch` reads a `condition` param and fires its `true` or `false` port; `loop` re-enters its `continue` port up to `maxAttempts` times before taking `onExhaust`. To try it against a real deployment, hand the file to `workflows.create` + `workflows.save_draft` (the same graph the dashboard editor would save), then `workflows.publish` when ready to go live — publishing arms whatever triggers the graph contains, so read each tool's description before calling it against anything but a scratch definition.
"description": "List every block type this deployment's workflow editor offers, with its presentation (label, group, description), its input contract, its output contract and the status variants it can report. `availability.available` is false for a block this deployment cannot run today (no provider configured), naming why in `unavailableReason`; the block still lists, because a graph authored now may become runnable once the provider is.",
852
+
"inputSchema": {
853
+
"type": "object",
854
+
"properties": {}
855
+
},
856
+
"annotations": {
857
+
"readOnlyHint": true,
858
+
"destructiveHint": false,
859
+
"idempotentHint": true,
860
+
"openWorldHint": false
861
+
}
862
+
},
863
+
{
864
+
"name": "blocks.get",
865
+
"description": "Read one block type's contract by name: the same object blocks.list returns for it. An unrecognized `type` is refused with NOT_FOUND rather than VALIDATION_FAILED, since block types are versioned by the deployment, not by this catalog.",
"description": "Roll up recent run outcomes and aggregate spend for a time window (default 24h, matching the dashboard's own default). `runs` is the newest page of outcomes in the window (`runsTruncated` says whether more exist); `cost` is the same windowed total, per-workflow breakdown and daily series the dashboard's cost view reads, computed from persisted per-run cost rather than an external provider.",
"List every block type this deployment's workflow editor offers, with its presentation (label, group, description), its input contract, its output contract and the status variants it can report. `availability.available` is false for a block this deployment cannot run today (no provider configured), naming why in `unavailableReason`; the block still lists, because a graph authored now may become runnable once the provider is.",
"Read one block type's contract by name: the same object blocks.list returns for it. An unrecognized `type` is refused with NOT_FOUND rather than VALIDATION_FAILED, since block types are versioned by the deployment, not by this catalog.",
"Roll up recent run outcomes and aggregate spend for a time window (default 24h, matching the dashboard's own default). `runs` is the newest page of outcomes in the window (`runsTruncated` says whether more exist); `cost` is the same windowed total, per-workflow breakdown and daily series the dashboard's cost view reads, computed from persisted per-run cost rather than an external provider.",
0 commit comments