关于 Neutra
Neutra 是一项远程服务,可让两人的 AI 助手安排会面,而不向对方透露各自的空闲时间。它匹配可用时段并发送一份日历邀请;其中一方也可通过 Google 登录页面、无需使用助手即可回复。
主要功能
- 01匹配双方的空闲时段
- 02发送双方共用的日历邀请
- 03保护双方的时间隐私
- 04支持无需助手的网页回复
- 05决定达成后删除排期数据
适用场景
- 01通过不同助手安排会面
- 02邀请未使用助手的人参与
- 03不共享日历也能协调时间
MCP 相关
Neutra 是支持 Google 登录的远程 MCP 服务。其工具可创建和回复排期请求、查询状态及取消请求。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://neutra.day/mcpclaude mcp add --transport http emokeo-neutra https://neutra.day/mcp{"mcpServers":{"emokeo-neutra":{"type":"http","url":"https://neutra.day/mcp"}}}在 Cursor 中打开{"servers":{"emokeo-neutra":{"type":"http","url":"https://neutra.day/mcp"}}}在 VS Code 中打开{"mcpServers":{"emokeo-neutra":{"type":"http","url":"https://neutra.day/mcp"}}}{"mcpServers":{"emokeo-neutra":{"serverUrl":"https://neutra.day/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
Neutra
一个中立的平台,让人们的 AI 助手替他们达成共识,同时任何人都看不到其他人的数据。
目前它只做一件事:让两个人的助手找到见面时间。每个助手都会告诉 Neutra 自己的用户何时有空。Neutra 找出双方都有空的时间,并向双方发送一封日历邀请。任何一方都看不到对方的时间。
sequenceDiagram
participant A as Anna's assistant
participant N as Neutra
participant B as Ben's assistant
A->>N: Anna's free times
N-->>A: a message for Anna to forward to Ben
Note over A,B: Anna forwards it in any chat
B->>N: Ben's free times + the code
N-->>A: calendar invite
N-->>B: calendar invite
它可与不同的助手协同工作:Anna 可以使用 Claude,Ben 可以使用其他助手,只要双方都支持 MCP 连接器。Ben 也可以不使用助手直接回复:消息中包含一个简单页面的链接,他可以在页面上使用 Google 登录,并填写自己有空的时间。
隐私,始于设计
- Neutra 不使用 AI。 Neutra 只是比较时间范围的普通代码。你的时间绝不会进入我们的 AI 模型。
- 任何人都看不到其他人的时间。 返回的只有匹配成功的见面时间。绝不会返回对方的时间,代码也只以哈希形式存储。
- 决定一旦敲定,时间就会被删除,最迟也会在 14 天后删除。回复的人完全不会存储时间。
- 重试无法推测日历。 回复的人最多只能尝试 3 次,而且每次提供的时间都必须至少是见面时长的两倍,因此没人能逐个时段探测你何时有空。
- 数据保留在欧盟境内,位于 Cloudflare 的欧盟管辖区域。
- 通过测试验证:
test/decisions.test.ts验证任何响应中都不会出现时间或代码。
详情:隐私页面。
试用
- 在 Claude 中:打开连接器目录中的 Neutra,然后点击 Connect。使用其他助手:将
https://neutra.day/mcp添加为自定义连接器。 - 使用 Google 登录。Neutra 只会使用你的姓名和电子邮件:用于将邀请发送到正确的地址,并确保只有你能回复。
- 提问:“使用 Neutra 下周和 Ben 约一个小时。我周二和周四 18:00–21:00 有空。” 转发它提供给你的消息。
面向 Agent 构建者
一个支持 Google 登录的远程 MCP 服务。资源遵循 Google 的 AIP:decisions/{decision} 和 decisions/{decision}/answers/{answer}。
| 工具 | 功能 |
|---|---|
create_decision | 使用你的用户有空的时间和见面时长发起一项决策。返回代码和一条可转发的消息。 |
create_answer | 使用消息中的代码(neutra:<id>.<code>)和你的用户有空的时间进行回复。匹配成功后会发送邀请。 |
get_decision | 查看状态(WAITING、NO_MATCH、INVITE_SENT、ACCEPTED、DECLINED、EXPIRED)和见面时间。 |
delete_decision | 取消你发起的决策,包括其邀请。 |
get_answer | 读取你自己的回复。 |
create_feature_request | 将你的用户希望 Neutra 实现、但目前尚不支持的功能告诉 Neutra 的开发者。 |
get_feature_request | 读取你提交的功能请求。 |
价格决策(默认关闭)
两个人在互不知晓对方底线的情况下商定价格(租金、售价或费用)。价格决策是一种决策:发起方的助手调用 create_decision,传入 decision.price(主题、详情、currencyCode、单位、answerBy)以及只含一个数字的 starterAnswer.price:如果发起方收款,则填写 minimumToAccept;如果发起方付款,则填写 maximumToPay。另一方调用 create_answer 并传入 answer.price,始终使用决策指定的币种。如果付款方的最高可付金额达到收款方的最低接受金额,就达成交易;否则,双方只会听到“未达成交易”。双方都会通过电子邮件收到结果。
decision.price.rule 用于指定交易在重叠区间内以什么价格成交,以及会透露哪些信息:
| 规则 | 价格 | 达成交易会透露的信息 |
|---|---|---|
MIDPOINT(默认) | 两个数字重叠区间的中点 | 双方都可以推算出对方的数字 |
LOWEST | 收款方的最低接受金额 | 付款方会知道该金额;付款方的数字仍保密 |
HIGHEST | 付款方的最高可付金额 | 收款方会知道该金额;收款方的数字仍保密 |
MIDPOINT_ROUNDED | 中点,按 roundTo 四舍五入(默认约为发起方数字的 1%),且不超出重叠区间 | 双方只能大致推算出对方的数字 |
RANDOM | 重叠区间内均匀随机选取的价格 | 双方只能知道对方的数字高于或低于该价格 |
OVERLAP_ONLY | 无:结果仅为“你们的数字有重叠”或“没有重叠”(薪资、初步筛选) | 不透露任何信息:双方的数字都不会显示 |
decision.price.maxAnswers(1 到 3,默认值为 1)表示对方最多可以提交多少个数字。如果未达成交易但仍有答复次数,请求会继续开放,对方可以继续提交;发起方看不到未成功的尝试。答复方在答复前,会通过交接消息、预览和网页收到用通俗语言说明的规则(ruleText)及剩余答复次数。
- 答复方的数字绝不会被存储,即使在多次尝试之间也不会。发起方的数字使用根据请求代码生成的密钥加密(请求代码仅以哈希形式存储),并会在请求完成或结束后立即清除。
- 使用
code调用get_decision会返回请求内容的preview,供答复前查看(yourSide为PAYS时,提交maximumToPay;为RECEIVES时,提交minimumToAccept),且不会消耗答复次数。 - 输入和输出遵循
neutra.v1消息(proto3 JSON):所有价格字段都位于price中,例如decision.price.agreedPriceText。 - 限价也可以是一个范围,例如
"10000-20000"(带有下限的薪资区间,或带有上限的价格)。两端都计入:交易要求双方的范围有重叠,规则会在重叠区间内选定价格。单个数字表示另一端不设限。内侧端点只能与对方对应的一侧比较,因此夸大它没有好处。发起方范围的两端都会被保密;答复方的范围绝不会被存储。 - 任一调用中的
validateOnly都会将数字返回给提交者确认,而不会发送任何内容。 - 每人每天最多可答复 3 个价格请求(同一请求的所有尝试只计为一次)。
- 在
wrangler.jsonc中通过PRICE_DECISIONS切换:off(对任何人都不产生变化)、testers(只有ALLOWED_EMAILS中的人员能在create_decision中使用decision.price;任何拥有代码的人都可以答复)或open。请参阅docs/RUNBOOK.md。
错误使用 google.rpc 代码:NOT_FOUND、PERMISSION_DENIED、FAILED_PRECONDITION、INVALID_ARGUMENT、RESOURCE_EXHAUSTED(已达到每日或每小时限制)。
运行 Neutra
运行于 Cloudflare Workers,并使用 D1,基于 Cloudflare 的 remote-mcp-google-oauth 模板。每次推送到 main 时,GitHub Actions(.github/workflows/deploy.yml)都会进行类型检查、测试并部署;每次部署前都会应用 migrations/ 中的迁移。所有更改都通过拉取请求提交。
设置(仅需完成一次)
Cloudflare
- 帐户 ID 和
MCP_RESOURCE地址位于wrangler.jsonc中。域名neutra.day已在 Cloudflare 控制面板中作为自定义域名绑定到 Worker。 - API 令牌:使用“Edit Cloudflare Workers”模板,并添加 D1: Edit 权限。
- D1 数据库(EU 区域)和
OAUTH_KV命名空间通过wrangler d1 create neutra --jurisdiction eu和wrangler kv namespace create OAUTH_KV创建一次;它们的 ID 位于wrangler.jsonc中。
Google Cloud(项目 neutra)
- Google Auth Platform:受众设为 External,发布状态设为 In production(测试模式会使刷新令牌在 7 天后过期)。品牌信息:使用上方的主页和隐私政策链接,授权域名为
neutra.day。 - Web 客户端的重定向 URI 为
https://neutra.day/callback,用于连接器登录和浏览器答复页面(仅在创建新的邀请者密钥时添加https://developers.google.com/oauthplayground;本地开发时添加http://localhost:8788/callback)。 - 已启用 Google Calendar API 和 Gmail API。
- 登录仅请求邮箱和个人资料。当
ACCESS_MODE为allowlist时,只有ALLOWED_EMAILS中的用户可以登录。
邀请者([email protected])
- 使用 Web 客户端自身的凭据,通过 OAuth 2.0 Playground 获取具有
calendar.events和gmail.send权限范围的刷新令牌(步骤见docs/RUNBOOK.md)。
GitHub 密钥(Settings → Secrets and variables → Actions)
| 密钥 | 内容 |
|---|---|
CLOUDFLARE_API_TOKEN | Cloudflare API 令牌 |
GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET | Web 客户端 |
COOKIE_ENCRYPTION_KEY | 任意较长的随机字符串 |
ALLOWED_EMAILS | 测试用户的邮箱,以逗号分隔 |
INVITER_REFRESH_TOKEN | 邀请者的刷新令牌 |
本地开发
运行 npm install,将 .dev.vars.example 复制为 .dev.vars 并填写内容,然后运行 npm run dev。使用 npx @modelcontextprotocol/inspector@latest 对 http://localhost:8788/mcp 进行测试。
许可证
MIT,详见 LICENSE。包含 Cloudflare 的 MIT 许可模板中的代码。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。