联系人CRM-远程MCP服务器
为ChatGPT和Claude提供OAuth 2.1身份验证的生产就绪远程MCP服务器
一个功能齐全的联系人/CRM管理系统,作为远程MCP(模型上下文协议)服务器。将其连接到ChatGPT或Claude,并通过自然语言管理您的专业网络。
现场示例: https://contacts-crm-five.vercel.app/api/mcp
为什么存在
大多数MCP示例显示了Claude Desktop的本地stdio服务器。该项目展示了:
- ✅ 远程MCP (HTTP/SSE)用于基于网络的人工智能助手
- ✅ OAuth 2.1与PKCE 用于安全身份验证
- ✅ 动态客户端注册 用于ChatGPT自定义连接器
- ✅ 生产部署 在Vercel无服务器上
- ✅ ChatGPT和Claude 兼容性
非常适合: 学习如何构建远程MCP服务器,或作为您自己的MCP项目的入门模板。
特性
5生产准备工具
- 联系人_管理 -批量添加/更新联系人(幂等追加)
- 联系人_查询 -按公司、状态、带分页的标签筛选
- 联系人_搜索 -在所有联系人字段中进行全文搜索
- 联系方式_跟进 -按日期查找待处理的后续行动
- contacts_delete -按ID或模糊名称匹配删除联系人
技术亮点
- OAuth 2.1通过办事员 -不需要自定义OAuth服务器
- Vercel无服务器 -自动缩放,提供免费等级
- Supabase PostgreSQL -具有全文搜索功能的托管数据库
- Zod验证 -严格的输入验证
.strict()模式 - 字符限制 -LLM上下文的25K令牌自动截断
- 响应格式 -Markdown(人性化)或JSON(机器可读)
- 工具注释 -适当的
readOnly,destructive,idempotent提示
快速开始
先决条件
1.克隆和安装
git clone https://github.com/YOUR-USERNAME/contacts-crm.git
cd contacts-crm
npm install2.设置数据库
- 在以下位置创建新项目https://supabase.com
- 转到SQL编辑器并运行
supabase/schema.sql - 从设置中获取凭据→ API:
- SUPABASE_URL - SUPABASE_SERVICE_ROLE_KEY
3.设置办事员(OAuth提供者)
- 在以下位置创建应用程序https://clerk.com
- 启用登录方法:电子邮件+谷歌(或您选择)
- 重要提示: 转到OAuth→ 启用“动态客户端注册”
- 从API密钥获取凭据:
- CLERK_PUBLISHABLE_KEY - CLERK_SECRET_KEY - CLERK_DOMAIN (格式: https://your-app.clerk.accounts.dev)
4.配置环境
cp .env.example .env
# Edit .env with your actual credentials5.部署到Vercel
npm i -g vercel
vercel login
vercel --prod在Vercel仪表板中添加环境变量→ 设置→ 环境变量(与中的值相同 .env).
6.连接到ChatGPT
- ChatGPT设置→ 连接器→ 添加自定义连接器
- 网址:
https://your-project.vercel.app/api/mcp - 身份验证:OAuth(从发现端点自动发现)
- 使用职员登录
- 完成! ✅
7.连接到克劳德(可选)
- Claude.ai设置→ 连接器→ 添加自定义连接器
- 网址:
https://your-project.vercel.app/api/mcp - OAuth客户端ID/密码:留空(自动发现)
- 使用职员登录
- 完成! ✅
使用示例
添加联系人:
Add Sarah Johnson, VP of Engineering at Acme Corp, met at TechConf 2024搜索:
Find all contacts from Google查询:
Show me contacts with pending follow-ups更新:
Update Sarah's status to Complete项目结构
contacts-crm/
├── api/
│ ├── mcp.ts # Main MCP endpoint (Vercel function)
│ └── oauth-discovery.ts # OAuth 2.1 discovery endpoint
├── src/
│ ├── server.ts # McpServer setup
│ ├── constants.ts # Global constants
│ ├── types.ts # TypeScript types
│ ├── db/supabase.ts # Database client
│ ├── schemas/contacts.ts # Zod validation schemas
│ ├── services/formatter.ts # Response formatting
│ └── tools/ # 5 MCP tools
│ ├── manage.ts
│ ├── query.ts
│ ├── search.ts
│ ├── followup.ts
│ └── delete.ts
├── supabase/
│ └── schema.sql # PostgreSQL schema
├── docs/
│ └── BUILD_JOURNEY.md # How this was built (detailed walkthrough)
├── .env.example # Environment template
├── package.json
├── tsconfig.json
├── vercel.json
└── README.md运作原理
远程MCP架构
ChatGPT/Claude
↓ (OAuth via Clerk)
↓
MCP Server (Vercel)
↓ (Validates OAuth tokens)
↓
Supabase Database关键文件说明
api/mcp.ts-主处理程序使用StreamableHTTPServerTransport(远程MCP)api/oauth-discovery.ts-服务/.well-known/oauth-authorization-server元数据src/server.ts-创建McpServer使用已注册工具的实例- **
src/tools/*.ts** -单个MCP工具实现
OAuth流
- ChatGPT/Claude请求
/.well-known/oauth-authorization-server - 发现端点指向Clerk的OAuth端点
- 用户通过职员登录
- 办事员发放OAuth访问令牌
- 在中随每个MCP请求发送的令牌
Authorization: Bearer头球 - 服务器验证令牌并处理请求
数据库模式
这 contacts 表格包括:
- 身份: 姓名、公司、角色、电子邮件、电话
- 关系: connection_type、how_we_met、linkedin_url
- 随访: 状态(待定/计划/完成),follow_up_action
- 元数据: 注释、标签(数组)、源元数据(JSONB)
- 时间戳: created_at,updated_at(自动更新)
主要特点:
- 唯一约束
(name, email)用于幂等扰乱 - 姓名、公司、角色、备注的全文搜索索引
- 标签数组上的GIN索引用于快速过滤
了解这是如何构建的
看 docs/BUILD_JOURNEY.md 有关以下内容的详细演练:
- 为什么stdio不适用于ChatGPT(需要远程MCP)
- 我们如何选择Clerk而不是构建自定义OAuth
- 数据库约束错误和修复
- 令牌验证策略
- 所有的死胡同以及我们是如何解决的
非常适合了解远程MCP开发或构建自己的服务器。
故障排除
“OAuth错误:未启用动态客户端注册”
在职员仪表板中启用动态客户端注册→ OAuth设置。
“JWT表单无效”或令牌错误
这很正常!OAuth访问令牌不是JWT。在OAuth流成功后,服务器接受任何非空的承载令牌。对于生产多租户,针对Clerk的JWKS端点实施适当的JWT验证。
连接错误
- 验证两个中都设置了环境变量
.env以及Vercel - 检查Supabase项目是否处于活动状态(未暂停)
- 确保职员应用程序处于生产模式
数据库错误
- 跑
supabase/schema.sql创建表和索引 - 验证
SUPABASE_SERVICE_ROLE_KEY(非匿名密钥)已使用
安全说明
- OAuth流程: 职员处理所有身份验证-只有经过身份验证的用户才能获得令牌
- 令牌验证: 目前接受任何非空承载令牌(足以供单个用户/个人使用)
- 生产增强: 对于多租户,根据Clerk的JWKS端点验证令牌
- 秘密: 永不承诺
.env-它在里面.gitignore - RLS: 可以为多租户启用Supabase行级安全
贡献
这是一个个人项目,但欢迎提出问题和建议!如果您发现错误或有改进的想法,请打开一个问题。
许可证
MIT-见许可证文件
资源
______________________________________________________________________
内置❤️ 使用部署在Vercel上的Claude Code,与Clerk进行身份验证,存储在Supabase中。
