Build1 publisher2 min readPublished
Apify's MCP server hands the agent an Actor schema written for a web form
A developer logged every byte his own Apify Actor sent back over raw JSON-RPC. The agent receives 9,135 characters of schema, 23 properties deep, with the Console form's emoji intact and nothing marked required.
The Engineer · Build desk

What happened
- Appending ?actors=lergassy/jobs-api to the Apify MCP server URL made one Actor show up as an agent tool, a step its author says took him two minutes.
- A tools/list call returned five tools: the Actor itself plus get-actor-run, get-dataset-items, get-key-value-store-record and abort-actor-run, the generic plumbing for starting, polling, reading and killing a run.
- The Actor's input_schema.json defines 23 properties, but the tool definition delivered to the agent carries 24, because the Apify server injects a field of its own.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- exposure With nothing marked required, the failure arrives as a success: the run completes having searched for nothing, and the caller gets no signal that the call was empty.
- decision Once the server appends prefill to the description, placeholder values stop being a Console convenience and become the example a model copies, so every prefill in a catalogue needs rereading.
- constraint The agent owns the run lifecycle, sequencing start, poll and dataset read through the generic tools before it holds any results.
Two details in the handshake decide whether a hand-rolled client talks to this server at all. The Accept header has to name both `application/json` and `text/event-stream`, or the server rejects the request [6]. The session id comes back in a response header instead of the body, so the author's script dumps the headers to a file and reads the id back out of it [7]. He used curl on purpose: the walkthroughs he found all ran through Claude Desktop or Cursor, and he wanted the traffic rather than a chat transcript [23].
Of the setup step he wrote, "That part is a footnote." [3] The schema is where the work is. One property he printed carries a magnifying-glass emoji in its title and `<code>` tags in its description, both written for the Apify Console input form, where they render [12]. In a tool definition, he wrote, they are "tokens an agent pays for and markup it has to ignore", and nothing in the path strips them [13]. The whole tool definition runs 9,135 characters [14]. Divide that by his 23 properties and each one carries about 397 characters into the agent's context [1].
One server-side rewrite is good engineering. `prefill` values get appended to the description as `Example values: ["python developer"]`, which turns a Console convenience into an instruction [15]. The author calls that "a genuinely good move" [16]. It also makes `prefill` documentation. He has about thirty Actors on the Apify Store [1], and on a couple of them prefill was a throwaway placeholder; those placeholders are now the example the model imitates [17].
The defect he owns is the empty `required` array. "That is my fault, not the server's," he wrote [18]. His schema requires nothing, so the definition tells the agent that a call with zero arguments is valid, and the Actor has no useful default search [19]. In his words: "An agent that believes the schema will produce an empty run, and the run will succeed while doing so" [20].
Treat the 9,135 characters as a measurement of his schema. It is a job-listings Actor that puts Indeed, LinkedIn and company career boards into one schema [21], and the figure moves with property count and with how much form copy sits in the descriptions. His threshold for expecting the same result is three: "If your Actor has more than three inputs, the same things will happen to you" [22].
The one thing the post withholds is the 24th field, the one the server adds [10]. He calls it "the single most important field in the whole exchange" and says he will come back to it [11].
What to watch
- Whether Apify starts stripping HTML and emoji from schema titles and descriptions before serving tool definitions.
- The identity of the 24th field the server injects, which the post calls the most important in the exchange but does not name.
- What the zero-argument run actually did, since the post breaks off at the point it starts.