Edge nodes — run jobs on your own machine
Pair a computer you own to Spikefrost so agents can dispatch work to it, executed by your own Claude Code or Codex seat. Setup, the agent-side API, what the machine can reach, the full flag reference, and the failure modes.
An edge node is a computer you own running a Spike worker. It pulls jobs from Spikefrost, executes them locally with your own Claude Code or Codex seat, and streams the result back into the conversation that asked for it.
Reach for one when the work has to happen on your hardware: a private repository, an internal network the cloud can't route to, a machine that already holds the credentials and tooling. As a side effect, the model usage bills to your own coding-agent account rather than your Spikefrost balance.
Before you start
| Requirement | Why |
|---|---|
The sf CLI, signed in |
Pairing and control run through it — The sf CLI |
| Claude Code or Codex on the machine, signed in | The node uses it as the executor. Without one, there is nothing to run the work |
git, only for GitHub or Bitbucket workspaces |
Spike app workspaces sync over built-in S3 support and need no git. PR creation additionally needs a source-code connector |
1. Create the cluster
In the web console open Connectors and add a Spike edge node connector.
The connector is the cluster. One connector can hold several machines, and agents address the cluster rather than any individual computer — so you can add a second machine later without touching agent code. Add a node to the connector and the console shows a pairing code.
2. Pair the machine
On the machine that will do the work:
sf edge pair
It prompts for the pairing code. Pairing binds the machine to the cluster and stores a runner token locally. Rotate that token any time:
sf edge regenerate-token
3. Start the worker
Run it in the foreground first, so you can watch the startup checks:
sf edge run --verbose
Once it looks right, install it as a background service. This survives a restart, starts on login, and keeps the machine awake so dispatched jobs aren't missed:
sf edge service start
status, stop and restart do what you'd expect. start installs the service first if it isn't installed yet.
4. Watch it
sf edge logs -f
sf edge logs -f stderr # one stream only
sf edge logs --lines 200
The line worth recognising early:
Connected, but this node is NOT paired to a cluster yet — its pairing token is not registered.
That means the runner reached Spikefrost but the pairing code was never registered against the cluster. Finish step 1 in the console; the node binds itself on the next retry. It is not an error state to debug on the machine.
5. Give the cluster its environment
Environment variables set on the cluster are handed to every execution on every node in it — the right home for an internal API base or a key the jobs need locally:
sf edge env list
sf edge env set API_BASE https://internal.example.com
sf edge env unset API_BASE
Using it from an agent
The machine becomes an agent's tool. Declare it on the agent class:
override tools = {
workstation: this.edgeComputerTool({
alias: 'my_mac_mini', // the connector — i.e. the cluster
provider: 'claude', // or 'codex'
repos: [ // mounted beside the app, always pulled
{ provider: 'github', fullName: 'acme/api' },
],
}),
};
Five behaviours decide whether your design works. They are not edge cases:
The turn ends at dispatch. The tool returns "started", not a result. The machine then works alone for minutes and the answer arrives later as a new message in the same conversation. Never await it, poll it, or re-dispatch — holding the turn open produces duplicate replies.
Dual mount, always fresh. The app's own code is always checked out, every declared repository beside it, and all of them pulled before the CLI starts. A tree with uncommitted work from a previous turn is not pulled — the agent is told so in its preamble rather than losing the work.
Two push verbs. sf app push publishes app code; git push publishes a mounted repository. The machine publishes neither on its own, and its workspace persists — so ending a turn mid-refactor is normal and safe.
The session is the conversation. Follow-up instructions resume the same CLI session on the machine, so the agent can refer back to earlier work. A different conversation gets a fresh session.
One job per computer and app. A second command for the same app while one is running is rejected with a typed error. Relay that to the user in plain language rather than retrying. A different app on the same computer runs concurrently.
And the constraint that shapes the prompt: no progress, no steering, no cancel mid-run. Describe the outcome you want, not the keystrokes, and expect nothing back until it finishes.
What the machine can reach
The node's access is yours to bound, and the defaults are conservative:
| Control | Default | Effect |
|---|---|---|
--workspace-root <path> |
— | Allowlist of directories the node may work in. Repeatable |
--no-ai-cli |
AI enabled | Disables agent execution entirely — the node still handles other local actions |
--max-tasks <n> |
5 | Concurrent local actions |
--max-runtime-ms <ms> |
— | Hard ceiling on a single local action |
--max-output-bytes <n> |
— | Caps inline stdout/stderr captured back |
Beyond that: a node only ever executes jobs dispatched to its own cluster, the runner token is rotatable, and the credentials the work uses are the ones already on your machine — Spikefrost never sees your Claude or Codex login.
Configuration reference
Every flag has an environment-variable equivalent, which is usually the better choice for a background service.
| Flag | Environment variable |
|---|---|
--gateway-url <url> |
SPIKE_EDGE_GATEWAY_URL |
--workspace-root <path> |
SPIKE_EDGE_WORKSPACE_ROOTS |
--no-ai-cli |
SPIKE_EDGE_ALLOW_AI_CLI=0 |
--max-tasks <n> |
SPIKE_EDGE_MAX_TASKS |
--no-cli-health-check |
SPIKE_EDGE_CLI_HEALTH_CHECK=0 |
--cli-health-timeout-ms <ms> |
SPIKE_EDGE_CLI_HEALTH_TIMEOUT_MS |
--no-auto-upgrade |
SPIKE_EDGE_AUTO_UPGRADE=0 |
--auto-upgrade-interval-ms <ms> |
SPIKE_EDGE_AUTO_UPGRADE_INTERVAL_MS |
--verbose |
SPIKE_EDGE_VERBOSE=1 |
--stream-output |
SPIKE_EDGE_STREAM_OUTPUT=1 |
--stream-agent-events |
SPIKE_EDGE_STREAM_AGENT_EVENTS=1 |
--no-reconnect |
— |
sf edge help prints the complete list, including the upgrade-source overrides.
Keeping it current
sf edge version # runner version
sf edge upgrade # reinstall
sf edge upgrade --force # reinstall even at the same version
The runner checks for upgrades while idle by default. Disable that on a machine where you want the version pinned, with --no-auto-upgrade or SPIKE_EDGE_AUTO_UPGRADE=0.
Troubleshooting
| Symptom | Cause |
|---|---|
| "Connected, but this node is NOT paired" | The pairing code was never registered against the cluster. Finish the console step; it binds on retry |
| Startup stalls on CLI checks | The node says hello to Claude/Codex on boot. If that seat isn't signed in, sign in — or skip the probe with --no-cli-health-check |
| Dispatch rejected with a typed error | Another job is already running for that computer and app. Wait, or dispatch to a different app |
| Jobs never arrive | Check the service is running (sf edge service status) and that the agent's alias matches the connector |
| Work not visible in the repository | The machine doesn't auto-publish. Use sf app push for app code or git push for a mounted repository |
| Agent describes work that didn't happen | Read the trace, not the reply — see Observability and costs |
Next
- Tools and data — the rest of what an agent can be granted.
- The sf CLI — installing and signing in.
- Download — get the CLI and the desktop app.
Frequently asked questions
What is an edge node?
A computer you own running a Spike worker. It pulls jobs from Spikefrost, executes them locally using your own Claude Code or Codex seat, and streams results back. The work happens on your hardware, with your credentials and your network access.
When would I want one?
When the work has to happen where you are — against a private repository, an internal network the cloud can't reach, or a machine that already holds the tools and credentials. Also when you'd rather the model usage bill to your own coding-agent seat.
Does the node bill against my Spikefrost balance?
No. The machine runs your own Claude or Codex seat, so that usage bills to that account. Spikefrost dispatches the work and carries the result.
Can an agent watch the job while it runs?
No, and designing around that matters. The agent's turn ends at dispatch; the machine works alone for minutes and the result arrives later as a new message in the same conversation. There is no progress stream, no steering and no cancel mid-run.
What can the machine actually reach?
Whatever you allow. Workspace roots are an explicit allowlist, the AI CLI can be disabled entirely, and concurrency and runtime are capped. The node only ever executes jobs dispatched to its own cluster.