用 dsh-calendar 给 DeepSeek Harness 接上 CalDAV 日历读写

前言

DeepSeek Harness(命令名 dsh)是 DeepSeek AI 开源的智能体运行时,核心理念写在官方仓库里:Everything is a Plugin(一切皆插件)。模型、工具、技能、会话、沙箱、存储、循环、调度和界面,都可以按 profile 增删,不必改 harness 源码。官方入门路径是装好 Node.js 后执行 npx @deepseek-ai/dsh web。目前仍是面向开发者的预览版,接口还会变。

智能体很擅长改代码、跑命令,但日程通常不在仓库里,而在 Google 日历、iCloud 或自建 Nextcloud 上。你让它「明天下午两点排一次评审」,它既看不到现有占用,也无法把事件写回去。社区插件 dsh-calendar 补的就是这一段:用 CalDAV 把列表、创建、更新、删除、搜索五件套交给模型。

需要先分清来源。本文引用的插件目录 deepseek-harness-plugin.com 是独立社区站点,用来发现和对比插件,与 DeepSeek / 幻方没有官方从属关系,不要把它当成官方应用商店。下面按该目录详情页、插件 GitHub 仓库(含 README、package.jsoncordis.patch.yml、源码入口)以及 DeepSeek Harness 官方资料交叉核对后整理。

这是什么

dsh-calendar 是一款 工具与能力 插件,由 STARDUSTLC666 维护,源码在 STARDUSTLC666/dsh-calendar。npm 包名同样是 dsh-calendar,当前版本 0.3.2package.json 与 npm registry 一致)。package.json 与 npm 元数据声明许可证为 MIT;仓库根目录目前没有独立的 LICENSE 文件,GitHub 仓库元数据里的 license 字段为空,安装前建议自行核对。

2026 年 8 月 18 日打开目录页和 GitHub 时,星标均为 3。目录页显示主要语言为 JavaScript,收录日期 2026-08-15,最近推送 2026-08-16。仓库源码在 src/ 下是 TypeScript,构建产物在 lib/;运行时要求 Node.js 18 或更高。依赖是 tsdavical.jsundici,没有原生扩展,README 写成「纯 Node 全平台」。

一句话定位:它把 CalDAV 日历变成五个面向模型的工具(calendar_list / calendar_create / calendar_update / calendar_delete / calendar_search),兼容 Google、iCloud、Nextcloud 以及任意自定义 CalDAV 端点。本轮是 node 半身,没有 Web 设置页,配置全部写在 profile 的 cordis.patch.yml 里。

缺配置时插件照常加载,不会把 dsh 拖垮;工具真正被调用时,才会抛出带中文指引的错误,提示补全配置后重启。这是 README 和 cordis.patch.yml 注释里写明的行为。

核心功能

按仓库 README 与源码入口 src/index.ts,插件在 apply(ctx, config) 里向宿主的 ctx.tools 注册五个工具。事件的稳定标识 uid 是 CalDAV 对象的完整 href,更新和删除都用它。

  1. calendar_list:列出某时间段内的事件。start / end 用 ISO 8601,缺省是未来 7 天。默认展开 RRULE 重复事件(expand 默认 truemaxOccurrences 默认 30,范围夹在 1–200):每个实例单独一行,带 isOccurrence: trueseriesStart;非重复事件保持 isOccurrence: false。把 expand 设为 false 时,重复事件按原始单条返回并带 rrule。结果按开始时间稳定排序。
  2. calendar_create:新建事件。summary / start / end 必填,description / location / allDay / rrule 可选。会校验真实日历日期,并要求 end >= start,拒绝 2025-02-30 这类不存在的日期。
  3. calendar_update:按 uid 改事件。未提供的字段保留原值。0.3.2 修过「改其他字段时把 rrule 弄丢」的问题。
  4. calendar_delete:按 uid 删事件。
  5. calendar_search:按关键词在标题、描述、地点、UID 上做客户端过滤,不区分大小写。limit 默认 50,范围夹在 1–200,结果按开始时间排序。搜索返回的是原始系列,不会展开重复实例。

时间约定也写在 README 里:输入输出统一 ISO 8601。定时事件输出为 UTC(例如 2025-01-15T01:00:00Z),全天事件输出 YYYY-MM-DD。输入可以带时区偏移(例如 2025-01-15T09:00:00+08:00),插件内部转成 UTC 再存储。带 TZID 的事件输出会转成 UTC;全天边界、夏令时等复杂规则不做精细处理。

