Suppose a tool can publish a built site. Should it offer a command line interface, an MCP server, or both?
The tempting answer is “MCP for AI, CLI for humans.” That is too simple: agents can run commands, and people can ask an MCP client to call tools. A better question is who decides the next step, and where does the data live?
Start with the caller
Choose a CLI when the caller already has a repeatable sequence: build, test, publish, inspect the result. A shell script or CI job can pass a path, use an exit code to detect failure, and parse JSON when it needs a URL or identifier. The command is also easy to run and debug locally.
# Illustrative command, not a package name
publisher publish ./dist --json
Choose an MCP tool when an assistant needs to discover an operation and call it as part of a conversation. A tool such as publish_page can declare that it accepts content and filename, then return a structured result. The assistant can use that result in its next step. MCP gives the client a standard way to list and call tools; it does not make a publication automatically safe or correct.
| Situation | Starting point |
|---|---|
| A fixed deployment job publishes the same build output | CLI |
| A developer wants one command after a local build | CLI |
| An assistant drafts a small page and asks to publish it | MCP tool accepting content |
| An assistant works with a local directory and its assets | Local MCP tool accepting a path, or CLI |
| A remote assistant has no access to the developer's disk | MCP tool accepting file contents or another upload mechanism |
These are starting points, not hard boundaries. If an agent already has a reliable terminal, invoking the CLI may be the simplest integration. If an application already speaks MCP, a tool can avoid teaching the assistant command syntax and output parsing.
Location matters more than the interface name
Consider a tool argument like publish_path({ path: "./dist" }). With a local MCP server launched over stdio, the server process can usually read that directory. With a remote MCP server over HTTP, ./dist means a path on the server, not the user's laptop. The same string has different consequences depending on the transport.
For a remote client, send the contents explicitly, or upload them through an API that provides a file handle to the server. For a local directory with many related assets, a local tool or CLI is often a better fit. The MCP transport documentation describes stdio and Streamable HTTP; the filesystem boundary follows from where each server runs.
Design the failure path, too
A useful CLI needs stable exit codes, script-friendly output, and a way to provide credentials without an interactive prompt. Keep human progress messages separate from machine-readable output. A useful MCP tool needs a precise input schema and a result that tells the client what succeeded or failed. For a stdio MCP server, stdout is the protocol channel, so ordinary logs belong elsewhere.
Publishing also deserves the same controls through either interface: make the destination clear, inspect what files will leave the machine, keep secrets out of the published bundle, and avoid returning a private claim or edit link as the public viewing URL. If an operation replaces an existing page, make that intent explicit in the arguments or flags.
If you offer both, share the operation
The two interfaces can sit on top of one publishing function. The CLI handles flags, terminal output, and exit codes. The MCP adapter handles tool definitions and structured results. Authentication, upload rules, size limits, and update behavior should come from the shared operation, so the two entry points do not quietly disagree.
My rule of thumb: use a CLI for a known sequence; use MCP when a tool-aware client is choosing actions; use a local interface for local paths. Then add the second interface only when a real caller needs it.
How do you draw that line in your own tools? Have you found cases where an agent calling a CLI works better than an MCP integration?
AI disclosure: An AI assistant drafted this article. The technical distinctions were checked against the MCP transport documentation and an implementation that exposes both CLI and MCP entry points. This post is intended as a discussion of interface design, not a product recommendation.
Top comments (0)