cd /news/ai-agents/ai-agent-vs-mcp-server-which-one-sho… · home › topics › ai-agents › article
[ARTICLE · art-143721] src=blog.apify.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

AI agent vs. MCP server: which one should you build?

The current Model Context Protocol specification revision 2026-07-28 defines 13 request methods and 8 notifications, none of which includes a field for a goal, task, or objective, according to a guide comparing AI agents with MCP servers. Testing against the Apify MCP server at mcp.apify.com showed that sending a goal such as "find a tool that scrapes flight prices" to the tools/call method's search-actors tool placed it in an undefined parameter, so the call ran as if arguments were empty and returned the default listing byte-identical to an empty-argument call with no error. The guide concludes that an agent owns the goal and the loop that selects tools and stopping conditions, while an MCP server owns the data, API, or product it exposes and holds no session state between calls.

by read24 min views1 publishedOct 2, 2026
AI agent vs. MCP server: which one should you build?
Image: Blog (auto-discovered)

If you are deciding between an AI agent and a Model Context Protocol (MCP) server, you are comparing two parts of one system. An agent has a goal and calls a model in a loop to choose each tool. An MCP server exposes tools and handles the calls the agent sends.

A tool call names one tool and passes that tool's arguments. If an agent adds its goal as an extra argument, a server can ignore it and return no error.

This guide shows what each one owns, what a connection costs, and which one yoxu should build.

What each one owns #

An AI agent and an MCP server share one job, and each takes a different part of it. The user gives the agent a goal, and the agent sends the server one tool call at a time:

Each side also has its own costs, and each is worth building in a different situation:

MCP server AI agent
Owns Something it provides: data, an API, or a product A task, and the loop that runs it
Receives A tool name and arguments A goal
Decides What happens inside each call it receives Which tool, which arguments, and when to stop
State between calls No session in the current MCP specification The plan, the conversation history, and the stopping condition
Costs Its tool definitions take up context in each agent that loads them You pay for model calls, retries, and whatever the tools charge
Build it when Agents you do not control need what you own The next step depends on the previous result

The agent is the program that runs the loop, and an MCP server is one way to give that loop its tools.

MCP has no field for a goal #

MCP identifies each revision of its specification by a date. The current revision, 2026-07-28, defines 13 request methods and 8 notifications. Each of the 13 request methods does one of these five jobs:

Job Methods
Discovery server/discover ,tools/list ,resources/list ,prompts/list ,resources/templates/list
Retrieval resources/read ,prompts/get ,completion/complete
Calling a named tool tools/call
Requests to the client elicitation/create , plus the deprecatedroots/list andsampling/createMessage
Updates subscriptions/listen

Not one of them has a field for a goal, a task, or an objective. tools/call is the method closest to taking a goal, but it requires a tool name, so the caller must choose the tool first.

Send a goal anyway, something like "find a tool that scrapes flight prices." mcp.apify.com, the Apify MCP server, lets you call its discovery tools without an API token, so you can repeat the test. A call to a method that does not exist fails, and two calls to a real search tool return results:

agent/run            the goal as a parameter
                     -> {"code": -32601, "message": "Method not found"}

search-actors        the goal in a parameter the schema does not define
                     -> the default listing, byte-identical to calling with empty arguments

search-actors        the goal in the real parameter, "keywords"
                     -> a different listing, flight tools first

In the middle call, the goal went into a parameter the tool does not define, so the call ran as if the arguments were empty and returned no error.

One command repeats that middle call:

URL="https://mcp.apify.com/?tools=search-actors,fetch-actor-details,search-apify-docs,fetch-apify-docs"
META='"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}'

curl -s -X POST "$URL" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" -H "Mcp-Name: search-actors" \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{$META,
       \"name\":\"search-actors\",\"arguments\":{\"not_a_real_field\":\"anything\"}}}"

