Tutorial

What is MCP? A complete 2026 guide to Model Context Protocol, JSON-RPC, AI agents, and tool calling

Cursor, Claude Desktop, and home-grown agents all say MCP. The protocol does not chat or reason. It says how a tool list is discovered, how one call’s JSON rides JSON-RPC, and how the result writes back into model context.

In 2026, any editor with an agent almost always shows MCP on the settings page. Some treat it as the next plugin store, some as a must-learn AI protocol, and some mash it together with tool calling, function calling, and A2A. This article uses an engineering definition: Model Context Protocol (MCP) is an open protocol that lets an AI client discover tools, resources, and prompts on a server and wire them into model context. The transport envelope is JSON-RPC 2.0; the business methods are tools/list, tools/call, and kin. It does not replace the model and it is not an agent — an agent is a loop; MCP is the layer inside the loop that says how remote tools are seen and called. When you finish you should be able to split four things: protocol, envelope, runtime, and the model picking a tool. We already have Schema mapping, stateless remote MCP, A2A layering, and an agent definition on this site. This piece is the entry door, not those deep dives.

What MCP is: not a model — a protocol for tools

The minimum definition needs three parties: a Host (the editor or agent process), a Client (the side inside the Host that talks to servers), and a Server (a process or HTTPS endpoint that exposes tools, resources, and prompts). The Client asks the Server for a catalog, injects each tool’s name, description, and inputSchema into model context, and after the model decides to call, sends tools/call. MCP governs discovery and call shape. It does not govern how the model thinks.

Calling it an “AI plugin” is only half right. A browser plugin hangs on one host; an MCP Server can be reused by many Clients — the same invoice search can serve Cursor, Claude Desktop, or your own orchestrator. The difference is not “can we call a function,” it is whether the catalog and call envelope are standardized. You can already call HTTP with a homemade OpenAPI adapter; a second Client means writing the adapter again. MCP folds that layer into a protocol. Official concepts and the spec live at theModel Context Protocol docs.

On the timeline: Anthropic open-sourced MCP in 2024; by late 2025 the protocol sat under the Linux Foundation’s Agentic AI Foundation (AAIF). In 2026 hosts treat it as the default remote-tool channel, not a demo. A protocol version appears in request _meta — 2026-07-28 is “both sides agree on this semantics,” not “the model got smarter.” How that differs from a chatbot or a cron workflow is inWhat is an AI agent: no loop and no checkable argument shape is just chat; a loop over local functions can still be an agent — it simply has no standard remote catalog.

JSON-RPC 2.0: why MCP uses this envelope

MCP did not invent a new RPC. Every protocol action sits in a JSON-RPC 2.0 envelope: jsonrpc, id, method, params, or error. Request and response share an id; notifications may omit it. For gateways and logs that is easier to split than a custom stream frame: read method first, then the business. Field rules are in theJSON-RPC 2.0 specification.

method is a protocol verb, not your business function name. tools/list lists tools; tools/call invokes one; resources/read reads a resource. The business name lives in params.name; arguments live in params.arguments. Writing searchInvoices as method is a common misread — that is your own JSON-RPC service, not MCP. A standard catalog request looks like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

The envelope solves three things: multiplexing (several ids in flight), classifiable errors (parse failure, unknown method, business reject), and swappable transport (stdio child process or Streamable HTTP carry the same JSON). It does not decide whether arguments are right. A legal JSON-RPC envelope can still hand a missing-field arguments object to the Server. The Server must parse and validate against inputSchema itself.

How an AI agent uses MCP: discover → pick → call

Peel the demo video and an MCP-wired agent loop is still five steps. What changes is that steps 2 and 4 are no longer glued to local functions:

  1. The user goal enters context (natural language plus optional system constraints).
  2. The Client sends tools/list to each connected MCP Server and turns the catalog into tools / functions the model can read.
  3. The model returns tool_calls (which function, which arguments) or a final text / Structured Output.
  4. The runtime JSON.parse arguments, then sends MCP tools/call and writes the result back into the messages.
  5. The model reads the result and picks the next tool or stops. maxSteps, user cancel, or Schema failure also stop the loop.

The MCP request at step 4 looks like this. params.arguments is already an object, not a string. A protocol version can hang on _meta so stateless routing has something to read:

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "searchInvoices",
    "arguments": {
      "startDate": "2026-01-01",
      "endDate": "2026-01-31",
      "status": "paid"
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28"
    }
  }
}

An agent does not depend on MCP. Local functions, OpenAPI, and your own HTTP all qualify as tools. MCP’s value is that one Server can be discovered by many Hosts, with the same catalog and call shape when you go remote. The test for adopting MCP is “will a second Client reuse this tool set,” not “does it look like 2026.” The engineering definition of the loop is inhow an AI agent works.

LLM tool calling: tool_calls vs tools/call

Engineering-wise, tool calling and function calling are one mechanism: the model does not touch the database; it emits a structured “please call this function with these arguments” request. MCP is the next hop: the runtime translates that request into JSON-RPC tools/call. Field names on the two hops get mixed constantly:

