The Relationship Between API, CLI, and MCP
Same business logic, two different doors. The CLI and the MCP server aren't rivals to the API - they're two clients of it, built for two different kinds of caller.
The cleanest way to understand the relationship between API, CLI, and MCP is to stop thinking of them as three competing technologies and start thinking of them as one piece of business logic exposed through two different doors. The API - and the business logic behind it - does the actual work: fetching data, writing records, calling downstream systems. The CLI and the MCP server are both clients of that same API, built for two fundamentally different kinds of caller: a human (or a script a human wrote) on one side, and a model deciding what to call and in what order at runtime on the other.
This is the third and most architectural post in our series on agent tooling, following why MCP needs a CLI and our decision framework for choosing between them. This post goes one level deeper: how the three actually connect architecturally, traced through one real operation, and what happens when one layer changes underneath the other two.
One API, Two Doors
An API surfaces raw endpoints - something like POST /issues - that return data or perform an action when called with the right method, parameters, and authentication. A developer needs to read documentation, know the exact request shape, and write client code to parse the response themselves. A CLI wraps those same endpoints into named terminal commands, handling argument parsing, authentication, and output formatting so a human can run gh issue create --title "Bug report" without writing any HTTP client code. An MCP server wraps the same underlying capability differently again - as a named, typed tool a model can discover and invoke at runtime, with the server translating that call into the actual API request behind the scenes.
All three sit on the same underlying business logic. The distinction is entirely about who's calling and how they decide what to call: a developer writing code calls an SDK or hits the API directly; an operator scripting a workflow calls a CLI; a model deciding autonomously what action serves the current goal calls MCP. None of the three replaces what's underneath it - each adds a different layer of convenience and structure for a different kind of consumer.
The M×N Problem MCP Actually Solves
The clearest way to see why MCP exists as a distinct layer, rather than agents simply calling APIs directly, is the integration math. Without a shared protocol, connecting M different agents to N different tools requires custom integration code for every single pairing - M×N bespoke integrations, each with its own authentication, error handling, and response parsing logic to build and maintain. MCP collapses that to M+N: each tool exposes one MCP server once, and each agent implements one MCP client once, and any agent can then talk to any tool through the same standard interface. For a handful of integrations the M×N cost is manageable and a direct API integration is often simpler; the crossover point where MCP starts saving real engineering time is generally once an organisation is maintaining somewhere around three to five or more integrations across multiple agents or products.
Tracing One Operation Through All Three Layers
Concretely tracing a single operation - creating an issue in a project tracker - through all three layers makes the relationship tangible rather than abstract.
Each layer down this list adds structure and removes a category of decision-making from the caller. What changes between CLI and MCP specifically isn't the underlying action - it's who decided to take it, and how much the caller needed to know about the API in advance to do so.
Two Ways to Build an MCP Server
When a team actually builds the MCP layer, there are two structurally different ways to do it, and the choice has real consequences.
Real production MCP server designs increasingly favour Option B deliberately, precisely because it avoids re-implementing authentication and request logic a mature CLI has already solved. One documented architecture pattern states this as an explicit design principle: wrap the CLI tool rather than call the API directly, specifically so that authentication - including OAuth flows and token refresh - is handled entirely by the CLI, and the MCP layer never needs to manage API keys or credentials itself. The same pattern typically spawns the CLI as a subprocess rather than using a shell-string execution call, specifically to avoid shell injection risk, passing arguments programmatically rather than interpolating user input into a shell command.
Pull vs Discovery: Two Different Request Models
Beyond the plumbing, CLI and MCP operate on genuinely different request models, and that difference explains a lot of the earlier debate about which is "better." A CLI is a pull model: the caller - a developer or a script - already knows the schema in advance, constructs the request explicitly, and owns pagination and error handling directly. Nothing is discovered at runtime; everything was decided ahead of time by whoever wrote the script. MCP is a discovery model: the agent doesn't necessarily know in advance what tools exist or exactly how they're shaped - it queries the server at runtime, inspects what's available, and decides which tool fits the current goal, all without the client-side code needing to change when the server adds new capability.
This is precisely why the two suit different callers. A CLI is the right choice when a human has already decided exactly what should happen and when - a deterministic, well-understood, unlikely-to-change integration with no reasoning layer involved. MCP earns its overhead when an LLM is the one deciding which tool to call and in what sequence, and the value of that decision-making flexibility outweighs the added discovery and schema cost.
What Changes Propagate Where
Because all three layers ultimately share the same underlying business logic, a change to that logic has to propagate through every layer built on top of it - but the layers absorb change very differently. An API version bump that changes a field name or adds a required parameter breaks any client - human or machine - built against the old contract; that risk is identical at every layer. Where the layers diverge is in how gracefully they degrade: a CLI's help output and flexible argument parsing can sometimes absorb minor drift without breaking existing scripts, especially if the CLI maintains backward-compatible aliases. An MCP server's typed schema is comparatively more brittle to the same drift, because the whole value of MCP's discovery model depends on the schema accurately describing what the tool actually expects - a stale schema doesn't just produce a confusing error, it actively misleads the agent's reasoning about what a valid call looks like.
If a CLI and an MCP server both wrap the same API, keep the CLI's command definitions and the MCP server's tool schemas generated from a single source of truth - an OpenAPI spec, a shared internal schema definition - rather than hand-maintained separately. Hand-maintained duplication is exactly where the two silently drift apart after the underlying API changes.
When MCP Doesn't Need an API Underneath at All
Worth noting as the exception to everything above: MCP doesn't strictly require an existing API or CLI underneath it. An MCP server can be a self-contained service that does the work directly - wrapping browser automation against changing web UIs, aggregating multiple data sources into one enriched response, or reading from continuously updated materialized views for high-volume, low-latency access rather than hitting a live API on every call. In these cases MCP isn't a wrapper around an existing interface at all; it's the primary interface, built MCP-native from the start because the capability it exposes doesn't have a natural CLI or REST shape to begin with. This is less common than the wrapping pattern, but it's a legitimate and increasingly common architecture for capabilities designed for agent consumption specifically, rather than retrofitted onto something built for humans first.
- API, CLI, and MCP typically share the same underlying business logic - the API does the actual work, while the CLI and MCP server are two different client interfaces built for two different kinds of caller: humans/scripts versus models deciding at runtime.
- MCP's real value is collapsing an M×N integration problem into M+N - each tool exposes one server, each agent implements one client, and any pairing works without bespoke integration code, with the payoff growing past roughly three to five integrations.
- Building an MCP server on top of an existing CLI, rather than reimplementing API calls and auth from scratch, is an increasingly favoured production pattern - it inherits the CLI's already-solved authentication and reduces duplicated logic.
- CLI operates on a pull model where the caller already knows the schema and constructs requests explicitly; MCP operates on a discovery model where the agent inspects what's available at runtime - which is exactly why one suits deterministic scripts and the other suits autonomous reasoning.
- A change to the underlying API propagates to every layer built on top of it, but MCP's typed schema is more brittle to drift than a CLI's flexible argument parsing - keeping both generated from a single source of truth avoids silent divergence.
Numlytics' AI and machine learning consulting practice designs the API, CLI, and MCP layers behind production AI agent integrations as one coherent architecture - not three separately maintained surfaces that quietly drift apart. Speak with a certified consultant about how your existing API and CLI should relate to the MCP layer you're planning to build.