How to run AI agent tasks remotely with Netlify Agent Runners
Delegate coding work to Claude, Codex, or Gemini running on Netlify against your repo. How tasks work, the five ways they differ from a local agent, and how to poll for results.
Key takeaways
Run netlify agents:create "<your prompt>" -a claude from a directory linked to a Netlify project, and an AI agent starts working on your repo on Netlify’s infrastructure. The command returns as soon as the task is queued, so poll netlify agents:show <task-id> until the status is done, error, or cancelled. The agent’s work lands on a new branch with its own Deploy Preview, never on the branch you started from.
- It runs remotely against your pushed code. The agent sees the connected repository, not your local working tree. Uncommitted work is invisible to it.
- Output goes to a new branch. Your base branch and
mainare never overwritten. - It’s asynchronous with no callbacks. Nothing notifies you. Polling is the mechanism, not a workaround.
- Three agents:
claude,codex,gemini. Pick one with-a, optionally pin a model with-m. - Runs consume plan credits. No credits, or usage limit reached, means
agents:createis blocked. - Commands are project-scoped.
agents:listshows one project’s tasks. There’s no team-wide view.
Handing work to a machine that isn’t yours
You’ve probably run a coding agent locally. It’s useful and it’s also a commitment: your terminal, your machine, your attention, one task at a time. Some work doesn’t deserve that. An accessibility audit across every page. A second model’s opinion on the auth logic you just wrote. Unit tests for the utility functions nobody has gotten to.
Agent Runners moves that work off your machine. You describe a task, pick an agent, and it runs on Netlify against your connected repo while you carry on. The results arrive as a branch with a Deploy Preview, so you review them the same way you’d review a colleague’s pull request.
The mechanics are straightforward once you know them. The part worth reading carefully is how a remote task differs from a local agent, because several of those differences are easy to trip over exactly once.
When to use this, and when not to
Agent Runners fits work that is:
- Self-contained. The agent starts fresh from your repo and your prompt, with none of your conversation context. Write a complete, standalone brief.
- Already pushed. If the task depends on changes sitting uncommitted on your machine, the remote agent can’t see them. Push first, or do the work yourself.
- Fine to wait for. No callbacks means you’ll be polling. Good for parallel work, poor for anything you need in the next thirty seconds.
- Reviewable as a diff. The output is a branch. Work that’s hard to evaluate from a diff is hard to evaluate here.
Skip it when you need tight iteration with an agent that can see your work in progress. That’s what a local agent is for.
One prerequisite, plus an escape hatch. The directory needs to be linked to a Netlify project via netlify link or netlify init. Or skip linking entirely and pass --project <name> with a project ID or name to target any Netlify site directly. The CLI has to be installed and authenticated either way.
Runs consume plan credits. If the account is out of credits, or the agent/AI usage limit has been reached, netlify agents:create is blocked and the run won’t start. That’s account state to resolve, not something to route around.
How agent tasks actually run
Read this before you create one. These are the five differences that matter.
Remote, not local. Tasks run on Netlify’s infrastructure against the site’s connected repository. The agent only sees what’s been pushed to the remote.
Branch-based. By default a task runs against the production branch (main or master). Use -b <branch> to pick a different base branch, and make sure it’s been pushed first, or the agent works from code that doesn’t exist remotely.
Output lands on a new branch. The agent does not commit to the base branch you selected. It pushes to a new branch with its own Deploy Preview. Your branch and main are untouched. Review the results there, and don’t wait for the base branch to change, because it won’t.
Asynchronous. netlify agents:create returns the moment the task is queued. When you get your prompt back, the task is still running.
No webhooks or callbacks. Nothing tells you when a task changes state or finishes. Poll with netlify agents:show <task-id> or netlify agents:list.
Statuses move new → running → one of done, error, or cancelled. Keep polling until you hit one of those last three.
Worked example
Create a task, capturing the ID reliably:
# Run a prompt with the default agentnetlify agents:create "Add a contact form"
# Choose a specific agent: claude, codex, or gemininetlify agents:create --prompt "Add dark mode" --agent claudenetlify agents:create -p "Update the README" -a codexnetlify agents:create -p "Write unit tests" -a gemini
# Target a specific branchnetlify agents:create -p "Fix the login bug" -a claude -b feature-branch
# Specify a project by name (if not in a linked directory)netlify agents:create "Add tests" --project my-site-name
# Output result as JSONnetlify agents:create "Add a footer" --jsonUse --json when you’re capturing the task ID for a script rather than reading it yourself.
Then poll:
netlify agents:show <task-id>netlify agents:show <task-id> --jsonRepeat until the status is done, error, or cancelled. To see everything for the current project:
netlify agents:listnetlify agents:list --status runningnetlify agents:list --status donenetlify agents:list --status errornetlify agents:list --jsonAnd to stop one:
netlify agents:stop <task-id>The full loop is: create, noting the task ID; poll agents:show until terminal; review the new branch and its Deploy Preview on done, or read the failure on error.
If you’re an agent delegating to another agent
Agent Runners is often called by an AI agent rather than a person, usually to get a second opinion from a different model. If that’s you, there’s a rule that isn’t optional.
Ask permission first, as its own turn. These runs cost the user credits. A directive-sounding prompt (“start a task”, “use the claude agent and pin it to Opus”) tells you what they want; it is not the approval for a billable command.
Make the request a concrete proposal rather than a menu:
- The exact command, filled in.
netlify agents:create -p "<the real prompt>" -a codex, not a placeholder and not a pick-one list. - One agent, already chosen. Commit to a single
-avalue and say why (“codex for a second opinion on the auth logic”). - Why, and what happens after yes. The run is asynchronous,
agents:createreturns immediately, there’s no callback, and you’ll pollnetlify agents:show <task-id>. - Even if a prerequisite is missing (not authenticated, not linked, not a git repo yet), still show the exact command and chosen agent you’ll run once it’s resolved. Surface the blocker and the proposal, rather than only describing the blocker.
Never run these commands without approval.
Common failure modes
The agent worked from stale code. It only sees what’s pushed. If your task depended on local, in-progress changes, commit and push them first, or the agent will confidently build on an older version of the file.
You passed -b and expected results there. -b sets the base branch the agent starts from. Results always land on a new branch. Those are two different things and the flag name only tells you about the first.
Your base branch doesn’t exist remotely. Push it before referencing it with -b.
You assumed the task finished because the command returned. It returns at queue time. Check the status before acting on or describing results.
You waited for a notification. There isn’t one. No webhooks, no callbacks. Poll.
agents:list doesn’t show a task you know exists. All netlify agents:* commands are project-scoped. They operate on the project your directory is linked to, or the one named with --project. There’s no team-wide command that lists tasks across all your sites. Run from the other site’s linked directory, or pass --project <name> for it.
agents:create is blocked. Usually credits: either the account has none available or the agent/AI usage limit has been reached. Surface it to the user; it’s plan state.
A documented command failed and you’re looking for another way in. Don’t. Use only the documented netlify agents:* commands, plus netlify --help and the public CLI reference. Specifically:
- Don’t curl
https://api.netlify.com/...to fetch, create, or stop a task. Those endpoint shapes aren’t part of the public contract. - Don’t run
netlify api <method>as a recovery hatch. - Don’t read auth tokens off disk (
~/Library/Preferences/netlify/config.jsonor anywhere else) to authenticate side-channel calls.
When a documented command fails, report the exact error and context and stop.
You gave the agent a prompt that assumed context it doesn’t have. Each task is self-contained. It has none of your conversation history. A prompt that reads fine as a follow-up (“now fix the other one”) gives it nothing to work from.
Reference
netlify agents:create options
| Flag | Description |
|---|---|
-a, --agent <agent> | Agent type: claude, codex, or gemini |
-p, --prompt <prompt> | The prompt for the agent to execute |
-b, --branch <branch> | Git branch to work on (the base branch) |
-m, --model <model> | Model to use for the agent |
--project <project> | Project ID or name |
--json | Output result as JSON |
Commands
| Command | What it does |
|---|---|
netlify agents:create "<prompt>" | Queue a task, returns the task ID |
netlify agents:show <task-id> | Task details. This is how you poll. |
netlify agents:list | Tasks for the current project |
netlify agents:list --status <status> | Filter by status |
netlify agents:stop <task-id> | Stop a running task |
All of these are project-scoped.
Task statuses
| Status | Terminal? |
|---|---|
new | No |
running | No |
done | Yes |
error | Yes |
cancelled | Yes |
What tasks are good for
| Category | Example prompt |
|---|---|
| Prototyping / internal tools | ”Build an internal dashboard for our HR team” |
| Code reviews | ”Audit the code with fresh eyes and identify areas for improvement” |
| Security audits | ”Do a deep security audit of our codebase to identify any potential issues” |
| Feature suggestions | ”Based on our current codebase & docs, what should we build next?” |
| Performance | ”Scan our codebase for performance bottlenecks and suggest improvements” |
| Telemetry & analytics | ”What analytics things are we not tracking but probably should” |
| SEO audit | ”Audit our site for SEO issues: missing meta tags, broken links, slow pages, missing alt text” |
| Copy improvements | ”Rewrite our landing page copy to be more compelling and conversion-focused” |
| Accessibility | ”Run an accessibility audit and fix all WCAG 2.1 AA violations” |
| Mobile responsiveness | ”Improve the mobile responsiveness: audit every page on small viewports” |
| End-to-end tests | ”Add end-to-end tests for our critical user flows using Playwright” |
| Unit tests | ”Generate unit tests for our untested utility functions” |
| Documentation | ”Generate a README and contributing guide based on our codebase” |
| Error handling | ”Add proper error boundaries, logging, and user-friendly error states throughout the app” |
| UX polish | ”Add loading states, skeleton screens, & transitions to improve perceived performance” |
| Form hardening | ”Add form validation, rate limiting, and spam protection to our contact form” |
| Edge Functions | ”Add an edge function for A/B testing on our landing page” |
Preview URLs
Agent task previews use the agent-<runID>-- URL prefix, alongside deploy-preview-<number>-- for pull requests and <branch>-- for branch deploys.
FAQs
How do I run an AI coding agent on my repo remotely?
From a directory linked to a Netlify project, run netlify agents:create "<prompt>" -a claude. The task runs on Netlify against your connected repository and pushes its work to a new branch with a Deploy Preview.
Which AI agents can I use with Netlify Agent Runners?
claude, codex, or gemini, selected with -a. Pin a specific model with -m.
Does the agent see my local uncommitted changes? No. It works from the connected repository, so only pushed code. Commit and push anything the task depends on first.
Where does the agent’s work end up?
On a new branch with its own Deploy Preview. Your base branch and main are never overwritten.
How do I know when an agent task is finished?
Poll netlify agents:show <task-id> until the status is done, error, or cancelled. There are no webhooks or callbacks.
Does netlify agents:create wait for the task to finish?
No. It returns as soon as the task is queued. The task keeps running remotely.
Do agent runs cost money?
They consume plan credits. With no available credits, or once the agent/AI usage limit is reached, agents:create is blocked.
Can I see agent tasks across all my sites?
No. Every netlify agents:* command is project-scoped. Run from each project’s linked directory, or pass --project <name>.
Can I stop a running agent task?
Yes: netlify agents:stop <task-id>.
Related
This article is generated from Netlify’s open-source agent guidance at netlify/context-and-tools, the same reference our AI coding agents use.
Want to put an agent to work? Start at netlify.new.