足球MCP服务器
✨ OpenAI应用SDK示例 -此应用程序重点介绍了如何使用OpenAI Apps SDK为Rails MCP服务器构建UI组件,包括使用流式HTTP传输和服务器发送事件(SSE)在ChatGPT内呈现的React小部件。
特性
- 可流式HTTP传输 -ChatGPT集成的推荐传输方式
- 服务器发送事件(SSE) -工具响应的实时流式传输
- 会话管理 -正确处理多个并发客户端
- React 19小部件 -在ChatGPT内呈现的交互式UI
- 组件注册表模式 -用于快速开发的可重用小部件架构
- 即将到来的日程小部件 -基于OpenAI Apps SDK的交互式购票CTA
- 小部件内跟进 -实时分数小部件可以触发后续提示(通过
sendFollowUpMessage)无需键入即可获取更深入的数据
⚠️ 生产警告
此应用程序尚未准备好生产。 它使用内存中的会话存储:
- 不适用于多个服务器或进程
- 重新启动时丢失所有会话
- 仅适用于开发、演示和单服务器部署
对于生产使用,实现Redis支持的会话或使用无状态模式。
截图
实时分数小工具
Live Scores Widget在ChatGPT内呈现的交互式React组件中显示实时足球比赛分数。
团队信息资源
球队信息资源提供结构化的NFL球队数据,包括分区、颜色和体育场信息。
设置
bundle install
npm install
cp .env.example .env
# Edit .env and set BASE_URL to your tunnel URL for ChatGPT testing启动服务器:
# Recommended: Start everything with one command (Rails + JS build + Cloudflare Tunnel)
# Note: Requires cloudflared to be installed and configured
bin/dev
# Alternative: For local testing only (no HTTPS tunnel, no auto-rebuild)
bin/rails server手动构建React小部件:
# One-time build
npm run build
# Watch mode (rebuilds on changes) - not needed if using bin/dev
npm run watch运行测试:
bin/rails test运行门楣:
rubocopChatGPT/OpenAI应用SDK集成
HTTPS隧道开发
ChatGPT需要HTTPS端点才能连接到本地开发服务器。您有几个选择:
选项1:Cloudflare隧道(推荐)
- 无浏览器警告或插播
- 使用您自己的域名
- 免费套餐可用
- 安装
cloudflared并在中进行配置Procfile.dev:
tunnel: cloudflared tunnel run your-tunnel-name- 长时间开发会话更稳定
选项2:ngrok(付费计划)
- 免费版显示浏览器警告 中断ChatGPT集成
- 付费计划(每月8美元以上)删除浏览器警告
- 简单设置:
ngrok http 3000 - 适合使用付费帐户进行快速测试
选项3:其他隧道服务
- localhost.run -基于SSH的隧道,无需安装
- 尾鳞片漏斗 -如果您使用Tailscale进行网络连接
- 钻孔 -基于Rust的开源替代方案
- VS代码端口转发 -如果使用GitHub代码空间或VS代码远程
重要提示: 免费ngrok帐户显示一个间隙“访问网站”警告页面,阻止ChatGPT加载您的资源。您需要一个付费的ngrok帐户或另一个隧道解决方案。
设置ChatGPT
- 配置Cloudflare隧道 在
Procfile.dev:
tunnel: cloudflared tunnel run your-tunnel-name- 从开始
bin/dev-这将运行Rails、JS watch和你的隧道
- 查找您的隧道URL 从Cloudflare仪表板进行更新
.env:
BASE_URL=https://your-tunnel-url.com- 重启
bin/dev使BASE_URL更改生效
添加工具
工具提供客户端可以调用的可调用函数。
步骤1:在中创建一个新的工具类 app/mcp_tools/
class MyTool "text", "text" => "Result: #{param}" }])
end
end步骤2:在中注册工具 app/controllers/mcp_controller.rb
将其添加到 tools: 数组中 create_transport 方法:
tools: [GetLiveScoresTool, MyTool]当前工具
- GetLiveScoresTool (
app/mcp_tools/get_live_scores_tool.rb):返回带有可选联赛过滤的模拟实况足球比分。演示响应格式和数据过滤模式。 - GetTeamInfo工具 (
app/mcp_tools/get_team_info_tool.rb):返回有关NFL球队的信息,包括分区、颜色和体育场详细信息。演示结构化数据响应。
添加资源
资源提供客户端可以访问的数据。它们可以是纯文本、JSON、HTML小部件或任何其他内容类型。
步骤1:在中创建新的资源类 app/mcp_resources/
class MyResource
VERSION = "v1" # Increment to v2, v3, etc. when content changes
URI = "my-resource://data?#{VERSION}"
class {
const toolOutput = useToolOutput();
if (!toolOutput) {
return
Waiting for data...
;
}
return (
My Widget
{JSON.stringify(toolOutput, null, 2)}
);
};
export default MyWidget;步骤2:在中注册组件 app/javascript/application.js
只需将您的组件添加到 COMPONENT_REGISTRY:
import MyWidget from './components/MyWidget';
const COMPONENT_REGISTRY = {
'LiveScoresWidget': LiveScoresWidget,
'MyWidget': MyWidget, // Add this line
};步骤3:在中创建资源类 app/mcp_resources/
# app/mcp_resources/my_widget_resource.rb
class MyWidgetResource
VERSION = "v1"
URI = "ui://widget/my-widget.html?#{VERSION}"
class true,
"openai/widgetDomain" => "https://chatgpt.com",
"openai/widgetCSP" => {
"connect_domains" => [ "https://chatgpt.com", base_url ],
"resource_domains" => [ base_url, "https://*.oaistatic.com" ]
}
}
end
end
end步骤4:在中注册资源 app/controllers/mcp_controller.rb
# Add to the resources: array in create_transport
resources: [
LiveScoresWidgetResource.to_resource,
MyWidgetResource.to_resource
]
# Add to the resources_read_handler block
resources_read_handler: lambda { |uri, server_context|
case uri
when LiveScoresWidgetResource::URI
LiveScoresWidgetResource.read
when MyWidgetResource::URI
MyWidgetResource.read
else
raise MCP::Error.new(
code: MCP::JSONRPC::ErrorCodes::INVALID_PARAMS,
message: "Unknown resource URI: #{uri}"
)
end
}步骤5:重建资产并测试
# Rebuild JavaScript
npm run build
# Increment VERSION in MyWidgetResource to v2, v3, etc. when making changes
# This forces ChatGPT to fetch the updated widget步骤6:在ChatGPT中测试
将您的MCP服务器添加到ChatGPT,然后在对话中引用您的新资源。ChatGPT将在iframe中加载您的小部件。
测试
# Run all tests
bin/rails test
# Run specific test file
bin/rails test test/controllers/mcp_controller_test.rb
# Run with verbose output
bin/rails test -v项目结构
app/
├── controllers/
│ └── mcp_controller.rb # Main MCP endpoint handler
├── mcp_tools/ # MCP tool implementations
│ ├── get_live_scores_tool.rb
│ └── get_team_info_tool.rb
├── mcp_resources/ # MCP resource implementations
│ ├── live_scores_widget_resource.rb
│ └── team_info_resource.rb
├── javascript/
│ ├── application.js # Component registry & mounting
│ └── components/ # React components
│ └── LiveScoresWidget.jsx
└── views/
└── mcp_widgets/
└── widget.html.erb # Shared widget template
config/
├── routes.rb # MCP endpoint routes
└── initializers/
└── cors.rb # CORS configuration
test/
└── controllers/
└── mcp_controller_test.rb # MCP endpoint tests许可证
麻省理工学院
