Choosing CLI vs MCP for Enterprise AI Agents: A Hybrid Approach Balancing Cost and Effectiveness
The article compares CLI and MCP as integration methods for enterprise AI agents, presents benchmark data showing CLI's lower cost and higher reliability, explains why MCP is needed for compliance and structured data, and recommends a "CLI‑first, MCP‑supplement" architecture with reusable Python or Java implementations across multiple AI tools.
1. From a Real‑World Scenario
A finance employee asks whether an AI agent can submit a reimbursement request through the ERP system. The author frames the problem as choosing between exposing ERP capabilities via a Command‑Line Interface (CLI) or via the Model Context Protocol (MCP).
2. What CLI and MCP Actually Are
CLI (Command Line Interface) lets a user type textual commands such as git commit -m "fix bug" or docker ps. It is stateless, simple, and has existed long before graphical interfaces.
MCP (Model Context Protocol) is a JSON‑RPC‑style standard released by Anthropic at the end of 2024. It defines a uniform schema for tools so that any AI model that implements the protocol can invoke external capabilities without custom plugins.
3. Benchmark Comparison (2026 Community Test)
A community benchmark ran the same batch of tasks using CLI and MCP. The results were:
Single‑call cost: CLI is the baseline; MCP costs 10‑32× more.
Task‑completion reliability: CLI 100 %, MCP 72 %.
Initialization overhead: CLI is almost zero; MCP must load a schema that consumes tens of thousands of tokens.
Error recovery: CLI simply re‑executes the command; MCP requires reconnection and schema reload.
Why the Gap Is So Large
Schema is a token black hole – loading a GitHub MCP server consumes ~55 000 tokens; an ERP with dozens of operations can require 80 000‑120 000 tokens, eating a quarter of a 200 K context window.
LLMs are already trained on billions of CLI examples (Shell scripts, man pages, Stack Overflow). MCP was defined only in late 2024, so models have almost no exposure to its JSON‑RPC format.
Composition capability – CLI commands can be piped, redirected, and orchestrated in scripts, enabling multi‑step workflows without additional token consumption. MCP can only invoke one tool at a time, each round incurring token overhead.
4. Detailed Dimension‑by‑Dimension Comparison
Model adaptation cost : CLI – zero (models already understand commands). MCP – requires a custom protocol wrapper.
Composition ability : CLI – arbitrary pipelines and scripts. MCP – limited to the set of tools exposed by the server.
Debugging : CLI – copy‑paste the command and run it directly. MCP – must inspect server logs and handle JSON responses.
Authentication : CLI reuses the local OAuth login state. MCP needs separate credential configuration per server.
Operations : CLI is stateless, exits after execution. MCP requires a long‑running server process.
Context efficiency : CLI fetches help on demand (few tokens). MCP loads the whole schema upfront (many tokens).
Standardisation : CLI formats differ across tools. MCP provides a unified JSON‑RPC contract.
Type safety : CLI parameters are plain strings. MCP schema defines explicit types.
Bot identity : CLI is awkward for bot accounts; MCP natively supports bot identities.
5. Scenarios Where MCP Adds Value
AI‑native integration: tools like Claude Code or Cursor ship with built‑in MCP support.
Structured data exchange: CI/CD pipelines or data platforms that need strict type guarantees.
Bot‑identity operations: scheduled syncs, batch processing, or system‑level automation.
Ecosystem compatibility: one implementation can be consumed by any MCP‑compatible platform.
6. Recommended Hybrid Architecture (CLI Primary, MCP Supplement)
The author proposes a three‑layer design:
First layer – existing ERP backend APIs.
Second layer – a CLI surface covering 200+ commands, exposing OAuth‑based personal login, and supporting JSON, table, or CSV output.
Third layer – three exit points:
AI agents call CLI commands directly for everyday tasks (token‑cheap).
Skill orchestration combines multiple CLI commands into complex workflows.
An MCP server thinly wraps the CLI for scenarios that require a persistent tool interface.
All business logic lives in the CLI implementation; the MCP server simply forwards calls to the same CLI binary, avoiding duplicate code.
6.1 Command Design Guidelines
Commands follow the pattern product + domain + action. Example commands (Python click implementation):
# erp_cli/cli.py
import click, requests
@click.group()
def cli():
"ERP command‑line tool – let AI agents operate ERP"
pass
@click.group()
def 报销():
"报销相关操作"
pass
@报销.command("提交")
@click.option("--type", "reimb_type", required=True, type=click.Choice(["差旅", "办公", "餐饮"]))
@click.option("--amount", required=True, type=float)
@click.option("--project", required=True)
def 报销提交(reimb_type, amount, project, description=""):
"提交报销单"
resp = requests.post("https://erp.internal/api/reimbursement", json={"type": reimb_type, "amount": amount, "project": project, "description": description}, headers=auth_headers())
result = resp.json()
click.echo(f"✅ 报销单已提交,单号: {result['id']}")6.2 Java Implementation (Picocli)
@Command(name = "提交", description = "提交报销单")
public class ReimburseSubmitCommand implements Callable<Integer> {
@Option(names = "--type", required = true, description = "报销类型: 差旅/办公/餐饮")
private String type;
@Option(names = "--amount", required = true, description = "金额")
private double amount;
@Option(names = "--project", required = true, description = "项目名称")
private String project;
@Override
public Integer call() throws Exception {
// Directly inject Spring service when ERP runs as a Spring Boot app
reimbursementService.submit(type, amount, project, "");
System.out.println("✅ 报销单已提交,单号: " + result.getId());
return 0;
}
}6.3 Skill Orchestration (YAML)
# skills/travel-reimburse.yaml
name: 差旅报销
description: 提交差旅报销并跟踪审批
parameters:
- name: amount
type: number
required: true
- name: project
type: string
required: true
steps:
- erp 报销 提交 --type=差旅 --amount={amount} --project={project}
- 等待返回的单号
- erp 报销 详情 --id={单号}
- if "待主管审批" in status: 通知主管
- if 48 小时未审批: 自动催办6.4 Authentication and Security
First‑time use runs erp auth login to obtain an OAuth token. Scopes are granted per domain (e.g., erp auth scope --add=报销,项目). The system enforces least‑privilege, requires user confirmation for high‑value actions, logs every CLI invocation, and rotates tokens regularly.
7. Connecting the CLI to Various AI Tools
7.1 Claude Code (direct CLI)
Install the CLI in the system PATH and let Claude Code issue natural‑language requests such as “帮我提交一个差旅报销,金额 3200,项目是智慧园区”. Claude Code parses the request, runs
erp 报销 提交 --type=差旅 --amount=3200 --project=智慧园区, and returns the result.
7.2 OpenClaw Plugin (MCP wrapper)
# openclaw_erp_plugin/manifest.yaml
name: erp-assistant
version: 1.0.0
description: 企业 ERP 系统助手
permissions:
- shell:execute # openclaw_erp_plugin/plugin.py
import subprocess
class ERPPlugin:
"OpenClaw 插件:通过 CLI 调用 ERP"
def get_tools(self):
return [{
"name": "erp_reimburse_submit",
"description": "提交报销单",
"parameters": {"type": "object", "properties": {"reimb_type": {"type": "string", "enum": ["差旅", "办公", "餐饮"]}, "amount": {"type": "number"}, "project": {"type": "string"}}, "required": ["reimb_type", "amount", "project"]}
}]
def execute(self, tool_name, params):
cmd = f"erp 报销 提交 --type={params['reimb_type']} --amount={params['amount']} --project={params['project']}"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return result.stdout7.3 Cursor / IDEs (CLI or MCP)
IDE terminals can call the CLI directly. For MCP, the same thin server ( erp_mcp_server.py) exposes the JSON‑RPC endpoint, and the IDE config points to python erp_mcp_server.py.
8. Enterprise‑Built AI Agent with Spring AI
Spring AI can register functions that invoke the CLI via ProcessBuilder. Example bean:
@Bean
@Description("提交报销单。参数:type(差旅/办公/餐饮), amount(金额), project(项目名)")
public Function<ReimburseRequest, String> submitReimbursement() {
return req -> {
ProcessBuilder pb = new ProcessBuilder(
"erp", "报销", "提交",
"--type=" + req.getType(),
"--amount=" + req.getAmount(),
"--project=" + req.getProject()
);
pb.redirectErrorStream(true);
Process p = pb.start();
String output = new String(p.getInputStream().readAllBytes());
p.waitFor();
return output;
};
}The same ReimbursementService is injected into the CLI command, the Spring AI function, and a REST controller that also hosts an MCP endpoint, ensuring the business logic is written once.
9. Final Principle
CLI provides the lightweight, token‑efficient core that LLMs already master. MCP offers a thin, standards‑based wrapper for compliance, type safety, and ecosystem compatibility. The optimal enterprise setup uses CLI as the primary interface and MCP as a supplemental layer, sharing a single service implementation across REST, CLI, AI functions, and MCP.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect's Ambition
Observations, practice, and musings of an architect. Here we discuss technical implementations and career development; dissect complex systems and build cognitive frameworks. Ambitious yet grounded. Changing the world with code, connecting like‑minded readers with words.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
