New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@shardflux/mcp

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shardflux/mcp

Shardflux MCP server (stdio): give Claude, Cursor, Codex or any MCP client serverless VMs to run commands, edit files, use git and a browser in. Uses your scoped Shardflux API key.

npmnpm
Version
0.25.0
Version published
Weekly downloads
856
-22.04%
Maintainers
1
Weekly downloads
 
Created
Source

@shardflux/mcp: shardflux-mcp

Saved computers resume in their existing environment, keeping files available for the next turn.

Queued messages retain their computer and native session when a pending upgrade choice is cleared or changed.

For error codes, retry timing, plan recovery, and disk growth actions, see the error reference.

Historical template file lists: reads queue checksum-verified reconstruction when a cold list is absent from the SQL cache. TypeScript SDK 0.27.0+ / Python 0.23.0+ wait full Retry-After for retryable API 409 file_list_indexing on GET/HEAD within the admission timeout. Template objects and version history stay available.

Plan-derived API budgets (0.20.0+, SDK 0.27.0): tool errors include rate_limit, retry_after_seconds and a hint naming the shared scope and delay. The SDK waits for proven pre-handler request refusals within the tool deadline. Workspace credential budgets retain their own reason and metadata.

Credential key pacing (0.20.2+): when the service enables plan budgets for an eligible finite non-Free grant, workspace credentials share organization and workspace hourly allowances, plus a separate API-key burst. A tool_token_budget refusal can name api_key; honor Retry-After and reuse valid credentials. Unmarked Free grants retain the legacy principal hourly/burst policy. It does not promise that lifecycle work has not started, so it never authorizes replay of an arbitrary POST.

Exec survives a dropped connection (0.20.0+): a lost start response is retried with the same session ID and reattaches to the command that already started, and a cut-off JSON answer is retried within the same safe retry boundary.

Suspension controls are available from 0.19.0. workspace_suspend_progress reads the actual phase/deadline and cancellation window; workspace_suspend_cancel requests cancellation before capture. Both require operation_id and the named workspace, and respect a pinned workspace. Cancellation waits for confirmed suspend_canceled original-workspace recovery by default; wait:false returns asynchronous acceptance. The host refuses an unavailable or closed preparation window. Neither tool resets, replaces or starts a provider turn. They are absent for pinned file-first workspaces, and unavailable progress stays explicit.

The Shardflux MCP server. It gives Claude Code, Claude Desktop, Cursor, Codex or any other MCP client serverless VMs called workspaces: open a workspace by key, then run commands, read and write files, use git, terminals and a browser in it, and suspend, resume or fork it.

It runs locally over stdio and uses @shardflux/sdk with the scoped project API key you give it. Each tool call becomes one SDK request or wait:

  • it has no agent loop of its own;
  • it keeps no local workspace directory;
  • it keeps no state beyond per-key workspace handles, so tool tokens are reused between calls.

Documentation: https://docs.shardflux.dev/reference/mcp.

Hosted, nothing to install. The same server runs at https://mcp.shardflux.dev/mcp (MCP Streamable HTTP with OAuth): add the URL to Claude, ChatGPT, Claude Code, Cursor or VS Code and sign in. In Claude Code:

claude mcp add --transport http shardflux https://mcp.shardflux.dev/mcp

Compatibility. The API is versioned (/v1). Breaking changes ship only in minor releases and are marked Breaking in the changelog.

Requires Node.js 24 or later and a Shardflux project API key (sfk_..., from the Shardflux console).

Filesystem recovery timing (0.22.0+): cold_boot_reason: guest_filesystem is included in resume timing, with a notice explaining retained files and restarted processes. See the workspace lifecycle.

Agent credentials (0.23.2+)

agent_credential_request asks securely for a named environment variable and suggests agents, project, or conversation scope. agent_secrets_list returns local metadata and agent_secret_delete erases a local credential. Values go through the secure credentials screen or shard needs-you answer <id> --credential --ask; model tools never accept or return a secret value. Credential purpose text is preserved in full.

Support and bug reports

Report a bug or request a feature. Include the package and runtime versions, a minimal reproduction, expected and actual behavior, and the request ID or error code when available. Reports are public: leave out secrets and confidential data.

For usage, account, billing, or private support, email shardflux@heliosone.fi. Report vulnerabilities through private security reporting. See the support guide for all reporting options.

Run

MCP clients start the server themselves (see "Client setup"). The command is:

npx -y @shardflux/mcp

with SHARDFLUX_API_KEY in its environment. To try it by hand:

SHARDFLUX_API_KEY=sfk_... npx -y @shardflux/mcp

It logs one JSON ready line on stderr and then waits for MCP messages on stdin (stdout is the protocol). Close stdin or press Ctrl-C to stop it.

Or install it globally and use the shardflux-mcp command instead of npx -y @shardflux/mcp:

npm install -g @shardflux/mcp

Client setup

Each example registers the server as shardflux. Replace sfk_... with your key, and add any other variable from "Configuration" the same way.

Claude Code

claude mcp add --scope user --env SHARDFLUX_API_KEY=sfk_... --transport stdio shardflux -- npx -y @shardflux/mcp
claude mcp get shardflux

Options go before the name (shardflux), and everything after -- is the command. --scope user makes the server available in every project; leave it out for the current project only, or use --scope project to write it to .mcp.json for your team. In .mcp.json, read the key from the environment instead of committing it:

{
  "mcpServers": {
    "shardflux": {
      "command": "npx",
      "args": ["-y", "@shardflux/mcp"],
      "env": { "SHARDFLUX_API_KEY": "${SHARDFLUX_API_KEY}" }
    }
  }
}

In a session, /mcp shows the server's status.

Cursor

Add the server to ~/.cursor/mcp.json (every project) or .cursor/mcp.json (one project):

{
  "mcpServers": {
    "shardflux": {
      "command": "npx",
      "args": ["-y", "@shardflux/mcp"],
      "env": { "SHARDFLUX_API_KEY": "${env:SHARDFLUX_API_KEY}" }
    }
  }
}

${env:SHARDFLUX_API_KEY} reads the key from the environment Cursor runs in; you can also put the key itself there.

Codex

Add the server to ~/.codex/config.toml (or .codex/config.toml in a trusted project):

[mcp_servers.shardflux]
command = "npx"
args = ["-y", "@shardflux/mcp"]
env_vars = ["SHARDFLUX_API_KEY"]  # forward the key from the environment Codex runs in
startup_timeout_sec = 30          # the first run downloads the package (Codex default: 10)
tool_timeout_sec = 180            # above the server's per-call deadline, 120 s by default (Codex default: 60)

To set the key in the file instead, replace env_vars with:

[mcp_servers.shardflux.env]
SHARDFLUX_API_KEY = "sfk_..."

Or from the command line:

codex mcp add shardflux --env SHARDFLUX_API_KEY=sfk_... -- npx -y @shardflux/mcp

workspace_open waits until the workspace is ready, up to the server's per-call deadline (SHARDFLUX_MCP_TOOL_TIMEOUT_MS, default 120000 ms). Keep tool_timeout_sec above it, or Codex gives up on the call first.

Claude Desktop

Open Settings, then Developer, then Edit Config. This opens claude_desktop_config.json (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows). Add:

{
  "mcpServers": {
    "shardflux": {
      "command": "npx",
      "args": ["-y", "@shardflux/mcp"],
      "env": { "SHARDFLUX_API_KEY": "sfk_..." }
    }
  }
}

Then quit Claude Desktop completely and start it again. The server's stderr goes to mcp-server-shardflux.log in Claude Desktop's log folder (~/Library/Logs/Claude on macOS, %APPDATA%\Claude\logs on Windows).

Other clients

Any client that starts stdio servers works: command npx, arguments -y @shardflux/mcp, environment SHARDFLUX_API_KEY.

Configuration (environment)

