Repository: https://github.com/doggy8088/mcp-cli Stars: 113 | Forks: 14 | Language: Rust | License: MIT npm: @willh/mcp-cli 最後更新: 2026-06-10


1. 專案概覽 (Project Overview)

1.1 什麼是 mcp-cli?

mcp-cli 是一套以 Rust 撰寫的輕量級 CLI (Command-Line Interface; 命令列介面) 工具與函式庫,專門用來與 MCP (Model Context Protocol; 模型上下文協定) 伺服器互動。

MCP 是一套讓 AI 模型透過標準化協定存取外部工具、API 與資料來源的開放標準。傳統做法是將所有 MCP tool schema 載入 AI 的 context window (上下文視窗),往往耗用數千 token。mcp-cli 採用「按需載入」的 CLI 模式,大幅降低 token 消耗,同時保留完整的 MCP 互動能力。

1.2 核心特色

特色說明
輕量單一 Binary純 Rust 實作,零外部 runtime dependency (執行期依賴),編譯後為獨立執行檔
Shell 友善call 指令輸出 JSON,可搭配 jq、pipe 與 shell script
Agent 導向專為 AI coding agents (如 Gemini CLI、Claude Code) 設計
雙傳輸協定同時支援 stdio (標準輸入輸出) 與 HTTP MCP 伺服器
連線池 DaemonLazy-spawn daemon 保留暖連線 (warm connection),預設 60 秒閒置逾時
Tool 過濾可透過 allowedTools / disabledTools 限制每個伺服器允許的工具
Rust Library提供 McpClient API,可嵌入其他 Rust 應用程式
可操作錯誤訊息所有錯誤包含結構化代碼、可用選項與修復建議

1.3 專案起源

此專案源自 Philipp SchmidBun/TypeScript mcp-cli,後由 Antigravity 完整改寫為高度最佳化的純 Rust 版本。目前由台灣知名技術社群貢獻者 Will 保哥 (doggy8088) 維護。


2. 核心架構 (Core Architecture)

2.1 模組架構總覽

mcp-cli 採用清晰的分層架構,將 CLI 界面、客戶端連線、設定管理與連線池 daemon 分離:


