关于 Workstream
Workstream 是面向协作团队的 MCP 服务,用于统一记录 AI Agent 与人员的计划和任务。它以原子认领、受控状态流转和追加式事件日志协调并发工作,并可同步 GitHub Projects 与 Slack。
主要功能
- 01原子任务认领与过期回收
- 02按状态图校验任务流转
- 03追加式变更事件日志
- 04同步 GitHub Projects V2 与 Slack
- 05按计划查看任务的只读仪表板
适用场景
- 01多个 Agent 协作领取开发任务
- 02追踪审计计划中的发现与修复
- 03在团队项目板和 Slack 查看任务更新
MCP 相关
Workstream 通过 HTTP 或 stdio 向 MCP 客户端提供项目、计划、任务认领和结果记录等工具。客户端可用这些工具管理协作任务。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e WORKSTREAM_DB_CONNECTION -e WORKSTREAM_ADMIN_TOKEN -e WORKSTREAM_PUBLIC_BASE_URL -e WORKSTREAM_USER_TOKEN ghcr.io/ahmad-codex/workstream-mcp:0.2.0WORKSTREAM_DB_CONNECTION密钥Npgsql connection string for the PostgreSQL 16 databaseWORKSTREAM_ADMIN_TOKEN密钥Bearer token for the /admin API, used to create usersWORKSTREAM_PUBLIC_BASE_URLPublic base URL used when returning user MCP URLsWORKSTREAM_USER_TOKEN密钥Your user token from POST /admin/users. Only used to build the client URL; the server does not read it.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/ahmad-codex/workstream-mcp:0.2.0Streamable HTTP工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
workstream-mcp
一个 MCP 服务,用于保存 AI Agent 与人类协作完成工作的权威状态记录: 计划、任务、认领、发现、修复尝试和判定均存储在 Postgres 中,并同步到 GitHub Projects 和 Slack。