Both headers, Mcp-Method and Mcp-Name, are required for tools/call in this revision. The command returns the same default listing.

The same test ran on 15 other public servers, using a tool that needs no arguments and the revision each server supports. All 15 ignored the undeclared parameter and returned no error. On these servers, a goal sent in a field the tool never declared can be lost, and the agent gets no warning.

The search with the goal in keywords shows that the text of a goal can reach a server. It arrives only inside a field the server defined, and only on a tool the agent already chose. An MCP server cannot choose the tool for you, because the agent names the tool in tools/call before the call reaches the server.

The agent keeps the task state #

Revision 2026-07-28 removed sessions from the protocol. The initialize handshake and the Mcp-Session-Id header are both gone. In this revision, every request includes its own protocol version and capabilities in a _meta field.

In a September 2026 test of servers from the official MCP Registry, every server that answered was on an older revision. The test asked 40 servers which revision they used. Ten answered: nine used 2025-06-18, and one used 2024-11-05. Most of the rest required authentication.

mcp.apify.com supports 2026-07-28, which it lists in its supportedVersions field, and it also responds to the initialize handshake that older revisions use.

Whichever revision a server uses, the agent keeps the plan and the conversation history. A session on an older revision held connection details, not the agent's plan or history. A server you build should support 2026-07-28 and the older revisions your clients still use, as mcp.apify.com does.

A server can still contain an agent #

MCP's sampling feature was the protocol's only standard way for a server to use the client's model. Revision 2026-07-28 deprecated it and suggests this replacement: "Integrate directly with LLM provider APIs."

A server can still call an LLM of its own inside a single tool call, run a full loop there, and return only the result. The Agents Working Group named those patterns, listing "agent-as-tool, remote-agent, and supervisor/sub-agent" among the use cases it was considering.

A tool can even accept a task description as one of its arguments. But the server never chooses which tool is called, because the agent makes that choice before it sends the call. What separates the agent from the server is who chooses the next tool.

An agent inside one tool call can hide its reasoning and its spending from the calling agent, which receives only what the server puts in the result.

What connecting a server costs in context #

An agent that loads a server's tool definitions keeps them in its context on every turn. Two calls measure what the server sends. The first gets the server's instructions, and the second gets its tool definitions:

URL="https://mcp.apify.com/?tools=search-actors,fetch-actor-details,search-apify-docs,fetch-apify-docs"
META='"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}'

for M in server/discover tools/list; do
  curl -s -X POST "$URL" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -H "MCP-Protocol-Version: 2026-07-28" -H "Mcp-Method: $M" \
    -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$M\",\"params\":{$META}}" \
    | sed 's/^data: //' | grep -E '"(result|error)"' > "${M//\//-}.json"
done

This script counts the tokens in both responses:

import json, tiktoken

enc = tiktoken.get_encoding("o200k_base")
listed = json.load(open("tools-list.json"))
discovered = json.load(open("server-discover.json"))
for r in (listed, discovered):
    if "error" in r:
        raise SystemExit(r["error"])

tools = listed["result"]["tools"]
instructions = discovered["result"].get("instructions", "")

defs = sum(len(enc.encode(json.dumps(t))) for t in tools)
instr = len(enc.encode(instructions))
print(f"{len(tools)} tools, {defs:,} + {instr:,} = {defs + instr:,} tokens")

That prints 4 tools, 5,576 + 971 = 6,547 tokens, the full payload the server sends. How much of it reaches the model depends on the client. In a September 2026 check, Claude Code gave the model only the server instructions and each tool's name, description, and input schema. So 3,608 of the 6,547 tokens reach the model on every turn.

The counts use o200k_base, an OpenAI tokenizer, so treat every token count here as an estimate. Recount with your own model's token counter, such as Anthropic's free token counting endpoint.