VariableMeaning
SHARDFLUX_API_KEYScoped project API key. Required. Its tool permissions decide which workspace tools are listed.
SHARDFLUX_API_URLDefault https://api.shardflux.dev. Plain http:// is allowed only for loopback hosts.
SHARDFLUX_WORKSPACE_KEYPins one workspace. workspace_key becomes optional on every tool, and a different key is refused with workspace_pinned.
SHARDFLUX_TEMPLATEDefault template for workspace_open. (0.9.0+) Also lets a workspace tool create its workspace: a workspace_key with no workspace yet is created from this template on first use (default is the platform default template).
SHARDFLUX_WORKSPACE_MODE(0.4.0) processful or file_first: the mode workspace_open sends when the call names none (unset: the API's default, processful for a new key). A pinned server also lists the tools of this mode until its workspace exists.
SHARDFLUX_MCP_TOOL_TIMEOUT_MSDefault and maximum deadline per tool call, 1000-3600000 ms. Default 120000. A call's timeout_ms can only shorten it.
SHARDFLUX_PREWAKE0.8.0+: on offers explicit workspace_hint; default off adds no early hint tool.
SHARDFLUX_WAKEon (default) or off. On: workspace tools resume a suspended workspace and then run (see "Contract"). Off: they return the workspace_not_running refusal.
SHARDFLUX_WAKE_TIMEOUT_MSLongest wait per tool call for a workspace to wake or finish a transition, 1000-3600000 ms. Default 120000. It is clamped to SHARDFLUX_MCP_TOOL_TIMEOUT_MS, and each wake also ends 250 ms before the call's own deadline.
SHARDFLUX_AGENT_LABELAttribution label of every tool token this server obtains. Default mcp. It appears as an agent session in GET /v1/workspaces/{id}/agent-sessions, the console and shard ws sessions.
SHARDFLUX_MCP_LOG_LEVELdebug, info (default), warn or error. Logs are JSON lines on stderr; stdout is the protocol. The key is never logged, and anything key-shaped is redacted.
SHARDFLUX_HTTP_KEEPALIVE0.6.0+: default private HTTP/1.1 pooling on Node 26; 0 forces close for diagnosis, 1 uses native pooling.
SHARDFLUX_CLI(0.18.0) The shard executable move_to_cloud runs. Default: shard on PATH, else npx -y @shardflux/cli@latest.
SHARDFLUX_NO_UPDATE_CHECK(0.4.0) 1, true, yes or on turns off the startup version check (see "Updates").
NO_UPDATE_NOTIFIER(0.4.0) The npm convention: any non-empty value also turns the check off.

Invalid configuration exits with code 2 before serving, with one JSON line on stderr, for example:

{"time":"2026-09-28T20:18:25.654Z","level":"error","service":"shardflux-mcp","message":"configuration error: SHARDFLUX_API_KEY is required (a scoped Shardflux project API key)"}

template_build reads local files (file, and from paths in a recipe) only inside the server's working directory: the directory your MCP client starts it in.

Feedback: preview and user approval

(0.19.0+) Every local and hosted server uses user-directed feedback. send_feedback with omitted or false user_approved returns {sent: false, authorization_required: true, preview, note} without submitting. Show the exact message and context to the user, then obtain explicit authorization before calling with the same content and user_approved: true. Earlier local versions encouraged proactive feedback. The legacy feedback: 'proactive' option now uses the same consent policy.

Coding agents: report only when your user asks to send feedback. Show the exact message and context first, then obtain explicit authorization. A failure or request for a feature is not consent. Leave out private data, secrets and code the user did not mean to share; paraphrase, never paste transcripts. Tell the user what was sent. Failed calls retain a feedback suggestion with request and error IDs; it asks for a preview and approval.

  • Arguments: message (1-8000 characters) and category (bug, confusing, missing, idea, praise, other), plus optional user_approved (true only after explicit approval), workspace (default: the pinned key), request_id, error_code and command.
  • The server adds client: shardflux-mcp/<version> and, as agent, the MCP client's name and version from initialize (e.g. claude-code/2.1.0; without one, SHARDFLUX_AGENT_LABEL when it is not the default mcp).
  • Approved submission result: {id, received_at, duplicate, note}. duplicate: true: the same message from this key in the last 24 hours; it is not emailed again.
  • Any API key may send it (no tool permission), so it is always listed. It is rate limited per key: rate_limited with details.retry_after_seconds, and a hint naming the wait and the fallback address, shardflux@heliosone.fi.

Updates (0.4.0+)

At startup, after the configuration is validated, the server asks the API's GET /v1/client-versions whether @shardflux/mcp at its version is current. It sends one request (3 s timeout) in the background: the MCP handshake and tool calls never wait for it, and any failure is ignored. When the server is outdated, or below the oldest version the API still supports, it logs one warn line on stderr:

{"time":"2026-10-01T09:00:00.000Z","level":"warn","service":"shardflux-mcp","message":"@shardflux/mcp 0.20.0 is outdated: 0.20.1 is available. Update: npm install -g @shardflux/mcp@latest","status":"outdated","package":"@shardflux/mcp","current":"0.20.0","latest":"0.20.1","minimum_supported":"0.1.0","upgrade_command":"npm install -g @shardflux/mcp@latest","release_notes_url":"https://www.npmjs.com/package/@shardflux/mcp?activeTab=versions"}
  • An unsupported server says ... is no longer supported by the Shardflux API (minimum <version>). Update: ... ("status":"unsupported"). It keeps running.
  • Otherwise it stays silent (one debug line), also when the API does not answer.
  • The server instructions do not carry the notice: they are fixed when the server is built, and the handshake does not wait for the check.
  • SHARDFLUX_NO_UPDATE_CHECK=1 or NO_UPDATE_NOTIFIER=1 turns the check off; createShardfluxMcpServer(config, { versionCheck: false }) does too.
  • The @shardflux/sdk client inside the server runs no check of its own (versionCheck: false). The SDK ships inside the server, so the update to install is the server's.

Tools

Workspace admission queues (0.22.0+, SDK 0.29.0): workspace_open follows the API queue automatically, retaining the same request body and Idempotency-Key and honoring Retry-After within its existing call deadline.

The management tools:

ToolDoes
workspace_openOpen by key: create on first use, reconnect or resume afterwards, never reset. Waits until the workspace is ready (its template's start commands and services included) unless wait: false. lifetime: "session" opens a workspace that is discarded after its idle timeout. inputs (0.3.0) passes the template's text inputs, {"NAME": "value"}. mode (0.4.0): processful or file_first (see "File-first workspaces"). allocation_mode and memory_mib_held (0.7.0): see "Elastic memory".
workspace_listList the project's workspaces, with prefix, state, lifetime, purpose, include_deleted, limit and cursor. By default only persistent standard workspaces are listed.
workspace_statusOne workspace plus its five most recent operations.
workspace_suspend, workspace_resumeLifecycle operation. Returns at once unless wait: true (then once it finished, through the SDK's own wait).
workspace_suspend with after_seconds(0.4.1) Suspend when idle: the workspace is suspended once it has been idle for after_seconds (0-3600; 0 = as soon as it is idle, 0.5.1+), instead of now. The description tells the agent to use it when it finishes its work, so the workspace stops using RAM soon after. Its next tool call on the workspace cancels it; a running command or a keepalive postpones it. Returns suspend_request (not_before: the earliest suspend) and a message; operation when a suspend was already in progress. Not with wait. workspace_status shows a pending request as workspace.suspend_request. Not for file-first workspaces.
workspace_suspend with durable: true(0.6.0+) Returns once the suspend is in durable storage. A suspend returns as soon as the workspace is sealed on its host, typically in a few hundred ms; its operation's durable turns true when the copy lands in durable storage, typically within a second (durability shows its progress).
workspace_forkFork into new_key. A fork of a running workspace carries durable and durability the same way (0.6.0+). Without caps the fork keeps the source's caps and memory allocation (allocation_mode, memory_mib_held: 0.7.0+). With wait: true the API holds the fork until the copy runs and returns it ready in the same request (0.7.0+).
workspace_resize(0.8.0) Change a workspace's memory, CPU or disk without a restart, running or suspended: memory_mib, memory_mib_held, allocation_mode, cpu_millis, disk_gib (at least one). Returns per resource what applied and when (applies_at: now, resume or next_start), the stored caps and a one-line message. See "Resize".
operation_waitKeep waiting for an operation. durable: true (0.6.0+): a suspend or fork, until its copy is in durable storage.
workspace_expose_port, workspace_list_ports, workspace_close_port, workspace_port_link(0.8.0) Serve a port of the workspace at its own private HTTPS URL, list the exposed ports, close one, and get a link that opens one in a browser. See Inbound ports.
workspace_set_computer_use, workspace_computer_desktop, workspace_computer_stream(0.9.0) Switch computer use on, off or to the template's (state); report, start at a screen size or stop the desktop; and get a link to watch or use it live. See Computer use.
usage_summaryThe organization's usage summary for the current period: meters, allowances with their cap state, allowance_exhausted with exhausted_reason, and (0.4.1+, an API with opt-in overage) spend_cap: the overage state, cap, charges, lines per allowance and the date the cap is projected to be reached. (0.18.0+) gpu on plans with GPU-hours: hours used, included, past the allowance and billed, cap_state and blocked_reason. See /limits.
agent_accounts_list(0.17.0+) The organization's Claude accounts and the current project's ChatGPT/Codex accounts with their usage, and which one is active for each provider (0.19.0+): new conversations and every running conversation VM of that provider use its login. Per account: label, email, plan_type, active, status (signed_in, low, limited, expired), usage windows (window, used_percent, resets_at), as_of and stale, and threads (open conversations on the active account). provider (claude or codex) narrows the list. Read-only: your user chooses the active account (shard agents accounts use <account>, or Make active in Shardflux's settings), and signs accounts in and removes them with shard agents accounts.
agent_models_list(0.22.0+) The models Claude and ChatGPT offer each account, asked with its own sign-in the way Claude Code and Codex fill their model pickers; never starts a computer. Default: the active account of each provider; account_id one account, all every account, provider one provider, refresh asks again. Per account: models (id, which you pass as model when you start a conversation; name; efforts; default_effort; available, with reason and reason_text when not; section), default_model, fetched_at, stale, source.
drive_list, drive_read, drive_save, drive_remove(0.21.0+) The project drive: the project's durable files (BOARD.md, notes, plans, a report's evidence and media), readable with every computer of the project gone. drive_save stores text (content) or, on the local server, a file from your computer (path) at drive_path and returns its ref {path, sha256, size, content_type}; drive_read returns text as content, reads exactly the version a ref names (sha256) and, on the local server, writes any file to your computer (save_to); drive_list pages the current files (prefix, limit, cursor); drive_remove takes a path off the drive. See Project drive.
model_template, model_template_set_primary, model_template_set_roles(0.21.0+) Which harness, model and effort each role of a task runs with (master, builder, hard, light, reviewer), from the Claude and Codex accounts the organization connected; harness keeps a task on its provider and attempt is a retry. model_template_set_primary marks the project's primary provider (claude, codex, or null to remove the mark) once your user chose it; model_template_set_roles (0.24.0+) chooses the provider of each role. See Project drive.
brain_list, brain_read(0.22.0+) Your user's brain, read-only: their archive kept by their orchestrator, with every published answer as reports/<day>/<folder>/report.md and its media, the orchestrator's notes and files, and index.md. brain_list pages the current files (prefix, limit, cursor) with the brain's version; brain_read returns text as content, reads exactly a version (sha256) and, on the local server, writes any file to your computer (save_to). See Your user's brain.
move_to_cloud(0.18.0+, local server) Continue this Claude Code or Codex session in the cloud, with its history and uncommitted edits. Optional worktrees scope (0.19.0+, CLI 0.22.0+); see Move to cloud.
send_feedback(0.19.0+) Preview feedback; user_approved: true sends after explicit user authorization: message, category, and optional workspace, request_id, error_code, command. See Feedback.
template_get(0.3.0) A template's versions with their settings (env, inputs, start commands, services, defaults) and (0.7.0) their immutable paths; with version, that version's recipe in request form.
template_languages(0.3.0) The languages and versions a base (<slug>@<version>) offers build.languages.
template_build(0.3.0) Build a version of an organization template from a recipe v2: recipe (the document) or file (a template.yaml or .json path). File entries may name local from paths, uploaded first (folders as a tar). Every local path must resolve inside the server's working directory; others are refused before any request. Unpublished unless publish: true; wait: true follows the build within the call's deadline.

The SDK's workspace tools come from workspaceTools():

  • exec, exec_read, exec_cancel (0.7.0+: background commands)
  • read_file, write_file, list_files, and search_files, edit_file (0.4.0+)
  • list_processes, signal_process
  • terminal_open, terminal_send, terminal_read, terminal_close
  • git_clone, git_status, git_commit
  • browser_screenshot, browser_content
  • computer, computer_batch (0.9.0+: the workspace desktop, while its computer use is on)

They are published with the SDK's JSON Schemas verbatim, plus workspace_key and, where the SDK schema has none, timeout_ms. They are filtered by the key's tool permissions when the server can read them; otherwise it lists every workspace tool. exec's cwd is an absolute path (default /home/user): a relative one is an error result with details.reason: invalid_cwd whose message names the absolute path it likely means, and a command that could not start (a cwd that is not a directory, a program not on PATH) returns exit_code: null with error: { code, message, reason: "exec_failed_to_start" } naming the workspace's reason (0.4.1+). browser_screenshot returns an MCP image content block. search_files is annotated read-only; edit_file replaces exact text and, without an expected_revision, reads the file's revision first so a concurrent change fails the edit (conflict, details.reason: revision_mismatch) instead of being overwritten.

Each workspace tool call first sends the wake hint (POST /wake-hint, without waiting for it): a parked workspace starts restoring while the call is prepared, and a suspended one starts resuming. read_file, list_files and search_files send none (0.4.0+): a suspended workspace is read from its saved disk, listed and searched there without resuming it (the state at suspension).

If search or patches are not available for a workspace, search_files and edit_file fail with conflict, reason: host_feature_unavailable (details.feature file_search or file_patch), retryable: false and a hint naming the fallback (exec with grep; read_file then write_file).

Deleting a workspace is deliberately not exposed to agents; use the CLI or the console.

Account-level actions are not tools either: registering, signing in, organizations, projects, API keys, members, invitations, billing and plan upgrades, spend alerts and the audit export. The server authenticates with a project API key, and the API refuses a project API key for them: 403 forbidden ("API keys cannot perform this action.") on the account routes, 401 on the /v1/auth session routes. They need a person's session. From 0.4.0 the server instructions tell the agent to use the shard CLI for them (shard --help; for example shard auth login, shard setup, shard billing upgrade <plan>), which signs a person in with a CLI session.

Setting Shardflux up for someone (0.16.1+): the instructions tell the agent to ask its user one question first, whether Shardflux is for a SaaS platform (their product runs VMs for its customers through these tools, the SDK or the API) or for their personal cloud coding agents, and point to shard setup --guide (CLI 0.17.1+), which lists the steps of both. From 0.19.0, the instructions run permitted setup steps and stop an action when a permission system refuses it. The agent gives the user the exact command and asks for its non-secret result, without bypassing the refusal; blocked or unobserved behavior stays unverified. Browser sign-ins and secret-entry pages remain the normal path.

Every tool finds its workspace by exact key across every lifetime and purpose, so sessions, template drafts and test instances resolve too. The live workspace wins over tombstones that ended sessions left with the same key. Workspace results include lifetime, purpose, disk_layout, idle_timeout_seconds, ended_reason and (0.3.0) startup: the state of the template's start commands and services (failed names the step, its exit code and output tail).

Inbound ports (0.8.0)

An agent can show what it builds: workspace_expose_port serves a TCP port of the workspace at its own HTTPS URL (https://<port>-<handle>.<domain>) and returns {port, url, created_at, callback, newly_exposed}; workspace_port_link returns a link ({url, expires_at}, path and ttl_seconds 60-604800, default a day) that opens the port in a browser, for the agent or the person it works for. Every port is private: the URL answers only a link's browser session, a port token or the port's callback URL. A request wakes a suspended workspace and is answered once it runs. workspace_list_ports lists the exposed ports; workspace_close_port closes one, and its links stop working at once. The server inside the workspace listens on 0.0.0.0:<port> (start it with workspace_exec_start). The refusals port_not_exposed, port_limit and inbound_ports_not_available carry a hint. Processful workspaces; a pinned file-first workspace does not list these tools.

Computer use (0.9.0)

A desktop in the workspace for agents that operate GUI software. workspace_set_computer_use with state: "on" switches it on ("inherit" follows the template); the platform starts the desktop on the first call. The computer tool takes one action of Claude's computer toolset per call (action plus its parameters: coordinate, text, scroll_direction, scroll_amount, region, ...): input actions answer with a screenshot taken after them as MCP image content, screenshot and zoom with the image, cursor_position with the pointer. computer_batch runs up to 50 of those actions in one call (click a field, type, press Return) and answers with each action's result, a zoom's image and one screenshot after them. Both take screenshot: false to skip the image, settle_ms (the wait before it, default 250) and format: "jpeg" with quality for smaller images. Programs started with exec in the background (e.g. chromium https://example.com &) open on the desktop. workspace_computer_desktop reports the desktop (action: "status"), starts it at a screen size ("start", width 640-2560, height 480-1600) or stops it ("stop"). workspace_computer_stream returns a link ({url, expires_at, port, interactive}) to watch the desktop live, or use it with interactive: true; stop: true ends every view. A call while computer use is off carries a hint to switch it on. Processful workspaces; a pinned file-first workspace does not list these tools.

Background commands (0.7.0)

exec with background: true starts a long command (a build, a test suite, a training run, a server) and returns {session_id, state} at once, so the agent keeps using the other tools. exec_read reads its state, exit code and output: the end of each stream, or from the next_stdout_offset / next_stderr_offset of the previous read, and wait_ms (up to 60000) waits for the exit and returns as soon as it happens. exec_cancel stops it (SIGTERM, then SIGKILL after grace_ms, 1-60000, default 5000). With background, timeout_ms is the command's own limit (up to a day) rather than the call's deadline, and the workspace stays awake while the command runs. A burst (burst: "always") runs in the foreground. workspace_exec_start (with timeout_ms, 0.7.0) starts sessions that exec_read and exec_cancel read and stop the same way. Processful workspaces.

Immutable paths (0.7.0)

A recipe's immutable list names directories every workspace of the template mounts read-only from the template's newest published version; workspaces pick up a new version at their next cold boot or resume. template_get shows each version's immutable ({paths, bytes}, or null), template_build results carry immutable_paths, and workspace results carry template.immutable_version: the version whose immutable paths the workspace has mounted. A recipe without immutable keeps the open version's list; each new version keeps every path of it. Writing under an immutable path returns reason: "read_only_path" with a hint; the build refusals immutable_path_removed, immutable_paths_unsupported_base and invalid_path (at recipe.immutable[<i>]) carry one too.

Elastic memory (0.7.0)

workspace_open and workspace_fork take allocation_mode (fixed or elastic) and memory_mib_held next to the caps. An elastic workspace holds only the memory its commands use and grows up to memory_mib when they need more; billing counts the memory it holds. It idles at memory_mib_held (default 1024). Package installs, test runners, compilers and bundlers get their memory before they start, so they see what they need from their first instruction; everything else starts at once and the workspace grows while it runs. fixed gives a static allocation of memory_mib. exec and workspace_exec_start take resource_hint (0.8.0): heavy gives the command its memory before it starts, light starts it at once, auto (the default) decides from the command. Workspace results carry memory ({allocation_mode, promised_mib, held_mib, plugged_mib}), and an exec result carries memory_grow ({outcome, from_mib, want_mib, got_mib, deliver_ms}) when the command's start grew the workspace.

Resize (0.8.0)

workspace_resize changes a workspace's memory, CPU and disk without a restart, running or suspended, fixed or elastic. Memory changes live and disks grow online; a suspended workspace gets its new size when it resumes, before its first call. CPU changes live within the vCPUs the workspace booted with; a larger CPU size applies at the next start. The new caps are stored, so every later start uses them. A typical result:

{ "state": "running",
  "memory": { "applies_at": "now", "previous_mib": 2048, "target_mib": 6144, "applied_mib": 6144, "converged": true, ... },
  "disk": { "applies_at": "now", "previous_gib": 10, "target_gib": 20, "applied_gib": 20, ... },
  "caps": { "memory_mib": 6144, "disk_gib": 20, "cpu_millis": null, "allocation_mode": "fixed" },
  "message": "memory 2048 → 6144 MiB now; disk 10 → 20 GiB now." }

Burst execution (0.7.0)

exec takes burst: "always" (with optional burst_vcpus and burst_memory_mib) to run one heavy command, such as a cold build or a full test suite, on a larger, short-lived burst VM over a copy of the workspace. Output and exit code are the command's own, and its file changes are applied back when it exits. The result adds burst (size, method, changes applied, overhead). If applying the changes fails (burst_apply_failed), call exec again with the same session_id to finish the apply.

File-first workspaces (0.4.0)

workspace_open with mode: "file_first" (or SHARDFLUX_WORKSPACE_MODE=file_first) opens a file-first workspace: a versioned file tree under /home/user with no VM between calls. It is ready at once and never suspended. Workspace results carry mode and, for file-first workspaces, tree_revision.

  • exec runs each command as an execution: a fresh VM on the workspace's files. Only files under /home/user persist between calls. The result adds execution_id, state, tree_revision and changed (the paths the command added, modified or deleted, up to 200, with changed_truncated). An execution runs to completion: when the call's deadline passes first, the error carries its execution_id and the execution continues server side.
  • The files tools work as on a processful workspace. Each change publishes the next tree revision.
  • The process, terminal, git and browser tools and workspace_suspend, workspace_resume, workspace_fork, workspace_resize and operation_wait do not apply. A pinned server lists only the tools of its workspace's mode: the mode of the pinned key once it is known, else SHARDFLUX_WORKSPACE_MODE, else processful. When the known mode changes what it listed (for example the pinned key is opened file-first after the first tools/list), it sends notifications/tools/list_changed. An unpinned server lists every tool; calling one the named workspace's mode lacks returns an error with reason: "not_supported_for_mode" and a hint, before any request.
  • Errors of file-first workspaces carry reason and a hint: not_supported_for_mode, mode_mismatch (a key's mode never changes), mode_not_available (the account does not have file-first workspaces), layout_unsupported (a legacy template), tree_revision_mismatch (with current_tree_revision), outside_tree_root, execution_in_progress (another execution holds the workspace), execution_id_reused and no_execution_host (the execution cannot be placed right now; retried with the same id; nothing ran).
{
  "mcpServers": {
    "shardflux": {
      "command": "npx",
      "args": ["-y", "@shardflux/mcp"],
      "env": { "SHARDFLUX_API_KEY": "sfk_...", "SHARDFLUX_WORKSPACE_KEY": "me/agent-files", "SHARDFLUX_TEMPLATE": "python-node-browser", "SHARDFLUX_WORKSPACE_MODE": "file_first" }
    }
  }
}

Contract

  • Arguments. They are validated against the published schema with the SDK's validateArgs before any request. A failure returns isError with code: invalid_arguments and the issues.

  • Errors are tool results. They carry isError: true and structuredContent.error = {code, message, status, request_id, retryable, operation_id, details, source}, using the API's or cell gateway's closed error codes. They are never protocol failures. The only protocol error is an unknown tool name (InvalidParams).

    • A failed operation is code: operation_failed with details.error_code (and details.reason when the operation error has one) and, from 0.2.1, retryable: the operation error's own flag.
    • An API or cell gateway the server cannot reach is code: network_error, retryable: true.
    • A start refused because an allowance is used up is code: allowance_exhausted (402) with reason (0.4.1+): allowance_used (upgrade, or turn on overage), overage_paused (a plan payment is past due) or spend_cap_reached (raise the spend cap or upgrade), and details.spend_cap. An owner or billing member acts on it in the console; retrying does not help.
    • (0.4.0+) A failed call has a feedback field next to error: a one-sentence suggestion to call send_feedback with category bug, the request_id and the error code. Preview first and obtain explicit user authorization before user_approved: true. Not for invalid_arguments, workspace_pinned or unauthenticated. A failed send_feedback carries a hint instead (when to retry, or the email address).
  • Start deadlines (0.2.1+). A queued open, resume or fork (capacity_pending) has a deadline 15 minutes after it was created; a wait that ends first returns code: timeout, and its message names the deadline. A start still pending then fails: operation_failed, details.error_code: capacity_unavailable, retryable: true, and a message telling the agent that nothing was started and it can retry. The server instructions say the same. (0.15.0+) A timeout of a wait carries operation_id and last_state, plus last_reason, deadline_at and queue_position as fields when the operation reports them.

  • Progress (0.15.0+). A request with _meta.progressToken gets notifications/progress while its call waits: on each change and at least every 10 s, with a message such as Queued for capacity (position 3); a new host is starting, ready by 21:40Z (an open, resume, fork, wake or operation_wait of a queued start), Waiting for room on the workspace's host (position 2) or Waiting for a free working slot: ... (a tool call waiting to be admitted), or the lifecycle phase (Resuming the workspace: queued). progress counts up; there is no total. A request without a token gets none. Clients that reset their request timeout on progress keep long waits alive this way.

  • Waiting for room (0.15.0+). A call refused before it ran because room is being made for it, on the workspace's host (503 host_capacity, details.queue_position) or in the plan's workspaces working at once (429 quota_exceeded), is sent again after each Retry-After until shortly before the call's deadline. A refusal that lasts is the error with retry_after_seconds and a hint; a deadline reached while waiting is code: timeout with reason, queue_position and retry_after_seconds, and nothing ran.

  • Timing (0.2.0+). A call that opens a workspace or waits says where the time went, from the SDK's lifecycle timing, compact for model context:

    "timing": {
      "action": "resume", "outcome": "succeeded", "operation_id": "01a0ead6-bd61-737a-ae88-66e2d01a6e25", "total_ms": 413,
      "phases": ["request 218 ms", "queued 195 ms"],
      "server": { "queued_ms": 51, "run_ms": 290, "total_ms": 341, "resume_path": "local_cache" },
      "outside_server_ms": 72, "retries": 0
    }
    
    • workspace_open and operation_wait always carry it. workspace_suspend, workspace_resume and workspace_fork carry it with wait: true. Workspace tools carry it when they had to wake the workspace (action: "wake"). Other results do not.
    • Phases are in order, as phase(reason) ms. request(held) means the API held the open (or, 0.7.0+, the fork) until the workspace was ready. capacity_pending(no_ready_host) is time queued to start.
    • server is the operation's own queued, run and total time, plus the start or resume path the cell reported. A resume also has memory_restored (0.5.0+) when the API reports it, and cold_boot_reason when it is false; host_lost (0.7.1+) after the machine the workspace ran on failed (restored_from, and state_as_of for a checkpoint).
    • outside_server_ms is everything else: network, polling, reading the workspace, the tool token.
    • A failed or timed-out call carries it too, next to error ({error, timing}).
    • workspace_open uses the SDK's waited open: the API holds the request until the workspace is ready and answers with the first tool token, which the next tool call reuses.
  • Deadlines. Every call has one: timeout_ms, clamped to the ceiling.

    • Waits time out just before the deadline with code: timeout and the operation_id; the operation continues server side (a queued start until its deadline, deadline_at in the error).
    • Any request still in flight at the deadline is aborted.
    • exec's command timeout is capped at the deadline minus 2 s, so its output comes back. With background: true (0.7.0+) the call returns at once and timeout_ms is the command's own limit.
  • Cancellation. MCP notifications/cancelled aborts the SDK work behind the call: waits, HTTP requests to the API and to the cell gateway, and backoff sleeps. No response is sent, and the server stays up. The lifecycle operation itself is not canceled.

  • Workspace tools wake suspended workspaces. With SHARDFLUX_TEMPLATE set (0.9.0+), a key that has no workspace yet is created from that template by the first workspace tool that names it (exec, workspace_exec_start and the file, process, terminal, git and browser tools), and that result carries workspace_created: true. Without it, a workspace that was never opened is not_found: call workspace_open first. Reads (read_file, list_files, search_files) of a suspended workspace are answered from its saved disk without waking it.

    • A suspended workspace is resumed (or the resume or open already running is joined), and the call runs once it is running. A call made during a suspend or resume waits for it to finish. The call never runs twice: the refused attempt did nothing. The resume is one request held until the workspace runs, answered with this server's tool token (0.4.0+, an API with the held resume).
    • The wait is bounded by SHARDFLUX_WAKE_TIMEOUT_MS and the call's deadline. Past it the result is code: timeout with the operation_id and last_state of the resume or open. That operation continues server side: operation_wait keeps waiting. A resume or open that fails returns code: operation_failed (retryable: true for capacity_unavailable: the workspace stays suspended).
    • With SHARDFLUX_WAKE=off the API's refusal comes back instead (conflict, details.reason: workspace_not_running, or workspace_not_running from the cell gateway).
    • Detecting a cold resume (0.5.0+). A resume restores memory and running processes. After a platform runtime update, or after the machine the workspace ran on failed (0.7.1+), a resume can boot from the saved disk instead of restoring memory (a cold boot), also when a workspace tool wakes it; check memory_restored. The call still runs with the files kept, and processes start fresh. The result (or the error result) then carries timing.server.resume_path: "cold_boot", memory_restored: false, cold_boot_reason (guest_filesystem from 0.22.0, runtime_changed or host_lost) and a notice the agent reads: to start its dev servers, databases, watchers and background jobs again. The server instructions and the workspace_resume description say so too.
    • Workspaces recover by themselves (0.7.1+). When the machine a workspace runs on fails, the workspace is suspended, and the next tool call on it resumes it. From its own disk it is the cold resume above (reason host_lost). From its newest checkpoint, the notice names the time its state is from (host_lost.state_as_of in the operation), so the agent checks the files it changed since.
    • Tool tokens are never returned to the model.
  • Keys, not ids. Tools take workspace keys, resolved by exact match within the key's project.

Use as a library

The package also exports the server for other MCP transports:

import { createShardfluxMcpServer, loadConfig } from '@shardflux/mcp';

const server = createShardfluxMcpServer(loadConfig(process.env)); // an MCP SDK Server
await server.connect(transport); // any @modelcontextprotocol/sdk transport

License

Apache-2.0

Integration controls (0.6.0+)

workspace_open accepts labels and idle_policy; workspace_list accepts exact label filters. workspace_set_labels replaces all labels. workspace_idle reads activity without waking, workspace_keepalive declares ongoing work, and workspace_set_idle_policy accepts adaptive, never, fixed:, or default. workspace_exec_start starts a tracked background command with optional stdin_open and (0.7.0+) timeout_ms; read it with exec_read and stop it with exec_cancel; workspace_exec_input writes data at an acknowledged byte offset and can send EOF with close. Both require exec permission and processful workspaces. Frames are bounded to 64 KiB; use the returned offset after partial acknowledgements. The host and guest must advertise pipe-input support. workspace_resume recovers failed IDs without replacing their disks. A completed delete frees the key for a new workspace ID. Protocol errors include their source; a bare 404 is not a workspace tombstone.

Prepare an imminent tool call (0.8.0+)

Set SHARDFLUX_PREWAKE=on to offer workspace_hint (default off). A host that observes model input streaming can call it with the workspace key ahead of a VM tool call. It returns without waiting for restore; the following tool uses the workspace normally. Resume a suspended workspace first. The MCP server receives completed tool arguments, so the host supplies the early signal explicitly. File-first workspaces do not list this tool.

Resize controls (0.10.0+): workspace_resize accepts at_least: true to grow only resources that need more capacity, and wait: false to return the held server answer with its operation. The default waits for completion. Fixed memory without memory_mib uses the template default.

New in 0.10.0

workspace_computer_stream reuses a link of the same kind with more than 60 seconds left. Set fresh: true to mint a link; stop: true ends the view and clears it. A computer_batch ending in screenshot or zoom returns that image once. SHARDFLUX_BASE_URL aliases SHARDFLUX_API_URL; the latter wins. The SDK transport honors environment HTTP(S)_PROXY and NO_PROXY.

Embed a live viewer (0.10.0+)

Watch the desktop or a port preview inside your web app. Choose 1–10 distinct HTTPS origins, then use the returned URL as the iframe source.

{"name":"workspace_computer_stream","arguments":{"workspace_key":"acme/demo","embed_origins":["https://app.example.com"]}}
{"name":"workspace_port_link","arguments":{"workspace_key":"acme/demo","port":3000,"embed_origins":["https://app.example.com"]}}
<iframe src="RETURNED_LINK_URL" title="Watch the agent" style="width:100%;height:600px;border:0"></iframe>

The browser session is partitioned by the top-level site. Each origin is exactly a scheme and host with an optional port, such as https://app.example.com:8443. The viewer permits framing by those origins; interactive viewing uses the same allowlist.

Idle deletion retention (0.10.0+)

Pass retention: {"delete_after_idle_days": 14} to workspace_open to delete a persistent conversation workspace automatically after 14 idle days. workspace_set_retention takes the same policy and workspace_key; pass retention: null to follow the project default. Workspace results include effective days and delete_at. Policies accept 1 through 3650 days. Tool calls and ongoing work postpone deletion.

Workspace upgrade (0.10.0+)

workspace_upgrade keeps files, installed package files and home through one cold start. Memory and processes end. Its at argument accepts now or next_resume; the returned operation says whether the upgrade is scheduled or applied. workspace_get includes available and pending targets.

The processful git_clone tool accepts optional filter: "blob:none" (0.11.0+, SDK 0.17.0). Current checkout files are fetched now; historical blobs fetch from origin when needed. Omit it for a complete clone. No shared cache is enabled.

Sealed-file reads (0.11.0+)

Additive: read_sealed_files is a read-only processful tool with ordered paths and optional generation. It reads up to eight complete files from a suspended sealed generation, returns exact base64 bytes with revisions and explicit errors, and sends no wake hint. It is excluded from file-first mode.

Use sealed-file reads for complete files from one suspended generation. If the generation changes, request a fresh read. See lifecycle for the read contract.

Parallel Git checkout (0.11.0+)

Set parallelism (1–16) to choose Git indexing threads and checkout workers for this clone. The git_clone tool forwards it; CLI callers use git -c pack.threads=4 -c checkout.workers=4 clone ... through shard ws exec.

Treeless Git clones (0.11.0+)

Set filter: "tree:0" (Python: filter="tree:0") to fetch the requested checkout and commit graph now, with historical trees and blobs fetched from origin as needed. CLI callers use git clone --filter=tree:0 through shard ws exec. See Git for clone options.

Explicit browser readiness (0.11.0+)

The browser_screenshot and browser_content tools accept an explicit readiness declaration. Set readiness to describe the visible state needed for this observation. Omit it to wait for the full page load.

A declaration requires 1–32 DOM conditions (selector, exact equals, and optional property: "text" | "value"). Optional images (up to 32 selectors), fonts (up to 16 CSS font descriptions and sample text), and focus declare the state needed by this observation. The helper binds to the new navigation, checks declared values, decodes images and loads fonts, captures the Chromium compositor surface, then rejects changed loader or page state. A timeout or unmet condition fails the request. See browser tools for readiness and timeout behavior.

Explicit pixel completion (0.11.0+)

The computer and computer_batch schemas accept pixel_predicate with timeout_ms and 1–16 region/sha256 objects. Unmatched completion is an MCP isError result with no image.

Explicit predicates are enabled when supplied; no environment switch is required. Omitted predicates retain ordinary 250 ms settling.

Require an appended lossless PNG and omit settle_ms. Digests cover row-major RGBA8 bytes including cursor pixels. The exact matched full frame is encoded and returned. A condition already satisfied before input refuses the batch unless allow_pre_satisfied explicitly allows that semantics. Timeout returns no success image; input may already have run, so inspect input results before retrying. Use a known, semantically unambiguous result. A pixel condition cannot certify unpainted backend state or infer completion from focus or quiet.

Exact text entry (0.11.0+)

pasteText replaces the clipboard with UTF-8 text and sends the chosen paste chord. Use shift+Insert for xterm. Ordinary type sends line breaks as Return. Start with all keys released. Clipboard replacement remains in effect after cancellation; see computer use for action results.

The computer tool accepts action: "pasteText", text, and optional paste_chord; computer_batch accepts the same action. Clipboard replacement must be explicit.

Initialized CPU services (0.11.0+)

Template services accept initialized_cpu with compatibility, reset, and timeout_seconds. Use cpu-service-v1 for immutable initialization, or cpu-service-fresh-inputs-v1 with fresh_env_names for values supplied at each open. Declare an unprivileged user and command readiness. Each open runs the reset script and its owned startup hooks before returning. Initialization-dependent and secret inputs use ordinary startup.

Waiting agent reachability (0.12.0+)

A message from claude.ai or the Claude app wakes a waiting Claude conversation at any time. Reply-traffic wakes count as parked time; agent work counts as awake time. The reachability duration is deprecated and ignored (0.14.0+).

Cloud agents (0.12.0+)

Install once with npm i -g shardflux, then use shard ./ on a project, shard for the command center, shard machine for your device environment and shard template for the project. The Shardflux app starts automatically the first time shard runs, with launch at login enabled; shard menubar stop turns it off (CLI 0.13.2+).

Run shard ./ in your project to start Claude Code or Codex, usable immediately while setup runs in the background. Machine saves require a machine source VM (labels.shard_layer = "machine"). On your computer, run shard machine open --json, make changes in that VM, then shard machine save --wait. The computer's CLI selects the machine VM; inside a VM, save uses that VM. A conversation or unmarked fork returns filesystem_source_mismatch: copy the intended files or repeat the install in the machine VM and save there. Project keys stay in their own project; a VM's native token cannot select another workspace. On an unpinned MCP server, machine_save selects workspace_id or uses the remembered source when omitted. A pinned server selects its own workspace; that workspace must be a machine source.

Your machine carries credentials, tools, dotfiles, logins and agent config; the project's template carries toolchains, dependencies, services and project secrets. Both are private filesystem templates and include secrets as ordinary files. Browser logins and Claude/Codex config belong to the machine. Set up tools and secrets normally inside the VM; your agent uses the matching machine or project save/rollback commands in its source VM. Every agent starts from both. Save or roll back with shard machine save|rollback and shard template save|rollback; changed files reach running agents live, software at the next start.

shard agents fork or f in the command center copies the whole running state into an independent workspace and conversation. Open in your terminal, Claude Desktop or the Codex app, and the terminal Claude conversation in claude.ai or mobile. Sessions are titled with their task and repository, like Add CSV export · todo-app. Waiting agents stay reachable on their own connections; see the settings and billing reference. Claude needs one cloud sign-in per account; Codex uses your copied login.

Import project secrets from hsec, 1Password, Bitwarden or Keychain. Approve browser fills from the attached CLI or the Shardflux app; remember a selected login for unattended work with automatic relay renewal. Bound secret values are redacted from command output and saved logs.

Imported secrets: stored encrypted with AWS KMS; only this project's workspaces can load it, and every load is logged. Vault fills: sent end to end from your vault to the workspace; Shardflux only relays encrypted bytes. Remembered credentials: stored encrypted with AWS KMS and filled straight into the page; agents never see it, and every use is logged.

Start a cloud agent · Machine and template · Credentials

shard templates remains the platform template build and management group.

The project environment tools are template_get with repo_remote, template_save, template_rollback and template_delete (0.19.0+), which deletes the project template: its saved versions go, new conversations start from the machine until setup saves a fresh one, and VMs running on it keep their files. machine_get, machine_save and machine_rollback manage the private machine. machine_save and template_save with wait: true return once the saved version is ready (0.12.1+); moved_to_image lists the home folders a save put into the image, linked back at the same paths (0.16.1+). template_get with slug and template_build remain the platform template tools.

volume_list (0.13.0+) includes each volume’s kind (shared or project_space) and measured storage usage.

Move to cloud (0.18.0+)

Tell Claude Code or Codex to "continue this in the cloud" and it calls move_to_cloud. The session moves to its own Shardflux cloud VM as soon as the current turn ends and continues there as the same session (claude --resume, codex resume), with its full history and the project exactly as it is, uncommitted edits included. Your working tree stays as it is, and the cloud work comes back to the folder by itself.

The session's checkout moves; the repository's other worktrees and local branches stay on this computer (CLI 0.23.0+). MCP 0.19.0+ with CLI 0.22.0+ accepts optional worktrees: "preserve-all" (or "selected-only", the default). Use preserve-all only when your user asks to include every worktree, after showing them shard move --last --plan --json: it copies local refs, staged/unstaged indices, dirty/untracked bytes and ignored files, including build/dependency caches, and keeps a migration-time recovery snapshot in the project space. Symlink targets and unrelated sibling folders stay local.

The server knows which session called: Claude Code starts it with the session's id and project folder in its environment, and Codex sends the thread and its workspace with every call. It runs shard move --session <id> --path <folder> --detach --json (CLI 0.19.0+) in the background, so the move outlives the call, and returns at once:

{
  "moving": true,
  "harness": "claude",
  "session_id": "3d085e35-aa66-4866-9a53-f09719d6767c",
  "folder": "/Users/you/code/todo-app",
  "log": "/Users/you/.config/shardflux/moves/3d085e35-aa66-4866-9a53-f09719d6767c.log",
  "pid": 48121,
  "message": "This session moves to the cloud as soon as this turn ends and continues there as the same session, …",
  "next_step": "End your turn now: tell your user in one line that this session continues in the cloud, and do no more work here."
}

The CLI's output goes to <config dir>/moves/<session id>.log (the CLI's config dir: SHARDFLUX_CONFIG_DIR, else ~/.config/shardflux). It runs with this server's API URL and key. A session that already continues in the cloud answers already: true with its conversation. shard move --last in a project folder moves a session from a terminal.

Conversations

Conversation create, fork, spawn and join accept from_conversation_id (0.23.2+). Inside an agent the SDK also uses SF_CONVERSATION_ID. Conversation and agent results retain orchestrator_conversation_id and the known orchestrator_input_id.

From 0.13.0, conversation_create, conversation_fork, conversation_spawn, conversation_join, conversation_list, conversation_get, conversation_send, conversation_wait, conversation_move and conversation_land work with project conversations directly from chat.

conversation_feed (0.21.0+) answers what changed across the project's conversations since a cursor, each conversation once, oldest change first: call it without cursor to get one, then pass next_cursor each time. With wait_seconds (up to 20) an empty answer waits for the next change. conversation_list takes updated_after (RFC 3339) to list only conversations changed since then. Conversations carry updated_at and title_short, the agent's own short name for them. Both take organization_id (0.21.0+): only that organization's conversations. A deleted conversation comes once in conversation_feed with deleted_at set: drop it.

conversation_create, conversation_fork, conversation_spawn and conversation_join take model and effort (0.16.0+): the model and reasoning effort the conversation's harness starts with, such as opus and xhigh for Claude or gpt-6-astra and high for Codex. Leave them out for the agent's own defaults; a fork keeps its parent's. The conversation's model and effort say what its harness runs. title_prefix (0.19.0+) sets the marker its Claude session title starts with in claude.ai and the Claude app (null for the default ☁, "" for none).

conversation_create needs only harness and route (0.21.0+): without repo_remote or base.commit the conversation starts from the project hub, checked out at the newest start the project's conversations saved there on base.branch (default main, then master). home: true starts a coordinator on your machine without a repository, which spawns threads in the project's repositories with conversation_spawn. Fork, spawn and join take their parent's repository and start by default. conversation_send takes files on the local server (0.21.0+): paths on your computer, up to 20 files of 64 MiB each, stored in the conversation's computer before the message, which lists their paths; the result's files names each one.

{ "name": "conversation_send", "arguments": { "conversation_id": "conv_6qz2dmu4kd3xa7v5l2hgmfnpjy", "text": "Why does the export drop the total?", "files": ["./export.csv"] } }

conversation_send reaches the agent at once (0.22.0+): a working agent takes the message into its running turn (Claude Code, Codex and Codex Cloud), and an idle one starts its next turn with it. The result's delivery says which: steered is true when the message went into the running turn and false when it started the next one.

{ "accepted": true, "seq": 12, "delivery": { "seq": 12, "conversation_id": "conv_6qz2dmu4kd3xa7v5l2hgmfnpjy", "created_at": "2026-10-16T18:00:00.000Z", "state": "delivered", "delivered_at": "2026-10-16T18:00:02.412Z", "steered": true } }

From 0.24.0, delivery.state can also be withdrawn: the board task the conversation worked on closed before its agent took the message, so it was not delivered. The tool returns it at once.

conversation_join accepts join_mode: "reviewer" for a read-only review of the parent’s worktree. usage_summary accepts project_id to read that project’s usage.

conversation_permissions lists what a conversation's agent asked permission for before running a tool, oldest first (0.21.0+): a needs_you conversation without a question waits on its pending requests, each with a title such as "Run npm test", the command, path or URL, and the options it takes. conversation_permission_answer answers one with allow_once, allow_always (the agent's harness stops asking for this kind of call) or deny once your user confirms in chat, and the agent goes on with its turn.

conversation_resume continues a saved conversation in a fresh VM under the same identity (0.13.0+). project_space_reader opens a small read-only workspace for saved project branches and transcripts; the normal files tools can read it, and adaptive idle reclaims it.

conversation_delete (0.21.0+) deletes a conversation everywhere at once, once your user confirms in chat: its agent stops, its computer is deleted (a computer other conversations share stays for them), and its messages, transcript and branch go with it, on every device. It returns {id, deleted, deleted_at, operation}, where operation is the deletion of its computer, and deleting it again answers the same; the conversation then reads not_found. People delete conversations, the person who started it or an organization owner or admin, so a server running in a conversation's computer (a conversation guest) gets 403 forbidden.

{ "name": "conversation_delete", "arguments": { "conversation_id": "conv_6qz2dmu4kd3xa7v5l2hgmfnpjy" } }

conversation_mark (0.23.0+) sets your user's own marks on up to 200 conversations, the same on every device: seen: true records that they opened them now (seen_at), archived: true archives them from their inbox and archived: false brings them back (dismissed_at). Give seen, archived or both. conversation_get, conversation_list and conversation_feed carry each conversation's seen_at, dismissed_at and needs_you_reason (permission, question, sign_in or turn_failed while it needs you); a result is new to your user when the conversation finished after its seen_at. Marks are personal: the conversation itself stays as it is. The result is {data, skipped}: the marked conversations with their marks, and the ids not found, deleted or outside what the key can read. Repeating a mark is safe.

{ "name": "conversation_mark", "arguments": { "conversation_ids": ["conv_6qz2dmu4kd3xa7v5l2hgmfnpjy"], "seen": true, "archived": true } }

conversation_transcript (0.21.0+) reads a conversation's transcript: the agent's own Claude Code or Codex JSONL, byte for byte, for a working, parked or finished conversation alike, without waking its VM. Each call returns a page of whole lines in data (about 32 KiB by default; limit_bytes up to 16 MiB) with offset, next_offset and size in bytes: call again with offset: next_offset until next_offset equals size. session_id reads an earlier session; conversation_wait waits for the conversation's next result or question.

Your user's orchestrator (0.22.0+)

orchestrator_say passes your user’s full words as one input; it does not shorten them before sending.

Your user's orchestrator is their own agent on top of every project, on its own Shardflux computer and the same on every device. The server's key reaches the orchestrator of the person who created it.

ToolDoes
orchestrator_saySends your user's words, exactly as they said them, with an optional selection (task_id, report_id, needs_you_id, input_id or conversation_id: the row they point at). Answered at once with the stored input (queued, its queue_position); every input is handled in parallel by its own thread. Returns {input}.
orchestrator_inputsYour user's recent inputs, newest first, and every one still in flight: each one's state (queued, working, waiting with its waiting line, done, merged with merged_into, failed with error.retryable), its answer card (headline, its facts or the points it grouped, sources, follow-up actions; stored as the agent wrote them, at any length), the task_ids it created or steered and the question_ids it asked. Pass cursor to hear only of changes (inputs: null when nothing changed); wait_seconds (up to 20) holds that answer until something changes. The text is one line per input; the structured result is {inputs, cursor, held}.

Queued inputs (0.23.4+) may already carry waiting.message, including a known usage-reset time. The text result includes that waiting line; the structured result retains the input and its queue position.

The orchestrator's questions wait in needs_you_list as oq_… items (needs_you_answer with text), and what it asked your user's computer while it was offline as dev_… items ("Waiting for your computer: list ~/code"; it runs when the computer is back, and decision: "cancel" drops it). Both carry the input_id they come from.

{ "name": "orchestrator_say", "arguments": { "text": "Lets check on our language model training progress" } }
{ "name": "orchestrator_inputs", "arguments": { "cursor": "Qm7c0lKb3pQ2Zr8vXy1wAa", "wait_seconds": 20 } }

orchestrator_inputs answers with text like this:

- in_s2o36mmfnstvcujcrra7cxqrnq [done] "Lets check on our language model training progress" · answer: Training is 73% done, step 7,300 of 10,000 (Loss 1.84, down from 2.31 at step 5,000; About 2 h 10 min left at this pace; Last checkpoint at step 7,000) · tasks task_fc3wxrtsirizwyhpvzsvawlg4y
cursor (pass it back for changes): Qm7c0lKb3pQ2Zr8vXy1wAa

Your user's brain (0.22.0+)

Your user's brain is their archive in the organization, kept by their orchestrator: every answer it publishes is filed as reports/<YYYY-MM-DD>/<folder>/report.md with the answer's media next to it (image thumbnails under .thumbs/), with the orchestrator's own notes and files and an index.md of everything, newest first. Their orchestrator writes it; brain_list and brain_read read it with every computer asleep. The server's key reads the brain of the person who created it.

{ "name": "brain_read", "arguments": { "path": "index.md" } }
{ "name": "brain_list", "arguments": { "prefix": "reports/2026-10-17/" } }
{ "name": "brain_read", "arguments": { "path": "reports/2026-10-17/training-progress-ab12cd34/loss.png", "save_to": "./loss.png" } }

brain_read returns UTF-8 text of up to 256 KiB as content with its ref {path, sha256, size, content_type}, and sha256 reads exactly that version. On the local server save_to writes any file to your computer (a report's images and videos). brain_list lists the current files in path order, a page at a time, with the brain's version, which moves whenever anything in it changes.

The board: route input and ask about the work (0.21.0+)

board_route and board_ask are deprecated (0.22.0); use orchestrator_say (and follow the input with orchestrator_inputs).

board_route reads a line of input the way the board's input bar does: kind is task, question or steer, and parts has one entry per task (up to 4), each in the person's own words with its project_id (home: true for personal work) and a title when the input was split. selected_task_id is the open task the person points at: input about it steers it (task_ref). uncertain: true means: confirm the project with your user.

board_ask answers a quick question about the project's work from its board: tasks, plans and states, sealed reports, the conversations behind them and what their agents last wrote. It returns text, needs_work (the answer ends with "Make it a task?"), sources, answered_by, first_token_ms and total_ms; pass task_id for the selected task and history for earlier turns. Neither tool starts work or wakes a computer.

{ "name": "board_route", "arguments": { "text": "fix the hero image on the landing page and add a GPU row to the pricing table" } }
{ "name": "board_ask", "arguments": { "text": "what is the healthz work doing right now?" } }

Board (0.21.0+)

The Orchestrator board: every task of the project in the person's own words, the reports their agents seal with evidence, everything that waits on a person, and the approval policy the agents work under. Every device reads the same board, and reading it never wakes a computer.

ToolDoes
board_getThe board: what waits on a person (needs_you) first, then the tasks by bucket (now, next, later) with their id, state, plan and latest report with its evidence labels, the approval policy and the cursor to follow it from. The text is a compact view; the structured result carries every field, the tasks grouped by bucket, and project_id (the key's project). project_id narrows it.
board_changesWhat changed since cursor: each changed task once in its current form (a deleted one has deleted_at), the reports sealed since, the policy when it changed and the whole needs_you list when it changed (null otherwise), with next_cursor and held. wait_seconds (up to 20) holds an empty answer until something changes. reset: true: read board_get again. Without cursor it returns the cursor to follow from.
task_addAdds a task in the person's words, kept exactly: text, and optional project_id, bucket, after (the task it follows; null puts it first), parent_task_id (a follow-up), suggested (an agent's proposal, waiting in Later), home (runs on the machine home) and title. The project's master picks it up. Returns {task}.
task_getA task and every report sealed for it, oldest first, with each report's milestone, outcome, plan, evidence and media: {task, reports}.
task_updateEdits or moves a task: any of text, title (null removes it), bucket, after (null moves it to the top), project_id, home, suggested: false (keep a suggestion) and cleared. Returns {task}.
task_steerSends the person's words to the task's master ("use postgres instead"), which adjusts the plan. Returns {task}.
task_deleteDeletes a task and every nested follow-up, cleaning up their owned conversations and computers. Shared masters stay for their other tasks. Returns {task} with deleted_at.
tasks_clear_doneClears every done or unverified task from the board; their reports stay readable with task_get. Returns {cleared}.
needs_you_listEverything that waits on a person, oldest first: permission requests, questions (the orchestrator's are oq_…), credential requests, finished branches to land, the prompt for old Later tasks, and what the orchestrator asked the person's computer while it was offline (device, dev_…, 0.22.0+): {data}.
needs_you_answerAnswers one, after your user confirmed it in chat: decision (allow_once, allow_always with scope project or everywhere, deny; keep, discard for a finished task's result, which lands on your user's computer with the Shardflux app or shard task land; cancel for a dev_… item, 0.22.0+), text for a question (oq_… too), answers for an agent's question in a permission request, keep for the Later prompt. Returns {answered, item, rule_id}.
approval_policy_getThe approval mode (default, per-project projects) and the always-allow rules. ask: every permission request comes to the person; routine: tests, builds, reads and installs are approved for them; trusted: everything except deploys, pushes to main and spending.
approval_policy_setSets a project's mode (projects, by project id; null goes back to the default) or the organization's default (set by a person signed in to Shardflux; a project key gets 403). Waiting requests the new mode covers are answered at once.
approval_rule_addAlways allows a tool (Bash, WebFetch, Edit) whose command, path or URL starts with pattern, for the key's project by default (project_id). Returns the rule.
approval_rule_removeRemoves a rule by id and returns the policy.

Only people answer needs-you items, clear the board and set the policy: the API refuses a conversation guest (the agent inside a conversation's own computer) with 403 forbidden.

{ "name": "task_add", "arguments": { "text": "Add CSV export to the todo list" } }

board_get answers with text like this (and every field as structured content):

Needs you (1)
- ask_rep_7pl5rwclyd2jtd4w3hcuwshrry question: Which region should the bucket live in? · options "eu-north-1" | "us-west-2" · task task_f65fbi7rmhu62m4wkge4xe56ri
Now (2)
- task_fezjj7km4t66c7n23mqyfr3l2m [done] Pricing copy · latest report done: "Pricing copy updated" (tests 12/12)
- task_f65fbi7rmhu62m4wkge4xe56ri [needs_you] Fix the wake race · latest report needs_you: "Which region?"
Next (0)
Later (0)
Approval policy: routine; always allow: Bash "pnpm test" (rule_xmlsdqx5f34auiqhvlafiogfrm)
project_id: 01a14173-8676-7788-a610-9925569bb225
cursor (pass it to board_changes): eyJ2IjoxLCJvIjoi…

A working task whose agent's computer is starting reads waiting: Waiting for its computer since <time>, 2 in line instead of its now: line, and a single step that waits says step s2: Waiting for its computer since <time> (0.25.0+).

Project drive (0.21.0+)

The project drive keeps a project's durable files: BOARD.md, notes, plans, and the evidence and media a report names (screenshots, logs, recordings). People, phones and agents read them whether or not any computer of the project exists. Paths are relative to the project space root, the names agents see under /shardflux/project in their computers (tasks/t_ab12/evidence/healthz.png), and every tool works on the API key's project.

Each drive_save is a new version named by the SHA-256 of its bytes; saving the bytes that are already current keeps that version. The result's ref is what a report's evidence names, and drive_read with that sha256 reads exactly that version, also after the path was overwritten or removed.

{ "name": "drive_save", "arguments": { "drive_path": "tasks/t_ab12/evidence/healthz.png", "path": "./healthz.png" } }
{ "file": { "project_id": "01a141d4-3b53-7f46-992b-6f38dd20f2d8", "path": "tasks/t_ab12/evidence/healthz.png", "sha256": "2f46547821cd7586a5d0387b0ac8f3eda3933da463b7916b23ce59077ea750dd", "size": 616, "content_type": "image/png", "conversation_id": null, "created_at": "2026-10-15T23:09:50.380Z", "current": true },
  "ref": { "path": "tasks/t_ab12/evidence/healthz.png", "sha256": "2f46547821cd7586a5d0387b0ac8f3eda3933da463b7916b23ce59077ea750dd", "size": 616, "content_type": "image/png" } }

content saves text instead of a file, and the type comes from the drive path's extension (.md is text/markdown, .png is image/png). drive_read returns UTF-8 text as content with its ref; on the local server save_to writes any file to your computer (its folders are created, and a folder path gets the drive file's name). drive_list lists the current files in path order, a page at a time, and drive_remove takes a path off the drive while every version stays readable by its sha256.

model_template tells an agent which harness, model and effort each role of a task runs with: master plans and coordinates, builder does the work, hard takes hard work, light small work and reviewer reviews with a fresh context. Pass a role's harness, model and effort to conversation_create or conversation_spawn. harness keeps a running task on its provider and attempt (1, 2, …) is a retry after a failure. A role with wait waits for its provider until wait.until, and wait.alternative is what the other provider would run, to offer your user. model_template_set_primary marks the provider that leads the project's roles once your user chose it (null removes the project's mark, and the organization's choice leads again).

model_template_set_roles (0.24.0+) chooses the provider of each role for the project once your user chose it: roles maps master, builder, hard, light and reviewer to claude or codex, whatever the primary, or to null to let that role follow the template again; roles left out keep their choice. A role's choice runs its new conversations on that provider (a running conversation keeps its own) and its retries stay on it. The template's role_marks shows each role's choice in force.

Codex Cloud (0.14.0+)

The server includes codex_connector_status, codex_connector_enable, and codex_connector_disable for the account's single billed executor. Create a codex-cloud conversation, prepare its returned worktree, then use codex_cloud_admit; codex_cloud_get returns its current thread id, browser URL (web_url) and ordered earlier thread IDs (previous_thread_ids), and codex_cloud_cancel cancels it and removes its VM. No machine pairing or per-conversation device entry is required. Setup uses the account's copied Codex ChatGPT login. codex_connector_status reports reason: codex_sign_in_required while Codex Cloud asks for a new ChatGPT sign-in (0.21.0+): the user signs in with codex login and runs shard agents credentials sync, and the executor starts again with it.

Save progress (0.19.0+): machine_save and template_save report source size and save phases through MCP progress notifications and include preflight and phases in their result. Failures and timeouts include the build id, recovery action and details.last_progress when available; the final failed build report retains its last phase and counters. A version larger than the plan's workspace disk is retryable: false, names its size and the disk, and details carry error_code, limit, value and actual (0.19.0+).

Pending execution cancellation (0.20.0+)

On guests advertising exec_cancel_pending.v1, successful cancellation can return the actual running state with canceled: true while the kernel holds a killed process. The execution's error explains pending drain, and becomes unverified after 30 seconds without claiming an exit or freeing ownership. Read/follow that session until its real final status; repeat cancellation is idempotent. An already exited foreground keeps its result while descendant drain can remain pending. TS/Python agent tools and MCP expose the reason as status_reason and keep the exit code null while active. CLI prints the reason and follow command. Older clients read the same session response fields.

codex_cloud_get (0.20.1+) includes web_url and ordered previous_thread_ids. Follow an earlier ID at https://chatgpt.com/local/<id> with its owning Codex account. It also names that account (0.21.0+): account for the current thread and previous_threads[].account for earlier ones. Sign in to Codex with ChatGPT using codex login, then copy the login with shard setup for Codex Cloud.

Default shared volumes (0.20.2+)

machine_volume_list, machine_volume_attach and machine_volume_detach manage mounts across machine conversations. template_volume_list, template_volume_attach and template_volume_detach take repo_remote for a project's conversations. Attach takes volume_id or name, mount_path and optional mode (rw by default); mutations accept idempotency_key and return live propagation and skipped-entry reasons. Removal waits for current work to finish and preserves manual mounts.

Question explanations (0.23.2+)

Needs-you tool text preserves self-contained questions and optional option_details for each suggested answer, without shortening the explanation. The first suggested answer is the agent’s recommendation. Secret values go through the project’s secure setup, never a question or its ordinary answer.

Conversation creation (0.23.2+) includes the optional launching conversation only when /v1/meta advertises capabilities.conversation_origin: true. Older APIs receive the existing create body; no rejected create is replayed with different fields.

Input attachments (0.23.3+)

orchestrator_say accepts files: local stdio servers stream local paths; local and hosted servers accept pinned drive references. Files-only inputs use text: "".

Local server example: orchestrator_say({"text":"Review this","files":[{"path":"./spec.pdf"}]}). On either server, reuse an uploaded file with {"name":"spec.pdf","file":{"path":"inputs/...","sha256":"<sha256>"}} in files. The API stores the references and delivers the files before the receiving turn; hosted servers use those drive references.

Device request outcomes (0.23.3+)

orchestrator_input takes { "id": "in_abcdefghijklmnopqrstuvwxyz" } and returns {input, device_requests}. Each request includes what ran, local and remote paths, state, exit code and recorded error, failures first. task_get includes the same outcomes for its linked conversations. Each request names its conversation; reading starts no computer.

Credential setup (0.23.3+)

Use device_credentials_setup with the asking conversation_id, optional local project path, and requested variable names. The connected computer finds existing credentials and transfers them directly to private machine or project files. The result gives names and status. If no source exists, use agent_credential_request to ask once through the secure credential field. Never put a credential value in any tool argument, chat answer or report.

Conversation delivery waits (0.23.4+)

conversation_send returns an explicit route wait in delivery.waiting immediately. Tell the user its message and retain the reason; this message’s delivery is unconfirmed. Route input files to native workers (terminal or acp); codex_cloud_input_files_require_native asks for that route before a Cloud worker or message is accepted.

Dismissed orchestrator inputs

Dismiss an orchestrator input before it starts to keep it from running. Restoring that queued input puts it back in line. Dismissing an input that already started leaves its existing work running.

Home computer updates

Updating a home conversation’s computer selects the organization’s current saved machine, including after a machine rollback. Repository conversations keep their project’s saved environment.

Recipient file support (0.23.4+)

The read-only orchestrator_capabilities tool returns {capabilities: {input_files}} for your user’s current recipient, including before first use. It creates or wakes no computer.

A conversation moves from a saved turn. A running conversation finishes its turn before moving; a new turn continues on its retained computer when an idle move has no checkpoint.

Available computer updates report the same current saved machine or project environment that an update applies, including a saved version selected by rollback.

Paged History (0.23.4+): Add read-only orchestrator_history pages, including old and dismissed answers, with cursor, limit, and next_cursor; the recent held-input tool is unchanged.

Pending native conversation messages retain their original sequence until the harness acknowledges delivery, including after the computer pauses or the API restarts.

Settled orchestrator turns (0.23.5+): finished orchestrator turns settle their published answers or tasks. Local project links keep independent device receipts after an answer is ready. Other device results can resume the same input. A failed no-answer input is reconsidered when its exact native thread finally takes accepted work or a later curated answer is stored; the agent still writes the actual board answer.

The paired CLI helper renews active device-request processing leases automatically for as long as it owns the work. Local link outcomes remain readable from input details after an answer is ready.

Renewable device-request claims (0.23.5+): a helper opts into renewable processing claims by advertising device_request_lease.v1 in its device heartbeat. It renews with a fresh running result within five minutes while it owns the work. The paired CLI helper does this automatically. An online older helper retains its existing long-running work without renewals; a lost device connection remains a retryable outcome.

Keywords

mcp

FAQs

Package last updated on 20 Oct 2026

Related posts