skopik

Remotes

A remote is a mount — a folder on a customer machine served into remote-bound sessions, plus any custom tools the host advertises. Skopik cloud still runs the agent; the remote serves files and tool calls from your machine into that work, keeping private files and local tools close without shipping them to the cloud.

Work stays local by design: a remote-bound session's work/ folder lives at {root}/sessions/{sessionId}/work/ on your machine and is never mirrored to cloud storage — no checkpoint archives, no background sync. Durable results leave through the channels you already trust: a git push, or the session's cloud-side output/ folder. When a session is canceled, the remote receives a cleanup assignment and deletes its local session folder; completed sessions keep theirs.

You use the SDK to register and manage remotes. The host side — long-polling for assignments, sending heartbeats, and serving operations — is handled for you by the Skopik desktop app, the CLI, or the Remote SDK (@skopiklabs/remote-sdk). remotes.heartbeat() and remotes.poll() are documented below for hosts built directly on the client.

Quick Links

Action Description
remotes.register() Register a desktop, CLI, or external remote.
remotes.list() List remotes.
remotes.get() Read remote details.
remotes.update() Update remote policy, status, or capacity.
remotes.heartbeat() Report host liveness and capabilities.
remotes.poll() Long-poll for the next assignment.

Common Flow

Register a remote with a workspace API key, then bind a session to it. The session's work/ folder is served from the remote's machine while the session runs — any session shape can bind, one-shot jobs and long-lived assistants alike.

const { remote, registrationToken } = await client.remotes.register({
	hostKind: 'cli',
	label: 'Jordan laptop',
	installId: 'jordan-mbp-001',
	maxConcurrentTasks: 1,
})

const { session } = await client.sessions.open({
	agent: 'mike',
	prompt: 'Review the mounted folder and summarize anything stale.',
	remote: remote.remoteId,
})

Store the returned registrationToken on the host — it is returned once, at registration, and never again. The desktop app, CLI, or Remote SDK authenticates with that token to heartbeat and poll for work. Bind any session to the remote by passing remote when you open it; omit it for cloud-only work, and open a new session to move work to a different remote.

Reference

remotes.register(input)

Register a customer-managed remote host.

const { remote, registrationToken } = await client.remotes.register({
	hostKind: 'desktop',
	label: 'Design workstation',
	installId: 'design-ws-014',
	tools: [
		{ name: 'render_preview', readonly: true, needsApproval: false },
	],
})

Parameters

Field Type Required Notes
hostKind string Yes desktop, cli, or external.
label string Yes Human-readable remote label.
installId string Yes Stable install id from the remote process.
enabled boolean No Whether this remote can claim serving windows. Defaults to true.
maxConcurrentTasks number No Maximum serving windows claimed at once. Defaults to 1.
readonly boolean No Whether the remote refuses write operations. Defaults to false.
tools RemoteToolDescriptor[] No Custom tools the remote advertises. See RemoteToolDescriptor.
version string No Remote version.

Returns RegisterRemoteResponse{ remote: Remote, registrationToken: string }. The registrationToken is only returned from this call; store it on the host.

remotes.list(params?)

List remotes in the current workspace.

const { data: remotes } = await client.remotes.list()

Parameters

Field Type Required Notes
limit number No Page size.
cursor string No Cursor from the previous page.

Returns ListResponse<Remote>{ data: Remote[], page? }. See Remote.

remotes.get(remoteId)

Read remote details.

const { remote } = await client.remotes.get(remoteId)

Returns { remote: Remote } — see Remote.

remotes.update(remoteId, input)

Update remote policy, status, or capacity.

const { remote } = await client.remotes.update(remoteId, {
	maxConcurrentTasks: 2,
	status: 'paused',
})

Parameters

Field Type Required Notes
label string No New label.
enabled boolean No Whether this remote can claim serving windows.
maxConcurrentTasks number No Maximum serving windows claimed at once.
status string No offline, connecting, online, busy, paused, or error.

