Your coding agent can write automations. Who reviews them before they ship?
An agent can build a Stripe refund workflow in a minute. Here is how it becomes code you can read, versions you can compare, and a deploy you approve first.
Harikrishnan H · CEO
7 min read
On this page
- Three ways agent-written automation ships today
- What reviewable means for MCP workflow automation
- The output is a file you can read
- The agent can't hand you the code that ships
- Every deploy is a version you can compare and roll back
- A person says yes, by default
- The refund workflow, call by call
- Authoring: four calls and a validation
- Review: the lines that matter
- Deploy: a prompt in your browser
- After: the workflow becomes a tool
- Limits, said up front
- Try it on your own agent
Ask Claude Code for "a Stripe refund flow that asks me in Slack before refunding anything over $500" and you will have a draft in about a minute. The hard part comes after: deciding to let it touch real money. That decision is where most MCP workflow automation still leaves you on your own.
This post is about that decision. It covers what you need to see before an agent-written automation goes live, how Nodes2Cloud handles each part, and where it still falls short. The example is the refund workflow from our homepage demo. Every code block below is the compiler's real output for that graph, cut from the build rather than retyped, so it changes when the compiler does.
Three ways agent-written automation ships today
The agent calls the APIs itself. Give it a Stripe key and it can issue the refund directly. That works once. When the chat ends there is nothing to review, version or run again, and the key sat in the conversation.
The agent picks from an action menu. Zapier MCP is the best-known example. It gives an agent actions across more than 9,000 apps, with app- and action-level permissions and a history of every action that ran (zapier.com/mcp, checked October 29, 2026). That answers which actions an agent may take and what it did afterwards, and it suits one-off work well. Zapier also lets supported AI clients build and deploy its Next Gen Zaps, in early access. I haven't seen how review works there yet, so check their docs rather than take my word for it.
The agent fills in a visual builder. Most builders save the workflow as a graph and interpret it at run time. You can look at the picture, and some tools export the graph as JSON or sync it to git. What you would diff then is the engine's input. The behavior lives in the engine.
A pull request gives you three things: the change as code, a check by something other than its author, and a person's approval before it merges. Agent-written automation needs the same three, plus a way back.
What reviewable means for MCP workflow automation
Every agent change in Nodes2Cloud passes four checks, in this order. The last one is you.
The output is a file you can read
Every workflow compiles ahead of time into a standalone TypeScript Worker, or into a Cloudflare Workflow when the graph has a step that waits. The compiler runs a parser, a structural validator, an analyzer, an intermediate representation and a code generator. The validator reports every error with the node it belongs to, and the agent can't skip it.
The compiled Worker is the workflow. No engine sits in front of it, and it makes no calls back to us when it runs. Export it as a Wrangler project and it runs with us removed.
The agent can't hand you the code that ships
The agent works on the graph. When it asks to deploy, deploy_workflow takes a workflow id and nothing else. Our server loads the saved graph, recompiles it, and uploads what it just compiled. The call has no field for a script, so the agent has no way to swap in code you didn't see.
Every deploy is a version you can compare and roll back
Each deploy is saved as a version with its graph frozen. The agent can fetch any version's graph next to the one before it, list versions, and roll back. In the editor you can compare any version with your canvas, then restore it or make it live.
A person says yes, by default
Every deploy an agent asks for waits for your approval in an open Nodes2Cloud tab. You set this per connected agent: never deploy, ask each time (the default), or deploy without asking. That last one is Pro's auto mode, for an agent you trust. AI is never a deploy bypass.
The refund workflow, call by call
Here is the sequence an agent goes through with our MCP server, from the prompt to a tool it can call.
Authoring: four calls and a validation
list_node_typessearches the 234 nodes on the canvas palette for a Stripe call, a Slack message and a wait.get_node_schemasreturns the exact properties of the node types it picked.create_workflowandupdate_workflowsave the graph. It has a tool trigger, a branch on the amount, a Slack message, a wait for a decision, a check on that decision, and two refund calls.validate_workflowwithincludeCode: truecompiles the graph without deploying it. It returns every error, or the compiled code when there are none.
If the agent needs a Stripe or Slack connection that doesn't exist yet, request_connections gives it a link to send you. You connect the service in your browser, and the agent never sees the secret.
Review: the lines that matter
The $500 branch is the expression the agent wrote, compiled to a plain comparison:
// === Node: over (if) ===
if ((ctx.input?.amount_cents > 50000)) {Refunds over that amount post to Slack and then park the run. As a Cloudflare Workflow, the run can wait up to 24 hours here without holding a request open:
// === Node: approval (wait_for_event) ===
ctx.nodes["approval"] = { ...(await step.waitForEvent("approval", { type: "refund_decision", timeout: "24 hours" })), timedOut: false };This is the refund itself, the part you most want to read before it goes live:
// === Node: refund_approved (http_request) ===
ctx.nodes["refund_approved"] = await step.do("refund_approved", async () => {
const refund_approved_res = await fetch("https://api.stripe.com/v1/refunds", { method: "POST", signal: AbortSignal.timeout(30000), headers: { "Idempotency-Key": `refund-${((__v) => __v !== null && typeof __v === "object" ? JSON.stringify(__v) : __v)(ctx.input?.payment_intent)}-${((__v) => __v !== null && typeof __v === "object" ? JSON.stringify(__v) : __v)(ctx.input?.amount_cents)}`, "Authorization": "Bearer " + String(env.CREDENTIAL_REFUND_APPROVED), "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ "payment_intent": ctx.input?.payment_intent, "amount": ctx.input?.amount_cents }).toString() });
const refund_approved_body = await refund_approved_res.text();
let refund_approved_json;
try { refund_approved_json = JSON.parse(refund_approved_body); } catch (__e) { refund_approved_json = undefined; }
if (!refund_approved_res.ok) throw new Error("HTTP " + refund_approved_res.status + ": " + refund_approved_body.slice(0, 200));
return { status: refund_approved_res.status, body: refund_approved_body, json: refund_approved_json };
});A retried step sends the same Idempotency-Key, so Stripe won't refund twice. A non-2xx answer throws, so a failed refund fails the run.
Both checks are readable without knowing our product. The idempotency key is built from the payment and the amount, so a retry can't double-refund. A refusal from Stripe stops the run instead of being logged and skipped. If either were missing, you would see it right here.
Deploy: a prompt in your browser
The agent calls deploy_workflow. An "Approve this deploy?" dialog opens in your Nodes2Cloud tab. It names the agent and the workflow, with a link to review the workflow in a new tab. Approve, and the server recompiles the saved graph and deploys it to your Cloudflare account.
Two details make the gate hold:
- It fails closed. If nobody approves within 90 seconds, nothing deploys. Closing the dialog counts as a no.
- It approves the workflow as it is now. If the workflow is edited while the approval is pending, the deploy is cancelled and the agent has to ask again.
After: the workflow becomes a tool
The graph starts with an MCP Tool trigger, so once it is live your agent sees refund_approval in its tool list. It can call the Worker directly with the tool's bearer token, or go through our MCP server with call_deployed_workflow.
This workflow waits, so a call answers straight away with a run id and a status of "started". The refund comes later. The Slack message asks you to tell your agent yes or no, and the agent sends the run a refund_decision event with control_run. The run picks up from there.
A workflow with no waiting step answers with its result instead. The free Developer plan includes 3 agent-callable tools, and Pro includes 25.
Limits, said up front
- You need a Cloudflare account. The free plan works. It is the one setup step we can't do for you, and it is why your runs execute in your account. See the token permissions it needs.
- The approval prompt is short. It shows which agent is asking, which workflow, and a link. The review itself happens in the editor. The agent name in the prompt is the one the client reports about itself; the policy that decides whether it may deploy is keyed on the agent's sign-in.
- The editor's version compare is a summary. It counts nodes added, removed and changed, and flags changed connections and settings. It is not a line diff of the code. On Pro, GitHub auto-push can commit each deployed version's
src/index.tsandwrangler.jsoncto your repo, and GitHub gives you the line diff. - The code
validate_workflowreturns is the preview build. The deployed build is the same compile plus run telemetry, which writes to Analytics Engine and KV in your own Cloudflare account. - Some calls pass through us. Test runs, live debug sessions, and tool calls made through our MCP server go through Nodes2Cloud in transit and are not stored. Calls made straight to your Worker don't touch us.
- Rollbacks and webhook-secret rotations skip the prompt. They redeploy a recompiled version and respect "never deploy" and the daily deploy cap, but they don't open the dialog.
- Export is a compiled artifact. You get a runnable Wrangler project, not source you can import back into the editor.
- Auto mode skips the prompt, on purpose. On Pro you can let a trusted agent deploy without asking. The validator, the recompile and the version history still apply to everything it ships.
Try it on your own agent
The MCP server is on every plan, including the free Developer plan, and it is the same server whichever client you use. We document setup for 46 clients, including Claude Code, Cursor and Codex. Once connected, the agent gets 28 tools. The catalogue covers 155 integrations, and the HTTP Request node reaches any REST API that isn't one of them.
Prefer to start without an agent? A refund approval template is on the templates page, and the quickstart goes from an empty canvas to a deployed Worker.
Connect your coding agent
The MCP server is on every plan, the free one included. The installer asks which client to configure and writes its config; every deploy your agent asks for then waits for your approval.
npx -y n2c-mcp@latest installOr, in Claude Code:
claude mcp add --transport http nodes2cloud https://api.nodes2cloud.com/mcp