🚀 Index Network MCP 服務器
Index Network MCP 服務器基於 Model Context Protocol (MCP),實現了 ChatGPT 與 Index Network 發現協議的集成。通過 React 組件,展示瞭如何與 ChatGPT 集成,並遵循 MCP 開發的最佳實踐。
🚀 快速開始
前提條件
- Node.js:版本 22.12.0 或更高
- 操作系統:macOS、Linux 或 Windows(建議使用 WSL2)
- 內存:至少 2GB RAM(開發建議 4GB)
- 端口:3002 端口可用(可通過
MCP_SERVER_PORT 配置)
- 網絡:需要網絡訪問以獲取 npm 包和使用 ngrok 隧道
安裝
npm install
cd widgets && npm install && cd ..
cp env.example .env
開發
npm run dev
此命令將啟動 Vite 的監聽模式和 MCP 服務器,並支持自動重啟。編輯 widgets/src/echo/echo.css 文件並保存,約 2 秒後即可看到更改。
測試
npm test
✨ 主要特性
- 🔥 熱重載:在開發過程中編輯組件,可立即看到更改
- ⚡ 現代工具:使用 Vite + React 實現快速構建和最佳性能
- 🎨 自定義鉤子:提供
useWidgetProps、useOpenAiGlobal、useWidgetState 等鉤子,實現與 ChatGPT 的無縫集成
- 🛠️ MCP 檢查器:無需集成 ChatGPT 即可測試和調試組件
- 📦 TypeScript 5.7.2:全類型代碼庫,提供更好的開發體驗
- 🚀 開發就緒:優化構建,使用哈希資產,並正確實現 MCP 協議
- 📝 代碼整潔:遵循 TypeScript 註釋最佳實踐,使用 JSDoc 文檔
💻 使用示例
基礎用法
Use the echo tool to display "Hello, World!"
高級用法
自定義組件開發
import { useWidgetProps } from '../use-widget-props';
import { useOpenAiGlobal } from '../use-openai-global';
interface MyWidgetProps {
title: string;
data: any[];
}
export function MyWidget() {
const props = useWidgetProps<MyWidgetProps>({
title: '',
data: []
});
const theme = useOpenAiGlobal('theme');
return (
<div className={`widget ${theme}`}>
<h3>{props.title}</h3>
<ul>
{props.data.map((item, index) => (
<li key={index}>{item.name}</li>
))}
</ul>
</div>
);
}
環境配置
NODE_ENV=development npm run dev
MCP_SERVER_PORT=8080 NODE_ENV=production npm start
NGROK_AUTHTOKEN=your_token npm run dev
📚 詳細文檔
環境變量
| 屬性 |
詳情 |
MCP_SERVER_PORT |
服務器端口,默認值為 3002 |
NGROK_AUTHTOKEN |
ngrok 認證令牌,必需 |
NODE_ENV |
環境,默認值為 development |
獲取 ngrok 認證令牌:在 ngrok.com 註冊,然後運行 ngrok config add-authtoken YOUR_TOKEN
連接到 ChatGPT
- 構建:
npm run build
- 啟動:
npm start
- 暴露:
ngrok http 3002(或在 .env 文件中設置 NGROK_AUTHTOKEN)
- 配置 ChatGPT:使用
https://your-url.ngrok-free.app/mcp
🔧 技術細節
架構
src/server.ts # 註冊工具的 MCP 服務器
widgets/src/ # 帶有鉤子的 React 組件
widgets/dist/ # 構建後的資產(哈希文件名)
熱重載流程
文件更改 → Vite 重新構建 → Nodemon 重啟 → 更新組件
關鍵文件:
nodemon.json - 文件監聽配置
widgets/vite.config.ts - 構建配置
package.json - 腳本和依賴項
添加新組件
1. 創建組件
mkdir widgets/src/my-widget
創建以下文件:
MyWidget.tsx - React 組件
my-widget.css - 樣式
index.tsx - 入口點
index.html - 模板,包含 <div id="my-widget-root">
2. 更新 Vite 配置
在 widgets/vite.config.ts 中添加入口:
input: {
echo: './src/echo/index.html',
myWidget: './src/my-widget/index.html'
}
3. 註冊工具
在 src/server.ts 中:
const myWidgetHtml = readFileSync(
join(__dirname, '../widgets/dist/src/my-widget/index.html'),
'utf-8'
);
server.registerTool("my-tool", {
title: "My Tool",
description: "Tool description",
inputSchema: z.object({ data: z.string() })
}, async (params) => ({
content: [{ type: "text", text: "Result" }],
structuredContent: params,
_meta: {
"openai/widgetAccessible": true,
"openai.com/widget": {
type: "resource",
resource: {
uri: "ui://widget/my-widget.html",
mimeType: "text/html+skybridge",
text: myWidgetHtml
}
}
}
}));
組件鉤子
import { useWidgetProps } from '../use-widget-props';
import { useOpenAiGlobal } from '../use-openai-global';
import { useWidgetState } from '../use-widget-state';
function MyWidget() {
const props = useWidgetProps<{ message: string }>();
const theme = useOpenAiGlobal('theme');
const [state, setState] = useWidgetState({ count: 0 });
return <div>{props.message}</div>;
}
性能優化
優化提示
- 熱重載:開發更改約 2 秒內反映
- 構建優化:Vite 提供快速構建,使用哈希資產進行緩存清除
- 內存使用:使用
node --trace-sync-io 監控開發過程中的內存消耗
- 包大小:組件作為單獨的塊構建,以實現最佳加載
監控
node --trace-sync-io dist/server.js
node --inspect dist/server.js
開發性能
- 靜態資產:組件資產使用適當的緩存頭提供服務
- 熱重載:使用 Vite 進行快速開發迭代
- 構建優化:使用哈希資產進行緩存清除
- 日誌記錄:使用控制檯日誌進行開發調試
🔒 安全
漏洞檢查
定期檢查依賴項是否存在已知漏洞:
npm audit
npm audit fix
npm outdated
安全最佳實踐
- 環境變量:切勿將敏感數據提交到版本控制
- CORS 配置:開發時服務器使用寬鬆的 CORS (
origin: '*'),生產環境中應限制
- ngrok 隧道:生產部署使用認證的 ngrok 會話
- 依賴項:保持所有依賴項最新,並定期檢查
- HTTPS:生產環境始終使用 HTTPS
開發安全檢查清單
- [ ] 設置
NODE_ENV=development
- [ ] 使用 ngrok 進行安全隧道
- [ ] 運行
npm audit 並修復漏洞
- [ ] 保持依賴項最新
- [ ] 使用環境變量存儲敏感數據
- [ ] 審查 CORS 配置以確保生產就緒
🛠️ 故障排除
常見問題
端口 3002 已被使用?
lsof -ti:3002 | xargs kill -9
MCP_SERVER_PORT=3003 npm run dev
熱重載不起作用?
- 檢查終端是否顯示
[nodemon] restarting due to changes...
- 確保 Vite 正在運行:
cd widgets && npm run dev
- 清除構建緩存:
rm -rf widgets/dist && npm run build
組件未在 ChatGPT 中顯示?
- 驗證 ngrok 隧道是否激活:
ngrok http 3002
- 檢查 MCP 端點是否可訪問:
curl https://your-url.ngrok-free.app/mcp
- 確保組件 HTML 已構建:
npm run build
TypeScript 錯誤?
- 運行類型檢查:
npm run type-check
- 清除 TypeScript 緩存:
rm -rf node_modules/.cache
- 重新安裝依賴項:
rm -rf node_modules && npm install
環境變量未加載?
- 確保
.env 文件存在:cp env.example .env
- 檢查變量名是否完全匹配(區分大小寫)
- 更改後重啟開發服務器
🤝 貢獻
我們歡迎對 Index Network 的 MCP 服務器進行貢獻!以下是開始的步驟:
開發設置
- 分叉倉庫
- 克隆你的分叉:
git clone https://github.com/your-username/index-network-mcp.git
- 安裝依賴項:
npm install && cd widgets && npm install && cd ..
- 創建功能分支:
git checkout -b feature/your-feature-name
- 按照我們的編碼標準進行更改
- 提交拉取請求,並提供清晰的描述
編碼標準
- 所有新代碼使用 TypeScript
- 遵循現有代碼風格和模式
- 為新功能添加測試
- 根據需要更新文檔
- 確保所有 linting 通過:
npm run lint
註釋最佳實踐
本項目遵循整潔代碼註釋原則:
- 公共 API 使用 JSDoc:所有導出的函數、類和類型使用 JSDoc,包含
@param、@returns 和 @example 標籤
- 代碼自解釋:優先使用清晰的變量名和小函數,而不是解釋性註釋
- 最小化內聯註釋:僅在非明顯的業務邏輯或架構決策時使用
// 註釋
- 避免冗餘註釋:避免陳述顯而易見的內容或重複代碼已顯示的信息
- 維護文檔:保持註釋與代碼更改同步
良好註釋實踐的示例可在以下文件中找到:
widgets/src/use-widget-props.ts - 帶有示例的全面 JSDoc
widgets/src/use-widget-state.ts - 實際使用示例
src/server.ts - 導出項和路由處理程序的 JSDoc
報告問題
發現漏洞或有功能請求?請:
- 首先檢查現有問題
- 創建新問題,並提供清晰的重現步驟
- 包括環境詳細信息(Node.js 22.12.0+、操作系統等)
📞 支持
需要幫助?以下是你的選擇:
- 文檔:查看本 README 和 參考資料 部分
- 問題:通過 GitHub 問題 報告漏洞或請求功能
- 社區:加入 Index Network 社區:index.network
- 郵件:聯繫我們:hello@index.network
📄 許可證
本項目採用 MIT 許可證,詳情請見 LICENSE。
📚 參考資料