Returns { remote: Remote } — see Remote.

remotes.heartbeat(remoteId, input?)

Report host liveness and refresh advertised capabilities. Hosts send heartbeats authenticated with the registration token; the desktop app, CLI, and Remote SDK do this for you on the returned nextHeartbeatInSeconds cadence.

const heartbeat = await client.remotes.heartbeat(remote.remoteId, {
	status: 'online',
	version: '1.4.2',
})
console.log(heartbeat.nextHeartbeatInSeconds)

Parameters

Field Type Required Notes
status string No offline, connecting, online, busy, paused, or error.
version string No Remote version.
readonly boolean No Whether the remote refuses write operations.
tools RemoteToolDescriptor[] No Replacement tool list. See RemoteToolDescriptor.

Returns RemoteHeartbeat.

remotes.poll(options?)

Long-poll for the next assignment — a serving window for a remote-bound session, or a workspace cleanup. The remote is identified by the registration token, so there is no remote id in the path: construct the client with the registration token as its token. Resolves null when the wait window closes with no work (HTTP 204); poll again in a loop.

const host = createSkopikClient({ token: registrationToken })

const assignment = await host.remotes.poll({ wait: 25 })
if (assignment?.kind === 'session.serve') {
	// prepare sessions/{sessionId}/work and serve operations for this window
}

Parameters

Field Type Required Notes
wait number No Seconds to hold the poll open before the server returns empty.

Returns RemoteAssignment | nullnull when no work arrives within the wait window. See RemoteAssignment.

Types

Remote

Field Type Notes
remoteId string Remote id.
orgId string Workspace id.
hostKind string desktop, cli, or external.
label string Remote label.
installId string Stable install id.
enabled boolean Whether the remote can claim serving windows.
maxConcurrentTasks number Maximum serving windows claimed at once.
activeTaskCount number Serving windows currently claimed.
readonly boolean Whether the remote refuses write operations.
tools RemoteToolDescriptor[] Custom tools the remote advertises. See RemoteToolDescriptor.
version string or null Remote version.
status string offline, connecting, online, busy, paused, or error.
lastHeartbeatAt string or null ISO timestamp.
lastPollAt string or null ISO timestamp.
createdAt string ISO timestamp.
updatedAt string ISO timestamp.

RegisterRemoteResponse

Field Type Notes
remote Remote Registered remote. See Remote.
registrationToken string Host token. Returned only at registration — store it on the remote.

RemoteToolDescriptor

Field Type Notes
name string Tool name.
description string or null Tool description.
readonly boolean Whether the tool only reads.
needsApproval boolean Whether calls require human approval.
inputSchema object or null JSON Schema for tool input.

RemoteHeartbeat

Field Type Notes
remoteState string Server-side remote status.
nextHeartbeatInSeconds number When to send the next heartbeat.
serverTime string ISO timestamp.
remote Remote Updated remote when included. See Remote.

RemoteAssignment

A discriminated union on kind: session.serve (a claimed serving window) or workspace.cleanup (remove a canceled session's local folder).

session.serve

Field Type Notes
kind string session.serve.
assignmentId string Assignment id.
remoteId string Remote id.
orgId string Workspace id when included.
session object { runId, sessionId, agentId, agentLabel?, userId? } for the window.
lease object { leaseId, expiresAt } — the claim on this window.
runtimeToken string Token for run-scoped runtime calls during the window.
runtimeTokenExpiresIn number Runtime token lifetime in seconds.
nextHeartbeatInSeconds number When to send the next heartbeat.

workspace.cleanup

Field Type Notes
kind string workspace.cleanup.
assignmentId string Assignment id.
remoteId string Remote id.
orgId string Workspace id when included.
sessionId string Session whose local folder ({root}/sessions/{sessionId}/) should be deleted.
reason string or null Cleanup reason (e.g. session_canceled).
nextHeartbeatInSeconds number When to send the next heartbeat, when included.