🚀 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。
📚 参考资料