I pinned my Actors to the MCP URL, the way the docs recommend. The agent lost every way to see what a call costs.
I publish 23 Actors on the Apify Store. All 23 are pay-per-event.
Last week I measured how an AI agent actually reaches them. The answer was uncomfortable. A
default MCP connection hands an agent 11 tools. None of mine is one of them.
So you pin. You name your Actors in the connection URL. The
Apify MCP documentation tells you to:
For production deployments, explicitly specify which tools to load rather than relying on
defaults. This ensures consistent behavior across updates.
That is good advice for reliability. I followed it. Then I measured what the agent receives
afterwards, and found something the docs do not mention.
Pinning removes the agent's ability to see what a call costs. It also removes its ability to
cap what a call spends.
Below are the measurements. Then the three tools that disappear. Then the half of this that is
my own fault rather than the platform's.
What pinning actually changes
I connected three ways and listed the tools each time. Same account, same day, 2026-08-12.
Every listing came from a tools/list call over the
MCP HTTP transport. That is what the client
library hands the model.
Default connection, no parameters. Eleven tools:
search-actors get-key-value-store-record report-problem
fetch-actor-details abort-actor-run apify--rag-web-browser
call-actor search-apify-docs
get-actor-run fetch-apify-docs
get-dataset-items
Pinned with two of my Actors, using the documented parameter
?tools=aiqlabs/seo-audit-tool,aiqlabs/pdf-inspector. Six tools:
aiqlabs--seo-audit-tool get-actor-run abort-actor-run
aiqlabs--pdf-inspector get-dataset-items
get-key-value-store-record
Pinned with all 23. Twenty-seven tools: my 23, plus the same four.
The four survivors are all post-run tools. Each one reads a run, reads a dataset, reads a
key-value record, or aborts something already running.
Every tool that helps an agent decide before it calls is gone. Three of the missing ones
matter for money.
The three tools that carried the price
I searched the full JSON of each default tool definition for pricing language. These are the
strings that came back.
search-actors returns pricing in its results. Its own description says so:
- **Pricing:** Details with pricing link
Its output schema enumerates the models. FREE, PRICE_PER_DATASET_ITEM,
FLAT_PRICE_PER_MONTH, and a pricePerUnit field.
fetch-actor-details takes a flag whose description reads, in full:
Include pricing model and costs.
call-actor is the one that actually protects the caller. It accepts maxTotalChargeUsd:
Pay-per-event Actors only — ignored otherwise.
Caps total USD billed; does NOT limit work. Prefer the Actor's own input fields to bound work.
That is a spending ceiling. The caller sets it, at call time. Note the second sentence. I will
come back to it, because it is the sentence that indicts me.
All three tools are in the default set. None of them survives pinning.
An agent holding my Actors directly cannot look up what they cost. It cannot put a ceiling on
what it spends. It can only call them.
What my own definitions tell the agent about price
Nothing. I checked, and I checked wrong the first time.
My first pass searched each tool definition for a dollar sign. It reported a hit on 23 of 23.
For about a minute I believed my descriptions already carried prices.
They do not. The dollar signs were $id, the JSON Schema keyword:
"required":[],"$id":"https://apify.com/mcp/aiqlabs--app-store-audit"
I searched again for a dollar sign followed by a digit. An actual amount. The count was
0 of 23.
The words price and cost do appear in a few of my definitions. Every one of them is about
the subject matter, not the invoice.
One Actor notes that prices and availability differ by storefront. Another explains that each
archived URL costs a request to the live site.
Those are useful sentences. Neither tells an agent what calling the tool will cost.
Meanwhile every one of the 23 is metered. Each has two charge events, configured the way
Apify's monetization docs
describe:
| Event | Price |
|---|---|
apify-actor-start |
$0.00005 |
apify-default-dataset-item |
$0.002 – $0.01 depending on the Actor |
The per-item price is the one that moves.
I wanted to be sure those events fire on their own. My Actors never call a charge function. So
I read a real run record rather than assuming:
run thLehE7kk3NVRAvqm SUCCEEDED
chargedEventCounts: {"apify-actor-start":4,"apify-default-dataset-item":608}
They fire. Another run in the same batch recorded 1,000 dataset items. At my highest per-item
price, one call like that is ten dollars.
The part that is my fault
Go back to that sentence in call-actor:
Prefer the Actor's own input fields to bound work.
Apify is right about this. A billing cap stops the invoice, not the work. The real bound
belongs in the
input schema,
where the author controls it.
So I checked whether my own Actors carry that bound.
All 23 have a field for it. maxUrls, maxPages, maxApps, maxPdfs, maxVehicles,
maxOrganizations, maxStories. Twenty-three out of twenty-three.
Not one of them declares a JSON Schema maximum.
pdf-inspector maxPages(none), maxPdfs(none), maxFileMb(none), maxLinksToCheck(none)
sitemap-checker maxUrlsToCheck(none), maxSitemaps(none), maxDepth(none)
http-status-checker maxUrls(none), maxRedirects(none), maxConcurrency(none)
I named the fields as if they were limits. I never made them limits.
An agent can pass maxUrls: 1000000. The schema will accept it. I told the schema that any
integer is fine.
So the failure has two halves. Only one of them is the platform's.
Pinning removes the caller-side ceiling. That is the platform's shape. My Actors have no
author-side ceiling. That is mine, in 23 files I wrote myself.
An agent holding my pinned tools has no cap available from either direction.
What I got wrong on the way here
I started this measurement expecting a different problem.
My hypothesis was time. Actor runs are slow. Agents time out waiting. Authors ship tools an
agent cannot practically await.
I pulled the run history for all 23 and computed durations from the API.
| Value | |
|---|---|
| Median of per-Actor medians | 4.05 s |
| Slowest single run observed | 58.0 s |
| Actors with a median above 60 s | 0 of 23 |
There is no timeout problem. My hypothesis was wrong.
I dropped that half of the article rather than stretching the numbers to fit it. Only five of
the 23 had enough run history to produce a median, and that limit is worth stating. But nothing
in the data pointed toward latency. I would rather report a dead hypothesis than a decorated
one.
What to change, concretely
Three changes. The first two are the author's job. The third is a question for the platform.
1. Put a real ceiling in the input schema.
A field named maxPages should refuse an absurd value. The
maximum keyword does
this before your code runs:
"maxPages": {
"title": "Max pages per PDF",
"type": "integer",
"default": 50,
"minimum": 1,
"maximum": 2000,
"description": "Hard cap. Each page produces one billed result row."
}
default is not a limit. prefill is not a limit either, and the two are easy to confuse in
Console. That distinction bit me once already, from the correctness side. This is the same
lesson arriving from the money side.
You can verify the deployed schema rather than trusting the file:
curl -s https://api.apify.com/v2/acts/<user>~<actor> \
| grep -o '"maximum":[0-9]*' | head
2. Say the price in the description the agent reads.
Once you pin, the agent has no other source. One clause is enough:
Each result row is one billed event ($0.002). A 500-URL input bills roughly $1.00.
That sentence costs you nothing. It is the only pricing signal a pinned agent will ever see.
3. The platform question.
call-actor exists in the default set and carries maxTotalChargeUsd. Pinned tools are
invoked directly, so no wrapper carries it.
A per-call spending cap that survived pinning would close the gap. It could be an optional
argument on every metered tool, or a connection-level parameter. Either way it would spare each
author from rediscovering this alone.
I do not know whether that is on anyone's roadmap. I am reporting the shape I measured.
Where this leaves an Actor author
Two connection modes, and a cost to each.
Leave the default. The agent can search, can read your pricing, can cap its spend. It will also
almost certainly never receive your Actor. The default set is 11 tools and none of them is
yours.
Pin your Actors. The agent receives them and calls them directly. It does so without a price
and without a ceiling.
I do not think either mode is wrong. I think the second one quietly moves a responsibility onto
the Actor author. The docs that recommend it do not mention the move.
Until they do, the fix is the schema you already control. Mine was missing it in all 23 files.
I only found out because I went looking for a different problem entirely.
Measurements were taken on 2026-08-12 against mcp.apify.com with a single account. Tool
listings came from tools/list over the MCP HTTP transport. Run durations and charge counts
came from
Apify API run records. No Actor was executed to
produce these numbers, so nothing here cost anything to measure.


Top comments (0)