Why MCP Exists When We Already Have REST APIs and CLIs
Agents can already call REST and run shell commands. The design case for MCP — runtime discovery, typed tools, auth — and where curl is still right.
- ai-agents
- domains
- explainer
Namefi's own machine-readable policy file, published at namefi.io/llms.txt, tells any agent that reads it: "REST/curl is a fallback only when: your client cannot install MCP, the MCP install failed or is blocked, or the user explicitly asks for raw HTTP." It even lists an anti-pattern — "Don't lead with curl when MCP can be installed."
That is an instruction, not an argument. It asserts a preference without saying why the preference is correct, and the objection writes itself: HTTP has worked for thirty years, every language ships a client for it, and a language model can already emit a curl command. Adding a protocol on top of a protocol looks like a tax.
This post is the missing argument. It is not a setup guide — How to Register a Domain with Your AI Agent covers configuration for six clients, and the Namefi MCP server catalog covers the tool surface. This is the design rationale: what problem the Model Context Protocol solves that a REST API and a shell prompt structurally cannot, and — the part most MCP advocacy skips — where raw HTTP genuinely remains the better answer.
It is also deliberately the protocol question, sitting upstream of two adjacent ones: what a registrar has to ship before an agent can use it at all (What Is an Agent-Native Domain Registrar?) and which platforms expose which interface today (AI-Agentic Domain Platforms: The 2026 Guide).
The premise: an integration nobody wrote
Every REST API on the internet assumes a specific sequence: a developer finds the docs, reads them once, writes client code by hand, and ships it. After that the integration runs unattended — but only because a person already did the interpretive work, months ago, off the clock.
An AI agent breaks that assumption at the root. It arrives with no prior integration, and it arrives again on the next conversation, and the next. That cold-start framing is developed in full in What Is an Agent-Native Domain Registrar?; the short version is that every session is effectively a new developer with seconds of context budget and no ability to go read a docs site properly.
The rest of this post takes that premise as given and asks the narrower question: given a cold-start caller, what does a protocol have to provide that HTTP alone doesn't?
"Just read the OpenAPI spec" doesn't survive contact with a context window
The obvious rebuttal is that the machine-readable answer already exists. Publish an OpenAPI document, point the agent at it, done.
It fails on arithmetic. Namefi's own OpenAPI 3.1.1 document, fetched from api.namefi.io/v-next/openapi/doc.json and measured on August 3, 2026, is 415,601 bytes describing 41 paths and 49 operations. That is a mid-sized API by any standard — and dropping ~416 KB of JSON into a context window to answer "is example.com available" is not a discovery mechanism, it's a denial-of-service against your own token budget.
Size is the visible problem. Three others matter more:
- A spec describes transport, not intent. OpenAPI tells you that
POST /v-next/orders/register-domainaccepts a body with certain fields. It does not tell you that registration is asynchronous, that you must poll a second endpoint until the order reaches a terminal status, or which of the 49 operations fits the task in front of you. - Specs aren't reliably discoverable. There is no
/openapi.jsonconvention that servers actually honor. An agent handed a base URL has no standard way to find the document, and often no way to know one exists. - A spec is a superset of what you're allowed to call. It describes the API; it does not describe your API — the operations your credentials actually permit.
MCP's tools/list inverts all four. It returns a paginated, cacheable list of tools the caller can invoke right now, and the current specification is explicit that the set "MAY vary by the authorization presented on the request — for example, returning only the tools the caller's granted scopes permit" (MCP specification, 2026-07-28). The agent doesn't fetch a description of everything the server can do and then filter. It asks what it can do, and gets an answer scoped to itself.
The schema is the contract, and the error is written for the model
Each tool in a tools/list response carries an inputSchema: "JSON Schema defining expected parameters," defaulting to JSON Schema 2020-12, and it "MUST be a valid JSON Schema object (not null)" (MCP specification). An optional outputSchema does the same for the result, and when one is present, servers "MUST provide structured results that conform to this schema."
This is not decoration. It moves argument validation to a place where it can be enforced before a call is made rather than diagnosed after one fails. The equivalent in REST-land is a prose sentence in a docs page — "durationInYears must be between 0 and 10" — that a model may or may not have in context at the moment it constructs the request.
The error design is the sharper difference. MCP splits failures in two. Protocol errors — unknown tool, malformed request — come back as JSON-RPC errors and are described as "issues with the request structure itself that models are less likely to be able to fix." Tool execution errors come back inside a successful result with isError: true, and the spec says explicitly that they "contain actionable feedback that language models can use to self-correct and retry with adjusted parameters." The spec's own example is a date validation failure that tells the model what today's date is.
Read that as a design statement rather than a schema detail: MCP has a category of error whose audience is the model, distinct from the category whose audience is the developer. HTTP has status codes, whose audience is a caching proxy, plus a response body whose shape nobody agreed on. A 400 Bad Request with a human sentence in it is not the same artifact.
Tool descriptions are context, not documentation
Here is the part with no REST analogue at all.
A tool's description field is not read by a developer at design time. It is loaded into the model's context window at tool-selection time, on every turn where those tools are available. That makes its length a runtime cost and its phrasing part of the interface — a distinction the specification acknowledges directly when it asks servers to return tools in a stable order, because "deterministic ordering enables clients to reliably cache the tool list and improves LLM prompt cache hit rates when tools are included in model context."
That sentence is quietly remarkable. A wire protocol is making a normative recommendation about the inference cost of the thing on the other end. No REST specification has ever had a reason to care whether your endpoint names cache well in a language model's prompt.
The same logic runs through the rest of the surface. Servers can return an instructions string described as "optional natural-language guidance for LLMs on how to use this server effectively." When guidance about state lifetime is needed, the spec says to put it in the creation tool's description — "e.g., 'baskets expire after 24 hours of inactivity'" — explicitly "so the model can see it when deciding to create state."
Documentation, in MCP, is not a separate artifact that ships beside the API. It is the API, and you pay for it per token.
Capability negotiation, and a protocol willing to break itself
An agent connecting to a server needs to know what version it's speaking and which optional features exist. REST's answer is convention: a version in the URL path, or a header, or nothing, with no standard way to signal a mismatch and no standard way to ask what's supported.
MCP's answer has changed once already, which is the more interesting fact. The 2025 revisions used an initialize handshake in which client and server exchanged protocol versions and capability objects before any real work. The current revision, 2026-07-28, threw that out: "There is no negotiation handshake. Every request carries its protocol version, and the server accepts or rejects each request independently." A version the server doesn't implement produces an UnsupportedProtocolVersionError carrying the list of versions it does support, so the client retries correctly instead of guessing. A server/discover method — which "Servers MUST implement" — returns supported versions, capabilities, and identity in one request for clients that want to ask up front.
The specification also publishes a full client-era × server-era compatibility matrix, naming the two eras "modern" and "legacy," so implementers can predict exactly which combinations break. That is the point worth taking: versioning here is a specified mechanism with a specified failure mode, not a convention each vendor invents. An incompatible client hitting an incompatible server gets a structured error, not a 404 and a shrug.
State: the part MCP tried, and then deleted
You will read, in a lot of MCP explainers, that MCP is better than REST because it maintains a stateful session while REST is request-scoped. As of the current specification, that is wrong, and the correction is more interesting than the claim.
The 2026-07-28 revision states it flatly: "MCP has no protocol-level session, so a server cannot rely on implicit per-connection state to relate one tool call to the next." Even the local transport is stateless now — if a server process dies, "because the protocol is stateless, any in-flight requests are simply lost and the client can retry them against the fresh process."
MCP started with implicit session state and moved toward REST's statelessness, for the same reasons REST had it: connections drop, processes restart, and load balancers exist. What it kept is the part that actually helps a model: state is now explicit and typed. A server that needs continuity returns a handle from a creation tool and accepts it as an argument on later calls, with the specification setting out guidance on authorization ("a handle is a name, not a capability"), opacity, lifetime, and expiry errors that "say so, so the model can recover by creating a new one."
There is one genuinely stateful thing MCP added that HTTP has no vocabulary for: a tool call can come back input_required, carrying a request for more information — a login, a disambiguation, a confirmation — plus an opaque requestState blob the client returns with the retry. A REST endpoint that needs one more field from the user can only fail and hope the caller reads the message.
Why not just shell out to a CLI?
The strongest objection isn't REST. It's that agents can already run shell commands, and every serious service ships a CLI that a person already knows how to use. Why is namefi register example.com worse than a tool call?
Five reasons, and one concession that matters.
A CLI assumes a host. It assumes a POSIX-ish machine, an installed binary at a known version, a package manager that can put it there, and a shell to invoke it from. A hosted agent — an assistant in a browser tab or a chat product, anything running where the user has no filesystem — has none of that. Notably, MCP did not reject local processes: its stdio transport is one, where "the client launches the MCP server as a subprocess" and speaks JSON-RPC over its standard streams. What MCP rejected is the framing, not the locality — and the same server, unchanged, is reachable over Streamable HTTP by clients that can't spawn anything.
Text output is not a schema. Parsing --help gives you flags, not types or constraints or which combinations are valid. Parsing results means regexes against human-formatted output that changes between versions with no compatibility contract. Some CLIs offer --json; almost none publish a schema for what that JSON contains.
Streams get contaminated. MCP's stdio transport had to legislate what a normal CLI does casually: the server "MUST NOT write anything to its stdout that is not a valid MCP message," while clients "SHOULD NOT assume stderr output indicates error conditions" (MCP specification). Every progress bar, deprecation notice, and update nag a normal CLI prints to stdout is noise a model has to interpret.
The blast radius is the whole machine. A tool call reaches exactly the operations a server exposes. A shell command reaches the filesystem, the network, the environment, and every other binary installed. Sandboxing shell access is a genuinely hard problem; enumerating a tool list is not.
And it doesn't compose. Two MCP servers connected to one client present one merged tool list in one vocabulary, and the spec anticipates the obvious failure — clients aggregating tools from multiple servers "SHOULD implement a disambiguation strategy such as prefixing tool names with a server identifier." Two CLIs present two sets of undocumented conventions and no shared error vocabulary.
The concession. None of this makes MCP the right answer everywhere, and Namefi's own documentation doesn't claim it does. Every operation reachable through the MCP server is also a plain HTTPS endpoint, and How to Register a Domain with Your AI Agent documents the raw curl path as a first-class route, not an apology. Use REST or a CLI when: the caller is a script with a fixed integration written once by a human, where cold-start discovery buys nothing; the runtime is a CI job or cron task with no MCP client; latency or dependency budget rules out a protocol layer; you're debugging and want to see the wire; or the operation is a single unauthenticated read — Namefi's availability endpoint needs no credentials at all, and is documented as the explicit search-only exception to its own MCP-first policy.
The dividing line isn't sophistication, it's who wrote the integration. If a human wrote it in advance and it runs the same way every time, an API is the correct tool and the protocol is overhead. MCP earns its cost precisely when nobody wrote the integration.
Auth is a layer, not a token pasted into a config file
The default agent-credential story is bleak: a long-lived API key in a JSON config file, in plaintext, in a home directory, frequently committed by accident, with the same permissions as the human who created it and no expiry.
MCP specifies an alternative rather than leaving it to each vendor. Authorization is "OPTIONAL for MCP implementations," but when an HTTP-based server supports it, the shape is fixed: the server acts as an OAuth 2.1 resource server, "MCP servers MUST implement OAuth 2.0 Protected Resource Metadata (RFC 9728)" so a client can discover the authorization server from a 401 response, and "MCP clients MUST implement PKCE" — and must refuse to proceed if the authorization server doesn't advertise support for it. Tokens must carry an RFC 8707 resource parameter binding them to the specific server, and servers must reject tokens issued for anyone else.
The practical effect is that a user can connect a client to a server it has never seen, complete a browser sign-in, and end up with a scoped, expiring, audience-bound token — with no secret stored in a config file. Namefi's own discovery descriptor advertises exactly this path alongside the x-api-key header. One caveat worth flagging: Namefi's llms.txt documents dynamic client registration (RFC 7591), which the current MCP revision has demoted — it is now "deprecated and retained for backwards compatibility" in favor of Client ID Metadata Documents.
Note the deliberate carve-out: local stdio servers "SHOULD NOT follow this specification, and instead retrieve credentials from the environment." The protocol is not claiming OAuth everywhere. It is saying that remote servers, where the trust boundary is real, get a specified answer instead of a per-vendor one.
Frequently Asked Questions
Is MCP just a wrapper around a REST API?
Mechanically, most MCP servers are — Namefi's tools are generated from its OpenAPI specification. But the wrapper is the point. It converts a document written for a developer to read once into a runtime query (tools/list) that returns only what the current caller can invoke, with JSON Schema on every argument, errors written for a model to recover from, and a specified authorization flow. The underlying HTTP endpoints don't change; what changes is whether a caller with no prior integration can use them.
Why can't an agent just read the OpenAPI spec?
Three reasons. Size: Namefi's spec is over 400 KB of JSON, verified August 3, 2026 — expensive context for one availability check. Discovery: there is no reliable convention for finding a spec from a base URL. Scope: a spec describes the whole API, not the operations your credentials permit, whereas a tools/list response can be filtered by the authorization presented on the request.
Does MCP keep a session open the way a database connection does?
No, and this is a common misconception. The current specification states that "MCP has no protocol-level session." Servers that need continuity across calls return an explicit handle from a creation tool and accept it as an argument later, with lifetime and expiry documented in the tool description itself. MCP moved toward statelessness over time, not away from it.
When is raw REST or a CLI actually the better choice?
When a human wrote the integration in advance and it runs identically every time: scripts, CI jobs, cron tasks, anything in a runtime with no MCP client, and one-off debugging where you want to see the wire. Namefi documents a full curl path for exactly these cases. The protocol earns its cost when nobody wrote the integration ahead of time — not merely because the caller happens to be a program.
Is MCP a finished, stable standard?
Not yet. The current revision is 2026-07-28, and it replaced the initialize handshake used by 2025-11-25 and earlier with per-request version metadata — a breaking change roughly eighteen months after MCP's initial release on November 25, 2024. The specification publishes a compatibility matrix for mixing eras, so the churn is documented rather than silent, but treat any specific mechanism described here as current-as-of-publication rather than permanent.
Does using MCP mean an agent can spend my money without asking?
No more than an API key does, and the specification is direct about it: "there SHOULD always be a human in the loop with the ability to deny tool invocations." That guardrail lives in the client, not the protocol — which is the same open row flagged in the agent-native checklist, where no major registrar yet documents a server-side spend cap.
Try it against a real API
The fastest way to evaluate any of this is to point a client at a server that implements the whole surface — typed tools, structured errors, OAuth or a header key — and watch what your agent does with a task it has never been given an integration for. Namefi, an ICANN-accredited registrar, runs one at https://api.namefi.io/mcp over Streamable HTTP, with the same operations available as plain HTTPS endpoints when raw HTTP is the right call — including the x402 wallet-payment path, which lives outside MCP entirely.
Generate a Namefi API key, or connect with OAuth and let your client discover the sign-in flow on its own.
Sources and further reading
- Model Context Protocol — Versioning (establishes 2026-07-28 as the current revision and the dated-revision scheme)
- Model Context Protocol — Tools (2026-07-28) (
tools/list,inputSchema/outputSchema, per-authorization tool sets, the two error categories, prompt-cache guidance, and the "no protocol-level session" statement) - Model Context Protocol — Versioning and Compatibility (2026-07-28) (per-request version declaration replacing the
initializehandshake; modern/legacy compatibility matrix) - Model Context Protocol — Discovery (2026-07-28) (
server/discoveras a mandatory server method returning versions, capabilities, and identity) - Model Context Protocol — stdio transport (2026-07-28) (subprocess launch, newline-delimited framing, the stdout/stderr rules cited in the CLI section)
- Model Context Protocol — Authorization (2026-07-28) (OAuth 2.1 roles, RFC 9728 protected-resource metadata, RFC 8707 resource binding, the stdio environment-credentials carve-out, DCR deprecation)
- Model Context Protocol — Authorization Security Considerations (2026-07-28) (PKCE requirement and the obligation to refuse servers that don't advertise support)
- Anthropic — Introducing the Model Context Protocol (initial release, November 25, 2024)
- IETF — RFC 9728: OAuth 2.0 Protected Resource Metadata (the discovery mechanism MCP servers must implement)
- IETF — RFC 8707: Resource Indicators for OAuth 2.0 (audience binding for MCP access tokens)
- Namefi — api.namefi.io/v-next/openapi/doc.json (the OpenAPI 3.1.1 document measured at 415,601 bytes / 41 paths / 49 operations on August 3, 2026)
- Namefi — namefi.io/llms.txt (the mandatory agent policy quoted in the opening, the REST/curl fallback rules, and the search-only exception)
- Namefi — namefi.io/.well-known/mcp/servers.json (MCP discovery descriptor: transport, OAuth 2.1 + PKCE, dynamic client registration,
x-api-key)
Contributors
Aileen Wright is a student in her twenties living in New York City, where the distance between a museum wall and a library reading room is a short walk and a long afternoon. She came to name writing through art and history — the way a single portrait, coin, or manuscript margin can carry a name across centuries and change its meaning on the way.
Most weeks you can find her in Central Park with a paperback, or in the quiet of a public reading room chasing down where a name actually comes from rather than what a name-list says it means. She is also teaching herself to code, which has made her oddly precise about spelling, sorting, and the small details that decide whether a name ages well.
For Namefi she writes about the history and culture behind domain names, the stories brands carry as they rename, and the difference between a good story and a verified source.
Victor Zhou is a technology founder and standards editor focused on digital identity and trust. He founded Namefi, edits Ethereum Improvement Proposals, and previously led smart-contract architecture work at Google Labs.
His work sits at the intersection of naming, ownership, and the systems people use to establish identity online. That perspective makes him especially interested in the way names move between personal meaning, public recognition, and digital infrastructure.
For Namefi, Victor edits and writes about domains as durable digital identity: how names become ownable onchain assets, how tokenization changes custody and trust, and what naming can learn from the systems people use to establish identity online.
Related guides
- What Is an Agent-Native Domain Registrar?Registrars have had APIs for decades, but an API alone isn't agent-native. The checklist: discovery, docs, errors, payment, and policy hooks.
- How AI Agents Buy Domains Without a Human (2026)In April 2026, domain registration moved into the agent layer. How AI agents search, price, and register domains — and the guardrails that still matter.
- "AI Domain Search" Means Two Different Things in 2026"AI domain search" can mean an assistant that suggests or an agent that buys. A two-column test to know which you need and where to get each.
- Beyond the AI Domain Name Generator: The Agent EraAI name generators stop at suggestions. The capability ladder from suggest to search, configure, transact, and manage — and who ships each rung.