Same tool, different caller
A CLI exposes functionality to a person typing commands. An MCP server exposes functionality to a model deciding what to call. Often they wrap the exact same logic — the difference is who is on the other end and what they need from the interface.
A human at a CLI reads help text, remembers flags, and interprets output with their own judgment. A model needs the tool described in a structured way it can reason about: what the tool does, what arguments it takes, what it returns. MCP provides that structured description; a CLI's --help was written for eyes, not for a scheduler.
Why not just let the model run CLI commands
It is tempting to give a model shell access and let it call your existing CLI. This works in demos and is risky in practice. A CLI's surface is unstructured — the model has to construct command strings, parse free-text output, and guess at error meanings, all of which are error-prone.
More importantly, shell access is a blunt, dangerous capability: a model that can run one command can usually run any command. An MCP server exposes exactly the operations you chose, with typed arguments and defined results, which is both safer and more reliable than hoping the model assembles the right incantation.
When a CLI is still the right answer
If the primary user is a human, build the CLI. Scripting, CI pipelines, and interactive terminal use are all better served by a command than by a protocol designed for models. Not every tool needs an MCP interface, and adding one to a tool no model will call is wasted effort.
Many tools legitimately want both: a CLI for people and an MCP server for agents, sharing the same core logic underneath. That is a reasonable architecture — the two interfaces serve different callers and neither makes the other redundant.
Deciding for your tool
Ask who calls it. Humans in terminals and scripts: CLI. A model in a conversation choosing actions: MCP server. Both audiences: both interfaces over shared logic.
If you are wrapping an existing CLI for model use, resist the urge to just shell out to it. Model the operations you actually want the model to perform as proper MCP tools with typed inputs — you will get more reliable behavior and a far smaller blast radius than handing over the whole command line.