remindctl mcp
Rust中封装的MCP服务器 remindctl 因此远程客户端可以通过macOS主机管理Apple提醒。
此项目专为Linux机器(或任何非苹果机器)需要通过Mac读/写提醒的设置而设计。
它暴露了什么
- 主控程序 工具 用于提醒和列表管理(
reminders_list,reminder_add,reminder_delete,lists_list,process_pending_actions等等) - 主控程序 资源 用于状态/列表/配置快照
- 可流式HTTP传输
/mcp
需求
- 带有Apple提醒的macOS主机
remindctl在该主机上安装并授权- 防锈工具链(
cargo)
在主机上快速验证:
remindctl status --json --no-input构建并运行
从该目录:
cargo run --release默认情况下,服务器绑定到 127.0.0.1:8787.
环境变量
BIND_ADDR(默认值:127.0.0.1:8787)AUTH_REQUIRED(默认值:true)API_KEY(需要时AUTH_REQUIRED=true)REMINDCTL_BIN(默认值:remindctl)REMINDCTL_READ_TIMEOUT_SECS(默认值:10)REMINDCTL_WRITE_TIMEOUT_SECS(默认值:20)
示例:
# Safe default: auth enabled
AUTH_REQUIRED=true API_KEY="change-me" BIND_ADDR=127.0.0.1:8787 cargo run --release
# Local trusted testing only
AUTH_REQUIRED=false BIND_ADDR=127.0.0.1:8787 cargo run --release快速安装(macOS服务)
如果你只想在Mac上启动/登录时运行它:
API_KEY="change-me" AUTH_REQUIRED=true BIND_ADDR=127.0.0.1:8787 ./scripts/install-macos-service.sh如果您有很多提醒,请设置更高的读取超时时间:
API_KEY="change-me" AUTH_REQUIRED=true BIND_ADDR=127.0.0.1:8787 REMINDCTL_READ_TIMEOUT_SECS=60 ./scripts/install-macos-service.sh安装程序解析 REMINDCTL_BIN 在写入之前,先转到绝对路径 launchd plist,因此该服务不依赖于您的交互式shell PATH.
然后验证:
launchctl print gui/$(id -u)/com.remindctl.mcp以macOS服务运行(启动时启动)
使用 launchd 因此MCP服务器在登录/引导时自动启动。
建议:使用自动化脚本。
# install/update binary, write plist, load and start service
API_KEY="change-me" AUTH_REQUIRED=true BIND_ADDR=127.0.0.1:8787 ./scripts/install-macos-service.sh可选变量:
SERVICE_LABEL(默认值:com.remindctl.mcp)BIND_ADDR(默认值:127.0.0.1:8787)AUTH_REQUIRED(默认值:true)API_KEY(需要时AUTH_REQUIRED=true)REMINDCTL_BIN(默认值:解析remindctl从您当前的PATH安装时)REMINDCTL_READ_TIMEOUT_SECS(默认值:60在安装程序中)REMINDCTL_WRITE_TIMEOUT_SECS(默认值:20在安装程序中)
卸载:
./scripts/uninstall-macos-service.sh手动设置(如果您愿意)
将二进制文件安装到 ~/.cargo/bin,然后将服务指向稳定, 绝对路径。
- 构建+安装/更新二进制文件:
cargo install --path . --locked --force
# binary path: ~/.cargo/bin/remindctl-mcp- 创建日志目录:
mkdir -p ~/.openclaw/logs- 创建
~/Library/LaunchAgents/com.remindctl.mcp.plist:
Label
com.remindctl.mcp
ProgramArguments
/Users/YOUR_USER/.cargo/bin/remindctl-mcp
EnvironmentVariables
BIND_ADDR
127.0.0.1:8787
AUTH_REQUIRED
true
API_KEY
change-me
REMINDCTL_BIN
/opt/homebrew/bin/remindctl
RunAtLoad
KeepAlive
StandardOutPath
/Users/YOUR_USER/.openclaw/logs/remindctl-mcp.out.log
StandardErrorPath
/Users/YOUR_USER/.openclaw/logs/remindctl-mcp.err.log
- 加载并启用它:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.remindctl.mcp.plist
launchctl enable gui/$(id -u)/com.remindctl.mcp
launchctl kickstart -k gui/$(id -u)/com.remindctl.mcp- 验证服务+端点:
launchctl print gui/$(id -u)/com.remindctl.mcp
npx mcporter list remindctl
npx mcporter call remindctl.server_health注:未加工 curl 请求 /mcp 必须遵循MCP初始化 (initialize -> notifications/initialized ->同一会话中的工具调用)。 召唤 tools/list 直接无需初始化返回: Unexpected message, expect initialize request.
有用的命令:
# Check status
launchctl print gui/$(id -u)/com.remindctl.mcp
# Restart after binary/env changes
launchctl kickstart -k gui/$(id -u)/com.remindctl.mcp
# Tail logs
tail -f ~/.openclaw/logs/remindctl-mcp.err.log
# Stop and remove service
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.remindctl.mcp.plist笔记:
- 替换
YOUR_USER和API_KEY在装载之前。 - 使用绝对值
REMINDCTL_BIN路径在plist因为launchd通常不会继承你的shellPATH. - 代码更新后,运行
cargo install --path . --locked --force然后launchctl kickstart -k .... - 更喜欢
AUTH_REQUIRED=true对于任何非本地主机的暴露。 LaunchAgents在登录的用户会话中运行,这通常是您想要的提醒访问权限。
OpenClaw+MCPorter设置
该项目旨在通过以下方式从OpenClaw中消费 mcporter.
安装MCPorter(任意一个):
npx mcporter list
# or: pnpm add -g mcporter
# or: brew install steipete/tap/mcporter创建 ~/.mcporter/mcporter.json (或 config/mcporter.json 在您的工作空间中):
{
"mcpServers": {
"remindctl": {
"description": "Apple Reminders MCP via remindctl-mcp",
"baseUrl": "http://127.0.0.1:8787/mcp",
"headers": {
"Authorization": "Bearer change-me"
}
}
}
}如果 AUTH_REQUIRED=false,删除 headers.Authorization 钥匙。
使用MCPorter快速验证:
npx mcporter list remindctl
npx mcporter call remindctl.server_health
npx mcporter call remindctl.reminders_list filter=pending______________________________________________________________________
远程访问选项1:SSH隧道
当MCP服务器在Mac上运行,而客户端在Linux上运行时,请使用此选项。
1) 在Mac上运行服务器(仅限本地主机)
AUTH_REQUIRED=true API_KEY="change-me" BIND_ADDR=127.0.0.1:8787 cargo run --release2) 创建从Linux到Mac的隧道
ssh -N -L 8787:127.0.0.1:8787 your-mac-user@your-mac-host现在Linux可以到达MCP端点:
http://127.0.0.1:8787/mcp3) 将MCPorter(在Linux上)指向本地主机
集 baseUrl 在MCPorter配置中 http://127.0.0.1:8787/mcp 并保持相同的承载密钥。
为什么这是好的:
- 无公共港口暴露
- 简单且加密
- 无需更改防火墙/路由器即可工作
______________________________________________________________________
远程访问选项2:尾秤
当两台机器位于同一尾网上时,请使用此功能。
1) 在两台机器上安装/登录Tailscale
- Mac主机和Linux客户端必须同时出现在
tailscale status.
2) 在Mac上运行服务器
您可以保留localhost+Tailscale SSH,也可以直接绑定以访问Tailnet:
AUTH_REQUIRED=true API_KEY="change-me" BIND_ADDR=0.0.0.0:8787 cargo run --release然后使用Mac Tailnet IP(示例 100.x.y.z).
3) 在Linux上配置MCPorter
{
"mcpServers": {
"remindctl": {
"description": "Apple Reminders MCP via remindctl-mcp",
"baseUrl": "http://100.x.y.z:8787/mcp",
"headers": {
"Authorization": "Bearer change-me"
}
}
}
}然后验证:
npx mcporter list remindctl
npx mcporter call remindctl.server_health建议使用Tailscale硬化
- 保持
AUTH_REQUIRED=true(纵深防御) - 使用Tailnet ACL将访问权限限制为仅限您的Linux节点/用户
- 请勿通过公共隧道/漏斗暴露此服务
______________________________________________________________________
行为说明
- 写入操作从不使用数字索引语义。
- 只有在明确的情况下才接受短ID。
reminder_delete是幂等友好的:
- 默认情况下,可以报告已经丢失的引用,而不会失败 - 当没有提供ID时,可以使用最近的提醒上下文
OpenClaw技能
此repo包括与OpenClaw兼容的技能 skill/remindctl-mcp/SKILL.md.
要在OpenClaw中使用它:
- 复制/符号链接
skill/进入您的OpenClaw工作区skills/remindctl-mcp/. - 确保
mcporter已安装,您的MCPorter配置具有remindctl服务器入口。 - 开始一个新的OpenClaw课程(技能在课程开始时快照)。
该技能教OpenClaw使用MCPorter进行提醒流,只需最少的调用,并避免无关的文件系统验证。
它还为OpenClaw定义了一个离线安全队列工作流:
- 队列文件:
./.openclaw/{current_workspace}/remindctl-pending-actions.jsonl - 当MCP关闭时,写操作会排队,而不是在紧循环中重试
- 使用一个批处理调用在每个心跳节拍上重试排队的操作(
process_pending_actions)
这与OpenClaw的心跳优先自动化模型相匹配,适用于长时间离线窗口。
{current_workspace} 应与活动的OpenClaw工作区名称/路径上下文匹配。 队列文件必须是工作区范围的,这样不同的工作区就不会混合挂起的操作。
HEARTBEAT.md说明(复制/粘贴一次)
将此块添加到您的OpenClaw HEARTBEAT.md 一次:
- If `./.openclaw/{current_workspace}/remindctl-pending-actions.jsonl` exists and has entries:
- Call `remindctl.server_health` once.
- If unhealthy, keep the queue unchanged and respond with `HEARTBEAT_OK`.
- If healthy, send queued actions in one call to `remindctl.process_pending_actions`.
- For each success result, remove that action from queue.
- For each failure result, increment attempts and keep it queued with last error.
- If one or more actions were applied, notify the user with a concise summary of what was completed.
- If no actions were completed in this cycle, keep output concise and respond with `HEARTBEAT_OK`.重要提示:
- 不要多次附加此块。
- 如果相同的指令已存在于
HEARTBEAT.md,按原样重复使用它们。 - 首选流程:要求OpenClaw仅在缺少块时添加块。
发展检查
cargo fmt
cargo clippy --all-targets --all-features -- -D warnings
cargo test