You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An agent developing an Actor over MCP needs to read and change the Actor's source. The drafted push-actor (#1333) takes the full content of every file it touches, so a one-line fix resends the whole file, and a version stored as a zip needs the whole source resent every time. Coding agents work the other way: they read the current content and apply small, exact edits.
Review feedback on the drafts asked for three things:
tools that follow the version API rather than the CLI (get-actor-version and update-actor-version instead of pull and push),
writing kept separate from building,
no tool that waits for a build.
Proposal
Five tools in a new source category, which is not enabled by default:
Tool
What it does
get-actor-version
Reads a version: the file list with a size and a hash per file, a revision, and the content of the files asked for.
update-actor-version
Writes, edits, or deletes files of a version in one call. Files the call does not mention stay as they are.
create-actor
Creates a private Actor with its first version and files. It never touches an existing Actor.
create-actor-version
Adds a version to an existing Actor, with files or as a copy of another version.
delete-actor-version
Deletes a version. The platform refuses to delete the last one.
Building and running stay with build-actor, get-actor-build, and call-actor. The source tools can start a build (autoBuild, default false) but never wait for it.
The tools work on any Actor the token can write. The platform checks permissions, Actor names, the 3 MiB limit, path length, and version numbers, and its error goes to the agent unchanged.
What replaces push-actor
push-actor was used to
Now
push files under a new name, creating the Actor
create-actor
push files to an existing version
update-actor-version
push files to a version the Actor does not have yet
create-actor-version
Keeping creation separate removes the guessing push-actor had to do from a name: an Actor ID mistaken for a new name, or a typo that creates a new Actor.
get-actor-version
Without paths, it returns the file list only.
paths: [...] returns those files, in order, within 256 KiB. Files that do not fit, or do not exist, are named in omittedPaths or notFoundPaths.
One path with startLine and lineCount returns part of a large file.
Binary files come back as base64.
hash is the first 16 hex characters of the SHA-256 of a file's bytes. revision identifies the whole file set. Neither depends on how the version stores its files, so they stay the same once zip-stored versions are supported.
update-actor-version
One call applies a list of operations, all or nothing, and saves the version with one PUT:
write: create a file, or overwrite one (overwriting needs the file's current hash),
edit: search and replace inside a file; each oldText must match exactly once,
delete: remove a file (needs its hash).
With expectedRevision, the call fails if any file changed since the agent read the version. Renaming a file is a delete and a write.
The PUT carries only the files, never env vars or the build tag, so secrets stay untouched.
Conflicts
The platform has no per-file API and no concurrency check on the version PUT. So every write reads the version again first, and the hash, exact-match, and revision checks refuse a change when the file changed since the agent read it, whoever changed it: another agent, Apify Console, or apify push. The error names the operation, the file, and the reason, so the agent re-reads that file and tries again.
What these checks cannot catch is a save that lands between our read and our PUT. Closing that needs a conditional version PUT on the platform.
Versions not stored as files
A version built from a Git repository or a gist has no files on Apify. apify push stores sources over 3 MiB as a zip in the Actor's actor-<actorId>-source key-value store. The source tools refuse both kinds and name the URL, with any credentials in it hidden. The server never clones or downloads anything.
Reading and writing zip-stored sources comes in a later step, with adm-zip 0.6.1 or later. Apify already uses it: apify-core unpacks Actor template zips into source files with it, and apify pull reads source zips with it. That step downloads zips only from the session's own API host, caps the entry count and unpacked size, and refuses symlinks, encrypted entries, and unsafe names, since the server unpacks the zip in memory.
Reading and writing sources stored as a zip, after a staging check that the build worker downloads the record URL the server builds.
In the first version there is no lock between concurrent MCP calls; the checks above are the only guard.
Relation to the API tools
The generic API tools (#1443) are plain proxies to the API. They cover what these tools leave out: env vars, build tags, Git sources, and replacing every file at once. For changing files, these tools are the better way: they send only the change, keep env vars untouched, and refuse a change that conflicts with a newer save.
What this replaces
This supersedes #1217 (push-actor), #1379 (zip storage), and #1427 (pull-actor). Their drafts (#1333, #1380, and #1433) will be closed once the new tools are in review.
Open questions
The hosted server's request body limit (reportedly 100 kB) caps how much source one call can send. Should it be raised to 4 MB?
Does the hosted server run several replicas? If so, a later lock between MCP calls has to live outside the process.
Acceptance
get-actor-version
create-actor and update-actor-version
create-actor-version and delete-actor-version
Zip-stored sources
Evals: create an Actor from scratch, fix one line, and a change across several files, each ending in a successful build and run
Problem
An agent developing an Actor over MCP needs to read and change the Actor's source. The drafted
push-actor(#1333) takes the full content of every file it touches, so a one-line fix resends the whole file, and a version stored as a zip needs the whole source resent every time. Coding agents work the other way: they read the current content and apply small, exact edits.Review feedback on the drafts asked for three things:
get-actor-versionandupdate-actor-versioninstead of pull and push),Proposal
Five tools in a new
sourcecategory, which is not enabled by default:get-actor-versionrevision, and the content of the files asked for.update-actor-versioncreate-actorcreate-actor-versiondelete-actor-versionBuilding and running stay with
build-actor,get-actor-build, andcall-actor. The source tools can start a build (autoBuild, default false) but never wait for it.The tools work on any Actor the token can write. The platform checks permissions, Actor names, the 3 MiB limit, path length, and version numbers, and its error goes to the agent unchanged.
What replaces push-actor
create-actorupdate-actor-versioncreate-actor-versionKeeping creation separate removes the guessing push-actor had to do from a name: an Actor ID mistaken for a new name, or a typo that creates a new Actor.
get-actor-version
paths, it returns the file list only.paths: [...]returns those files, in order, within 256 KiB. Files that do not fit, or do not exist, are named inomittedPathsornotFoundPaths.startLineandlineCountreturns part of a large file.hashis the first 16 hex characters of the SHA-256 of a file's bytes.revisionidentifies the whole file set. Neither depends on how the version stores its files, so they stay the same once zip-stored versions are supported.update-actor-version
One call applies a list of operations, all or nothing, and saves the version with one PUT:
write: create a file, or overwrite one (overwriting needs the file's currenthash),edit: search and replace inside a file; eacholdTextmust match exactly once,delete: remove a file (needs itshash).With
expectedRevision, the call fails if any file changed since the agent read the version. Renaming a file is adeleteand awrite.The PUT carries only the files, never env vars or the build tag, so secrets stay untouched.
Conflicts
The platform has no per-file API and no concurrency check on the version PUT. So every write reads the version again first, and the
hash, exact-match, andrevisionchecks refuse a change when the file changed since the agent read it, whoever changed it: another agent, Apify Console, orapify push. The error names the operation, the file, and the reason, so the agent re-reads that file and tries again.What these checks cannot catch is a save that lands between our read and our PUT. Closing that needs a conditional version PUT on the platform.
Versions not stored as files
A version built from a Git repository or a gist has no files on Apify.
apify pushstores sources over 3 MiB as a zip in the Actor'sactor-<actorId>-sourcekey-value store. The source tools refuse both kinds and name the URL, with any credentials in it hidden. The server never clones or downloads anything.Reading and writing zip-stored sources comes in a later step, with adm-zip 0.6.1 or later. Apify already uses it: apify-core unpacks Actor template zips into source files with it, and
apify pullreads source zips with it. That step downloads zips only from the session's own API host, caps the entry count and unpacked size, and refuses symlinks, encrypted entries, and unsafe names, since the server unpacks the zip in memory.Delivery
get-actor-version: feat: Add get-actor-version tool #1450.create-actorandupdate-actor-version: feat: Add create-actor and update-actor-version tools #1453, stacked on feat: Add get-actor-version tool #1450.create-actor-versionanddelete-actor-version: feat: Add create-actor-version and delete-actor-version tools #1454, stacked on feat: Add create-actor and update-actor-version tools #1453.In the first version there is no lock between concurrent MCP calls; the checks above are the only guard.
Relation to the API tools
The generic API tools (#1443) are plain proxies to the API. They cover what these tools leave out: env vars, build tags, Git sources, and replacing every file at once. For changing files, these tools are the better way: they send only the change, keep env vars untouched, and refuse a change that conflicts with a newer save.
What this replaces
This supersedes #1217 (push-actor), #1379 (zip storage), and #1427 (pull-actor). Their drafts (#1333, #1380, and #1433) will be closed once the new tools are in review.
Open questions
Acceptance
get-actor-versioncreate-actorandupdate-actor-versioncreate-actor-versionanddelete-actor-version