With a different URL, the same loop and script should work on other servers that use 2026-07-28. For an older server, send initialize with protocolVersion, capabilities, and clientInfo, save its result as server-discover.json, and send notifications/initialized. Then send the tools/list call with the returned Mcp-Session-Id header. Most other servers also need an access token, sent as an Authorization: Bearer header.

The client can change the cost too. The MCP Apps UI extension lets a server show interactive UI in the client. mcp.apify.com supports it, and a client that declared it also got interactive widget versions of search-actors and fetch-actor-details. With io.modelcontextprotocol/ui and its text/html;profile=mcp-app MIME type in clientCapabilities.extensions, the commands above showed 9,604 tokens instead of 6,547.

Results from one server do not show the typical cost. A separate September 2026 test of 141 servers from the official MCP Registry found 33 that answered without authentication. Measuring all 33 shows the range:

The largest sent 23,809 tokens, 11.9% of a 200k context window. Servers that require authentication are missing from this sample, including many from large vendors, so the median across all servers is probably higher.

The darker bar is mcp.apify.com with no tools parameter, measured the same way but with an API token. It returned the default tool set. An Actor is Apify's name for a ready-made tool that does one job on the web, such as fetching a page or collecting data. A defaults.actors constant in the server's open-source code preloads RAG Web Browser (apify/rag-web-browser) and Web Fetch ( apify/web-fetch), so a new connection can fetch a page on its first turn.

The default connection sent 17,816 tokens. More than half of them were output schemas, which describe the structured results each tool returns. Claude Code did not pass them to the model, so 7,567 reached the model. The chart shows what each server sends, so a server with large output schemas can sit above the band while the part that reaches the model sits inside it.

The preload costs tokens but saves round trips, and the tools parameter lets you choose which matters more:

Value of ?tools= Server sends Reaches the model in Claude Code What the agent can use
apify/rag-web-browser 8,826 3,111 that one Actor, plus tools to read its runs and results
actors 11,889 5,233 Actors you name, after a search and a details lookup
omitted 17,816 7,567 the actors and docs tools, plus the preloaded Actors, callable immediately

The table was measured on September 24, 2026. The third column counts only the parts Claude Code passed to the model. Tool definitions and client behavior can change with any release, so measure your own connection.

MCP's client guidance recommends on-demand , which it calls progressive discovery: the agent loads a definition only when it needs that tool. It suggests switching once definitions exceed a threshold, such as 1% to 5% of the context window. On a 200k context window, that is 2k to 10k tokens. The guidance says that every definition upfront "wastes tokens, increases latency, and degrades model performance."

Changing the tools array mid-conversation invalidates the provider's prompt cache, which reuses the unchanged start of a prompt at a lower price. The guidance warns that the resulting cache miss "can cost more tokens than the definitions you removed."

The guidance gives two fixes. The first is to add new definitions after the cache breakpoint, the point where the cached part of the prompt ends. The second is to send every call through one fixed call_tool({name, args}) tool, so the tools array never changes.

Three pages fetched with apify/rag-web-browser produced 13,179 tokens of Markdown, so one result can use more context than a server's whole tool list. Nothing in the protocol limits a result's size.

Servers can set their own limits. mcp.apify.com returned the run's status first, and the agent read the pages with a separate get-dataset-items call, which supports paging. On this server, large resource reads return a download URL and a pagination hint instead of the content, so a big result does not fill the model's context.

Anthropic's November 2025 approach has the agent write code that calls servers. In one example, reading only the tool definitions it needed cut token use from 150k to 2k. The code can also stop intermediate results from reaching the model.

In an A/B test from August 8, 2026, code execution with Code runtime (apify/code-runtime), a sandbox Actor, cut model cost by 73% across seven tasks compared with ordinary tool calls. Apify publishes the full results in its public repository, including two tasks where the sandbox gave worse results, so check accuracy as well as cost before you switch.

The tool description works as a prompt #

Of the 6,547 tokens the four-tool connection sent, 2,161 were tool descriptions and server instructions, 33% of the payload. In the 3,608 tokens that reached the model in Claude Code, the same text was 60%. These are exact quotes from that connection:

Use the Actor's **README** to understand its capabilities.
Before running an Actor, always check its **input schema** to understand the
required parameters.
Choose the most appropriate Actor based on the conversation context.

Schemas used most of the payload, and output schemas were the largest part. Claude Code did not pass those to the model:

Input schemas tell the model which arguments a call takes. The descriptions and instructions tell it what to do.

A server that writes tool descriptions and instructions can influence the decisions the calling agent makes, without ever making one itself.

Across the 33 public servers, descriptions and instructions had a median share of 26%. Ten of the servers were above 40%, and the highest was 66%. So the four-tool connection's 33% is typical, not extreme.

Tests show how much the wording matters. The Apify MCP server's public repository has evals that check the first tool an agent calls and evaluate full agent runs. A November 2025 failure analysis covered six earlier tool-selection experiments. It linked the most severe group of failures, 29% of the failed cases, to one cause: description wording.

A server you connect adds its text to your agent's context, so review it like any other dependency. Published eval results are one sign that the wording was tested with models.

Check a server before you connect it #

Every check here works on a server you are considering, with only the access you have as a user of it.

  • Measure the tool definitions with the client and model you will use. Client capabilities can change what a server sends, and the tool format a client uses can change what reaches the model.
  • Read the tool descriptions and server instructions. That text can change what your model does.
  • Send a parameter the schema does not declare. Onetools/call with an undeclared field, on a tool that requires no arguments, shows whether the server ignores fields it does not recognize and returns no error.
  • Check what long-running calls return. A tool that starts a job may wait for it or return early. Apify's Actor tools wait for a configurable time that keeps each call under the time limit some MCP clients set, andApify's MCP docs list the current default. If the run is still going, the tool returns the run's status and names the call that checks it again. Your tool timeout has to be longer than the wait, and your loop has to make that call.
  • Test what happens with an oversized result. Request more pages or a higher limit than you need, and read the response. An error, a truncated response with no warning, and a successful response with a download link each need different handling in your loop.

Add up the tool definitions that reach your model from all your servers. Load them all upfront while that total stays under your threshold, such as 1% to 5% of the context window. Above it, switch to progressive discovery. When individual tool calls return more than a few thousand tokens, consider code execution.

Cases that confuse people #

Agent Skills and command-line tools also give an agent new abilities, so both are often compared with MCP servers. Each one does a different job:

MCP server Agent Skill Command-line interface (CLI)
Gives the agent Tools to call Instructions for a task, with optional scripts and reference files Commands to run
Uses context From the first turn, for each tool definition the client loads About 100 tokens, until a task needs the rest Only for the output of the commands the agent runs
Needs An MCP client A file system and a shell A shell, with the CLI installed
Reaches agents you do not control Yes, through their MCP clients Only agents that install it Only machines that install it

MCP vs. Agent Skills

Agent Skills are an open format, originally developed by Anthropic, for packaging the instructions for a task. Each skill is a folder with a SKILL.md file, plus any scripts and reference files the task needs. A skill tells the agent how to do a job, and an MCP server gives it tools to call.

Skills load in stages, a design Anthropic's documentation calls progressive disclosure. The agent keeps only each skill's name and description in context. It reads SKILL.md when a task matches, and opens other files when a step needs them.

Apify has a skill and an MCP connection for the same job: finding and running Actors, its ready-made web tools. In September 2026, the name and description of its apify-ultimate-scraper skill measured 101 tokens. When a scraping task starts, the skill's steps have the agent read SKILL.md and two reference files, for 5,592 tokens in total. For comparison, 5,233 tokens reach the model in Claude Code on every turn when Apify's MCP server loads its Actor tools (?tools=actors):