30 秒快速体验
使用一个容器运行 Postgres 和演示模式下的服务,并预置一个项目、一个有效计划 和三个任务:
docker run --rm -p 127.0.0.1:8080:8080 ghcr.io/ahmad-codex/workstream-mcp:demo
claude mcp add --transport http workstream-demo http://localhost:8080/demo-insecure-token/mcp
然后让 Claude 执行“列出 workstream 项目,并认领演示计划中的下一个任务”。
演示令牌是公开的,并拥有管理员权限,因此请将端口绑定到 127.0.0.1;关闭演示模式时,
服务会拒绝该令牌。容器停止后,数据将消失。
打开 http://localhost:8080/demo-insecure-token/ui/,在[仪表板](./docs/dashboard.md)上查看计划。
若要观察多个 Agent 争抢任务,请使用 -e WORKSTREAM_ADMIN_TOKEN=local-admin 启动容器,
并运行 WORKSTREAM_ADMIN_TOKEN=local-admin node scripts/simulate-agents.mjs。
与 Claude Code 一起设置
克隆仓库,在其中打开 Claude Code,然后粘贴:
Set up workstream-mcp for me on this machine. Follow the README quick start using the
published Docker image, create an admin user for me, and connect this Claude Code session
to it. Then create a project and a development plan with three sample tasks, activate it,
and claim one task to show it works. When that is done, ask me whether I want GitHub
Projects or Slack sync, and walk me through docs/github-setup.md or docs/slack-setup.md
step by step, telling me exactly what to click and which values to paste back.
想手动操作?请参阅快速入门。
为什么需要它
协调 Agent 工作的一种常见方式,是在仓库中编写 Markdown 计划:由 Agent 阅读、编辑并提交的清单。 这种方式适用于单个会话中的单个 Agent。但多个 Agent 和人员同时执行同一计划时,就会出现问题:
- 两个 Agent 选中同一项,因为没有任何机制阻止这种情况。
- Agent 在任务中途退出后,该项会永远停留在“进行中”状态。
- 文件编辑会相互冲突,而谁做了什么的历史记录只能从 git 差异中查找。
- 计划不会出现在团队常用的位置,例如项目看板和 Slack。
workstream-mcp 用一个小型服务取代文件。Agent 调用 MCP 工具来认领工作、提交结果并记录判定。 认领操作是原子的,并且会过期;状态转换会根据状态图进行校验;每次变更都会写入只追加的事件日志; GitHub 和 Slack 则通过发件箱更新,因此即使它们发生故障,也不会阻塞 Agent。
功能
目前代码的功能:
- 带 TTL 的原子认领。 在一个事务中使用
SELECT ... FOR UPDATE SKIP LOCKED,因此并发认领者不会领取到同一个任务,也不会互相阻塞。未刷新的认领会过期,任务将返回到任务池。已通过 32 个认领者的并发测试套件验证。 - 数据驱动的状态机。 状态、合法转换、允许的角色、角色 TTL、重试上限和看板列映射都存储在
plan_types.state_graph(JSONB)中。提供两种计划类型:audit(查找、验证、修复、重新验证)和development(实现、审查)。非法转换会返回illegal_transition和allowed_next,以便调用模型进行修正。 - 仅追加的事件日志。 每次状态更改都会写入一条
events记录。触发器会阻止对events和verdicts执行UPDATE和DELETE。 - GitHub Projects V2 同步。 任务会成为 Projects V2 看板上的 issue(对于不关联仓库的项目,则创建草稿条目),列会随任务状态变化,审计计划会创建一个里程碑。带签名的 webhook 端点会验证传入的看板事件,但目前尚未应用这些事件(见路线图)。使用 GitHub App。
- Slack 通知。 每个项目频道都会收到 Block Kit 消息,按任务建立线程,Agent 帖子使用角色人设,并通过 Slack 签名密钥验证交互式按钮。
- 发件箱。 GitHub 和 Slack 调用会在请求事务中排入
board_sync_log和slack_notify_log,再由后台工作线程重试并处理。 - Web 仪表板。 每个计划都有一个只读看板,路径为
/<token>/ui/:显示按状态分类的任务、带 TTL 倒计时的认领者、依赖关系、卡住的工作,以及每项任务的事件时间线。参见 docs/dashboard.md。 - 以 URL 作为凭据的身份验证。 每位用户都会获得类似
https://host/<token>/mcp的 URL。将其粘贴到 MCP 客户端中即可完成全部设置。令牌可以轮换;令牌会从路径和日志中剥离。 - 审计调度器(可选)。
request_audit会将一次审计运行加入队列;一个旁路容器会克隆仓库,并在 tmux 会话中通过 Claude Code 启动项目的审计编排器。 - 管理 API 和 CLI。
/admin/*端点通过静态 bearer 令牌保护,用于管理用户和看板;另提供用于用户管理的workstream-adminCLI。项目和计划通过受管理权限保护的 MCP 工具进行设置。 - 卡住的工作报告。 每小时运行的任务会将过期认领、过时发现和空闲计划的数量写入
stuck_work_reports。
架构
flowchart LR
subgraph Clients
CC[Claude Code / Desktop / Cursor]
ORCH[Orchestrator agents]
end
CC -- "POST /<token>/mcp<br/>JSON-RPC 2.0" --> API
ORCH -- "POST /<token>/mcp" --> API
subgraph Server
API[Workstream.Api<br/>token middleware, MCP tools,<br/>state machine, claims]
BSW[BoardSyncWorker]
SNW[SlackNotifyWorker]
DISP[AuditDispatchWorker<br/>dispatcher role]
end
API -- "one transaction:<br/>state + events + outbox rows" --> PGB[(PgBouncer)]
PGB --> PG[(Postgres 16)]
BSW -- drain board_sync_log --> PG
SNW -- drain slack_notify_log --> PG
DISP -- drain audit_dispatch_log --> PG
BSW -- GraphQL / REST --> GH[GitHub Projects V2,<br/>issues, milestones]
SNW -- chat.postMessage --> SL[Slack]
GH -- signed webhook --> API
SL -- signed interactivity --> API
DISP -- tmux + claude --> REPO[checked-out repos]
| 项目 | 职责 |
|---|---|
src/Workstream.Api | ASP.NET Core 主机、令牌中间件、JSON-RPC 端点、管理 API、webhook、调度器 |
src/Workstream.Core | 领域模型、状态图解析器、StateMachineService、认领规则 |
src/Workstream.Data | Npgsql + Dapper 仓储、发件箱、SQL 迁移运行器 |
src/Workstream.Mcp | MCP 工具类及其注册 |
src/Workstream.GitHub | GitHub App 身份验证、Projects V2 客户端、看板同步工作线程 |
src/Workstream.Slack | Slack 客户端、Block Kit 构建器、通知工作线程、签名检查 |
src/Workstream.Telemetry | OpenTelemetry 设置和指标定义 |
tools/workstream-admin | 运维人员 CLI |
deploy/ | Dockerfile、compose 文件、迁移、计划类型配置文件、Caddy、PgBouncer、Grafana 和 Prometheus 配置 |
更多信息请参见 docs/architecture.md 和 docs/state-machine.md。
快速开始(约 5 分钟)
需要 Docker。此操作只会启动 Postgres 和 API;GitHub、Slack 和 dispatcher 保持关闭。
git clone https://github.com/ahmad-codex/workstream-mcp.git
cd workstream-mcp
docker compose -f deploy/docker-compose.quickstart.yml up -d --build
curl http://localhost:8080/healthz
# {"ok":true}
若要跳过本地构建,请改为运行已发布的镜像:
WORKSTREAM_IMAGE=ghcr.io/ahmad-codex/workstream-mcp:latest \
docker compose -f deploy/docker-compose.quickstart.yml up -d --no-build
API 启动时会应用 SQL 迁移,包括 audit 和 development 计划类型。
创建用户。响应中会包含一次性显示的用户 MCP URL;请复制保存。
curl -s -X POST http://localhost:8080/admin/users \
-H "Authorization: Bearer local-admin-token" \
-H "Content-Type: application/json" \
-d '{"githubUsername":"alice","displayName":"Alice","actorType":"human","isAdmin":true}'
# { "user": {...}, "url": "http://localhost:8080/<token>",
# "mcp_endpoint": "http://localhost:8080/<token>/mcp", "warning": "..." }
isAdmin 允许此用户调用设置工具(create_project、create_plan,……)。
检查 URL:
curl http://localhost:8080/<token>
# {"ok":true,"actor":{"id":"...","github_username":"alice","is_admin":true},...}
然后连接 MCP 客户端(见下一节),让它创建一个项目、一个开发计划 和几个任务,激活该计划,并领取其中一个任务。
使用 docker compose -f deploy/docker-compose.quickstart.yml down 停止服务(添加 -v 可删除数据)。
连接 MCP 客户端
服务器通过 HTTP(JSON-RPC 2.0 POST 请求)在 <base>/<token>/mcp 上提供 MCP 服务。无需
额外请求头;路径中的 token 用于识别用户。
Claude Code
claude mcp add --transport http workstream http://localhost:8080/<token>/mcp
Claude Desktop(claude_desktop_config.json)。Claude Desktop 会从此文件启动 stdio 服务,因此请使用
mcp-remote 桥接程序(需要 Node.js):
{
"mcpServers": {
"workstream": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8080/<token>/mcp"]
}
}
}
如果可通过 HTTPS 从互联网访问服务器,也可以在 Claude Desktop 的设置中将 URL 添加为 自定义连接器。
stdio(任意客户端)。同一二进制文件通过 --stdio 使用 stdin/stdout 提供 MCP 服务,以
WORKSTREAM_USER_TOKEN 中的 token 对应的用户身份,连接到
WORKSTREAM_DB_CONNECTION 中指定的数据库(仍需在某处运行 HTTP 服务器,以清空 GitHub
和 Slack 发件箱):
{
"mcpServers": {
"workstream": {
"command": "dotnet",
"args": ["/path/to/Workstream.Api.dll", "--stdio"],
"env": {
"WORKSTREAM_DB_CONNECTION": "Host=localhost;Database=workstream;Username=workstream;Password=...",
"WORKSTREAM_USER_TOKEN": "<token>"
}
}
}
}
如果未设置 WORKSTREAM_DB_CONNECTION,--stdio 会以发现模式启动:initialize 和
tools/list 可以正常使用,所有工具调用都会返回 not_configured 错误。Glama 等目录扫描器会使用
此模式。
Cursor(~/.cursor/mcp.json,或项目中的 .cursor/mcp.json):
{
"mcpServers": {
"workstream": {
"url": "http://localhost:8080/<token>/mcp"
}
}
}
此 URL 是凭据。请勿提交;将其保存在用户级配置中。 完整的入门流程请参阅 docs/onboarding.md。
MCP 工具
36 个工具。每个响应的格式均为 { ok, data, error };错误包含稳定的 code
(stale_claim、illegal_transition、retry_cap_exceeded 等)。完整详情见
docs/mcp-tools.md。任何调用都可以传入 as_agent,设置发布到 Slack 时使用的角色人格。
| 分组 | 工具 | 功能 |
|---|---|---|
| 发现 | list_projects | 列出项目及其活跃计划数量和调用者未结的认领 |
list_plans | 列出项目的计划,可按状态筛选,并显示各状态的任务数量 | |
get_plan_dashboard | 状态数量、接下来可认领的工作、我的认领、卡住的工作和近期事件 | |
get_my_active_work | 调用者持有的所有认领 | |
| 认领 | claim_next_task | 为某个角色认领优先级最高的待处理任务 |
claim_specific_task | 按 ID 认领一个任务 | |
claim_next_finding_for_verification | 审计:认领一条待验证的发现 | |
claim_next_finding_for_fix | 审计:认领一条已确认、待修复的发现 | |
claim_next_attempt_for_review | 预留;v1 占位项 | |
refresh_claim | 延长认领的 TTL,以支持长时间工作 | |
release_claim | 归还工作,不提交 | |
| 提交 | start_work | 将 claimed 变为 in_progress |
submit_findings | 审计:提交任务的发现 | |
submit_verification_verdict | 审计:提交已确认、已驳回或有歧义的判定 | |
submit_attempt | 提交代码更改;强制执行重试上限 | |
submit_attempt_verdict | 审计:提交修复已确认、修复失败或部分修复的判定 | |
submit_review_decision | 开发:提交已批准或需要修改的决定 | |
| 生命周期 | mark_task_status | 将任务标记为 deferred、blocked、skipped、out_of_scope 或 needs_human_review |
record_commit | 附加提交哈希 | |
create_task / create_tasks | 向计划添加任务,单个或批量添加 | |
override_verdict | 强制更改状态;需要 can_override_verdict | |
| 取证 | get_event_log | 查看一个实体的事件时间线 |
get_stuck_work | 查看超过 TTL 的任务和尝试、等待超过 24h 的发现以及空闲计划 | |
export_plan | 将计划快照导出为 markdown 或 JSON | |
get_finding | 获取一条发现的完整内容:严重性、根本原因、复现步骤、状态和认领者 | |
| 设置(管理员) | create_project | 新建项目 |
add_project_repo | 关联一个 GitHub 仓库 | |
add_project_board | 注册一个 Projects V2 看板 | |
set_project_slack | 设置 Slack 频道和机器人令牌引用 | |
create_plan | 新建草稿计划 | |
add_phase | 向计划添加阶段 | |
activate_plan | 将草稿计划转为活跃计划;将看板项目加入队列 | |
archive_plan | 将计划关闭为 Completed 或 Canceled | |
| 审计调度(管理员) | request_audit | 为一个或多个项目加入审计运行队列 |
cancel_audit | 请求正在运行的审计停止并清理 |
配置
API 读取的环境变量。每个 _FILE 变体都会从文件中读取值
(Docker secrets)。
| 变量 | 必需 | 用途 |
|---|---|---|
WORKSTREAM_DB_CONNECTION | 是 | Npgsql 连接字符串。Password=__from_secret__ 会替换为 WORKSTREAM_DB_PASSWORD_FILE 的内容 |
WORKSTREAM_DB_PASSWORD_FILE | 否 | 保存数据库密码的文件 |
WORKSTREAM_ADMIN_TOKEN / _FILE | 管理 API 必需 | /admin/* 的 Bearer 令牌。未设置时,管理请求会被拒绝 |
WORKSTREAM_PUBLIC_BASE_URL | 否 | 返回用户 URL 时使用的基础 URL。默认为请求主机 |
WORKSTREAM_GH_APP_ID | GitHub 集成必需 | GitHub App ID |
WORKSTREAM_GH_INSTALLATION_ID | GitHub 集成必需 | App 安装 ID |
WORKSTREAM_GH_APP_KEY_PATH | GitHub 集成必需 | App 私钥(PEM)的路径 |
WORKSTREAM_GH_WEBHOOK_SECRET / _FILE | GitHub 集成必需 | Webhook HMAC 密钥 |
WORKSTREAM_SLACK_SIGNING_SECRET / _FILE | Slack 按钮必需 | Slack 签名密钥 |
WORKSTREAM_ROLE | 否 | api(默认)或 dispatcher |
WORKSTREAM_TRANSPORT | 否 | 使用 stdin/stdout 提供 MCP 服务的 stdio(与 --stdio 相同) |
WORKSTREAM_USER_TOKEN | stdio 模式必需 | stdio 服务代表其操作的用户 |
WORKSTREAM_DEMO | 否 | true 会填充演示数据并接受公开演示令牌。仅用于本地试用 |
WORKSTREAM_AUDIT_DISPATCH_ENABLED | dispatcher 模式必需 | true 表示运行审计分发器 |
WORKSTREAM_AUDIT_DISPATCH_SCRIPT | dispatcher 模式必需 | audit-dispatch.sh 的路径 |
WORKSTREAM_AUDIT_DISPATCH_TIMEOUT | 否 | 分发脚本超时时间,单位为秒 |
WORKSTREAM_OTEL_ENDPOINT | 否 | 用于跟踪和指标的 OTLP 端点。未设置表示关闭遥测。URL 令牌会在 span 中被隐藏 |
WS_SSH_MCP_HOST / WS_SSH_MCP_USER | dispatcher 模式 | 可选的测试主机,会作为 ssh-host MCP 提供给审计运行 |
每个项目的 Slack 机器人令牌都是 secrets 目录下的文件,通过
set_project_slack 引用。请参阅 docs/slack-setup.md 和
docs/github-setup.md。
从源代码构建
dotnet build
dotnet test tests/Workstream.UnitTests # no Docker
dotnet test tests/Workstream.IntegrationTests # Docker (Testcontainers, Postgres 16)
dotnet test tests/Workstream.ConcurrencyTests # Docker
使用你自己的 Postgres 运行 API:
export WORKSTREAM_DB_CONNECTION="Host=localhost;Database=workstream;Username=workstream;Password=devpass"
export WORKSTREAM_ADMIN_TOKEN="dev-admin-token"
dotnet run --project src/Workstream.Api
文档
- 架构:模块、请求生命周期、并发模型
- 状态机:状态图格式和两种种子计划类型
- MCP 工具:每个工具、错误代码、
as_agent - 入门:为开发者授予访问权限
- GitHub 设置:GitHub App、Projects V2 看板、webhook
- Slack 设置:机器人令牌、频道、交互功能
- 审计分发:分发器 sidecar
- 部署:生产环境 compose、PgBouncer、Caddy、备份
- 审计编排器示例:端到端驱动审计计划的提示词
- 仪表板:只读 Web 视图及其 API
- 路线图:现在、接下来和以后
- 构建规范:完整设计
状态
早期版本,版本号为 0.2.1。已知不足:
claim_next_attempt_for_review目前只是空操作。workstream-admin apply(声明式引导)只会打印文件。- 卡住工作报告会被存储,但尚未发布到 Slack。
- 仅支持最新的
master;没有发布分支。
请参阅 CHANGELOG.md 和路线图。
社区
- 问题和想法:GitHub Discussions
- 错误和功能请求:issues
- 获取帮助:SUPPORT.md。决策方式:GOVERNANCE.md
- 安全问题:SECURITY.md
贡献
请先阅读 CONTRIBUTING.md 和 适合新手的问题。计划中的工作见 ROADMAP.md。此仓库可在已配置 .NET 10 SDK 和 Postgres 的开发容器或 GitHub Codespaces 中打开。
贡献者
许可证
MIT。版权所有 © 2026 Ahmad Shawar。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。