关于 Time Doctor
Time Doctor 是面向需要查询员工工时数据的组织和 AI 助手的 MCP 服务,通过 Time Doctor API 提供公司、用户、项目、任务、工作时段和时间使用统计。
主要功能
- 01列出并查询公司和用户
- 02按条件查找项目与任务
- 03按时间范围读取工作时段日志
- 04获取汇总时间使用统计
- 05在内部处理登录与令牌续期
适用场景
- 01按公司或用户查看跟踪的工作
- 02查找项目中的任务
- 03检查指定日期范围内的工作时段
- 04按应用或类别汇总时间
MCP 相关
该 MCP 服务将 Time Doctor API 操作作为工具提供,涵盖公司、用户、项目、任务、工时日志、邀请检查和时间使用数据。支持 stdio 或 HTTP 传输,并在内部处理 Time Doctor 登录和令牌续期。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e TIMEDOCTOR_EMAIL -e TIMEDOCTOR_PASSWORD -e MCP_TRANSPORT -e AUTH_MODE -e LOG_LEVEL ghcr.io/wyre-ai/timedoctor-mcp:v1.0.3TIMEDOCTOR_EMAILTime Doctor account email addressTIMEDOCTOR_PASSWORD密钥Time Doctor account passwordMCP_TRANSPORTTransport mode for the server. Set to 'stdio' for local CLI use; the image defaults to 'http' for gateway hosting.AUTH_MODE密钥Credential source: 'env' reads vars locally, 'gateway' expects header injection from the WYRE MCP Gateway.LOG_LEVELLog verbosity: debug, info, warn, error本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/wyre-ai/timedoctor-mcp:v1.0.3stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Time Doctor MCP 服务
面向 AI 助手和 WYRE Conduit 网关的 Time Doctor 员工工时追踪/生产力监控 API 的 MCP 服务,涵盖公司、用户、项目、任务和时间使用统计。
身份验证
Time Doctor 当前官方文档记载的 API(https://timedoctor.redoc.ly,API Version 1.0.0)使用用户登录 app.timedoctor.com 时所用的同一邮箱和密码进行身份验证,不需要单独的客户端 ID/密钥应用注册流程。POST /api/1.0/login 会将邮箱和密码换成有效期为六个月的 JWT bearer token(后续每次调用均需在 Authorization 中传入 JWT {token})。此服务会在内部处理凭据交换(并在遭到拒绝时重新登录),调用方只需提供邮箱和密码。
部分 Time Doctor 账户登录时需要 TOTP(2FA)代码;此连接器目前不支持启用了 2FA 的账户。
配置
复制 .env.example,并设置以下变量。
| 环境变量 | 必填 | 说明 |
|---|---|---|
TIMEDOCTOR_EMAIL | stdio 和 AUTH_MODE=env 时必填 | Time Doctor 账户邮箱地址。 |
TIMEDOCTOR_PASSWORD | stdio 和 AUTH_MODE=env 时必填 | Time Doctor 账户密码。 |
MCP_TRANSPORT | 否 | stdio(默认)或 http。 |
AUTH_MODE | 否 | gateway(Docker 镜像和 Compose)或 env。Gateway 模式要求每个 /mcp 请求都提供 X-TimeDoctor-Email 和 X-TimeDoctor-Password,且不会回退使用 TIMEDOCTOR_*。env 模式仅在 S2S 身份验证成功后使用这些变量。未设置时默认为 env(stdio 和单租户 HTTP)。 |
CONDUIT_S2S_SECRET | HTTP 模式下必填 | 服务间密钥。如果该值为空或为已知占位符(changeme、secret、replace-me、replace-with-a-real-secret 及其他示例值),HTTP 服务会记录错误并以非零状态码退出。使用 openssl rand -hex 32 生成密钥。未设置该值时,Compose 不会启动。此值绝不会写入日志。 |
MCP_ALLOW_INSECURE_DEV | 否 | 仅在本地开发时准确设为 1,以便在没有 CONDUIT_S2S_SECRET 的情况下启动 HTTP。进程会记录警告,不会强制验证 X-Gateway-S2S,且只绑定到 127.0.0.1。非环回地址的 MCP_HTTP_HOST 会导致启动失败。已知占位符密钥仍会导致启动失败。 |
MCP_HTTP_HOST | 否 | 设置了有效 CONDUIT_S2S_SECRET 时的绑定地址。未设置时沿用历史绑定地址 0.0.0.0。镜像和 Compose 会在容器内将其设为 0.0.0.0。未设置密钥时,MCP_ALLOW_INSECURE_DEV=1 会强制绑定到 127.0.0.1。 |
MCP_HTTP_PORT | 否 | HTTP 端口。默认为 8080。 |
LOG_LEVEL | 否 | debug | info(默认)| warn | error。 |
/health 和 /healthz 无需身份验证,也不会读取凭据。stdio 传输不使用 CONDUIT_S2S_SECRET。
HTTP 身份验证
设置了 MCP_TRANSPORT=http 和 CONDUIT_S2S_SECRET 时,每个 /mcp 请求都必须包含 X-Gateway-S2S。验证逻辑位于 src/s2s-verify.ts 的 verifyS2sHeader 中:标头值的格式为 t=<unix seconds>,v1=<hex>,其中十六进制值是以 CONDUIT_S2S_SECRET 为密钥、对字面字符串 t=<unix seconds> 计算得出的 HMAC-SHA256(64 个小写十六进制字符)。时间戳与服务器时钟的偏差不得超过 300 秒。缺少标头或标头无效时,会在读取供应商凭据之前返回 HTTP 401。
TS=$(date +%s)
SIG=$(printf 't=%s' "$TS" | openssl dgst -sha256 -hmac "$CONDUIT_S2S_SECRET" -hex | awk '{print $NF}')
curl -sS http://127.0.0.1:8080/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "X-Gateway-S2S: t=${TS},v1=${SIG}" \
-H "X-TimeDoctor-Email: $TIMEDOCTOR_EMAIL" \
-H "X-TimeDoctor-Password: $TIMEDOCTOR_PASSWORD" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
在 AUTH_MODE=gateway 模式下,/mcp 还要求提供 X-TimeDoctor-Email 和 X-TimeDoctor-Password。这些标头是该请求唯一的凭据来源。AUTH_MODE=env 仍要求提供经过签名的 X-Gateway-S2S 标头,然后使用环境变量中的 TIMEDOCTOR_EMAIL 和 TIMEDOCTOR_PASSWORD。
请求限制
- HTTP 请求正文上限为 256 KiB(262144 字节)。通过
X-Gateway-S2S检查(在网关模式下还需通过凭据标头检查)后,如果Content-Length超过上限,则返回带有 JSON-RPC 错误的 413。没有Content-Length的正文受 MCP SDK 传输层限制。未通过身份验证的请求仍会优先收到 401。 tools/call参数最多可包含 10,000 个元素(任意深度的每个数组项和对象键都计为一个元素)。输入超出上限时,会返回带有固定消息 "Tool input exceeds the maximum of 10000 elements" 的isError工具结果,且绝不会进行分发。
这些限制用于应对 CVE-2026-111768 / GHSA-46jr-4wx8-v453(验证期间内存耗尽)和 GHSA-f897-62hf-6gxq(请求正文/批次缺少上限)。
工具
公司
timedoctor_list_companies- 已通过身份验证的用户拥有或管理的公司(工作区)。timedoctor_get_company- 按 ID 获取单个公司。
用户
timedoctor_list_users- 用户列表,可按公司限定范围,并按电子邮件/姓名筛选。timedoctor_get_user- 按 ID 获取单个用户。timedoctor_check_invitation- 检查电子邮件地址是否存在公司邀请(只读)。
项目
timedoctor_list_projects- 公司中的项目。timedoctor_get_project- 按 ID 获取单个项目。
任务
timedoctor_list_tasks- 公司中的任务,可按项目、名称或开放/关闭状态筛选。timedoctor_get_task- 按 ID 获取单个任务。
活动/统计数据
timedoctor_get_worklog- 指定时间范围内某位用户或某家公司的详细工作时段日志(开始时间、时长、任务/项目、模式)。timedoctor_get_timeuse_stats- 指定时间范围内某位用户或某家公司的汇总生产力统计数据(各应用/类别的用时、生产性与非生产性用时)。
范围
这是一个 v1/MVP 范围,仅涵盖 MSP 时间跟踪监督工作流的核心内容:跟踪了谁、在哪跟踪,以及他们的时间分配情况。目前明确不在范围内的功能包括:文件(屏幕录像/屏幕截图)、类别、工作计划(价值较低的管理配置)、任何用户邀请/创建/删除操作,以及“以该用户身份登录”的用户模拟端点(这是一个涉及安全的实际功能)。如果有需求,后续可以添加这些功能。
开发
npm install
npm run build
npm test
npm run lint # tsc --noEmit
# HTTP refuses to start until CONDUIT_S2S_SECRET is set
CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" npm run start:http
# Local HTTP only, without a service-to-service secret (binds 127.0.0.1)
MCP_ALLOW_INSECURE_DEV=1 MCP_HTTP_HOST=127.0.0.1 npm run start:http
Docker
镜像在容器内监听 0.0.0.0(MCP_HTTP_HOST),默认使用 AUTH_MODE=gateway。请将端口发布到回环地址,并传入真实的 S2S 密钥。在网关模式下,Time Doctor 凭据会作为标头随每个请求传入;不会从环境中读取这些凭据。
docker build -t timedoctor-mcp .
docker run \
-e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
-p 127.0.0.1:8080:8080 \
timedoctor-mcp
如果未设置 CONDUIT_S2S_SECRET,Compose 会拒绝启动。网关服务会设置 AUTH_MODE=gateway,不会注入 TIMEDOCTOR_EMAIL 或 TIMEDOCTOR_PASSWORD,并会发布 127.0.0.1:8080:8080:
CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" docker compose up
单租户 HTTP(AUTH_MODE=env)仍需 S2S 密钥,然后使用 TIMEDOCTOR_EMAIL 和 TIMEDOCTOR_PASSWORD。它与上文的网关 Compose 服务相互独立。
docker run \
-e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
-e AUTH_MODE=env \
-e [email protected] \
-e TIMEDOCTOR_PASSWORD=your-password \
-p 127.0.0.1:8080:8080 \
timedoctor-mcp
不带密钥的本地 HTTP 仅用于开发。它绑定到 127.0.0.1 并记录警告。如果 MCP_HTTP_HOST 为非回环地址(包括镜像默认值 0.0.0.0),启动将退出:
MCP_TRANSPORT=http MCP_HTTP_HOST=127.0.0.1 MCP_ALLOW_INSECURE_DEV=1 npm run start:http
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。