huckleberry-mcp-worker
huckleberry-mcp-worker
一个为 Huckleberry 婴儿追踪应用实现的 模型上下文协议 服务器,运行在 Cloudflare Worker 上。
这是 bckenstler/py-huckleberry-mcp 的 TypeScript 移植版本。原作是一个通过 google-cloud-firestore 与 Firestore 通信的 Python stdio 服务器,由于使用 gRPC 协议,无法在 Workers 上运行。此移植版本通过 fetch 调用 Firebase REST API 访问同一后端,并通过 Streamable HTTP 提供 MCP 服务。
实际区别是:它始终在线。客户端记录小睡时无需笔记本电脑保持唤醒。
工具
Python 服务器中的所有 23 个工具均已实现,此外还增加了 delete_record。
领域 | 工具 |
儿童 |
|
睡眠 |
|
喂养 |
|
尿布 |
|
成长 |
|
记录 |
|
每个历史工具都会报告每条记录的 interval_id,这正是 delete_record 所接受的参数。
针对 Python 服务器的修复
移植过程中发现了四个缺陷,已在此修正。
母乳喂养时长单位错误。 后端将 leftDuration / rightDuration 以秒为单位存储——应用的计时器也是这么写的——但 log_breastfeeding 直接传递了调用者的分钟值。记录一次 5 分钟的喂养会被记录为 5 秒。调用者之前必须传入 300 来表示 5 分钟;此处 left_duration_minutes: 5 表示五分钟。
单日历史查询无结果。 日期范围的两端都被解析为午夜,因此当 start_date == end_date 时会生成一个空窗口,服务器报告某一天没有记录,而实际上那天有很多记录。现在范围采用半开区间 [start_of_start_date, start_of_end_date + 1 day),使得两端都包含在内。
睡眠历史中的 end_time 始终为 null。 代码读取了一个后端从未写入的 end 字段。现已从 start + duration 推导得出。
list_children 中的 birth_date 始终为 null。 后端字段名为 birthdate;而服务器读取的是 birthDate。
get_feeding_history 现在还会返回每条记录的 mode,以及相关的详细信息:奶瓶的量和类型,固体食物的名称和反应。没有这些信息,固体食物记录会显示为空行,与零长度的哺乳时段无法区分——这正是一条完好的记录被误认为缺失记录的原因。
设置
需要 Node 18+ 和一个 Cloudflare 账户。
npm install
npx wrangler login设置密钥——它们由 Cloudflare 加密存储,永不保存在仓库中:
npx wrangler secret put HUCKLEBERRY_EMAIL
npx wrangler secret put HUCKLEBERRY_PASSWORD
npx wrangler secret put MCP_AUTH_TOKEN # a long random string you generate
npx wrangler secret put HUCKLEBERRY_TIMEZONE # e.g. America/Sao_PauloHUCKLEBERRY_TIMEZONE 默认为 America/New_York。它决定了如何解释像 "2026-08-17T15:47:00" 这样的朴素日期时间,因此正确设置它很重要。
部署:
npm run deploy身份验证
Worker 的 URL 是公开的,而服务器持有儿童健康记录的凭据,因此每个请求都必须携带 bearer token:
Authorization: Bearer <MCP_AUTH_TOKEN>未经有效令牌的请求会在调用 Huckleberry 之前得到 401 响应。使用类似 openssl rand -base64 32 的命令生成一个令牌。
无法发送标头的客户端
某些 MCP 客户端只接受一个 URL——例如 claude.ai 的自定义连接器,它接受一个 URL 和可选的 OAuth 凭据,但没有用于 Authorization 的字段。对于这些客户端,服务器也支持将令牌作为 URL 的最后一段路径:
POST https://<your-worker>.workers.dev/mcp/<MCP_URL_TOKEN>MCP_URL_TOKEN 是与 MCP_AUTH_TOKEN 不同的密钥,这样做是故意的:请求路径会出现在访问日志、浏览器历史和引用来源中,而标头不会。将它们分开意味着通过 URL 泄露不会危及标头凭据,并且任一凭据都可以独立轮换。如果 MCP_URL_TOKEN 未设置,路由会回退到 MCP_AUTH_TOKEN,这很方便,但放弃了上述分离性。
npx wrangler secret put MCP_URL_TOKEN在客户端支持的情况下,优先使用标头方式。
客户端配置
对于 Claude Code:
claude mcp add --transport http huckleberry https://<your-worker>.workers.dev/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"本地开发
cp .dev.vars.example .dev.vars # then fill it in; .dev.vars is gitignored
npm run devcurl -X POST http://localhost:8787/mcp \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'设计说明
无状态。 每个请求通过 Cloudflare 的 agents SDK 中的 createMcpHandler 创建一个全新的 McpServer。不涉及 Durable Objects 或会话存储,因为每个工具都是一个自包含的读取或写入操作。
令牌缓存。 Firebase ID 令牌有效期为一个小时,缓存在模块作用域内,因此落在热隔离区的请求可以跳过重新身份验证。冷隔离区多耗费一次往返。在空中被拒绝的令牌会触发一次重新身份验证和重试。
数值类型。 Firestore 区分整数和双精度浮点数,应用将某些字段写为一种类型,将其他字段写为另一种类型。必须存储为双精度浮点数的值会包装在 dbl() 中,以便此服务器写入的记录与应用写入的记录匹配。
多条目文档。 历史数据有两种形态:带有顶层 start 的普通文档,以及在 data 下包含许多条目的批量文档。嵌套的起始时间无法在服务器端过滤,因此批量文档会被整体获取并在 Worker 中过滤。记录通过 is_multi_entry 报告它们来自哪种形态。
删除记录
Python 服务器没有删除功能,普遍认为后端不允许删除。事实并非如此:对文档路径的 DELETE 操作会返回 200。真正缺少的是记录的 ID,历史工具从未报告过它。
因此历史工具现在会返回 interval_id,而 delete_record 会删除其指定的记录。批量条目——多个记录打包在一个文档的 data 下——通过 <documentId>#<entryKey> 进行寻址,并作为其父文档的一个字段被移除。
删除操作还会将 prefs.last* 重新指向最新的幸存记录。应用直接读取这些指针,因此删除操作如果不重新指向,会导致应用显示一条已不存在的记录。
已知限制
删除是永久性的。 无法撤销。在调用
delete_record之前,请先通过历史查询进行确认。固体食物只读。
get_feeding_history会报告固体食物条目及其食物名称和反应,但没有创建固体食物条目的工具。start_sleep不会阻止已运行的计时器。 Python 服务器记录说明它会在这种情况下失败,但实际上从未检查过;此处保留了此行为,而未进行静默更改。备注不会往返进入睡眠记录。
details字段是一个固定的复选框结构,不是自由文本。
许可证
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
Cloud-hosted MCP server for durable AI memory
Hosted remote MCP server for YNAB on Cloudflare Workers with OAuth
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jcrispiniano/huckleberry-mcp-worker'
If you have feedback or need assistance with the MCP directory API, please join our Discord server