A skill needs an agent with a file system and a shell, and an MCP server needs only an MCP client. The two also work together. A skill can name the MCP tools to call, and MCP's official Skills extension lets a server offer skills as resources. Use a skill when the agent has access and needs a procedure, and an MCP server when it needs access it does not have.

MCP server vs. CLI

A CLI serves agents that can run shell commands, and an MCP server serves any agent with an MCP client. With a shell, the agent can use a CLI directly, and the CLI adds nothing to the context until the agent runs a command. The agent can also filter the output, for example with jq, so only the part it needs enters the context. It still has to learn which commands exist, from its prompt, from --help output, or from a skill.

An MCP server works where a shell is missing or unwanted. Chat apps and hosted agents often cannot run commands, and a remote MCP server runs without a local installation. A shell can let the agent run any command its user can, while a server exposes only the tools it defines.

Apify offers both. The Apify CLI can search for Actors and run them from a terminal, and mcp.apify.com exposes the same Actors as MCP tools. For an agent with a shell on a machine you control, a CLI is usually the simpler choice. For other agents, an MCP server is.

What to build and when #

The decision starts with one question: do you own the task, or do you own something the task needs? The answer leads to one of four choices:

Build an MCP server when you own data, an API, or a product that agents you do not control should use, such as your customers' or other teams' agents. One server gives all of them the same interface, so you do not write an integration for each client. Your job is to expose it through clear tools, describe them in text a model reads correctly, and return structured results. If only your own agent will call it, a direct function call is usually simpler.

Build an agent when you own a task whose next step depends on the previous result. That includes multi-step research, debugging, and any task where you cannot know the plan before the first result arrives. You own the loop, the memory, the stopping condition, and the cost.

Build both when you run a platform, a product other developers use to build their own software. Their agents can use your server, and your own features may need an agent. Keep the two separate in code, even when you release them together.

Build neither when a single API call or a fixed workflow already does what you need. Anthropic's December 2024 guidance advises starting with the simplest solution, and notes that agentic systems are often slower and more expensive, in return for better results. A loop that always runs the same three steps is a script. Scripts are usually cheaper, faster, and easier to debug than agents.

If you build a server, every tool you add takes up context in each connecting agent, on every turn. Keep the list short, and let clients choose a subset, as the ?tools= parameter on mcp.apify.com does.

If you build an agent, owning the loop also means handling its failures. When a tool call times out, you often cannot tell whether the action happened. Retries, idempotency, and compensating actions are your responsibility, and the protocol does not handle them for you.

Besides a normal result, a server's response can take four other forms. A missing tool or a malformed request returns a JSON-RPC error, which reaches the model only if your agent adds it to the model's context. Revision 2026-07-28 says models are less likely to recover from these errors. Even so, pass the model any error with code -32602 (invalid params), because that error is about a tool name or argument the model chose.

A call that fails inside the tool, such as a documentation fetch returning a 404, usually returns an ordinary result with isError: true, which the model can use to recover. On some servers, a size-limited resource read returns a link instead of the data. A result with resultType: "input_required" means the server needs something first, such as an answer to an elicitation/create question, and a loop that ignores it cannot continue.

Building an agent needs one more decision.

Build or buy what your agent depends on #

If you own the loop, most of what it depends on is something to build or buy. Many agents need real-time web data, and that is one of the harder parts to build yourself.

Sending the HTTP request is the easy part. An agent that scrapes its own sources often has to manage rotating IP addresses, browser fingerprints, browser sessions, and page layout changes that break selectors without warning. Every hour you spend on that work is an hour you do not spend on your own loop.

Apify Store, a marketplace of ready-made Actors running as serverless programs, can handle much of that work. Its thousands of Actors work with search engines, marketplaces, maps, and social platforms. You call them over MCP, through the REST API, from the JavaScript and Python client libraries, or with the Apify CLI.

Connecting an agent over MCP can take as little as one configuration block. The exact keys vary by client, and a typical block looks like this:

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=actors",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}