另外两个实现细节值得单独记下:

  • 插件级代理:配置项 proxyUrl(例如 http://127.0.0.1:7890)只把本插件的 CalDAV 请求转到本机代理端口,不改系统代理,也不影响其他插件。README 写明:中国大陆访问 Google / iCloud 的 CalDAV 端点通常需要填这项;国内可直连的服务(例如自建 Nextcloud)可以不填。
  • 客户端失败可重试:0.3.2 起,CalDAV 客户端创建失败后会清空缓存,下一次调用可以重新建连,不再永久复用被拒绝的 Promise。

安装与启用

目录页给出的安装命令如下,以页面原文为准:

dsh plugin add github:stardustlc666/dsh-calendar

如需可复现安装,按目录页说明固定 commit 哈希。撰写时仓库 main 最新提交是 596f0420ac0f72db190d078cec91a4c18916b60b(2026-08-16):

dsh plugin add github:stardustlc666/dsh-calendar#596f0420ac0f72db190d078cec91a4c18916b60b

仓库 README 还写了一种按 npm 包名、并指定 web profile 的装法:

dsh plugin --profile web add dsh-calendar

两种写法指向同一份社区插件。目录页强调:插件以当前 dsh 进程的权限运行,安装时可能执行代码;安装前请检查源代码仓库和许可证。

安装后需要重启 dsh。插件会向 profile 插入一行 id 为 calendar 的配置(见包内 cordis.patch.yml)。默认 providercustom,且未填凭证。

配置与典型用法

所有配置都在当前 profile 的 cordis.patch.yml 里,按 id 覆盖 calendar 这一行的整个 config。通用字段如下:

  • providergoogle | icloud | nextcloud | custom
  • caldavUrl:完整日历集合 URL(custom / icloud 必填;google / nextcloud 也可手填覆盖预设)
  • username:CalDAV 账号(Google / iCloud 用账号邮箱)
  • password:密码;Google / iCloud 请用应用专用密码。推荐改用环境变量 DSH_CALENDAR_PASSWORD,避免明文写进配置文件
  • proxyUrl:本机代理地址
  • calendarId:仅 Google,日历 ID(通常是邮箱)
  • host / user / calendar:仅 Nextcloud

Google 示例(URL 由插件拼成 https://apidata.googleusercontent.com/caldav/v2/<calendarId>/events):

- id: calendar
  name: dsh-calendar
  config:
    provider: google
    username: you@gmail.com
    calendarId: you@gmail.com
    # password 推荐用环境变量 DSH_CALENDAR_PASSWORD
    # 若 CalDAV 端点无法直连,再填:
    # proxyUrl: http://127.0.0.1:7890

iCloud 需要完整日历集合 URL(含用户 ID 与日历 ID),仓库说明可在 iCloud 的日历 CalDAV 设置里找到,插件不做 principal 自动发现:

- id: calendar
  name: dsh-calendar
  config:
    provider: icloud
    username: you@icloud.com
    caldavUrl: https://caldav.icloud.com/123456789/calendars/<日历ID>/

Nextcloud 示例(插件会拼成 https://cloud.example.com/remote.php/dav/calendars/alice/personal/):

- id: calendar
  name: dsh-calendar
  config:
    provider: nextcloud
    username: alice
    host: https://cloud.example.com
    user: alice
    calendar: personal

自定义 CalDAV:

- id: calendar
  name: dsh-calendar
  config:
    provider: custom
    caldavUrl: https://dav.example.com/calendars/me/work/
    username: me

应用专用密码不要和登录密码搞混。README 的路径是:

  • Google:myaccount.google.com → 安全 → 两步验证(需先开启)→ 应用专用密码,生成 16 位密码。
  • iCloud:appleid.apple.com → 登录与安全 → App 专用密码。

调用返回 401/403 时,仓库说明多半是用了登录密码而不是应用专用密码,插件会给出中文提示。认证方式只有 Basic,没有 Google / iCloud 的 OAuth 流程。

配好之后,在会话里可以直接让模型调用这些工具,例如:列出接下来一周的事件、新建一场带 rrule 的周会、按关键词搜「评审」、或按 uid 改时间 / 删除。工具参数以仓库当前 README 为准,本文不另编对话记录。

适用场景与注意事项

适合已经在用 CalDAV 的个人或小团队:希望 DeepSeek Harness 里的智能体能查看空档、写入会议、改时间或按标题搜索,而不必再切到日历网页。自建 Nextcloud 或其它可直连的 CalDAV 服务,配置相对简单;接 Google / iCloud 时,要准备应用专用密码,并按网络环境决定是否填写 proxyUrl

使用前把下面这些限制看清楚,它们都来自仓库「已知限制」,不是推断:

  1. 重复事件calendar_list 默认用 ICAL.RecurExpansion 展开,受 maxOccurrences 封顶;calendar_search 不展开。calendar_update / calendar_delete 针对整个重复系列,不能只改或只删某一次发生(不支持 RECURRENCE-ID)。
  2. 不做 OAuth、不做日历发现:iCloud 必须手填完整集合 URL;没有多日历选择器。
  3. 没有设置页 UI:本轮配置只走 cordis.patch.yml
  4. 超时:工具整体超时 timeoutMs 为 60 秒,不会把 AbortSignal 透传到每一次网络请求。
  5. 凭证与权限:密码会出现在配置或环境变量里,插件能列出、创建、修改和删除日历事件。它以当前 dsh 进程的权限运行,安装前应检查源码与许可证。

小结

dsh-calendar 做的事情很具体:把 CalDAV 日历接到 DeepSeek Harness 的工具层,让智能体在已有的 Google / iCloud / Nextcloud / 自定义日历上完成列表到搜索这一套操作。它不提供设置页,也不做 OAuth;换来的是纯 Node、缺配置不崩启动、以及只作用于本插件的 proxyUrl

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-calendar/

GitHub:https://github.com/STARDUSTLC666/dsh-calendar

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