Announcing CIMD support for MCP Client registration
Learn more

Apify MCP vs Apify API for AI Agents (2026)

Saif Ali Shaik
Founding Developer Advocate

TL;DR

  • Apify MCP exposes 19 tools for Actor discovery, running, run monitoring, storage reads, and documentation search. The REST API exposes the full platform. Webhooks, schedules, request queues, Actor builds, and saved tasks are REST-only.
  • Apify MCP accepts both an OAuth sign-in and a bearer API token, so it can run headless. This breaks the usual "MCP is interactive-only" rule. The REST API is API-token-only; there is no OAuth to Apify's own platform.
  • Apify tokens do not expire by default, but they can carry an expiration and can be revoked or regenerated at any time. Neither path detects revocation for you.
  • MCP is the faster path for agents that find and run Actors from natural language. The REST API is the right path for scheduled pipelines, webhook-driven flows, and Actor lifecycle management.
  • Scalekit's Apify connector vaults the token, scopes the tool surface per user, and surfaces revocation as a connected-account state, so the MCP vs API choice does not change your auth infrastructure.

Your agent needs to pull data off the web. Apify ships an official MCP server at mcp.apify.com and a full REST API at api.apify.com, and you have to decide which one your agent should call. The usual shortcut does not apply here. For most tools, the MCP server is OAuth-only, so anything headless goes through the API. Apify's MCP server also accepts a plain API token, which blurs that line. This article gives you the actual decision framework: capability coverage, auth model, and what per-user credential management costs you in production.

What Apify MCP and Apify API actually are

These are two different objects with different jobs. You have almost certainly called the REST API before; the MCP server is the newer surface, so it is worth being precise about both.

Apify MCP

The Apify MCP server is Apify's official, open-source server hosted at mcp.apify.com. It exposes Apify Actors, storage, and documentation as tools to any MCP client. Transport is Streamable HTTP; the older SSE transport is removed as of April 1, 2026. Auth is either a browser-based OAuth sign-in to your Apify account or a bearer API token, and a local stdio build runs through npx @apify/actors-mcp-server on Node.js v18 or higher.

Apify API

The Apify REST API is versioned under https://api.apify.com/v2 and controls the whole platform: Actors, tasks, runs, datasets, key-value stores, request queues, webhooks, schedules, builds, and proxy configuration. Authentication is your Apify API token, passed as Authorization: Bearer <token> (recommended) or as a ?token= query parameter. There is no OAuth flow. Official clients for JavaScript and Python wrap the API and implement retries and backoff for you.

What your agent can actually do

The MCP server covers the discover, run, and read loop that most scraping agents live in. The gap shows up the moment your agent needs to manage infrastructure or react to events rather than just call an Actor.

The capability table

The table below maps the actions that matter for agent workloads. The MCP column reflects the official tool set; the API column reflects the full v2 surface.

Capability
Apify MCP
Apify REST API
Discover Actors in Apify Store (search-actors)
Yes
Yes
Inspect an Actor's input schema (fetch-actor-details)
Yes
Yes
Run an Actor and get results (call-actor, sync or async)
Yes
Yes
Add a new Actor as a tool at runtime (add-actor)
Yes
No
Read dataset items with pagination (get-dataset-items)
Yes
Yes
Read key-value store records
Yes
Yes
Poll run status and logs (get-actor-run, get-actor-log)
Yes
Yes
Search Apify and Crawlee docs (search-apify-docs)
Yes
No
Structured output schema inference
Yes (hosted only)
No
Manage request queues (crawl frontier)
No
Yes
Create and manage webhooks and schedules
No
Yes
Manage Actor builds, versions, and saved tasks
No
Yes

Where the MCP surface stops

Everything above the run-and-read layer is REST-only. If your agent has to register a webhook so it wakes on run completion, create a schedule, drive a request queue across a long crawl, or deploy and version an Actor, the MCP server has no tool for it. That is not a temporary gap; it reflects what the MCP server was built to do, which is expose Actors to an AI client, not administer the platform.

What MCP makes easy that raw REST does not

The MCP path buys you three things the API leaves to you. Dynamic tool discovery lets the agent chain search-actors, add-actor, and call-actor to find and use a scraper it was never preconfigured with. The hosted server infers output schemas so the model knows the result shape before it calls. And every tool arrives with an LLM-ready description, whereas with REST you write and maintain those tool schemas around each endpoint yourself. For a deeper look at how MCP and APIs differ structurally, the tradeoffs go beyond just tooling convenience.

