Choosing Between CLI and MCP for Your AI Agent Workflows
I've been building agent workflows for about a year now, and one question keeps coming up from developers: should I use a CLI tool or build an MCP server for this task? It seemed obvious to me at first, but the more I explained it, the more I realized there's genuine confusion here. Let me clear it up.
What are we comparing here?
When I say CLI in this context, I'm not talking about running commands in your terminal. I'm talking about how AI agents invoke external tools. There are two main patterns:
Shell command execution works by executing shell commands directly. The agent essentially runs something like npm run build or python script.py and parses the output.
MCP (Model Context Protocol) is an open protocol developed by Anthropic that uses JSON-RPC 2.0 for communication between AI applications and external systems. Rather than executing shell commands, the agent calls structured tools exposed by an MCP server. The server discovers available tools via the tools/list method, and the agent executes them using tools/call with typed parameters.
The key difference: shell commands give the agent a raw string to execute, while MCP gives the agent structured, type-safe tool definitions with clear input schemas.
When shell commands make sense
Let me give you a concrete example. In my portfolio site, I have scripts that generate redirects from my old WordPress blog posts to new Next.js pages. I didn't build an MCP server for this. Why? Because it's a simple, one-off operation that already existed as a Node script.
Shell commands win when:
- You already have a working script or command
- The task is simple and doesn't need complex state management
- You're prototyping and want to move fast
- The tool is well-established and has a stable CLI interface
Another scenario: I use ffmpeg for audio processing in my projects. Do I want to build an MCP server for ffmpeg? Absolutely not. It's a decades-old tool with a stable CLI interface. The agent just needs to construct the right command string.
The agent doesn't need type-safe tool definitions here. It just needs to pass arguments through to an external process.
When MCP shines
Now here's where MCP becomes worth the investment. I built an MCP server for my RFP search tool. The functionality isn't simple at all. It's a full-text search across thousands of government contracting documents, with filtering, ranking, and AI-powered summaries.
If I had done this as shell commands, the agent would be constructing complex command strings with dozens of arguments. It would be error-prone and hard to maintain. Instead, the MCP server exposes clear tools with proper input schemas: search_rfps(query, filters) and get_rfp_details(id). The agent calls these with typed arguments, and the MCP server handles the complexity.
MCP wins when:
- You have complex, multi-step workflows that need proper structure
- You need type-safe interfaces with JSON Schema for inputs
- You're building something from scratch that will be used repeatedly
- You want the agent to discover available tools dynamically
- You need fine-grained control over what the agent can do
- You want to support both local (STDIO transport) and remote (HTTP transport) deployments
The protocol also supports capability negotiation during connection initialization, so servers can advertise what features they support and clients can adapt accordingly.
What about interacting with APIs?
This comes up a lot. If the agent needs to call a REST API, should it use curl or build an MCP server?
CLI approach means the agent constructs command strings like curl -X GET https://api.example.com/data -H "Authorization: Bearer $TOKEN". It works, but the agent has to get every header, query parameter, and authentication detail right. Get one thing wrong and the call fails.
MCP approach exposes tools like get_data(filters) or search_customers(query). The MCP server handles the HTTP calls, authentication, error handling, and retries internally. The agent just passes structured parameters.
For a quick one-off call, CLI is fine. For anything you use regularly, MCP is cleaner. The server can handle OAuth token refresh, rate limiting, and proper error messages. Your agent does not need to know about any of that.
The decision framework
Here's how I think about it now:
Start with shell commands if: the task is a simple wrapper around an existing command, it's a one-off or low-frequency operation, or you just need something working quickly.
Move to MCP if: the tool has complex inputs that need validation, will be used frequently in agent workflows, or needs proper tool discovery. The overhead of setting up an MCP server only makes sense when the complexity of the tool justifies it.
There's also a learning curve consideration. Your team needs to understand how MCP works — it's an open protocol with SDKs for multiple languages. If you're the only one building agent tools and you just need something done, shell commands are fine. If you're building tools for a team or want reusable infrastructure, MCP pays off.
What about combining both?
You can, and you should when appropriate. I have an MCP server for my blog that handles complex operations like generating translations or managing post metadata. But it still calls shell commands internally for things like running Node scripts or accessing git. MCP is the orchestration layer, shell commands are one of the tools it can use.
Don't think of it as either/or. Think of MCP as a way to give agents a cleaner interface to your existing tools, including shell commands. The protocol uses JSON-RPC 2.0 messages regardless of transport, whether that's STDIO for local processes or Streamable HTTP for remote servers.
The next time you're building something for an agent, ask yourself: is this a simple wrapper around an existing command, or does it need its own structured interface with type-safe tool definitions? That answer will tell you which path to take.