关于 OpenWork MCP Gateway
OpenWork MCP Gateway 的简介称,它通过一个 OAuth MCP URL 提供 OpenWork 组织的技能、插件、工作流和连接。所附 README 描述的是 Den API 控制面,包括身份验证、组织、工作器和管理员路由。
主要功能
- 01基于 Hono 的 Den 控制面
- 02身份验证与桌面交接路由
- 03组织和 SCIM 管理路由
- 04工作器与管理员端点
- 05可选的 Redis 读穿缓存
- 06可选遥测后端
适用场景
- 01在本地运行 Den API
- 02创建本地演示组织
- 03管理组织和 SCIM 路由
- 04使用 OTEL 或 Sentry 观测请求
MCP 相关
简介称该项目通过一个 OAuth MCP URL 提供 OpenWork 组织的技能、插件、工作流和连接。README 描述的是 Den API 控制面,未说明网关的 MCP 工具或协议行为。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://api.openworklabs.com/mcp/agentclaude mcp add --transport http com-openworklabs-openwork https://api.openworklabs.com/mcp/agent{"mcpServers":{"com-openworklabs-openwork":{"type":"http","url":"https://api.openworklabs.com/mcp/agent"}}}在 Cursor 中打开{"servers":{"com-openworklabs-openwork":{"type":"http","url":"https://api.openworklabs.com/mcp/agent"}}}在 VS Code 中打开{"mcpServers":{"com-openworklabs-openwork":{"type":"http","url":"https://api.openworklabs.com/mcp/agent"}}}{"mcpServers":{"com-openworklabs-openwork":{"serverUrl":"https://api.openworklabs.com/mcp/agent"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
Den API
基于 Hono 的 Den 控制平面实现(den-api,原名 den-controller)。
此软件包是当前的 Den 控制平面实现。
它以分层的 Hono 结构承载迁移后的完整 Den API 路由面,方便 Agent 一次浏览一个区域,无需扫描整个服务。
快速开始
pnpm --filter @openwork-ee/den-api dev:local
本地演示组织初始化
运行本地 Den MySQL 数据库后,初始化一个演示组织:
pnpm --filter @openwork-ee/den-api seed:demo-org
此操作会创建 Acme Robotics,并包含演示用户、团队、待处理邀请,以及导入的 Anthropic Knowledge Work Plugins marketplace。该操作受 OPENWORK_DEV_MODE=1 保护,默认使用本地 Den DB URL,且不会创建 worker 或启用外部集成。
默认所有者登录信息:[email protected] / OpenWorkDemo123!。
可观测性
DEN_OBSERVABILITY_BACKEND 用于选择一个后端:none、otel 或 sentry。
none(默认):将结构化 JSON 日志写入 stdout。otel:在导入 Hono/DB 前初始化 OpenTelemetry Node SDK,通过标准OTEL_*变量导出 OTLP HTTP/protobuf traces、metrics 和 logs,并使用@hono/otel生成规范化的请求 spans/metrics,不进行入站 HTTP 自动插桩。sentry:在导入应用前初始化@sentry/hono/node,并使用官方 Hono 中间件处理错误、追踪和 Sentry Logs。不要将其与 OTEL 后端组合使用。
请求访问日志会记录请求 ID、方法、规范化路由、状态、耗时,以及该请求执行的数据库语句数量(db_queries,仅计数),并省略健康检查/就绪检查产生的噪声。健康检查/就绪检查请求也会跳过 den-api 的 Hono 可观测性中间件。应用遥测会对授权信息、cookie、请求正文和查询参数值进行脱敏。OTEL_SERVICE_NAME 可覆盖默认服务名称 den-api。Daytona 自身的 OTEL 引导仍处于禁用状态;不要通过 den-api 设置 Daytona OTEL 启用变量。
构建会生成 source maps。仅当 DEN_OBSERVABILITY_BACKEND=sentry 且存在 SENTRY_AUTH_TOKEN、SENTRY_ORG、SENTRY_PROJECT 和 SENTRY_RELEASE 时,才会上传 Sentry source maps;如果设置了 SENTRY_DIST,也会一并传递。认证令牌必须保存在密钥存储中,绝不能写入环境变量示例或日志。
已批准的 Web 来源
组织所有者和管理员可在 Den 控制面板的 组织设置 → 已批准的 Web 来源(/v1/org/web-origins)中,批准自托管的 OpenWork Web 实例。每个条目都必须是精确的 HTTPS 来源——包含协议、主机和可选端口,且不得包含路径、查询参数、片段、凭据或通配符;每个组织最多可批准 20 个来源。只有当该组织处于活跃状态时,已批准的来源才能接收发回 /signin 的 Web 登录交接,并可用于向 Den API 发起携带凭据的浏览器请求。每次请求都会检查交接是否获批;CORS 批准状态按进程缓存,并会在大约 30 秒内于每个 Den API 副本上生效。如果设置了 DEN_CORS_HANDLED_BY_EDGE=true,边缘层也必须允许相同的精确来源以及 Authorization 预检请求。
当前路由
GET /->302 https://openworklabs.comGET /health- 在
/api/auth/*挂载 Better Auth /v1/auth/*下的桌面交接路由/v1/me*下的当前用户路由/v1/orgs*下的组织路由/v1/scim*下的活跃组织 SCIM 管理路由/v1/admin*下的管理路由/v1/workers*下的 worker 列表、删除和活动心跳路由(OpenWork Web 实例对应 worker 记录;其生命周期由/v1/cloud/*管理)
文件夹概览
src/routes/auth/:Better Auth 挂载点和桌面端交接端点src/routes/me/:当前用户和当前用户所在组织的解析路由src/routes/org/:按领域拆分的组织增删改查类接口src/routes/admin/:仅限管理员使用的报告端点src/routes/workers/:Worker 列表、删除和活动心跳端点src/middleware/:用于身份验证上下文、组织上下文、团队和验证的可复用 Hono 中间件src/cache.ts:共享的 Redis 支持读穿缓存。在此添加开销较大的读取辅助函数,键格式为cache:${cacheParent}:${cacheChild}:${id};例如cache.auth.session(token)和cache.org.members(orgId)。Redis 是可选的,因此每个辅助函数都必须回退到 DB 加载器。
每个主要文件夹也都有自己的 README.md,方便后续的 Agent 单独检查某个领域。
共享查询缓存
使用 src/cache.ts 为 Den API 提供读穿 Redis 缓存。不要在路由处理程序或领域模块中直接调用 Redis。
当前公开的辅助函数:
const session = await cache.auth.session(token)
const members = await cache.org.members(orgId)
缓存键格式:
cache:${cacheParent}:${cacheChild}:${id}
键示例:
cache:auth:session:<token>
cache:org:members:org_...
添加缓存辅助函数的规则:
- 在
src/cache.ts导出的cache命名空间下添加辅助函数。 - 每个辅助函数都应采用读穿方式:检查 Redis,缓存未命中时运行 DB 加载器,将结果写入 Redis,然后返回加载的值。
- Redis 是可选的。未设置
DATABASE_REDIS_URL时,辅助函数也必须正常工作。 - 非本地 Redis 应使用
rediss://。仅当redis://端点为私有、非公开,且仅限可信内部网络访问时,才设置DATABASE_REDIS_ALLOW_INSECURE_INTERNAL=1。 - 除非有明确且经过测试的失效机制,否则应使用较短的 TTL。
- 身份验证会话以 DB 为权威数据源,缓存时间最长为一小时。删除任何会话或进行任何更改身份的更新时,都必须使
cache.auth.deleteSession(token)失效。 - 未明确失效机制并经过测试时,不要新增对安全性至关重要的缓存辅助函数。
- 优先使用类似领域调用的名称,例如
cache.auth.session(token)或cache.org.members(orgId)。
SCIM 现有用户接入
src/auth.ts 中的 SCIM 插件要求用户已加入连接器所属的组织,才能接入现有账户。其 shouldLinkUser 回调还会根据规范化后的用户 ID 和组织 ID,通过未缓存的查询检查成员关系,并要求 removed_at IS NULL。Better Auth 1.7.0-beta.10 内置的成员关系查询不会排除已移除的记录,因此这两项检查都必须保留。未关联用户的邀请、已移除的成员关系、组织外账户,以及不含组织信息的令牌,均不能授权接入。没有适用于邮箱域名的例外。成功接入会保留用户 ID 和成员角色;新用户配置流程保持不变。
插件会在账户创建事务开始之前评估此策略。新的查询会排除已移除的成员关系,但不会通过串行化来避免并发移除与关联同时发生。要消除这一竞态,需要插件提供事务性策略支持;此回调不是原子性的成员关系锁。
在独立的 Node 进程中运行已安装插件的回归测试套件:
pnpm --filter @openwork-ee/den-api test:scim-existing-user-linking
该测试使用 Better Auth 的内存适配器,并编译成员关系 SQL,但不执行 SQL。它不会导入 Den 的完整身份验证依赖图、启动 MySQL、配置 OAuth,也不需要真实凭据。
TypeID 验证
- 共享的 Den TypeID 验证位于
ee/packages/utils/src/typeid.ts。 - 如果端点接受或返回 Den TypeID,请使用
typeId.schema("...")或兼容辅助函数,例如normalizeDenTypeId("...", value)。 ee/apps/den-api/src/openapi.ts提供denTypeIdSchema(...),使路径参数、请求正文和响应字段都使用相同的验证规则和 Swagger 示例。- Swagger 现在会为 Den ID 标明必需的前缀和固定长度为 26 个字符的 TypeID 后缀,因此无效 ID 会在路由逻辑运行前被请求验证拦截。
OpenAPI 契约
packages/docs/openapi.json是由pnpm den:contract生成并被忽略的构建产物,使用pnpm api:lint进行 lint。CI 从源代码生成 OpenAPI/SDK,并在生成或类型错误、Spectral 错误,或警告数量超过.spectral-baseline.json中的基线时失败。托管文档会从/openapi.json?public=1读取相同的标准化公开契约;生产环境提供契约变更后,.github/workflows/refresh-api-docs.yml会重新构建文档。- 每个路由注册都包含一个带有
summary、tags、security和responses的describeRoute();约定和已记录的例外情况见docs/api-style.md。
迁移方法
- 将
den-api(原名den-controller)保留为 Den 控制平面行为的唯一事实来源。 - 每次针对一个接口领域,在专门的 Hono 路由组中添加端点。
- 复用共享中间件和 Zod 验证器,而不是重复实现请求、会话和组织相关的处理逻辑。
- 每当路由区域的结构发生变化时,都在其中保留一份简短的 README,方便后续 Agent 快速了解上下文。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。