MCP:电影上下文提供程序
A. 演示OpenAI应用程序 与建 OpenAI应用软件开发工具包,已准备好部署 渲染.
管理您的个人电影观看列表,获得人工智能推荐,并直接在ChatGPT中与漂亮的小部件进行交互。电影数据由 TMDB。具有多提供商LLM支持和PostgreSQL数据持久性。
   
______________________________________________________________________
这是什么?
这个演示实现了一个带有观察列表、评级和人工智能推荐的电影发现应用程序,完全集成到ChatGPT中。
https://github.com/user-attachments/assets/82e33bd5-8a5e-4f03-b8df-44c352dc1ded
你将学到什么:
- 创建 交互式小部件
- 实施 MCP工具
- 部署方式 零配置
- 整合 多个LLM提供商 (OpenAI、Anthropic、谷歌)
分叉此存储库 构建自己的MCP驱动的OpenAI应用程序。自定义它,从中学习,并将自己的版本部署到Render。
______________________________________________________________________
目录
______________________________________________________________________
特性
MCP工具
搜索与发现
search_movies-按标题搜索一部或多部电影discover_movies-高级筛选(导演、演员、类型、年份、评级)get_movie_details-演员阵容、收视率和海报小部件的完整细节
观察名单管理
add_to_watchlist,remove_from_watchlist,get_watchlist
观看历史
mark_as_watched,mark_as_watched_batch,get_watched_movies
偏好设置
set_preferences,get_preferences,remove_preference_item
AI功能 (需要LLM API密钥)
get_recommendations-基于您的观看历史和偏好的个性化电影建议
所有工具均在backend/src/tools/注: 只有get_recommendations工具需要一个LLM API密钥。所有其他功能都只使用TMDB API密钥。
小部件
在ChatGPT中呈现的交互式UI组件:
- 电影海报 -全细节视图,包括演员、背景和快速动作(添加到观察列表,标记已观察)
- 电影列表 -带有内联操作的搜索结果和观察列表的可排序网格
- 偏好设置 -最喜欢的流派、演员、导演的可视化编辑器(帮助人工智能推荐)
多提供商AI
建议支持OpenAI(GPT-5)、Anthropic(Claude Sonnet 4.5)或Gemini(2.5 Flash)。基于可用API密钥的自动检测。
性能和缓存
内置Valkey缓存,实现最佳性能:
- TMDB API调用 -人物搜索(7天)和电影详细信息(30天)
- 用户偏好 -缓存5分钟,更新时自动失效
- 结果:缓存数据的响应时间为亚毫秒,而API调用为200-300毫秒
由于我们的蓝图设置,Valkey在Render上自动配置。无需额外配置。
______________________________________________________________________
入门
快速入门:部署到渲染
此应用程序旨在部署到 渲染 零配置。包括 render.yaml 蓝图会自动提供您需要的一切。
先决条件
准备好API密钥(您将在部署过程中添加它们):
- TMDB API密钥 (必填,免费):
1. 在以下位置创建帐户 themoviedb.org 1. 首选 设置→ API 1. 请求API密钥(选择“开发人员”供个人使用) 1. 复制您的“API密钥(v3-auth)”-这是您将要使用的
- LLM API密钥 (可选,仅适用于推荐工具):
- OpenAI API密钥 (付费)-GPT-5 - 无烟煤API密钥 (付费)-克劳德·十四行诗4.5 - Google Gemini API密钥 (提供免费套餐)-适用于Gemini 2.5 Flash - 如果跳过此步骤,则所有功能都可以工作,除了 get_recommendations
分3步部署
1.分叉此存储库
单击此页面右上角的“Fork”按钮创建自己的副本。
2.在Render上创建新的蓝图
- 首选 渲染仪表板
- 点击 新 → 蓝图
- 连接您的GitHub帐户并选择您的分叉存储库
- 渲染器将检测
render.yaml文件自动
3.将API键添加为环境变量
出现提示时,添加这些 秘密 环境变量:
| 变量 | 必填? | 描述 |
|---|---|---|
TMDB_API_KEY | ✅ 必需 | 您的TMDB API密钥(用于所有电影数据) |
OPENAI_API_KEY | 🤖 可选\* | OpenAI API密钥(建议使用GPT-5) |
ANTHROPIC_API_KEY | 🤖 可选\* | Anthropic API密钥(建议使用Claude Sonnet 4.5) |
GEMINI_API_KEY | 🤖 可选\* | Google Gemini API密钥(推荐2.5 Flash) |
ADMIN_API_KEY | ✨ 推荐 | 您的个人MCP访问密钥(如果未设置,则自动生成) |
ADMIN_EMAIL | 可选 | 管理员用户电子邮件(默认为 admin@localhost) |
**\*至少需要一个LLM API密钥** 如果你想使用 get_recommendations 工具。所有其他功能(搜索、观察列表、首选项等)无需任何LLM即可工作。免费等级备注: 提供的Render蓝图是预先配置的,因此每个服务都在免费计划上运行(托管的Postgres实例在前30天是免费的)。免费服务在空闲时会减速,因此长时间暂停后的第一个请求可能会很慢或偶尔超时。一旦实例处于活动状态,一切都会正常运行。如果你想要类似生产的响应能力,可以将服务升级到Starter或Standard计划。
点击 应用 Render将:
- ✅ 提供PostgreSQL数据库
- ✅ 提供Valkey缓存(用于性能)
- ✅ 部署后端Node.js服务
- ✅ 部署前端小部件静态站点
- ✅ 自动运行数据库迁移
- ✅ 将一切联系在一起
- ✅ 分配HTTPS域
就是这样! 大约5分钟后,您的应用程序将在以下网址上线:
- 后端MCP服务器:
https://your-app-name.onrender.com - 小部件用户界面:
https://your-app-name-widgets.onrender.com
创建OpenAI应用程序
https://github.com/user-attachments/assets/bacc934b-670b-48ac-89bd-4acaf2d6889d
创建一个OpenAI应用程序,在ChatGPT中使用您的MCP服务器:
步骤1:找到您的API密钥
您需要您的API密钥才能进行连接。查找方式:
- 检查渲染部署日志(在首次部署后显示)-查找以下行:
Connection URL: https://your-app-name.onrender.com/mcp/messages
API Key (Bearer token): moviemcp_xxxxx...
OpenAI App MCP URL: https://your-app-name.onrender.com/mcp/messages?api_key=moviemcp_xxxxx...- 复制
OpenAI App MCP URL,您将在下面的步骤3中需要它
步骤2:启用开发人员模式(仅限第一次)
- 打开ChatGPT并转到 设置 (左下角的齿轮图标)
- 导航到 应用程序和连接器
- 向下滚动并单击 高级设置
- 启用 开发人员模式
步骤3:创建您的OpenAI应用程序
- 回到 应用程序和连接器
- 点击 创建 (或 新连接器)
- 填写连接器详细信息:
- 名字: Movie Context Provider (或您喜欢的任何名称) - 描述 (可选):简要描述其功能 - MCP服务器URL:粘贴 OpenAI App MCP URL 您在步骤1从服务器日志中复制的值。它应该看起来像https://your-app-name.onrender.com/mcp/messages?api_key=your_API_key_here - 认证:选择“无身份验证” - 检查 “我信任此应用程序” (自定义连接器需要)
- 点击 创建
ChatGPT将测试连接并添加MCP服务器。
步骤4:在聊天中启用应用程序
重要:除非您在ChatGPT对话中启用该应用程序,否则该应用程序将无法工作。
- 打开ChatGPT chatgpt.com
- 点击 + 按钮(左下角,消息输入旁边)
- 选择您的 电影上下文提供程序 列表中的应用程序
- 开始聊天: _《寻找盗梦空间》_ 或 _“显示我的监视列表”_
替代方案:其他MCP客户端(不带小部件)
您还可以将此MCP服务器与其他MCP兼容客户端(如Claude Desktop或Cursor)一起使用。添加此配置:
其他MCP客户端\ 添加到MCP配置中:
{
"mcpServers": {
"movies": {
"url": "https://your-app-name.onrender.com/mcp/messages",
"headers": {
"Authorization": "Bearer YOUR_ADMIN_API_KEY"
},
"transport": "streamableHttp"
}
}
}备注:只有ChatGPT支持OpenAI小部件,其他MCP客户端使用基于文本的响应而不是交互式UI组件进行响应。
______________________________________________________________________
小部件的工作原理
小部件在ChatGPT中提供交互式UI组件:
- 后端 在中返回结构化数据+小部件元数据
_meta领域 - ChatGPT 呈现小部件(例如。,
ui://widget/movie-poster) - 小部件 通过调用工具
window.openai.callTool()用于交互 - 状态更新 自动不刷新页面
可用小部件:
movie-poster-带有动作的详细电影视图movie-list-可排序/可过滤的电影网格preferences-管理喜爱的流派、演员、导演
看 frontend/src/widgets/ 了解实施细节。
______________________________________________________________________
多提供商LLM(可选)
AI推荐支持三个提供商(优先级:OpenAI→ Anthropic→ 双子座):
| 提供者 | 型号 | 备注 |
|---|---|---|
| OpenAI | GPT-5 | 最新推理模型 |
| 拟人 | 克劳德·十四行诗4.5 | 最佳速度/智力平衡 |
| Gemini | Gemini 2.5 Flash | 最佳性价比,免费套餐 |
设置任意一个API键以启用 get_recommendations 工具。模型是固定的,并根据可用密钥自动检测。
身份验证和用户管理
演示身份验证说明\ 此项目使用简单的API密钥身份验证作为 用于演示目的的快捷方式.每个API密钥同时用作身份验证和用户标识,从而可以轻松地支持多个用户,而无需复杂的OAuth流。 用于生产应用程序,考虑实现OAuth 2.0,它提供: - 确保用户同意流程的安全 - 令牌过期和刷新 - 无需更改密码即可撤销访问 - 行业标准安全实践 这里的API关键方法被有意简化,以专注于显示 MCP和OpenAI应用程序SDK概念 而不是身份验证最佳实践。
自动管理员用户设置
好消息! 如果你设置 ADMIN_API_KEY 在部署过程中,管理员用户是 自动创建 在数据库迁移期间。您可以使用管理员密钥立即连接:
# Your ADMIN_API_KEY works as both:
# 1. Protection for /admin endpoints
# 2. Your personal MCP API key
# Connect immediately after deployment
https://movie-mcp-server.onrender.com/mcp/messages?api_key=YOUR_ADMIN_API_KEY创建其他用户
使用管理员端点为其他人创建用户:
curl -X POST https://movie-mcp-server.onrender.com/admin/create-user \
-H "Authorization: Bearer YOUR_ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'答复:
{
"success": true,
"user": {
"id": 2,
"email": "user@example.com",
"apiKey": "moviemcp_abc123_def456..."
},
"message": "User created successfully. Save this API key securely!"
}💡 每个用户都获得一个唯一的API密钥 用于独立的观察列表和偏好
使用API密钥
使用API密钥连接到MCP服务器:
# Via query parameter
https://movie-mcp-server.onrender.com/mcp/messages?api_key=YOUR_API_KEY
# Via Authorization header
curl https://movie-mcp-server.onrender.com/mcp/messages \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'管理端点
受保护 ADMIN_API_KEY 环境变量:
- POST/admin/创建用户 -使用自动生成的API密钥创建新用户
- GET/admin/用户 -列出所有用户(未显示API密钥)
- GET/admin/health -检查管理员端点状态
替代方案:手动SQL
您还可以直接通过SQL创建用户:
INSERT INTO users (email, api_key)
VALUES ('user@example.com', 'moviemcp_' || floor(random() * 1000000000)::text || '_' || md5(random()::text));生产建议:
- 迁移到OAuth 2.0
______________________________________________________________________
应用程序使用示例
在ChatGPT中
User: Search for sci-fi movies from 2010
→ Displays movie list widget with Inception, Tron Legacy, etc.
User: Tell me about Inception
→ Displays movie poster widget with full details
User: Add it to my watchlist
→ Confirms added, updates widget state
User: Mark Inception as watched, 5 stars
→ Saves rating, removes from watchlist
User: Show my watchlist
→ Displays watchlist in list widget (sortable, filterable)
User: Recommend me some movies for a cozy evening
→ AI analyzes your taste, displays personalized recommendations高级查询
"Find highly-rated Christopher Nolan movies"
"Show me popular action movies from the 90s"
"Give me Tom Hanks movies I haven't watched"
"Recommend thought-provoking sci-fi like Arrival"
"What's in my watchlist?"
"Show my highest-rated movies"______________________________________________________________________
当地发展(可选)
在部署之前,您想在本地进行开发或测试吗?方法如下:
先决条件
- Node.js 20+
- PostgreSQL 15+ (本地实例或Docker)
- 上面的API密钥
设置步骤
1.克隆您的分叉存储库
git clone https://github.com/YOUR_USERNAME/movie-context-provider
cd movie-context-provider2.安装依赖项
# Backend
cd backend
npm install
# Frontend
cd ../frontend
npm install3.配置环境
cd backend
cp env.example .env编辑 .env 使用本地数据库和API密钥:
# Local database
DATABASE_URL=postgresql://user:password@localhost:5432/movies_db
# API Keys (same as Render)
TMDB_API_KEY=your_tmdb_api_key
OPENAI_API_KEY=your_openai_api_key
# Local URLs
MOVIE_POSTER_WIDGET_URL=http://localhost:5173
PORT=3000
NODE_ENV=development4.建立数据库
cd backend
npm run migrate创建表格和演示用户: demo@example.com /API密钥: demo_api_key_change_in_production
5.运行开发服务器
# Terminal 1 - Backend (with hot reload)
cd backend
npm run dev
# Terminal 2 - Frontend widgets (with hot reload)
cd frontend
npm run dev6.连接到ChatGPT
{
"mcpServers": {
"movies": {
"url": "http://localhost:3000/mcp/messages",
"headers": {
"Authorization": "Bearer demo_api_key_change_in_production"
},
"transport": "streamableHttp"
}
}
}开发脚本
后端:
npm run dev # Hot reload (tsx watch)
npm run build # Compile TypeScript
npm start # Run compiled code
npm run migrate # Run database migration
npm run type-check # TypeScript check前端:
npm run dev # Dev server with hot reload
npm run build # Build both widgets
npm run build:poster # Build poster widget only
npm run build:list # Build list widget only添加新工具
添加简单工具的快速示例:
// backend/src/tools/myTool.ts
export const myToolDefinition = {
name: "my_tool",
description: "Does something cool",
inputSchema: {
type: "object",
properties: {
param: { type: "string", description: "Parameter description" },
},
required: ["param"],
},
};然后在中注册 backend/src/server/tool-registry.ts.
📖 完整的演练 (包括小部件),请参阅 TUTORIAL.md.
______________________________________________________________________
扩展应用程序
想添加自己的功能吗?以下是要更新的内容:
| 添加 | 文件 |
|---|---|
| 新工具(无小部件) | tools/yourTool.ts → tool-registry.ts |
| 新工具+小部件 | + widgets/yourWidget.tsx → build-all-widgets.js → mcp-handlers.ts |
尝试的想法:
rate_movie-使用星级选择器小部件快速评分similar_movies-TMDB的类似电影端点movie_quiz-生成琐事问题cast_filmography-显示演员的所有电影
📖 完整的分步指南: TUTORIAL.md 走过一座完整的建筑 compare_movies 带有小部件的工具。
______________________________________________________________________
故障排除
小部件未显示
检查后端响应是否包括小部件元数据:
_meta: {
'openai/outputTemplate': 'ui://widget/movie-poster',
'openai/widgetAccessible': true,
'openai/resultCanProduceWidget': true
}验证MOVIE_POSTER_WIDGET_URL是否设置正确:
echo $MOVIE_POSTER_WIDGET_URL
# Should be: https://your-frontend.onrender.com数据库连接问题
# Test connection
psql $DATABASE_URL
# Render requires SSL:
DATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=requireLLM提供者问题
检查正在使用哪个提供程序:
# Backend logs will show:
🤖 Using OPENAI for recommendations验证是否设置了API密钥:
echo $OPENAI_API_KEY
# Should output your key______________________________________________________________________
Gotchas和已知问题
1.424错误: structuredContent 必须是对象
问题: 间歇的 424 Failed Dependency 调用以下工具时ChatGPT中的错误 set_preference 和 add_to_watchlist.
我们学到了什么:
这是我们最棘手的调试挑战之一。以下是让它变得棘手的原因:
- 错误似乎不一致 跨不同的工具,使其看起来像是无关的问题
- 后端日志显示成功 -我们的服务器返回了200 OK和有效的JSON
- 没有客户端错误详细信息 -ChatGPT UI显示“工具失败,状态为424”,没有具体说明
- 这个bug很微妙 -响应看起来正确,并遵循MCP协议结构
经过仔细调试和比较工作与失败的工具响应,我们发现了根本原因:
解决方案:
这 OpenAI应用软件开发工具包 预期 toolOutput 成为一个对象(由TypeScript类型暗示) ToolOutput extends UnknownObject).原始值被拒绝:
// ❌ BAD - Causes 424 error
return {
content: [{ type: "text", text: "Preference set" }],
structuredContent: true, // Primitive rejected!
};
// ✅ GOOD - Always use objects
return {
content: [{ type: "text", text: "Preference set" }],
structuredContent: { success: true }, // Object works!
};调试提示:
- 逐字节比较工作工具响应与失败响应
- 检查是否有
structuredContent返回基元(布尔值、字符串、数字) - 始终将简单值包装在对象中:
{ success: true }不true - 使用TypeScript获得更好的类型提示(尽管运行时验证仍然会有所帮助)
OpenAI SDK团队: 添加带有描述性错误的运行时验证(例如,“structuredContent必须是一个对象,received:boolean”)将显著改善开发人员体验,并减少此常见错误的调试时间。
关键要点: 当您的工具响应包括 structuredContent,它必须是一个对象(而不是类似原始的对象 true, "success",或 42).如果不需要将结构化数据传递给小部件,可以省略 structuredContent 完全且公正地使用 content.
______________________________________________________________________
2.小部件数据传递问题
问题: 最初很难将电影数据从后端传递到小部件。
进化:
- 第一次尝试: 用过的
_meta从模型中隐藏数据→ 数据未到达小部件 - 第二次尝试: 用过的
widgetDescription在_meta→ 模型仍显示重复内容 - 最终解决方案: 输入数据
structuredContent并保持content简洁
课程: structuredContent 是将数据传递给小部件的可靠方法。保持 content 简介(模型摘要),以及从中读取的小部件 toolOutput.structuredContent.
______________________________________________________________________
3.ChatGPT在小部件下方显示文本内容
发生了什么: 即使您的工具返回了一个小部件,ChatGPT也经常在其下方显示额外的纯文本内容,复制小部件中已经显示的信息。
为什么会发生这种情况: 这似乎是OpenAI的故意行为。该模型使用 content 从工具响应中提取字段,以生成文本摘要,并将其显示在小部件旁边。
无法从代码配置: 没有元数据标志或选项来禁用后端的此文本输出。
解决方法: 您可以在对话级别指示ChatGPT:
"For this movie app, please show only the widget without additional text explanations when displaying movie details or lists."此用户级提示可以引导ChatGPT变得不那么冗长,尽管行为仍可能因对话上下文而异。
______________________________________________________________________
4.小部件构建大小注意事项
每个小部件的大小约为260 KB,原因如下:
- 完全自包含(包括React,所有依赖项)
- 无代码拆分(小部件独立性要求)
- 捆绑自己的共享实用程序副本
这是 故意的 -OpenAI Apps SDK需要自包含的小部件包。权衡是更大的文件大小,以实现更简单的部署和可靠性。
______________________________________________________________________
下一步和想法
功能扩展
电视节目支持
- 使用TMDB的电视端点为电视剧添加类似的工具
- 跟踪观看的剧集,赛季进展
- 关于“如果你喜欢X,就看Y”的建议
分析与洞察
- “今年最受关注的流派”
- “董事的平均评分”
- “随时间观看的电影”图表
- 类型偏好趋势
🎬 流媒体集成
- 显示每个电影都有哪些服务(JustWatch API)
- 按“在Netflix上可用”过滤搜索
- 跟踪您订阅的服务
______________________________________________________________________
技术改进
- 认证:OAuth 2.0,带刷新的JWT令牌
- 测试:工具的单元测试、集成测试、MCP的E2E
- 监控:结构化日志记录、错误跟踪、使用情况分析
______________________________________________________________________
技术说明
MCP传输
该项目使用 可流式HTTP传输,这是MCP服务器的推荐现代方法(从规范版本2025-03-26开始)。旧的仅限苏格兰和南方能源公司的传输已被弃用。
为什么是流式HTTP?
- 支持SSE流和直接HTTP响应
- 更好的会话管理(有状态或无状态)
- 使用标准HTTP方法(GET/POST)
- 比仅SSE传输更灵活、更可扩展
参考文献
______________________________________________________________________
安全注意事项
⚠️ 这是一个演示项目。对于生产使用,请考虑:
- 环境变量:从不承诺
.env或版本控制的API密钥 - 速率限制:保护您的端点免受滥用(使用以下软件包
express-rate-limit) - API键旋转:实现重新生成用户API密钥的方法
- 仅限HTTPS:Render会自动提供此功能
- 输入验证:已经在使用Zod,但考虑进行额外的消毒以防止SQL注入
- 审核日志记录:跟踪谁访问了什么以及何时访问
______________________________________________________________________
资源
______________________________________________________________________
贡献
这是一个教育项目,演示如何在Render上开发和托管OpenAI应用程序。欢迎将其用作您自己应用程序的起点!
学习要点:
- OpenAI Apps SDK小部件开发
- MCP协议实现
- 数据库事务和数据建模
- 外部API集成(TMDB)
- 多提供商LLM集成
- 生产部署模式
______________________________________________________________________
许可证
MIT许可证-仅适用于此演示代码。
第三方服务: 此应用程序使用 TMDB, OpenAI, Anthropic,以及 谷歌双子座 API,每个都有自己的术语。你负责合规。TMDB提供的电影数据。
______________________________________________________________________
问题?问题?打开GitHub问题!