The ?tools=actors parameter loads the Actor tools, including search-actors, fetch-actor-details, and call-actor, plus tools for runs and storage. Then call-actor can run Actors from the marketplace by name. Name a single Actor in ?tools= instead when the agent needs only one.

An agent written in your own code can connect to the same URL through an MCP client library. It can also call Actors without MCP, through the Apify API client for Python or JavaScript.

The discovery tools, such as search-actors and search-apify-docs, work without an API token when ?tools= lists only them, and the server's README keeps the current list. The other tools run with an API token, or with OAuth sign-in in clients that support it.

Coding agents such as Claude Code, Cursor, and Codex can use Apify Agent Skills instead of a server connection, or together with one. One command installs the scraping skill:

npx skills add https://github.com/apify/agent-skills --skill apify-ultimate-scraper

The skill guides the agent to choose an Actor, check its input schema, run it with the Apify CLI, and fetch the results. To authenticate the CLI, run apify login or set an APIFY_TOKEN environment variable. The same repository has skills for building Actors and for turning existing code into Actors.

A three-page fetch through apify/rag-web-browser cost less than a cent in September 2026. The free plan needs no credit card and includes monthly usage credits, and RAG Web Browser's Store page shows its current pricing.

Hosting the agent on the Apify platform is a separate decision. It suits agents that run as jobs, started by an API call or a schedule, with runs, storage, and spending limits in one place. The Apify SDKs for Python and JavaScript let you package an agent as an Actor, with templates for LangGraph, CrewAI, Pydantic AI, LlamaIndex, smolagents, and others. OpenRouter (apify/openrouter) lets the agent call models without your own API key from a model provider.

An agent hosted as an Actor often needs the user's own tools too. MCP connectors let an Actor call third-party MCP servers, such as Notion, Slack, GitHub, Sentry, and Supabase, on the user's behalf. The user authorizes a connector once, in Settings > API & Integrations in Apify Console.

The Apify MCP Proxy adds the user's credentials to each request, so they never enter the Actor. The Actor can call only the tools it declares, and its access ends when the run ends. With connectors, the Apify platform works on both sides of the split between agent and server:

Three parameters of the Run Actor endpoint let you set limits on the agent's run: memory, timeout, and maxTotalChargeUsd. Set all three. A crash usually stops on its own and costs little, but a loop that keeps running without an error keeps spending until a limit stops it.

Final thoughts #

The protocol splits the work: tools/call needs a tool name, so the agent decides and the server runs the tool it is asked for. Build a server when agents you do not control need what you own, and build an agent when the next step depends on the previous result. Token counts, tool sets, and client behavior can change with any release, but this division of work is likely to stay the same, because a server that runs a full loop inside one tool call still never chooses the agent's next tool.

Each server whose tool definitions you load adds tokens to the context on every turn, and on mcp.apify.com, a ?tools= parameter that lists fewer tools reduces what reaches the model. Measure your tool definitions with your own client before the first user message, and switch to progressive discovery once they exceed your threshold.

FAQ #

Are AI agents and MCP the same?

No. MCP is a protocol that connects AI applications to data and tools. An agent is the program that has a goal, chooses tools, and decides when to stop. An agent can run without MCP, and an MCP server waits for a client to call it.

Is MCP required for agentic AI?

No. An agent needs a model, a loop, and some way to call tools. Direct API calls or a local function registry can handle the tool calls. MCP is useful when you want one interface across many tool providers, or when you want tools that agents you do not control can discover without a custom integration.

Why MCP instead of direct API calls?

Direct API calls are usually cheaper for one known endpoint. MCP often works better across many endpoints, because discovery and schemas work the same way on every server, and a new tool on the server works without a new version of the client. The cost is the context that tool definitions take up.

── more in #ai-agents 4 stories · sorted by recency
── more on @model context protocol 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/ai-agent-vs-mcp-serv…] indexed:0 read:24min 2026-10-02 · —