🥗 宏MCP服务器
一个生产就绪的MCP(模型上下文协议)服务器,用于使用OAuth 2.0身份验证进行个人宏跟踪。使用Express.js构建,使用Docker容器化,并准备在Railway、AWS或任何容器平台上进行云部署。
✨ 特性
- 📊 膳食跟踪:保存并查询包含完整营养数据的用餐历史记录
- 🔐 安全认证:OAuth 2.0,带PKCE流+谷歌登录+电子邮件/密码
- 👤 用户隔离:行级安全确保每个用户只看到自己的数据
- 🎨 现代用户界面:带有标签导航的漂亮登录/注册体验
- 🐳 Docker就绪:完全容器化,实现一致部署
- ☁️ 云便携:部署到Railway、AWS ECS、Google Cloud Run或任何平台
- 📝 生产测井:使用AsyncLocalStorage进行请求跟踪的结构化JSON日志
- 🔄 多客户端支持:与Claude Desktop、Cursor和ChatGPT无缝协作
📋 先决条件
- Node.js 20+ 促进地方发展
- 码头工人 (可选,用于容器化部署)
- 辅助数据库账户 启用身份验证(开始)
- 创建项目 - 使用Google OAuth提供程序设置身份验证(可选) - 启用电子邮件/密码身份验证
🚀 快速开始
1.克隆和安装
git clone
cd macro-mcp
npm install2.配置环境变量
创建一个 .env 项目根目录中的文件:
# Server Configuration
PORT=3000
NODE_ENV=development
LOG_LEVEL=info
BASE_URL=http://localhost:3000
# Supabase (from your Supabase project settings → API)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your_anon_key_here
# OAuth Secret (generate with: openssl rand -base64 32)
OAUTH_CLIENT_SECRET=your_random_secret_here3.建立数据库
创建餐桌:
-- Create meals table
CREATE TABLE fact_meal_macros (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
created_at TIMESTAMPTZ DEFAULT NOW(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
meal TEXT NOT NULL CHECK (meal IN ('breakfast', 'morning_snack', 'lunch', 'afternoon_snack', 'dinner', 'extra')),
meal_day DATE NOT NULL,
calories INTEGER NOT NULL,
macros JSONB NOT NULL,
meal_items JSONB NOT NULL
);
-- Create index for faster queries
CREATE INDEX idx_meal_macros_user_day ON fact_meal_macros(user_id, meal_day DESC);
-- Enable Row Level Security
ALTER TABLE fact_meal_macros ENABLE ROW LEVEL SECURITY;
-- Policy: Users can only see their own meals
CREATE POLICY "Users can view own meals"
ON fact_meal_macros
FOR SELECT
USING (auth.uid() = user_id);
-- Policy: Users can only insert their own meals
CREATE POLICY "Users can insert own meals"
ON fact_meal_macros
FOR INSERT
WITH CHECK (auth.uid() = user_id);
-- Policy: Users can update their own meals
CREATE POLICY "Users can update own meals"
ON fact_meal_macros
FOR UPDATE
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
-- Policy: Users can delete their own meals
CREATE POLICY "Users can delete own meals"
ON fact_meal_macros
FOR DELETE
USING (auth.uid() = user_id);在Supabase中配置OAuth重定向URL:
- 首选 认证 → URL配置
- 添加这些重定向URL:
- 本地: http://localhost:3000/oauth/supabase-callback.html - 生产: https://your-app.railway.app/oauth/supabase-callback.html
启用Google OAuth(可选):
- 首选 认证 → 提供商 → 谷歌
- 启用Google提供商
- 添加您的Google OAuth客户端ID和密码
- 设置授权重定向URI:
https://your-project.supabase.co/auth/v1/callback
配置电子邮件身份验证:
- 首选 认证 → 提供商 → 电子邮件
- 确保“启用电子邮件提供程序”处于打开状态
- 根据需要配置电子邮件模板
- 可选择禁用“确认电子邮件”以加快测试速度
4.运行服务器
开发模式(热重载):
npm run dev生产方式:
npm start服务器将在 http://localhost:3000
5.测试服务器
检查它是否正在运行:
curl http://localhost:3000/health预期响应:
{
"status": "ok",
"service": "macro-mcp",
"version": "2.0.0",
"timestamp": "2025-11-05T10:30:00.000Z"
}🔌 连接到AI客户端
克劳德桌面
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json\ 视窗: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"macro-mcp": {
"url": "http://localhost:3000/mcp"
}
}
}生产:
{
"mcpServers": {
"macro-mcp": {
"url": "https://your-app.railway.app/mcp"
}
}
}光标
macOS: ~/.cursor/mcp.json\ 视窗: %USERPROFILE%\.cursor\mcp.json
{
"mcpServers": {
"user-macro-mcp": {
"url": "http://localhost:3000/mcp"
}
}
}OAuth流
- 重新启动AI客户端(Claude/Cursor)
- 客户端将检测到需要OAuth
- 出现提示时,单击“连接”或授权
- 您将看到一个包含两个选项的现代身份验证页面:
- 登录:适用于现有用户(谷歌或电子邮件) - 注册:对于新用户(谷歌或电子邮件)
- 完成身份验证
- 您将看到“成功-完成身份验证…”
- 窗口将重定向回您的客户端
- 现在你可以使用所有工具了!
🛠️ 可用工具
save_meal
将一顿饭保存到您的个人跟踪数据库中。
🔐 需要身份验证
参数:
meal(枚举):breakfast,morning_snack,lunch,afternoon_snack,dinner,extrameal_day(字符串):YYYY-MM-DD格式的日期(例如,“2025-11-05”)calories(整数):一餐的总热量macros(对象):常量营养素作为关键价值对
- 例子: {"protein": 25.5, "carbs": 30.2, "fat": 10.5}
meal_items(对象):以克为单位的食品
- 例子: {"chicken breast": 150, "rice": 100, "broccoli": 80}
示例用法:
User: "I had 150g chicken breast, 100g rice, and 80g broccoli for lunch"
Claude: [Calculates macros and saves with save_meal tool]get_meal_data
通过灵活的过滤和聚合查询您的用餐历史。
🔐 需要身份验证
参数:
query_type(必填,枚举):
- recent:最后N餐 - by_date:特定日期的餐食 - date_range:两次约会之间的用餐 - by_meal_type:按膳食类型筛选(早餐、午餐等) - daily_totals:按天汇总卡路里和宏量 - weekly_totals:按周汇总 - monthly_totals:按月汇总
limit(可选,整数):要返回的记录数(默认值:10,用于recent和by_meal_type)date(可选,字符串):YYYY-MM-DD格式的日期(用于by_date,或开始日期date_range)end_date(可选,字符串):的结束日期date_range查询meal_type(可选,枚举):按膳食类型筛选by_meal_type查询
示例用法:
User: "What did I eat yesterday?"
Claude: [Uses get_meal_data with query_type: "by_date"]
User: "Show me my last 5 meals"
Claude: [Uses get_meal_data with query_type: "recent", limit: 5]
User: "What are my daily calorie totals this week?"
Claude: [Uses get_meal_data with query_type: "daily_totals"]
User: "Show all my breakfast meals"
Claude: [Uses get_meal_data with query_type: "by_meal_type", meal_type: "breakfast"]🐳 Docker部署
使用Docker Compose(建议本地使用)
docker-compose up --build手动Docker
# Build the image
docker build -t macro-mcp .
# Run the container
docker run -p 3000:3000 --env-file .env macro-mcpDockerfile使用Alpine Linux的多阶段构建,以获得最小的映像大小(~100MB)。
☁️ 生产部署
铁路(推荐)
- 连接您的存储库:
- 首选 铁路 - 点击“新建项目”→ “从GitHub仓库部署” - 选择宏mcp存储库
- 设置环境变量:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your_anon_key_here
OAUTH_CLIENT_SECRET=your_random_secret_here
NODE_ENV=production
LOG_LEVEL=info注: 铁路自动提供 PORT -不要设置它!
- 获取您的部署URL:
- Railway提供了一个类似的URL https://macro-mcp-production.up.railway.app
- 更新BASE_URL:
- 添加到铁路环境变量:
BASE_URL=https://macro-mcp-production.up.railway.app- 更新Supabase重定向URL:
- 转到Supabase仪表板→ 认证→ URL配置 - 添加: https://macro-mcp-production.up.railway.app/oauth/supabase-callback.html
- 部署:
- 铁路自动推送至主干道 - 检查健康状况: https://your-app.railway.app/health
其他平台
AWS ECS/Fargate
# Push to ECR
docker build -t macro-mcp .
docker tag macro-mcp:latest :latest
docker push :latest
# Create ECS task with environment variables
# Deploy as ECS service谷歌云运行
gcloud run deploy macro-mcp \
--image gcr.io/
/macro-mcp \
--platform managed \
--region us-central1 \
--set-env-vars="NODE_ENV=production,SUPABASE_URL=...,SUPABASE_ANON_KEY=...,OAUTH_CLIENT_SECRET=..."Fly.io
flyctl launch
flyctl secrets set SUPABASE_URL=... SUPABASE_ANON_KEY=... OAUTH_CLIENT_SECRET=...
flyctl deploy🔐 安全特性
- ✅ OAuth 2.0与PKCE:行业标准认证
- ✅ 多种登录方法:谷歌OAuth+电子邮件/密码
- ✅ 行级安全(RLS):数据库强制用户隔离
- ✅ JWT令牌验证:每个API请求都经过验证
- ✅ 异步本地存储:请求作用域身份验证上下文
- ✅ 需要HTTPS:生产强制SSL
- ✅ 秘密管理:仅环境变量
- ✅ 非根容器:Docker以无特权用户身份运行
- ✅ 输入验证:所有工具参数均已验证
📊 监控与调试
结构化日志记录
所有日志都是JSON格式,便于解析:
{
"level": "info",
"timestamp": "2025-11-05T10:30:00.000Z",
"message": "Request authenticated",
"user_id": "abc-123-def",
"path": "/mcp"
}日志级别
通过设置 LOG_LEVEL 环境变量:
error:只有错误warn:警告和错误info:一般信息(建议生产)debug:详细调试(仅用于开发)
MCP检验员测试
# Terminal 1: Start your server
npm run dev
# Terminal 2: Launch inspector
npm run inspector开放时间: http://localhost:6274 用于工具和OAuth流的可视化测试。
🆘 故障排除
“需要身份验证”错误
原因: 令牌已过期或未通过身份验证
解决方案:
- 在您的客户端中,断开并重新连接MCP服务器
- 再次完成OAuth流程
“数据库错误:权限被拒绝”
原因: RLS策略设置不正确
解决方案:
-- Check existing policies
SELECT * FROM pg_policies WHERE tablename = 'fact_meal_macros';
-- Ensure you have the policies listed in the setup sectionOAuth重定向循环/“缺少必需的OAuth参数”
原因: 重定向URL不匹配或缺少OAuth状态
解决方案:
- 检查Supabase身份验证设置是否与您的BASE_URL完全匹配
- 确保
/oauth/supabase-callback.html位于重定向URL列表中 - 对于Cursor/ChatGPT:服务器会自动处理丢失的OAuth参数
客户端中未显示工具
原因: 服务器未正确连接
解决方案:
- 检查服务器是否正在运行:
curl http://localhost:3000/health - 验证配置文件是否具有正确的URL
- 重新启动AI客户端
- 检查客户端日志中的连接错误
注册页面显示“配置错误”
原因: Supabase凭据未正确注入
解决方案:
- 确保服务器正在运行(不直接访问静态文件)
- 验证是否在中设置了SUPABASE_URL和SUPABASE_ANON_KEY
.env - 更改环境变量后重新启动服务器
📁 项目结构
macro-mcp/
├── src/
│ ├── index.js # Express app entry point
│ ├── config/
│ │ └── env.js # Environment variable validation
│ ├── routes/
│ │ ├── oauth.js # OAuth 2.0 + PKCE implementation
│ │ └── mcp.js # MCP protocol handler (uses AsyncLocalStorage)
│ ├── tools/
│ │ └── meals.js # Meal tracking tools
│ └── utils/
│ └── logger.js # Structured JSON logging
├── public/
│ └── oauth/
│ ├── signup.html # Modern auth UI (sign in + sign up)
│ └── supabase-callback.html # OAuth callback handler
├── Dockerfile # Multi-stage Alpine build
├── docker-compose.yml # Local development with Docker
├── railway.json # Railway platform configuration
├── package.json # Dependencies and scripts
├── .env.example # Environment variable template
├── mcp-config.json # MCP Inspector configuration
└── README.md # This file🧪 发展
添加新工具
- 在中创建工具定义
src/tools/yourTool.js:
export function getYourTools() {
return [{
name: 'your_tool_name',
description: 'What your tool does',
inputSchema: { /* JSON schema */ },
requiresAuth: true, // or false
handler: async (args, authInfo) => {
// Your logic here
return {
content: [{
type: 'text',
text: 'Result'
}]
};
}
}];
}- 注册
src/routes/mcp.js:
import { getYourTools } from '../tools/yourTool.js';
const yourTools = getYourTools();
const allTools = [...mealTools, ...yourTools];- 更新README文档
运行测试
# Unit tests (when implemented)
npm test
# Manual testing with MCP Inspector
npm run inspector📜 许可证
MIT许可证-有关详细信息,请参阅许可证文件
🤝 贡献
欢迎投稿!拜托:
- 分叉存储库
- 创建要素分支
- 进行更改
- 提交拉取请求
💬 支持
- 问题:在GitHub上打开一个问题
- 文档:查看此README和故障排除部分
- MCP规范: 模型上下文协议
🙏 致谢
- 模型上下文协议 -协议规范
- Supabase -身份验证和数据库
- Express.js -Web框架
- 铁路 -部署平台
______________________________________________________________________
内置❤️ 对于MCP社区
