{"slug": "remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back", "title": "Remote MCP tools that run long: what your agent actually gets back", "summary": "A team of Apify web-scraper developers traced raw JSON-RPC traffic against Apify's hosted MCP server (mcp.apify.com, v0.17.1) on Oct 2, 2026 to see what an agent actually receives when a remote MCP tool outlives a single call. They found the server returns both structured state (runId, status, dataset item count) and plain-English instructions telling the model to poll, that get-actor-run rejects waitSecs above 45 with a JSON-RPC -32602 error rather than a tool result, and that a Google Maps scraper job can finish SUCCEEDED with zero dataset items when an upstream dependency fails.", "body_md": "Most MCP demos show a tool that answers in a second. Real tools often don't: a scraper, a crawl or a report job can take minutes. We build web scrapers on Apify, so this is a problem we run into daily. We wanted to know what an agent actually receives when a remote MCP tool runs longer than one call, so we traced the raw JSON-RPC traffic against Apify's hosted MCP server (`mcp.apify.com`, version 0.17.1 at the time) on Oct 2, 2026. The job: a YellowPages scraper reading one results page, which takes about 35 seconds.\n\nAfter `initialize`, `tools/list` returned one tool per scraper we had allowed through the server URL, plus four helper tools that only make sense for long-running work:\n\n`get-actor-run` checks a run's status and can wait for it,`get-dataset-items` reads the results in pages,`get-key-value-store-record` reads a stored file or record,`abort-actor-run` stops a run.\nThe helpers are the first hint: the server expects the agent to come back for results.\n\nThe agent calls the scraper tool with ordinary arguments:\n\n```\n{ \"searchKeyword\": [\"plumbers\"], \"location\": \"Austin, TX\", \"maxPages\": 1 }\n```\n\nThe response arrived after about 30 seconds, while the job was still running. It had two content parts. The first is structured:\n\n```\n{\n  \"runId\": \"…\",\n  \"status\": \"RUNNING\",\n  \"storages\": { \"datasets\": { \"default\": { \"id\": \"…\", \"itemCount\": 23 } } }\n}\n```\n\nThe second is plain text written for the model:\n\n```\nRUNNING for 30s. In progress. 23 results so far.\nUse get-actor-run with runId=… and waitSecs=30 to poll for completion.\n```\n\nThat second part is the interesting design choice. The server returns machine-readable state and also tells the model, in plain English, what to do next. An agent that only parses the JSON still works. An agent that only reads text also knows to poll.\n\nWe first asked `get-actor-run` to wait 60 seconds and then 120. Both came back as a JSON-RPC error, not a tool result:\n\n```\nMCP error -32602: Invalid arguments for tool \"get-actor-run\".\nValidation errors: /waitSecs: must be <= 45.\n```\n\nWith `waitSecs: 30` the call returned `SUCCEEDED`, the run time (about 35 seconds) and the dataset item count (37). The result also carried a `_meta` block with the run's platform usage, which a client can show the user before it starts anything bigger.\n\nTwo things to handle here:\n\n`-32602`), not as tool results with `isError`. If your client only checks `get-dataset-items` takes the dataset ID plus `offset` and `limit`, and returns:\n\n```\n{ \"datasetId\": \"…\", \"items\": [ … ], \"itemCount\": 37, \"totalItemCount\": 37, \"offset\": 0, \"limit\": 100 }\n```\n\nFor a big job, page through with `offset` instead of pulling everything into the model's context at once.\n\nThe same evening a second test job, a Google Maps scraper, ran for about 157 seconds and finished with status `SUCCEEDED`, but `get-dataset-items` came back empty:\n\n```\n{ \"items\": [], \"itemCount\": 0, \"totalItemCount\": 0, \"offset\": 0, \"limit\": 100 }\n```\n\nAn upstream dependency was failing, and the job ended cleanly with nothing to show. If your agent treats `SUCCEEDED` as \"done, report success\", it will tell the user everything worked. Check the item count, and treat \"succeeded but empty\" as a result the user needs to hear about.\n\nHow does your MCP client deal with tools that outlive one call: polling, progress notifications, or something else? We're curious what holds up in production.\n\n*Written with AI assistance. Every request and response above comes from real calls we made on Oct 2, 2026.*", "url": "https://wpnews.pro/news/remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back", "canonical_source": "https://dev.to/zebudata/remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back-4gf6", "published_at": "2026-10-02 17:22:01+00:00", "updated_at": "2026-10-02 17:37:27.896399+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "developer-tools"], "entities": ["Apify", "mcp.apify.com", "MCP", "YellowPages", "Google Maps"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back", "markdown": "https://wpnews.pro/news/remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back.md", "text": "https://wpnews.pro/news/remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back.txt", "jsonld": "https://wpnews.pro/news/remote-mcp-tools-that-run-long-what-your-agent-actually-gets-back.jsonld"}}