The auth path each one puts you on

This is where Apify departs from the rest of the series, so read it carefully rather than assuming the usual pattern.

Apify MCP takes a token or an OAuth sign-in

The hosted MCP server supports two methods: a browser-based OAuth sign-in to your Apify account, or a bearer API token passed in the request. Because the bearer-token option exists, a background agent can authenticate against the MCP server without a person in the loop. The OAuth-only constraint that blocks headless MCP for tools like Salesforce or GitHub simply does not apply here.

The Apify API is token-only

The REST API authenticates with your Apify API token and nothing else. There is no Authorization Code flow, no per-user delegated OAuth, no service-account grant. A token identifies an Apify account, and every call made with it acts as that account. Tokens can be given an expiration and can be revoked or regenerated in the Apify console at any time.

The multi-tenant reality

Apify is not a per-end-user SaaS the way Slack or Salesforce are. In most agents, you own one Apify account and one token, and the agent scrapes on behalf of all your users. The per-user credential question appears only when your product lets each customer bring their own Apify token, for example to bill against their own credits or reach their own private Actors. In that model you are back to N tokens to store, isolate, and revoke, and neither path manages that lifecycle for you. The problem of who holds the token and owns the credential lifecycle is one that survives the MCP vs API choice entirely.

What you own in production

Both paths hand you the raw capability and leave the operational surface to you. What differs is how much of it, and where it breaks.

On the MCP path

Apify hosts and scales the server and updates the tool schemas, so you do not run a container or maintain endpoint definitions. You still own the token that authenticates the connection, keeping it out of the agent runtime and the model context, and handling the case where it is revoked. You also pin your tool selection explicitly for production rather than relying on the default set, so behavior stays stable across server updates.

On the API path

You own the full stack: endpoint selection, request construction, pagination, error handling, retries, and the token lifecycle. That is more surface area and more control. If Apify ships a new platform capability, you can call it immediately instead of waiting for a tool to appear on the MCP server, and you decide when to adopt changes.

Rate limits and schema drift

The MCP server allows up to 30 requests per second per user and returns 429 when you exceed it. The REST API applies global and per-resource rate limits, also surfaced as 429, and the official clients implement exponential backoff for you. On stability, MCP tool schemas can change when Apify updates the hosted server, while the REST API is versioned so you migrate on your own schedule. For a deterministic pipeline where an unexpected schema change is an incident, that difference matters. The broader question of production auth patterns for tool-calling agents covers more of these failure modes in depth.

When to use MCP, when to use the API

The decision is rarely all-or-nothing; many production agents use both. These lists are the practical split.

Use Apify MCP when

  • Your agent finds and runs Actors from natural language, for example an assistant that scrapes a site the user names mid-conversation.
  • You want dynamic tool discovery so the agent can adopt a new scraper without a code change.
  • You are prototyping and want LLM-ready tool descriptions and output-schema inference instead of writing them.
  • Your workload is the discover, run, and read loop rather than platform administration.

Use the Apify API when

  • Your agent runs on a schedule or reacts to webhooks: nightly crawls, run-completion handlers, pipeline notifications.
  • You manage request queues, schedules, Actor builds and versions, or saved tasks, none of which the MCP server exposes.
  • You need bulk writes or high-volume dataset operations under your own rate-limit and retry control.
  • You are building a deterministic pipeline where you pin an API version and cannot absorb an unplanned schema change.

The credential problem that exists on both paths

Naming this is the point of the article, because it survives the MCP vs API choice unchanged.

N tokens, one lifecycle problem

Whether the token reaches Apify through the MCP server or a direct REST call, it is still a secret that must live somewhere: encrypted at rest, isolated per tenant, and out of the agent runtime and model context. In a bring-your-own-token multi-tenant product, that is one credential per customer, each with its own lifecycle. Apify tokens do not expire on a fixed schedule, but they can be revoked or regenerated at any time, and your agent has no built-in way to know that happened until a call fails. Secure token management for AI agents at scale is a problem that requires dedicated infrastructure, not just good intentions.

Where Scalekit fits

