Content
# CLI vs MCP Repo Stats
Side-by-side implementation of the same GitHub repo stats task as a plain CLI
tool and as an MCP server.
## Setup
CLI:
```sh
make cli
.venv/bin/python cli/repo_stats.py https://github.com/pallets/click
```
MCP:
```sh
make mcp
.venv/bin/python mcp/server.py
```
Comparison:
```sh
make compare
```
Set `GITHUB_TOKEN` for higher GitHub REST API rate limits:
```sh
export GITHUB_TOKEN=...
```
## Comparison Results
| repo | cli_tokens | mcp_tokens | mcp/cli ratio | cli_wall_time | mcp_wall_time |
|---|---:|---:|---:|---:|---:|
| pallets/click | 254 | 612 | 2.41 | 2.00s | 1.62s |
| vercel/next.js | 307 | 671 | 2.19 | 3.38s | 2.98s |
| torvalds/linux | 398 | 753 | 1.89 | 4.86s | 4.74s |
## What This Shows
For this narrow one-shot task, the CLI path is cheaper on model tokens because
the model only needs to spend tokens on a shell command and plain stdout. The
MCP path pays a fixed schema cost before any useful result, so it used about
1.9x to 2.4x as many tokens in this run. MCP still makes the contract clearer:
tool names, docstrings, arguments, defaults, and structured results are visible
to the model. Reach for the CLI when the job is simple and throwaway; reach for
MCP when the tool will be reused, composed with other tools, or needs a stable
typed interface.
## Claude Desktop Config
```json
{
"mcpServers": {
"repo-stats": {
"command": "/Users/holdy/projects/mcp_cli_lesson/.venv/bin/python",
"args": ["/Users/holdy/projects/mcp_cli_lesson/mcp/server.py"],
"env": {
"GITHUB_TOKEN": "optional-token-for-higher-rate-limits"
}
}
}
}
```