ezremoteDocs

Use the computer

For agents with an active connection. Get exact inputs from tools/list. MCP tool names use underscores (files_read) and REST operation names use dots (files.read). Numbers are in limits.

Every operation takes deviceId from devices. An optional requestId must be a fresh UUID; the service rejects a reused one and doesn't replay its result. An optional deadlineInMs makes the helper refuse a call that arrives late. It doesn't cancel a running command.

Read or change a file

  • files_read with path, absolute or starting with ~/. Without limit it returns the whole file. Page a large file with offset (zero-based line) and limit, or tail: true.
  • files_write with path and content replaces the whole file.
  • files_edit with path, oldText and newText replaces text that matches exactly once.

Write a file back only after a read with status: "complete". Writing back a partial read deletes the rest. Binary and oversized files need transfers.

files_list takes path, depth and limit. files_stat returns size, type and modification time. files_search takes path, a literal query, and mode (names or content), and returns the first matching line per file. timeoutMs and maxBytes raise its budget.

statusMeaningDo
completeThe requested range is covered.Done. An empty result means nothing matched.
partialAnother page exists, or files were skipped.Call again with cursor and the same options.
truncatedIt hit a size or entry budget.Raise limit or maxBytes, or narrow path.
timed_outIt hit the time budget.Continue with cursor, or narrow path.

skipped names binary, oversized and unreadable files and symlinked folders; keep it across pages. Report what you could not cover.

Run a command

shell_exec with command, and optional cwd and timeoutMs. Check code, stdout and stderr. A nonzero code means the command ran and failed.

When the Terminal sandbox refuses something, the result has sandbox.blocked: true and stderr has a <sandbox_violations> block naming what was refused. Tell the person and drop that approach. update_helper_for_terminal_sandbox means the helper is too old to sandbox, so the person must run setup again or allow full access.

Keep a Terminal session

Use a session for commands that may run longer than 30 seconds, servers and prompts.

  1. shell_start with command, and optional cwd and idleMinutes. Save sessionId.
  2. shell_read with sessionId and cursor, starting at 0. Pass the returned cursor back unchanged. more: true means output is waiting, bytesDropped above 0 means some output was lost, and running and code show whether the process exited.
  3. shell_write with sessionId and input. End a line with a newline.
  4. shell_status, shell_list and shell_kill inspect or stop sessions.

Sessions use pipes, so programs that need a TTY fail. A background job (cmd &) dies with the session's shell, so end the command with wait. A session ends when it sits idle or when the connection ends. Sessions run in the same sandbox as shell_exec.

Transfer files

Small upload: transfer_start with path, transfer_chunk with transferId, index from 0 and base64 per chunk, then transfer_finish. Small download: transfer_pull with path, repeating with offset set to nextOffset until done is true.

Large download:

  1. bulk_export with path.
  2. bulk_status with transferId until status is ready.
  3. Fetch downloadUrl with your own tool and save the bytes yourself. A hosted MCP server can't write to your disk.

Large upload:

  1. bulk_upload with the exact byte size.
  2. PUT each partSize slice to uploadUrl with a partNumber query parameter added, from 1, keeping the other parameters. Send Content-Length and X-Content-SHA256, the part's lowercase hex SHA-256. An empty file is one empty part.
  3. POST completeUrl.
  4. bulk_import with transferId and the destination path, then bulk_status until completed or failed.

Use one credential for the whole transfer and keep download links out of logs. bulk_cancel deletes the cloud copy, not a file already delivered. Over REST, send a UUID requestId to bulk.export or bulk.upload. It becomes the transferId, so a lost response is recovered with bulk.status, not a second start.

Use the browser

Browser access covers every tab in the approved profile, including signed-in sites.

  1. browser_call with name: "tools/list", then browser_call with a returned tool as name and its arguments.
  2. For sign-ins the person imported, call name: "profiles/list" and pass the chosen profile UUID on every call. Leave out browser.

browser_installing means Chromium is still downloading and nothing ran. Wait a few seconds and call again; it is the one error you retry. The person imports sign-ins on the computer, as browser sign-ins describes.

Use the computer's MCP servers

mcp_servers lists servers configured on the computer for Claude, Claude Code, Codex, Cursor or Windsurf, without their commands or secrets. Then mcp_tools with server, and mcp_call with server, tool and arguments. Stdio servers start for one call. They run with their own permissions, outside the Terminal sandbox.

When the computer is offline

device_offline means nothing ran. Drop the work, or queue it. Queueing work the person already asked for needs no new confirmation.

  1. queue_operation with deviceId, a dotted operation such as files.read, args, and a fresh requestId. For a different deadline, pass expiresInSeconds, or waitUntil as "3 hours", "3:30pm" with an IANA timeZone, or an ISO time.
  2. Tell the person the work is waiting. The reply has jobId and the deadline it settled on as waitUntil.
  3. Call job_wait once with jobId. It returns completed, failed, cancelled, expired or outcome_unknown. If your host drops the call, call job_wait again with the same jobId instead of polling job_status.
  4. job_cancel stops a queued job. cancelled: false means it already went out.

A job never outlives its connection, and the service rechecks permissions before sending it. job_result_too_large means it may have run but the result wasn't kept. Hosts with MCP task support can run job_wait as a task. REST uses POST /api/jobs, then /api/jobs/wait, /status or /cancel with {"jobId": "..."}.

Resolve an uncertain outcome

outcome_unknown means the call may have run. Never retry it automatically or with a new requestId, because a new ID is new work.

  1. Call resolve_operation with deviceId and requestId, or POST /api/operations/resolve. It never runs anything.
  2. Act on state:
stateMeaningDo
finishedIt ran. reply has the result, minus the body if resultTruncated.Use the reply.
runningIt started and hasn't finished.Resolve again later.
refused_expiredIt never started.Send it as new work if still needed.
unknownHelper offline, no record, or restarted. Read-only calls always land here and are safe to retry.Go to step 3.
  1. Check operations and whatever the call would have changed, then tell the person what you couldn't establish.