Scalekit's Apify connector handles token storage, per-user isolation, and revocation detection for both paths, so the MCP vs API decision does not change your auth infrastructure. When a user revokes their Apify token, the connected account moves to a revoked state, which lets you prompt for re-credentialing instead of returning a generic failure.

Building an Apify agent with Scalekit

The connector wraps the Apify tool surface behind Scalekit's connected-account model, so credentials never touch the agent runtime. The examples below use Python and LangChain. The connector name is apifymcp, and it must match the connection name configured in your Scalekit dashboard exactly.

Set up the connector

Install the SDK, then register the user's Apify token as a connected account. Because this connector uses bearer-token auth, there is no redirect or OAuth flow; you store the token once per user.

pip install scalekit-sdk-python langchain-openai
import os from scalekit.client import ScalekitClient scalekit_client = ScalekitClient( env_url=os.getenv("SCALEKIT_ENV_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), ) actions = scalekit_client.actions # connection_name must match the connection configured in the Scalekit dashboard actions.upsert_connected_account( connection_name="apifymcp", identifier="user_123", # your user's unique ID credentials={"token": "apify_api_..."}, # the user's Apify API token )

Discover the scoped tool surface

Before the agent runs, it loads the tools the current user's connected account is authorized to call, not a catalog of every Actor on the platform. get_tools returns that scoped surface as native LangChain tools, which is the distinction between a per-user agent and a shared-credential one. This is exactly the kind of pattern that LangChain tool calling enables when paired with proper credential management.

tools = actions.langchain.get_tools( identifier="user_123", connection_names=["apifymcp"], page_size=100, # avoid missing tools when a connector paginates ) tool_map = {t.name: t for t in tools}

Run the agent loop with LangChain

Bind the scoped tools to the model and run the tool-calling loop. Scalekit executes each call under the user's stored token and returns the result; the agent never sees the credential.

from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [HumanMessage("Find an Instagram scraper and pull the last 10 posts from @apify")] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: result = tool_map[tc["name"]].invoke(tc["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

Going multi-tool and multi-tenant with Virtual MCP

A raw MCP server exposes every tool it has. A summarizer agent that only needs apifymcp_rag_web_browser should not hold call_actor or storage tools. Scalekit Virtual MCP servers let you declare exactly which tools an agent role sees, enforcing least privilege at the tool level and cutting the token overhead that a full surface adds to every context window.

The model is two objects. You define the Virtual MCP server once per agent role, choosing which connections and tools it exposes, and you get one static mcp_server_url. Before each run, you mint a short-lived session token scoped to that specific user's connected accounts, so one server definition serves every user with no credential sharing between them.

import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, ToolMessage async def run(mcp_url: str): async with MultiServerMCPClient( {"scalekit": {"transport": "streamable_http", "url": mcp_url}} ) as client: tools = client.get_tools() tool_map = {t.name: t for t in tools} llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [HumanMessage("Scrape today's top AI headlines and summarize them")] while True: response = await llm.ainvoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: result = await tool_map[tc["name"]].ainvoke(tc["args"]) messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"])) asyncio.run(run(mcp_url))

Observability: audit logs on every tool call

Every execute_tool call runs as a specific user, and Scalekit records it: who authorized the connected account, which tool ran, the scope it ran under, and the result. That log is per-user and exportable, so an Apify run is attributed to the customer who triggered it rather than to a shared service account. For a scraping agent that can touch external sites and burn Actor credits, that attribution is what turns a compliance question into a query. Agent tool observability is the layer that tells you whether your agent is actually doing what you think it is doing in production.

Which one to build against

If your agent discovers and runs Actors from natural language and lives in the run-and-read loop, build against the MCP server. It is the faster path, and the bearer-token option means it can run headless too. If your agent schedules crawls, reacts to webhooks, manages request queues, or deploys and versions Actors, build against the REST API, because those surfaces do not exist on the MCP server. Most production Apify agents end up using both, and either way the credential management problem is identical. That is the part that needs production-grade infrastructure.

Get help building your Apify agent

Two links to build against: the Scalekit Apify connector docs for the tool list and setup, and the Scalekit Apify connector page for the connector overview. For the upstream surfaces, see the official Apify MCP server documentation and the official Apify API reference.

If you are building an Apify agent and want a hand, join the conversation in the Scalekit Slack community, or talk to us for immediate help.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
zero upfront cost.

Every feature unlocked. No hidden fees.