This hop Who emits it What arguments look like
Model tool calling OpenAI / Anthropic / Gemini (and similar) model APIs Usually a JSON string inside tool_calls or tool_use
MCP tools/call The MCP Client inside the Host params.arguments is a JSON object
Downstream business API The MCP Server or your adapter HTTP JSON body / SQL params — same-origin Schema
Final Structured Output The model’s last hop The answer to the user or downstream — not tool inputs

When the model calls, a typical tool_calls item looks like this. arguments is still a string. The runtime must parse first, then place the object in MCP params.arguments. Do not stuff the string raw into JSON-RPC — it becomes “a string field named arguments” and Server Schema validation fails immediately.

{
  "id": "call_8f3a",
  "type": "function",
  "function": {
    "name": "searchInvoices",
    "arguments": "{\"startDate\":\"2026-01-01\",\"endDate\":\"2026-01-31\",\"status\":\"paid\"}"
  }
}

Vendor shells differ: OpenAI uses tools[].function.parameters, Anthropic input_schema, Gemini function_declarations. MCP uses Tool.inputSchema. Names differ; the canonical Schema should be one file. How fields line up, and why strict mode requires every property in required, is inMCP and JSON Schema. Final answers use Structured Output — do not share that file with tool inputs.

The 2026 map: local, remote, stateless, A2A

Two main transports. Local stdio: the Host spawns a child process and JSON-RPC rides stdin/stdout — good for the local filesystem or a local database. Remote Streamable HTTP: the Client POSTs the same envelope to an HTTPS endpoint — good for shared invoices, tickets, internal APIs. Remote no longer means “handshake, then bind a Session ID.” Around 2026-07-28, requests try to be self-describing so a gateway can rate-limit by method.

Stateless means the protocol layer: any instance can take any request. The application still has a database, idempotency keys, and user identity. Reading “protocol stateless” as “tools need no validation” is backwards — without a session cache you must not assume last turn’s tools/list is still live. A stale catalog writes the wrong shape into tools/call. Protocol details:stateless MCP and JSON-RPC.

MCP is also not a multi-agent protocol. A planner handing work to pricing, compliance, and logistics agents uses A2A message/send, not tools/call. Each specialist can still use MCP for its own database. “Protocol war” is usually the wrong frame: one layer faces tools, the other faces agents. CompareA2A vs MCP. Spec and implementations live in theMCP GitHub — trust the spec repo for version changes, not a single Host’s blog.

Validation on the ground and JSONVue

Every hop: parse → Schema → business rules. A legal MCP envelope does not make arguments legal. A clever model does not replace those three steps.

  1. Model arguments string: JSON.parse; on failure log raw + tool_call id and return a retryable error envelope — do not hit downstream yet.
  2. Validate against inputSchema / parameters (Draft 2020-12); emit path and keyword.
  3. Business gate: date range, enum vs permissions, foreign keys. Only then let the Server call the downstream API.

Line up three blobs: model arguments, the params.arguments you send to MCP, the object the Server actually used. Mismatch is almost always the adapter. In the browser:JSON formatter for parse;JSON Schema validator for arguments vs the Schema file;JSON Diff for model arguments vs the MCP / HTTP body. Share valid / missing-field / wrong-enum fixtures in CI and manual debug.

Further reading: What is an AI agent, MCP and JSON Schema, Stateless MCP, A2A vs MCP.

FAQ

Are MCP and tool calling the same thing?

No. Tool calling / function calling is the model-API hop: the model picks a function name and arguments. MCP is the next runtime hop: the Client discovers and calls a remote tool over JSON-RPC. You can do tool calling without MCP; you can write an MCP Server without a model. Merge the hops into one word and logs cannot tell you which layer failed.

Can we build an AI agent without MCP?

Yes. An agent is a model choosing actions in a loop while a runtime executes tools. Local functions, OpenAPI, and your own HTTP qualify if arguments and results are validatable. MCP’s value is a standard catalog and transport — especially remote and multi-client. Do not add a layer just to “look like 2026.”

JSON-RPC is an old protocol — why does MCP still use it?

Because it is old, small, and parseable everywhere. MCP needs a routable method, an alignable id, and a stable error — not another frame format. Streamable HTTP swaps transport, not the envelope. Calling JSON-RPC “not modern” usually does not fix wrong arguments.

Does the MCP Server validate tool arguments for me?

No. inputSchema is a declaration; the protocol does not run a validator. Both Client and Server should parse + Schema locally. Trust only the model or only the peer and missing fields hit the business. Taxonomy: the AI JSON errors guide.

Summary and next steps

MCP in 2026: discover and call tools over JSON-RPC, write results back into model context. It is not a model, not an agent, and not A2A. Tool calling governs how the model picks a function; MCP governs how the runtime finds and calls a remote tool; JSON Schema governs the shape of each hop.

Next: list the three JSON payloads in your system (model arguments, MCP params.arguments, downstream body) and check they share a Schema; replay valid / missing-field / wrong-enum in JSONVue. Protocol details in the stateless MCP article; field mapping in the Schema article; multi-agent in the A2A comparison.