Article · Writing

用 Gradio 建立 MCP Server:讓 Python 函式成為可呼叫的工具

用 Gradio 將一個有型別與說明的 Python 函式暴露成 MCP tool,檢查本地 endpoint,再準備部署到 Hugging Face Spaces。

7 分鐘閱讀

Evidence trail

Provenance

這篇內容的 canonical URL 是 /writing/using-gradio-mcp-to-create-a-server/,發布日期為 2025年6月23日。

這篇內容也保留在其 Series 關係中;正文不需要依賴前一篇才能閱讀。

相容的歷史路徑:/posts/using-gradio-mcp-to-create-a-server/

文章目錄

有網頁介面,不代表它已經是 MCP Server

Gradio 很容易做出一個可以點擊的 Python 網頁,但 MCP 客戶端需要的不是按鈕,而是一組可探索、可呼叫、具有輸入 schema 的工具。兩者的差別在於:網頁介面服務人,MCP endpoint 服務能替模型呼叫工具的客戶端。

Gradio 的 MCP integration 把這個轉換縮成一個明確的開關:launch(mcp_server=True)。它仍會啟動一般 Gradio UI,同時產生 MCP 入口;函式的名稱、型別註記與 docstring 會影響工具名稱、參數與說明。因此真正要設計的是函式契約,而不是先畫一個漂亮的介面。

先做一個最小、可檢查的工具

先建立隔離的 Python 環境,再安裝 Gradio 的 MCP extra:

python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
pip install "gradio[mcp]"

下面的範例只做一件事:計算文字中某個字元出現幾次。它不依賴外部 API,所以可以先把「函式如何變成 MCP tool」和情感分析、模型服務等其他變因分開。

import gradio as gr


def letter_counter(word: str, letter: str) -> int:
    """Count how many times a letter appears in text."""
    return word.lower().count(letter.lower())


demo = gr.Interface(
    fn=letter_counter,
    inputs=[gr.Textbox("strawberry"), gr.Textbox("r")],
    outputs=gr.Number(),
    api_name="predict",
)


if __name__ == "__main__":
    demo.launch(mcp_server=True)

這段程式有三個值得保留的設計。函式的 type hints 讓工具參數有可判讀的型別;docstring 提供模型需要的用途說明;launch(mcp_server=True) 才真正開啟 MCP integration。若函式名稱或說明含糊,客戶端即使連線成功,模型仍可能不知道什麼時候該用它。

Gradio 會提供哪些入口?

執行 python app.py 後,Gradio 會啟動一般網頁介面,並在 console 印出 MCP URL。官方目前的格式是:

http://<host>:<port>/gradio_api/mcp/

工具 schema 可從下列路徑檢查:

http://<host>:<port>/gradio_api/mcp/schema

也可以在 Gradio 網頁頁尾開啟 View API,再切到 MCP 面板,取得要貼到 MCP 客戶端的設定。對應第 5 篇的遠端設定會是:

{
  "mcpServers": {
    "letter-counter": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:7860/gradio_api/mcp/"
    }
  }
}

這裡使用的是 Streamable HTTP 的單一 endpoint;不要把舊文章中的 /gradio_api/mcp/sse 當成所有版本都適用的固定網址。若某個 client 只支援 legacy SSE,應先查它的相容性說明,或改用伺服器與 client 都明確支援的 transport。

工具的輸入契約比 UI 更重要

Gradio 會把 API endpoint 轉換成 MCP tool,但這不會自動替你決定安全邊界。函式是否會寫檔、呼叫外部 API、消耗 GPU 或處理使用者秘密,都應該在工具說明與伺服器設計中明確表達。尤其不要因為工具能從 UI 執行,就假設任何 MCP client 都應該自動批准它。

如果工具需要從請求讀取使用者憑證,Gradio 支援把 gr.Request 或特定的 gr.Header 參數注入函式。這種方式讓伺服器可以讀取 header,再把它轉交給真正的後端服務;token 不應硬編碼在 Python 檔案,也不應由模型自行「猜」出來。公開 demo 可以不需要認證,私有 Space 則必須在 client 端帶上合適的 token。

本地測試應該驗證什麼?

先在瀏覽器確認 Gradio UI 能接受輸入,再檢查 /gradio_api/mcp/schema 是否列出預期工具、參數與說明。最後用一個支援 MCP tool calling 的客戶端連線,確認它能完成初始化、工具探索與一次安全的呼叫。

如果 UI 可以使用、schema 卻不存在,問題多半在 mcp_server=True 或 Gradio 版本;如果 schema 存在、client 卻連不上,先回到 transport 與 URL;如果工具可以列出但呼叫失敗,再檢查函式本身的輸入、依賴與認證。這樣排查比直接重裝所有套件更容易保留原因。

部署前要先承認的限制

gradio[mcp] 會安裝目前套件解析出的依賴,因此部署時應記錄版本策略,避免本地環境與 Space 在不同版本下產生不同 schema。本文沒有把某一個 Gradio 版本寫死,因為 endpoint、transport 與 client 支援都可能演進;正式專案應使用 lockfile 或明確的相容性測試建立自己的版本邊界。

另外,Gradio 的 MCP integration 只負責把函式暴露成工具,不等於替工具提供使用者授權、資料隔離或副作用審批。這些問題要在 server 和 client 的認證、權限與批准策略中另外處理。下一篇會把同一個最小 server 放進 Hugging Face Spaces,並從 Git 認證與遠端 endpoint 兩端排查部署問題。

參考資料