如何編寫自定義 MCP Server 以連接私有資料庫
AI

如何編寫自定義 MCP Server 以連接私有資料庫

By Administrator

為什麼你需要編寫自定義 MCP Server?

對於工程師而言,將 LLM 接入私有資料庫最大的挑戰不在於連接字串,而在於上下文安全(Context Security)工具的決定論(Determinism)。Model Context Protocol (MCP) 提供了一種標準化方式,讓 AI Agent 能夠在受控環境下與你的數據進行互動,而不必直接將整個資料庫丟給模型。

本文專注於如何架構一個自定義 MCP Server,透過定義清晰的工具接口(Tool Schema),讓 Agent 能夠執行精確的 SQL 查詢或數據操作,並有效防止模型隨意執行 DROP TABLE 等破壞性指令。

先決條件與適用場景

在開始編寫之前,請確認這是否為最佳方案:

  • 適用場景:需要頻繁與內部資料庫交互、需要對 Agent 的權限進行嚴格控制、需要標準化不同 Agent 之間的數據訪問方式。
  • 何時不要使用:如果你的資料庫架構極度變動,且不需要結構化查詢,直接使用現成的數據查詢代理可能更快。此外,若數據極度敏感,建議在 MCP 層之外增加 API Gateway 進行二次驗證。

如何編寫自定義 MCP Server 以連接私有資料庫

實作一個穩定的 MCP Server,核心在於定義 JSON-RPC 接口並實作 Tool Handlers。

步驟 1:定義環境配置與權限隔離

使用環境變數管理資料庫連接,切勿將密碼硬編碼。請務必使用擁有「最小權限」的資料庫用戶,例如僅具備 SELECT 權限的唯讀用戶。

步驟 2:初始化 MCP SDK

使用官方 MCP SDK(例如 Python 或 TypeScript 版本)。核心是定義 list_toolscall_tool

# 範例:定義一個查詢員工資料的工具
@mcp.tool()
def get_employee_by_id(employee_id: int) -> str:
    """根據 ID 查詢員工基本資料"""
    # 這裡執行 SQL 查詢
    return query_db(f"SELECT name, role FROM employees WHERE id = {employee_id}")

步驟 3:實作輸入驗證

這是最重要的一步。在執行 SQL 之前,必須進行參數清理,防止注入攻擊。

步驟 4:錯誤處理與反饋

當查詢失敗時,返回給 Agent 的錯誤訊息應該要包含足夠的上下文,而不是拋出原始的 SQL Stack Trace。

如需深入了解如何組織這些工具技能,以達到更好的模組化與維護性,建議參考 Mentalok Skills Hub

常見錯誤

  • 使用過大權限的 DB 連接:讓 Agent 連接具備寫入權限的生產資料庫。修正:使用專用的代理用戶,並透過視圖(View)來限制訪問。
  • 忽略 Schema 的複雜度:直接讓 Agent 理解整個資料庫結構。修正:只暴露必要的 Table 與 Columns。
  • 工具回傳過大結果集:導致 Context Window 溢出。修正:在工具端強制實作 LIMIT
  • 未實作工具驗證:對於刪除或修改指令未經人為確認。修正:加入確認請求流程。

常見 Bug 與坑點

  1. 無限循環:當 Agent 因工具調用結果不理想而連續嘗試同樣的錯誤 SQL 時。
  2. 幻覺參數:模型嘗試調用不存在的字段。這意味著你的 Tool Schema 定義不清。
  3. Connection Stale:在長時間運行的 Server 中,資料庫連接斷開。記得實作 Connection Pooling 或重連機制。

快速檢查清單

  • [ ] 是否已實作唯讀權限的資料庫用戶?
  • [ ] 是否在工具描述中清楚定義了輸入參數的格式?
  • [ ] 是否有設定 LIMIT 以免回應過大?
  • [ ] 是否已隱蔽掉資料庫底層錯誤代碼?
  • [ ] 測試過無效查詢時,Agent 是否能優雅地恢復?

FAQ

Q: MCP 與直接使用 SQLAlchemy 寫 API 有什麼不同?
A: MCP 是專門為 LLM 設計的標準協議,它將函數定義與執行結果標準化,讓 Agent 能夠自動發現並以一致的方式調用工具。

Q: 我的 MCP Server 為什麼一直顯示 'tool not found'?
A: 這通常是因為 Server 啟動時未能正確回傳 list_tools 的 JSON 對象。

Q: 如何在多個 Agent 間共享這些工具?
A: 透過將 MCP Server 部署為獨立的服務,你可以讓多個 Agent Runtime 同時接入同一個端點。