iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
生成式 AI

被AI之箭射中了 - 是覺醒還是死去系列 第 9

Day09 - MCP:踩坑 MCP Proxy Server 的安全機制實作(下)

  • 分享至 

  • xImage
  •  

前言

在上一篇有描述要實作的安全機制流程,以及一些零碎的程式碼,在這一篇我會盡量把實作細節補上。

最後,請布加拉提不要靠近我,謝謝。

如何實作 MCP Proxy Server

以我的實作來說,主要包含以下三個大部分:

  • 產生 MCP Server 實例:作為提供 LLM Agent 上下文的伺服器
  • 設定與其他 MCP Server 的通訊方式:在前面的篇章有提過, MCP 主要有 Stdio / HTTP 兩種連線方式
  • 建立 MCP Server 工具:因為 LLM 實際上使用的是你的 mcp server 提供的工具

公開說明:以下實作有請 Claude 協助,在此提前告知,若有發現錯誤請讓我知道!

產生 MCP Server 實例

官方提供多種語言的 SDK 讓開發者去建立 MCP Server ,我選擇的是 Typescript SDK,完成下載後,透過它提供的 McpServer 方法來建立伺服器

//server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

// 建立 MCP Server 實例
const server = new McpServer({ name: "mcp-proxy-protect", version: "1.0.0" });

這邊的一個重點是 你的 Proxy Server 要同時肩負兩個任務

  • MCP Client(跟其他 MCP Server 互動)
  • MCP Server (提供 LLM Agent 工具)

所以在連線設計上,你可根據需要設定連線方式

https://ithelp.ithome.com.tw/upload/images/20250923/201412722AIfj44EXK.png

SDK 同樣有提供方法進行設定,這邊我先處理跟 Server 端的連線設定,這邊選擇使用 Stdio 連線方式,是因為 LLM 客戶端運行在本機

import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

//伺服器的啟動邏輯
async function startProxyServer(){
	const transport = new StdioServerTransport();
	await server.connect(transport);
}

//啟動
startServer().catch((error) => {
	console.error("❌ Server 啟動失敗:", error);
});

接著將這個 MCP Server 加入 Cursor MCP 配置中,連線成功!

https://ithelp.ithome.com.tw/upload/images/20250923/20141272rIaJAHoPBi.png

建立 MCP Client 連接 Figma MCP Server

接著我們需要在伺服器內部運行 MCP Client ,由它去跟其他 MCP Server 索取工具方法(如下圖)

┌─────────────┐
│   上游 AI   │
└──────┬──────┘
       │ 
       ▼ tools/list
┌─────────────┐
│Proxy Server │ ──────> 回傳所有聚合的工具
└──────┬──────┘
       │
   ┌───┴───┬───────┬────────┐
   ▼       ▼       ▼        ▼
[Server1][Server2][Server3][Server4]
   │       │       │        │
 tools   tools   tools    tools

加入針對描述的安全檢查

我的目標是 在每次呼叫工具方法時,都要運行一次工具描述檢查,以下是實作運行時安全檢查的函數:

// 運行時安全檢查函數
function shouldExecuteTool(tool: any, args: any): { allowed: boolean; reason?: string } {
	const toolName = tool.name?.toLowerCase() || '';
	const description = tool.description?.toLowerCase() || '';
	
	// 🚫 危險操作檢查
	const dangerousKeywords = ['delete', 'remove', 'destroy', 'clear', 'erase'];
	if (dangerousKeywords.some(keyword => description.includes(keyword))) {
		return {
			allowed: false,
			reason: `工具包含危險操作關鍵字: ${dangerousKeywords.find(k => description.includes(k))}`
			};
		}
    // ✅ 默認允許執行
	return { allowed: true };
}

在每次呼叫 MCP 工具時,都會執行安全檢查

server.registerTool(
	toolName,
	{
		title: `[FIGMA] ${tool.title || tool.name}`,
		description: tool.description,
	},
	async (args) => {
		try {
			// 🔍 運行時安全檢查
			const securityCheck = shouldExecuteTool(tool, args);
			if (!securityCheck.allowed) {
			console.error(`安全檢查失敗: ${tool.name} --${securityCheck.reason}`);
		}catch(error){
			console.error('Figma 工具執行失敗:', error)
		}

小結

決定要放下這個實作了,中間在處理 MCP Server SDK 的時候,一直出現以下錯誤訊息

keyValidator.parse is not a function`

關鍵字查了才知道 Typescript SDK 跟 zod 有版本相容的問題, 算是給要試著實作的人一個提醒吧。

參考

Build an MCP server
Zod version compatibility issue with MCP SDK


上一篇
Day08 - MCP:踩坑 MCP Proxy Server 的安全機制實作
系列文
被AI之箭射中了 - 是覺醒還是死去9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言