- Published on
第一次學 Kotlin Koog AI 就上手 Day 21:標準化工具整合:MCP 協定實戰
在前一篇文章中,我們學習了如何將 Koog 整合到 Ktor API 應用中。今天我們將學習如何透過 Model Context Protocol (MCP)
協定,為 AI Agent 添加標準化的外部工具,展示如何建立一個具備即時文件查詢能力的 AI 開發助手
MCP 協定簡介
Model Context Protocol (MCP) 是 Anthropic 開發的開源標準,用於簡化 AI 模型與外部系統之間的整合。相較於我們之前自定義開發的工具,MCP 提供了一個統一的標準化介面,讓我們可以輕鬆使用由專業團隊維護的高品質工具
MCP 的核心優勢
相比於自定義工具開發,MCP 協定帶來以下優勢
- 標準化介面:統一的通訊格式,無需重複開發
- 專業維護:工具由專業團隊持續更新維護
- 即插即用:快速整合,大幅降低開發成本
- 品質保證:經過充分測試的穩定工具
MCP 核心元件
Koog 框架透過以下核心元件實現與 MCP 伺服器的整合
- McpTool:作為 Koog 工具介面與 MCP SDK 之間的橋接器,將 MCP 工具轉換為 Koog 可用的工具格式
- McpToolDescriptorParser:負責解析 MCP 工具定義,並將其轉換為 Koog 工具描述符格式
- McpToolRegistryProvider:建立 MCP 工具註冊表,透過不同的傳輸機制(stdio、SSE)連接到 MCP 伺服器
MCP 安全性考量
在使用 MCP 工具時,安全性是一個不可忽視的重要議題。由於 MCP 工具會在您的本地環境中執行,並可能存取系統資源,因此選擇可信任的來源至關重要
潛在安全風險
- 系統資源存取:MCP 工具可能存取檔案系統、網路連線、環境變數等敏感資源
- 程式碼執行:某些工具可能執行任意程式碼或命令
- 資料外洩:惡意工具可能竊取本地資料或 API 金鑰
- 依賴套件風險:第三方相依套件可能包含漏洞或惡意程式碼
安全選擇建議
優先選擇以下來源的 MCP 工具
官方 MCP 工具
- 主要雲端服務商(AWS、Google、Microsoft)的官方工具
- 知名開源專案的官方 MCP 整合
可信任的開源專案
- GitHub stars 數量較多
- 活躍的維護狀態(近期有更新)
- 透明的源碼和良好的文件
- 正面的社群評價和回饋
Context7 MCP 整合
讓我們以一個簡單的例子來展示如何將 Context7 MCP 工具整合到 AI Agent 中
Context7 MCP 基本設置
suspend fun main() {
// 建立整合了 Context7 MCP 工具的 AI Agent
val agent = createContext7Agent(ApiKeyManager.openAIApiKey!!)
val query = "如何在 Koog 中整合 MCP 工具?"
try {
println("\n正在查詢... $query")
val response = agent.run(query)
println("\n回應: $response")
} catch (e: Exception) {
println("\n錯誤: ${e.message}")
}
}
/**
* 建立整合 Context7 的 AI Agent
*/
suspend fun createContext7Agent(apiKey: String): AIAgent {
return AIAgent(
executor = simpleOpenAIExecutor(apiKey),
strategy = singleRunStrategy(),
systemPrompt = createSystemPrompt(),
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini,
toolRegistry = createToolRegistry()
)
}
/**
* 建立包含 Context7 MCP 工具的註冊表
*/
suspend fun createToolRegistry(): ToolRegistry {
// 基礎工具
val basicTools = ToolRegistry {
tool(AskUser)
}
// Context7 MCP 工具
val context7Registry = createContext7McpRegistry()
// 合併工具註冊表
return basicTools + context7Registry
}
/**
* 系統提示詞
*/
fun createSystemPrompt(): String {
return """
你是一個專業的 AI 開發助手,具備以下能力:
1. 回答 Koog AI 框架相關問題
2. 使用 Context7 工具查詢最新的 API 文件和程式碼範例
3. 提供準確、即時的技術支援
當開發者詢問 Koog 相關的 API 用法時,請主動使用 Context7 工具查詢最新文件。
請確保提供的資訊是最新且正確的,而且使用正體中文回答
""".trimIndent()
}
/**
* 建立 Context7 MCP 工具註冊表
*/
suspend fun createContext7McpRegistry(): ToolRegistry {
// 啟動 Context7 MCP 服務程序
val context7Process = ProcessBuilder(
"npx", "-y", "@upstash/context7-mcp"
).start()
// 建立標準輸入輸出傳輸通道
val transport = McpToolRegistryProvider.defaultStdioTransport(context7Process)
// 從傳輸通道建立工具註冊表
return McpToolRegistryProvider.fromTransport(transport)
}
要注意的是,
ProcessBuilder
的內容,就是把所有MCP
的command
和args
都依序放上去就對了
執行 AI 回應內容
正在查詢... 如何在 Koog 中整合 MCP 工具?
回應: 在 Koog 框架中整合 MCP(Model Context Protocol)工具,主要可以按照以下步驟進行:
1. 建立與 MCP 伺服器的連線傳輸(Transport):
- 可以透過標準輸入輸出(stdio)協定連接當地啟動的 MCP 進程。
- 也可以使用 SSE(Server-Sent Events)協定連接透過 HTTP 提供服務的 MCP 伺服器。
2. 使用 `McpToolRegistryProvider` 由 MCP 伺服器的傳輸通道建立工具註冊(ToolRegistry),此註冊包含 MCP 伺服器所提供的所有工具。
3. 在建立 Koog 的 `AIAgent` 時,將上述建立的 `toolRegistry` 傳入,使 Koog agent 能夠調用來自 MCP 伺服器的工具,並能利用由大型語言模型(LLM)提供的引數來呼叫這些工具。
以下為一個簡單示範範例,展示如何從啟動一個 MCP 伺服器進程開始,建立 stdio 連接,並整合到 Koog agent 之中:
import ai.koog.agents.core.agent.AIAgent
import ai.koog.agents.core.agent.singleRunStrategy
import ai.koog.prompt.executor.clients.openai.OpenAIModels
import ai.koog.prompt.executor.llms.all.simpleOllamaAIExecutor
import kotlinx.coroutines.runBlocking
import ai.koog.agents.mcp.McpToolRegistryProvider
fun main() {
runBlocking {
// 啟動 MCP 伺服器進程 (假設路徑已知)
val process = ProcessBuilder("path/to/mcp/server").start()
// 建立 stdio 傳輸通道
val transport = McpToolRegistryProvider.defaultStdioTransport(process)
// 從傳輸通道建立 MCP 工具註冊
val toolRegistry = McpToolRegistryProvider.fromTransport(transport)
// 建立 Koog agent,註冊 MCP 工具
val agent = AIAgent(
executor = simpleOllamaAIExecutor(),
strategy = singleRunStrategy(),
llmModel = OpenAIModels.Chat.GPT4o,
toolRegistry = toolRegistry
)
// 使用 Agent 執行任務並呼叫 MCP 工具
val result = agent.run("Use the MCP tool to perform a task")
println(result)
}
}
### 相關重要組件說明
- `McpToolRegistryProvider`:負責從 MCP 傳輸建立 Koog 工具註冊。
- `defaultStdioTransport(process)`:建立與本地 MCP Server 透過標準輸入輸出通訊的傳輸層。
- `defaultSseTransport(url)`:建立與網路 MCP Server 透過 SSE 的傳輸層。
- `McpTool`:作為 Koog 工具介面與 MCP SDK 的橋樑。
- `McpToolDescriptorParser`:解析 MCP 工具定義並轉成 Koog 工具描述格式。
### 其他範例
- 以 Docker 啟動 MCP 伺服器,搭配 Google Maps MCP 工具:
val process = ProcessBuilder(
"docker", "run", "-i",
"-e", "GOOGLE_MAPS_API_KEY=$googleMapsApiKey",
"mcp/google-maps"
).start()
val toolRegistry = McpToolRegistryProvider.fromTransport(
transport = McpToolRegistryProvider.defaultStdioTransport(process)
)
val agent = AIAgent(
executor = simpleOpenAIExecutor(openAIApiToken),
llmModel = OpenAIModels.Chat.GPT4o,
toolRegistry = toolRegistry,
)
agent.run("Get elevation of the Jetbrains Office in Munich, Germany?")
更多範例與詳細說明可以參考 Koog 官方文件對 MCP 整合部分的說明。若需要,我也可以進一步提供該文件的更多程式碼範例與教學。需要我為你展開嗎?
一開始我的 MCP 名稱寫錯,執行後就一直卡在那裡,也沒有出現任何錯誤… 如果執行後也是卡住的話,可以確認一下是不是相關的 command 有那裡寫錯了
Playwright MCP 整合
讓我們看看如何整合 Playwright MCP,為 AI Agent 添加網頁自動化能力
Playwright MCP 基本設置
suspend fun main() {
// 建立整合了 Playwright MCP 工具的 AI Agent
val agent = createPlaywrightAgent(ApiKeyManager.openAIApiKey!!)
val task = """
打開瀏覽器,幫我到 https://blog.cashwu.com 網站,
然後到「關於我」的相關頁面,
然後給我作者相關的自我介紹
""".trimIndent()
try {
println("\\n正在執行任務... $task")
val response = agent.run(task)
println("\\n回應: $response")
} catch (e: Exception) {
println("\\n錯誤: ${e.message}")
}
}
/**
* 建立整合 Playwright 的 AI Agent
*/
suspend fun createPlaywrightAgent(apiKey: String): AIAgent {
return AIAgent(
executor = simpleOpenAIExecutor(apiKey),
strategy = singleRunStrategy(),
systemPrompt = createPlaywrightSystemPrompt(),
llmModel = OpenAIModels.CostOptimized.GPT4_1Mini,
toolRegistry = createPlaywrightToolRegistry()
)
}
/**
* 建立包含 Playwright MCP 工具的註冊表
*/
suspend fun createPlaywrightToolRegistry(): ToolRegistry {
// 基礎工具
val basicTools = ToolRegistry {
tool(AskUser)
}
// Playwright MCP 工具
val playwrightRegistry = createPlaywrightMcpRegistry()
// 合併工具註冊表
return basicTools + playwrightRegistry
}
/**
* Playwright 系統提示詞
*/
fun createPlaywrightSystemPrompt(): String {
return """
你是一個專業的網頁自動化助手,具備以下能力:
1. 使用瀏覽器自動化工具執行網頁操作
2. 瀏覽指定網站並與頁面元素互動
3. 擷取網頁內容並分析結果
4. 執行複雜的多步驟網頁操作流程
當用戶要求執行網頁相關任務時,請使用 Playwright 工具進行自動化操作
請確保操作步驟清晰且符合網站的使用條款,而且使用正體中文回答
""".trimIndent()
}
/**
* 建立 Playwright MCP 工具註冊表
*/
suspend fun createPlaywrightMcpRegistry(): ToolRegistry {
// 啟動 Playwright MCP 服務程序
val playwrightProcess = ProcessBuilder(
"npx", "@playwright/mcp@latest", "--port", "8931"
).start()
// 等待服務啟動
Thread.sleep(3000)
// 建立 SSE 傳輸通道
val transport = McpToolRegistryProvider.defaultSseTransport("http://localhost:8931")
// 從傳輸通道建立工具註冊表
return McpToolRegistryProvider.fromTransport(transport)
}
執行 AI 回應內容
正在執行任務... 打開瀏覽器,幫我到 https://blog.cashwu.com 網站,
然後到「關於我」的相關頁面,
然後給我作者相關的自我介紹
回應: 作者Cash Wu的自我介紹如下:
- 一個半路出家誤入歧途的程式宅
- 雜食性技術開發者
- 每個領域各有一點點研究
- 意外的接觸到敏捷式開發而開始愛上它
- 相信寫程式可以改變世界
- 可以使用網站上的Link相關連結找到他
如果您需要進一步支持他的創作,也可以透過網站上的贊助連結支持他持續創作優質內容。
總結
MCP 協定為 AI Agent 開發帶來了標準化的工具整合方案。無論是文件查詢(Context7)、網頁自動化(Playwright),還是其他專業工具,都能透過統一的介面快速整合,大幅降低開發成本並提升系統可靠性
下一篇文章,我們將探討檢查點與狀態管理,學習如何實現 Agent 執行的持久化與故障恢復機制
參考資源
- Koog AI 官方文件
- Koog Model Context Protocol
- Context7 MCP GitHub
- Playwright MCP GitHub
- Model Context Protocol 官方文件
支持創作
如果這篇文章對您有幫助,歡迎透過 贊助連結 支持我持續創作優質內容。您的支持是我前進的動力!
圖片來源:AI 產生