graph TB
    subgraph "CLI 層 (main.rs)"
        MAIN["main.rs
指令解析 + 路由"] end subgraph "指令層 (commands/)" LIST["list.rs
列出所有 servers"] INFO["info.rs
查看 server/tool 詳情"] GREP["grep.rs
搜尋 tools"] CALL["call.rs
呼叫 tool"] end subgraph "客戶端層 (client.rs)" STDIO["StdioClient
stdio 傳輸"] HTTP["HttpClient
HTTP/SSE 傳輸"] CONN["McpConnection
統一連線介面"] end subgraph "基礎設施層" CONFIG["config.rs
設定載入 + env 替換"] DAEMON["daemon.rs
連線池 daemon"] DCLIENT["daemon_client.rs
daemon IPC 客戶端"] API["api.rs
McpClient 高階 API"] ERRORS["errors.rs
結構化錯誤"] OUTPUT["output.rs
格式化輸出"] end MAIN --> LIST & INFO & GREP & CALL LIST & INFO & GREP & CALL --> CONN CONN --> STDIO & HTTP CONN --> DCLIENT DCLIENT --> DAEMON LIST & INFO & GREP & CALL --> CONFIG API --> CONN & CONFIG MAIN --> ERRORS LIST & INFO & GREP & CALL --> OUTPUT style MAIN fill:#4a90d9,color:#fff style DAEMON fill:#e8a838,color:#fff style API fill:#50c878,color:#fff

2.2 連線池 Daemon 機制

mcp-cli 最重要的架構設計是 lazy-spawn connection pooling daemon (延遲啟動連線池守護程序)。每個 MCP server 擁有獨立的 daemon,透過 Unix domain socket (Unix 域套接字) 進行 IPC (Inter-Process Communication; 行程間通訊):


sequenceDiagram
    participant User as 使用者
    participant CLI as mcp-cli
    participant Socket as Unix Socket
/tmp/mcp-cli-{uid}/ participant Daemon as Daemon 程序 participant MCP as MCP Server User->>CLI: mcp-cli call server tool '{}' CLI->>Socket: 檢查 server.sock 是否存在? alt Socket 不存在 (首次呼叫) CLI->>Daemon: Fork 背景 daemon Daemon->>MCP: 建立連線 (stdio/HTTP) Daemon->>Socket: 建立 Unix socket Daemon->>Daemon: 啟動 60s idle timer CLI->>Socket: 連線到 socket else Socket 已存在 (後續呼叫) CLI->>Socket: 直接連線到 socket end CLI->>Daemon: 送出 JSON-RPC 請求 Daemon->>MCP: 轉發請求 MCP-->>Daemon: 回傳結果 Daemon-->>CLI: 回傳 JSON 結果 Daemon->>Daemon: 重置 idle timer CLI-->>User: 輸出結果 Note over Daemon: 60 秒無請求後自動終止

2.3 設定檔解析順序

CLI 依以下順序尋找 mcp_servers.json 設定檔:

  1. MCP_CONFIG_PATH 環境變數
  2. -c/--config 命令列參數
  3. ./mcp_servers.json (當前目錄)
  4. ~/.mcp_servers.json (家目錄)
  5. ~/.config/mcp/mcp_servers.json (XDG 設定目錄)

2.4 錯誤處理機制

所有錯誤都透過 CliError 結構化表達,包含四個層級的資訊:

欄位說明範例
code錯誤分類代碼ClientErrorServerErrorNetworkErrorAuthError
error_type錯誤類型字串AMBIGUOUS_COMMANDSERVER_NOT_FOUND
message人類可讀的錯誤描述Server "github" not found in config
suggestion修復建議Use one of: mcp-cli info filesystem

短暫性錯誤 (如 ECONNREFUSED、HTTP 502/503/504/429) 會自動以 exponential backoff (指數退避) 重試,預設最多 3 次。


3. 安裝與設定 (Installation & Setup)

3.1 安裝方式

有三種安裝方式可供選擇:

方式一:一鍵安裝腳本 (推薦)

1curl -fsSL https://raw.githubusercontent.com/doggy8088/mcp-cli/main/install.sh | bash

方式二:透過 Cargo 編譯安裝

1# 需要先安裝 Rust toolchain
2cargo install --git https://github.com/doggy8088/mcp-cli

方式三:透過 npm 安裝

1npm install -g @willh/mcp-cli

npm 套件是一層薄 wrapper,會從 GitHub Release 下載對應版本的原生 binary。

3.2 驗證安裝

1mcp-cli --version
2# 輸出: mcp-cli v0.1.1

3.3 建立設定檔

在專案目錄或 ~/.config/mcp/ 建立 mcp_servers.json

 1{
 2  "mcpServers": {
 3    "filesystem": {
 4      "command": "npx",
 5      "args": [
 6        "-y",
 7        "@modelcontextprotocol/server-filesystem",
 8        "."
 9      ]
10    },
11    "deepwiki": {
12      "url": "https://mcp.deepwiki.com/mcp"
13    }
14  }
15}

此設定檔格式完全相容 Claude Desktop、Gemini CLI 與 VS Code 的 MCP 設定。

3.4 設定檔進階功能

環境變數替換:在設定檔中使用 ${VAR_NAME} 語法,CLI 載入時會自動替換:

 1{
 2  "mcpServers": {
 3    "github": {
 4      "command": "npx",
 5      "args": ["-y", "@modelcontextprotocol/server-github"],
 6      "env": {
 7        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
 8      }
 9    }
10  }
11}

Tool 過濾:透過 allowedToolsdisabledTools 控制可用工具:

 1{
 2  "mcpServers": {
 3    "filesystem": {
 4      "command": "npx",
 5      "args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
 6      "allowedTools": ["read_*", "list_*"],
 7      "disabledTools": ["delete_*"]
 8    }
 9  }
10}

disabledTools 的優先順序高於 allowedTools,支援 glob pattern (*?)。

3.5 環境變數一覽

變數說明預設值
MCP_CONFIG_PATH設定檔路徑
MCP_DEBUG啟用 debug 輸出false
MCP_TIMEOUTRequest timeout (秒)1800 (30 分鐘)
MCP_CONCURRENCY平行處理的 servers 數量5
MCP_MAX_RETRIES短暫錯誤的 retry 次數3
MCP_RETRY_DELAYRetry base delay (毫秒)1000
MCP_STRICT_ENV${VAR} 缺失時是否報錯true
MCP_NO_DAEMON停用連線快取false
MCP_DAEMON_TIMEOUTDaemon idle timeout (秒)60

4. 使用方式與程式碼範例 (Usage & Code Examples)

4.1 指令總覽

1mcp-cli [options]                              列出所有 servers 與 tools
2mcp-cli [options] info <server>                顯示 server 詳情
3mcp-cli [options] info <server> <tool>         顯示 tool schema
4mcp-cli [options] info <server>/<tool>         同上 (斜線分隔格式)
5mcp-cli [options] grep <pattern>               用 glob pattern 搜尋 tools
6mcp-cli [options] call <server> <tool>         呼叫 tool (無 args 時從 stdin 讀取)
7mcp-cli [options] call <server> <tool> <json>  使用 JSON arguments 呼叫 tool
選項說明
-h, --help顯示說明
-v, --version顯示版本號
-d, --with-descriptions顯示 tool 描述
-c, --config <path>指定設定檔路徑

4.2 範例一:探索與查詢可用工具

這是最基本的工作流程,適合剛開始使用時了解有哪些 MCP server 與 tool 可用。

 1# 步驟 1:列出所有 servers 與 tools
 2$ mcp-cli
 3github
 4  • search_repositories
 5  • get_file_contents
 6  • create_or_update_file
 7filesystem
 8  • read_file
 9  • write_file
10  • list_directory
11
12# 步驟 2:加上 -d 顯示每個 tool 的描述
13$ mcp-cli -d
14github
15  • search_repositories - Search for GitHub repositories
16  • get_file_contents - Get contents of a file or directory
17filesystem
18  • read_file - Read the contents of a file
19  • write_file - Write content to a file
20
21# 步驟 3:用 glob pattern 搜尋特定 tool
22$ mcp-cli grep "*file*"
23github/get_file_contents
24github/create_or_update_file
25filesystem/read_file
26filesystem/write_file
27
28# 步驟 4:查看特定 tool 的完整 schema
29$ mcp-cli info filesystem read_file
30Tool: read_file
31Server: filesystem
32
33Description:
34  Read the contents of a file
35
36Input Schema:
37  {
38    "type": "object",
39    "properties": {
40      "path": { "type": "string", "description": "Path to the file" }
41    },
42    "required": ["path"]
43  }

4.3 範例二:呼叫 Tool 並串接 Shell Pipeline

call 指令輸出原始 JSON,非常適合搭配 jq 與 shell 工具進行資料處理。

 1# 基本呼叫:讀取檔案
 2$ mcp-cli call filesystem read_file '{"path": "./README.md"}'
 3
 4# 搭配 jq 擷取特定欄位
 5$ mcp-cli call github search_repositories '{"query": "mcp server", "per_page": 5}' \
 6  | jq -r '.content[0].text | fromjson | .items[].html_url'
 7
 8# 從 stdin 讀取 JSON(避免 shell escaping 問題)
 9$ echo '{"path": "./README.md"}' | mcp-cli call filesystem read_file
10
11# 使用 heredoc 處理含特殊字元的 JSON
12$ mcp-cli call server tool <<EOF
13{"content": "Text with 'single quotes' and \"double quotes\""}
14EOF
15
16# 進階串接:搜尋檔案後逐一讀取內容
17$ mcp-cli call filesystem search_files '{"path": ".", "pattern": "*.md"}' \
18  | jq -r '.content[0].text | split("\n")[]' \
19  | while read file; do
20      echo "=== $file ==="
21      mcp-cli call filesystem read_file "{\"path\": \"$file\"}" \
22        | jq -r '.content[0].text'
23    done
24
25# 條件式執行:先確認檔案存在再讀取
26$ mcp-cli call filesystem list_directory '{"path": "."}' \
27  | jq -e '.content[0].text | contains("README.md")' \
28  && mcp-cli call filesystem read_file '{"path": "./README.md"}'
29
30# 錯誤處理:在腳本中安全地呼叫 tool
31$ if result=$(mcp-cli call filesystem read_file '{"path": "./config.json"}' 2>/dev/null); then
32    echo "$result" | jq '.content[0].text | fromjson'
33  else
34    echo "File not found, using defaults"
35  fi

4.4 範例三:作為 Rust Library 嵌入使用

mcp-cli 也可以作為 Rust crate 在其他專案中使用。

Cargo.toml 加入依賴

1[dependencies]
2mcp-cli = { git = "https://github.com/doggy8088/mcp-cli" }

使用 McpClient 高階 API

 1use mcp_cli::McpClient;
 2
 3#[tokio::main]
 4async fn main() -> Result<(), mcp_cli::CliError> {
 5    // 載入 mcp_servers.json 設定
 6    let client = McpClient::load(None)?;
 7
 8    // 列出所有 server 名稱
 9    for server in client.server_names() {
10        // 列出每個 server 的 tools
11        let tools = client.list_tools(&server).await?;
12        println!("{}: {} tools", server, tools.len());
13
14        // 顯示每個 tool 的名稱
15        for tool in &tools {
16            println!("  - {}", tool.name);
17        }
18    }
19
20    // 呼叫特定 tool
21    let result = client
22        .call_tool(
23            "filesystem",
24            "read_file",
25            serde_json::json!({ "path": "./README.md" }),
26        )
27        .await?;
28
29    // 格式化並輸出結果
30    println!("{}", mcp_cli::output::format_tool_result(&result));
31    Ok(())
32}

底層模組直接控制

若需要更精細的控制,可直接使用底層模組:

 1use mcp_cli::prelude::*;
 2
 3#[tokio::main]
 4async fn main() -> Result<(), CliError> {
 5    // 手動載入設定
 6    let config = mcp_cli::config::load_config(Some("./my_config.json"))?;
 7
 8    // 取得特定 server 設定
 9    let server_config = mcp_cli::config::get_server_config(&config, "filesystem")?;
10
11    // 手動建立連線
12    let connection = mcp_cli::client::get_connection("filesystem", &server_config).await?;
13
14    // 列出 tools
15    let tools = connection.list_tools().await?;
16    println!("Available tools: {:?}", tools);
17
18    // 呼叫 tool
19    let result = connection
20        .call_tool("read_file", serde_json::json!({"path": "."}))
21        .await?;
22
23    // 關閉連線
24    connection.close().await?;
25    Ok(())
26}

5. 技術細節深度解析 (Technical Deep Dive)

5.1 Rust 原始碼結構

 1src/
 2├── main.rs          # CLI 進入點、指令解析、daemon 模式分支
 3├── lib.rs           # Library 公開介面 (re-exports + prelude)
 4├── api.rs           # McpClient 高階 API (library 使用者的主要介面)
 5├── client.rs        # StdioClient + HttpClient + McpConnection 統一介面
 6├── config.rs        # 設定檔載入、env 替換、tool filtering、hash 計算
 7├── daemon.rs        # 連線池 daemon 實作 (Unix socket listener)
 8├── daemon_client.rs # Daemon IPC 客戶端 + orphan 清理
 9├── errors.rs        # CliError 結構化錯誤系統
10├── output.rs        # ServerInfo / ToolInfo 格式化輸出
11└── commands/
12    ├── mod.rs       # 指令模組匯出
13    ├── list.rs      # `mcp-cli` (無子指令) — 列出所有 servers
14    ├── info.rs      # `mcp-cli info` — 查看 server/tool 詳情
15    ├── grep.rs      # `mcp-cli grep` — 搜尋 tools
16    └── call.rs      # `mcp-cli call` — 呼叫 tool

5.2 雙傳輸協定 (Dual Transport)

mcp-cli 透過 ServerConfig enum (列舉) 支援兩種傳輸協定:

傳輸方式設定格式適用情境
Stdio"command": "npx", "args": [...]本地 MCP server (透過 subprocess 啟動)
HTTP"url": "https://..."遠端 MCP server (HTTP + SSE 串流)

Stdio 模式使用 JSON-RPC over stdin/stdout,透過 tokio::process::Command 非同步管理子程序。HTTP 模式使用 reqwest 搭配 Server-Sent Events (SSE; 伺服器推送事件) 串流接收回應。

5.3 Daemon 連線池設計

Daemon 機制是 mcp-cli 最核心的效能最佳化:

  1. 首次呼叫:CLI 偵測到 /tmp/mcp-cli-{uid}/server.sock 不存在時,fork 自身為 daemon 模式 (--daemon flag)
  2. Daemon 啟動:建立 MCP server 連線 + Unix socket listener + PID file (含 config hash)
  3. 後續呼叫:CLI 直接透過 Unix socket 與 daemon 通訊,跳過 MCP server 啟動延遲
  4. Config 偵測:若設定檔 hash 變更,daemon 會被 respawn
  5. Idle timeout:60 秒無請求後 daemon 自動終止,清理 socket + PID file
  6. Fallback:daemon spawn 逾時 (5 秒) 時,退回 direct connection

5.4 Tool Filtering 實作

Tool filtering 使用 glob-to-regex 轉換,支援 * (任意字元) 和 ? (單一字元):

 1// 實際的 matching 邏輯 (簡化)
 2fn matches_pattern(name: &str, pattern: &str) -> bool {
 3    // 將 glob pattern 轉換為 regex
 4    // "*" -> ".*", "?" -> "."
 5    // Case-insensitive matching
 6}
 7
 8fn is_tool_allowed(tool_name: &str, config: &ServerConfig) -> bool {
 9    // 1. 先檢查 disabledTools -> 命中則 return false
10    // 2. 再檢查 allowedTools -> 有設定時必須命中才 return true
11    // 3. 兩者都未設定 -> return true (全部允許)
12}

5.5 編譯最佳化

Cargo.toml 中的 [profile.release] 設定了極致的 binary 最佳化:

1[profile.release]
2opt-level = 3      # 最高最佳化等級
3lto = true          # Link-Time Optimization (連結期最佳化)
4codegen-units = 1   # 單一編譯單元 (更慢的編譯,更快的 binary)
5panic = "abort"     # Panic 時直接 abort (減少 binary 大小)
6strip = true        # 移除 debug symbols

這些設定讓最終 binary 體積小、啟動快,特別適合作為 CLI 工具使用。

5.6 指令歧義偵測

main.rs 中實作了智慧型指令歧義偵測。當使用者輸入 mcp-cli server tool (缺少子指令) 時,CLI 不會猜測意圖,而是明確回報:

1Error [AMBIGUOUS_COMMAND]: Ambiguous command: did you mean to call a tool or view info?
2  Details: Received: mcp-cli filesystem read_file
3  Suggestion: Use 'mcp-cli call filesystem read_file' to execute,
4              or 'mcp-cli info filesystem read_file' to view schema

同時也會偵測常見的錯誤子指令 (如 runexecutelistget) 並提供正確的替代建議。


6. 與生態系的關係 (Ecosystem Relationships)

6.1 MCP 生態系定位


graph LR
    subgraph "AI Agents"
        CC["Claude Code"]
        GC["Gemini CLI"]
        OC["OpenCode"]
        CUR["Cursor"]
    end

    subgraph "MCP 存取方式"
        NATIVE["原生 MCP SDK
(載入全部 schema)"] MCPCLI["mcp-cli
(按需 CLI 存取)"] end subgraph "MCP Servers" FS["filesystem
檔案系統"] GH["github
GitHub API"] DW["deepwiki
技術文件"] DB["sqlite
資料庫"] CUSTOM["自訂 server"] end CC --> NATIVE & MCPCLI GC --> MCPCLI OC --> MCPCLI CUR --> NATIVE NATIVE --> FS & GH & DW & DB & CUSTOM MCPCLI --> FS & GH & DW & DB & CUSTOM style MCPCLI fill:#e8a838,color:#fff,stroke:#d4942e style NATIVE fill:#ccc,color:#333

6.2 與原生 MCP SDK 的比較

面向原生 MCP SDKmcp-cli
Token 消耗高 (載入全部 tool schema)低 (按需查詢)
啟動速度每次都需初始化連線Daemon 暖連線
整合方式程式庫嵌入CLI + Shell pipeline
適用場景內建 MCP 支援的 IDE任何支援 shell 的 agent
組合彈性受限於 SDK API可搭配任何 Unix 工具

6.3 與其他 AI Agent 工具的整合

方式一:System Prompt 整合

mcp-cli 的使用說明加入 AI agent 的 system prompt,讓 agent 透過 shell 呼叫 MCP tool。

方式二:SKILL.md Agent Skill

對支援 Agent Skills 的工具 (如 Gemini CLI、Claude Code),可直接使用 repo 中的 SKILL.md 作為技能文件。

6.4 設定檔相容性

mcp_servers.json 的格式完全相容以下工具:

  • Claude Desktop (claude_desktop_config.jsonmcpServers 段落)
  • Gemini CLI
  • VS Code MCP 擴充功能
  • 其他遵循 MCP 標準設定格式的工具

7. 優缺點分析 (Strengths & Limitations)

7.1 優點

面向詳細說明
效能Rust 原生編譯 + release 最佳化 (LTO + strip),啟動與執行速度極快
Token 節省按需載入 tool schema,不需將全部 schema 塞入 context window
零依賴單一 binary,不需要 Node.js、Python 或其他 runtime
Shell 整合JSON 輸出 + pipe 友善,可無縫融入 Unix 工具鏈
連線池Daemon 機制避免重複啟動 MCP server,大幅降低延遲
錯誤訊息品質結構化錯誤 + 修復建議,對人類與 AI agent 都友善
Tool 過濾可精確控制每個 server 暴露的工具,提升安全性
設定相容與 Claude Desktop、Gemini CLI 等主流工具共用設定檔
雙用途同時提供 CLI binary 與 Rust library API

7.2 限制

面向詳細說明
平台支援Daemon 使用 Unix domain socket,Windows 支援需要額外處理
學習曲線需要理解 MCP 協定基本概念
無 GUI純 CLI 工具,沒有圖形介面或 TUI
版本尚早v0.1.1,API 可能在後續版本有 breaking changes
僅限 MCP專為 MCP 設計,無法直接用於其他 RPC 協定
Daemon 清理異常終止時可能留下 orphaned socket 需手動清理

7.3 適用場景

最適合

  • AI coding agent 需要存取 MCP server 但想節省 token
  • 需要在 shell script 中自動化 MCP 操作
  • 在 CI/CD pipeline (持續整合/持續部署流水線) 中操作 MCP 工具
  • 多個 agent 或工具需要共享 MCP 連線池

不太適合

  • 需要即時 streaming UI 的應用程式
  • 需要在瀏覽器中直接使用 MCP 的場景
  • 只使用單一 IDE (已內建 MCP 支援) 的開發者

7.4 總結

mcp-cli 是一個設計精良的 Rust CLI 工具,巧妙地解決了 AI agent 使用 MCP 時的 token 消耗問題。透過連線池 daemon、按需載入與 shell 友善的設計,讓任何支援 shell 的 AI agent 都能高效存取 MCP 工具生態系。對於在多個 AI agent 間共享 MCP 設定、或需要在自動化腳本中操作 MCP 的場景,mcp-cli 是目前最佳的解決方案之一。