【免费下载链接】superplane
Open source factory for one-shot engineering
导读:
docs/prd/workspace-agent-resources.md是 SuperPlane 中"工作区级 Agent 资源"(Workspace Agent Resources)的设计蓝图(playbook),它定义了一个统一的目录(catalog):管理员只需在工作区设置页添加一次 MCP 服务器或内联 SKILL.md 技能,此后 factory 每次任务构建时都会自动把它们注入到 Claude Code、Codex、OpenCode 等 runner CLI 中,让包括任务细化(task refinement)在内的每一步都能使用这些资源。读完本文,你将掌握该功能的领域模型、配置 schema、OAuth 接入流程、运行时注入机制,以及当前仓库中对应的源码、迁移文件与测试实现,可以直接基于此进行二次开发或排查问题。
1. 功能定位与已锁定决策
这份 playbook 是 SuperPlane 中workspace MCP 服务器与技能(skills)的唯一事实来源。它开篇给出了 6 条"已锁定决策"(Locked decisions),这些决策直接决定了后续所有表结构、接口与注入路径的形态:
- 单一工作区目录表:所有资源都存进
factory_agent_resources一张表,kind区分mcp_server与skill两种;一个 attach 函数统一注入启用的行。禁止新增第二张目录表。 - MCP 与 Skills 设置页分离:两个页面都位于 Workspace 设置下,权限为
factories:update;实验性开关为workspace_mcp与workspace_skills;旧的workspace/agent-resources路由重定向到新页面。 - MCP v1 认证只支持 headers 或 OAuth:SuperPlane 在管理员浏览器里完成 OAuth,runner 只拿到 Bearer access token,绝不把 refresh token 写到 runner。
- 注入发生在任务构建(task build)阶段,而不是写进 canvas YAML:工作区 MCP 与第一方
planning_session_mcp.js服务器合并;名字superplane被保留。 - Skills v1 只支持单个 SKILL.md 文件:管理员在整页编辑器粘贴 markdown,SuperPlane 存
{ "source": "inline", "markdown": "..." }并把它写到 runner 上;GitHub 包(repository、ref、path)作为后续第三方技能来源,不引入npx skills安装。 - Storybook 是视觉规范:每个页面状态都必须在页面完成前有命名 story。
从源码看,这些决策已经被完整执行:表结构与第 1 条一致(见下文迁移文件),特性开关FeatureWorkspaceMCP = "workspace_mcp"与FeatureWorkspaceSkills = "workspace_skills"定义在 pkg/features/features.go,注入函数AttachWorkspaceAgentResources定义在 pkg/components/runner/workspace_agent_resources.go。
2. 目标与"不重复造轮子"清单
Goal(目标):工作区管理员只需添加一次 MCP 服务器和内联技能,factory runner 的**每一个步骤(包括任务细化)**都能使用这些资源;GitHub 技能包将来可以填进同一个目录,无需第二张表。
playbook 同时用"今天已存在什么"(What exists today)划清边界,避免重复实现:
- factory runner 任务已经为任务细化附加了第一方 stdio MCP 服务器(
planning_session_mcp.js)。 - Organization integrations 是带 setup wizard 和 webhooks 的产品应用,不是通用 MCP URL 目录。
- Organization secrets 已经能存 header 值,runner 的
environmentFrom已经能解析这些 secrets。 - GitLab 和 Jira 已经能在浏览器完成 OAuth,并在 SuperPlane 中加密、刷新 token。
- Canvas YAML 与
environmentFrom按节点绑定 secrets——这条路会漏掉现有自动化和细化节点,除非重写每个模板,所以注入必须发生在任务构建层。
3. 产品规则总表
playbook 用一张表把产品规则钉死,逐条对应源码中的常量与校验逻辑:
| 主题 | 规则 | 源码依据 |
|---|---|---|
| Catalog | 一张表,调用方传factory_id并按kind过滤 | pkg/models/factory_agent_resource.goListAgentResources |
| Kinds | mcp_server和skill | 同文件FactoryAgentResourceKindMCPServer/FactoryAgentResourceKindSkill |
| Name | slug,factory 内唯一;superplane保留 | factoryAgentResourceNamePattern、ReservedFactoryAgentResourceName = "superplane" |
| MCP transport | v1 仅 HTTP / streamable HTTP,不支持 stdio 或npx | FactoryAgentResourceConfig.Transport |
| Header auth | 可选;把 header 名映射到 organization secret 名与 key | FactoryAgentResourceHeader{Name, SecretName, SecretKey} |
| OAuth | SuperPlane 是 MCP OAuth 客户端,任务开始时注入 Bearer | StartFactoryAgentResourceOAuth与/api/v1/mcp-oauth/callback |
| Cap | 每个 workspace 最多 20 个启用的 MCP 服务器 | MaxEnabledFactoryMCPServers = 20与ensureEnabledMCPCapacity |
| Skills v1 | 仅内联 SKILL.md;不包含额外文件和脚本 | ValidateSkill拒绝非 inline source |
| Flags | workspace_mcp与workspace_skills | pkg/features/features.go |
| 设置页 | Workspace / MCP servers 与 Workspace / Skills | 见第 6 节前端文件 |
| 路由 | .../settings/workspace/mcp与.../settings/workspace/skills;skill 新建/编辑用/new与/:resourceId | 前端 pages 目录 |
| Tools | WorkspacedisabledTools加节点disabledAgentResourceTools;新工具默认开启 | assembleWorkspaceMCPServer中NormalizeDisabledTools合并两处配置 |
| Inject | AttachWorkspaceAgentResources在 broker-task 构建时执行,仅在对应 flag 打开时附加对应 kind | pkg/components/runner/superplane/component.go |
| Storybook | Factories/Pages/Settings/MCP and skills列出每个页面状态 | FactorySettingsAgentResources.stories.tsx |
4. 领域模型与表结构
playbook 给出的领域模型层级:
factory (workspace) └── factory_agent_resources kind: mcp_server | skill name, enabled, config JSONB └── factory_agent_resource_secrets (encrypted OAuth tokens) └── AttachWorkspaceAgentResources └── Claude / Codex / OpenCode run.js它已由迁移 db/migrations/20260918231901_add-factory-agent-resources.up.sql 落实:
factory_agent_resources:id(UUID PK)、organization_id、factory_id(均ON DELETE RESTRICT)、kind、name、enabled(默认 true)、config JSONB,以及一组 OAuth 相关列:oauth_status、oauth_error、oauth_connected_by、oauth_connected_at、oauth_metadata、oauth_pending_state、oauth_pending_expiry,外加时间戳。- 三个关键索引:
(factory_id, name)唯一(保证名字唯一)、(factory_id, kind)(按 kind 过滤)、以及oauth_pending_state的部分唯一索引(用于 OAuth 回调时按 state 反查资源)。 factory_agent_resource_secrets:resource_id外键ON DELETE CASCADE、name、value BYTEA(加密存储),(resource_id, name)唯一。
模型层 pkg/models/factory_agent_resource.go 则把规则编码成常量与校验函数:
- 认证方式:
headers/oauth;OAuth 状态机:not_connected/connected/needs_reconnect/vendor_rejected; - secrets 命名约定:
refresh_token、access_token、client_secret、code_verifier; - 技能 markdown 上限:
MaxFactoryAgentSkillMarkdownBytes = 64 * 1024(64 KiB); - 名字正则
^[a-z][a-z0-9-]{0,62}$,保留名superplane; CanonicalMCPServerURL对 URL 做规范化(小写 scheme/host、去尾部斜杠、去 fragment),用于"同一 URL 不允许重复连接"的判定。
4.1 MCPconfig:OAuth 认证
{ "transport": "http", "url": "https://api.mobbin.com/mcp", "auth": "oauth" }4.2 MCPconfig:Header 认证
{ "transport": "http", "url": "https://mcp.example.com/mcp", "auth": "headers", "headers": [ { "name": "Authorization", "secretName": "vendor-mcp", "secretKey": "token" } ], "disabledTools": ["create_issue"] }要点(playbook + 源码共同确认):
config里绝不存 token。OAuth 的 refresh / access token 加密存放在factory_agent_resource_secrets;header 值在任务构建时从 organization secrets 解析(ctx.Secrets.GetKey(secretName, secretKey),见 workspace_agent_resources.go)。- MCP URL 必须校验为
https,拒绝 loopback、link-local 与私有主机——对应 gRPC 层的validateMCPURL→mcp.ValidatePublicHTTPSURL(pkg/grpc/actions/factories/factory_agent_resources.go)。 disabledTools支持在服务器级预置(config 内),也会与节点/工作区级禁用手动工具合并去重。
4.3 Skillconfig:内联 SKILL.md(v1 唯一允许的创建方式)
{ "source": "inline", "markdown": "---\nname: review-copy\ndescription: Review UI copy.\n---\n\nWrite STE copy." }4.4 Skillconfig:GitHub 包(后续版本;v1 创建时不允许持久化)
{ "source": "github", "repository": "nextlevelbuilder/ui-ux-pro-max-skill", "ref": "<tag-or-sha>", "path": "." }4.5 OAuth 连接状态(行级字段)
not_connected— 已保存,仍需 Connectconnected— refresh token 已存在needs_reconnect— refresh 失败vendor_rejected— discovery、DCR 或 allowlist 失败
模型层的OAuthState()与MCPConnectionEstablished()直接消费这些状态:OAuth 连接的 MCP 只有connected才算建立;header 连接的 MCP 只要有 URL 就算建立(pkg/models/factory_agent_resource.go)。
5. 设置页面(Settings pages)
页面沿用 factory settings 的外观框架,标题为MCP servers与Skills,结构如下:
Workspace settings MCP servers catalog picker 或 Custom list 或 empty state primary action: Add MCP server Skills list 或 empty state primary action: Add skill full-page editor at /skills/new and /skills/:id- MCP server 行:绿色状态点(已连接)、name、URL、auth(Header 或 Sign-in)、状态(Connected / Not connected / Reconnect)、enable 开关、可展开的工具列表、菜单(Edit、Disconnect、Delete)。
- 工具行:name 加 Read 或 Write 标识,按 name、read-first 或 write-first 排序,不显示 description;在某处关闭的工具对所有自动化都关闭(这正是"Tools"产品规则的意义)。
- Skills 行:name、来源(内联显示为
SKILL.md)、enable 开关、菜单(Edit、Delete)。编辑器包含 name 字段、/command建议、以及整页 markdown 编辑器。 - 空状态文案:MCP 为空时显示 "No MCP servers yet. Add an MCP server so agents can use it on every run.";Skills 为空时显示 "No skills yet. Add a SKILL.md so agents can use it on every run."
- 文案统一使用 SuperPlane、workspace、MCP server、skill、agent 作为稳定名词。
前端落地文件(playbook 的 Maintenance notes 明确列出):
- MCP 页:FactorySettingsMCPPage.tsx
- Skills 页:FactorySettingsSkillsPage.tsx
- Skill 编辑器:FactorySettingsSkillEditorPage.tsx
- 路由:
/{org}/workspaces/{key}/settings/workspace/mcp与.../skills - Storybook:FactorySettingsAgentResources.stories.tsx,标题
Factories/Pages/Settings/MCP and skills
6. OAuth 流程:浏览器完成授权,runner 只拿 Bearer
核心约束:fleet runner 是无头的,无法打开登录窗口,所以 MCP OAuth 必须由 SuperPlane 在管理员浏览器中完成。playbook 给出的六步流程:
- 探测 MCP URL:读取 RFC 9728 protected-resource metadata。
- 发现授权服务器:RFC 8414 或 OpenID Connect discovery。
- 获取 client id:使用 Client ID Metadata Documents;若服务器通告了 Dynamic Client Registration(DCR)则用之。
- 授权码 + PKCE:重定向到
/api/v1/mcp-oauth/callback。 - 加密 refresh token,记录谁在何时连接的。
- 任务构建时:刷新 access token 并注入
Authorization: Bearer。
补充要求:
- authorize 与 token 请求都发送 RFC 8707 的
resource=<canonical MCP URL>。 - 如果 vendor 只 allowlist 了 Claude、Cursor 或 Codex,Connect 直接失败并给出明确错误;对同时提供 API key 的 vendor 保留 header auth。
- v1只在任务开始时刷新 access token,短 token 可能在长任务运行中过期;v1 不引入 SuperPlane MCP proxy。
源码对应:OAuth 回调处理器在 pkg/public/mcp_oauth.go(HandleMCPOAuthCallback,路由即/api/v1/mcp-oauth/callback),token 铸造在pkg/mcp/factory_tokens.go的MintFactoryAgentResourceAccessToken,由 workspace_agent_resources.go 在组装 MCP 服务器时调用——拿到 token 后拼进Authorization: Bearer <token>请求头。
7. 运行时注入:AttachWorkspaceAgentResources 的完整调用链
这是整个 playbook 的技术核心。每个 runner 组件已经会调用ResolveEnvironment和AttachPlanningSessionEnv,在此基础上新增AttachWorkspaceAgentResources。playbook 给出的六步流程:
- 从 canvas 解析 factory(
workflows.factory_id);canvas 不属于任何 factory 时直接 no-op。 - 加载启用的
mcp_server与skill行。 - 解析 header secrets,或铸造 OAuth access token。
- 在
SUPERPLANE_TASK_DIR下产出workspace_mcp.json,并把环境变量SUPERPLANE_WORKSPACE_MCP_CONFIG设为$SUPERPLANE_TASK_DIR/workspace_mcp.json。 - 每个
run.js在 planning 开启时把远端服务器与 SuperPlane 的 stdio MCP 合并。 - 把每个内联技能写到
SUPERPLANE_TASK_DIR下的.claude/skills/<name>/SKILL.md与.agents/skills/<name>/SKILL.md;提示步骤在 CLI 启动前把这些文件拷进 agent 工作目录;如果仓库里已有同名技能目录,保留项目文件、跳过工作区拷贝。
7.1 源码级实现
实现位于 pkg/components/runner/workspace_agent_resources.go:
- 入口
AttachWorkspaceAgentResources(ctx, environment, files):先解析 orgID,检查两个特性 flag(FeatureWorkspaceMCP/FeatureWorkspaceSkills,见 pkg/features/features.go);flag 全关时直接原样返回。随后用FindFactoryIDForCanvas确认 canvas 归属 factory(非 factory 画布 no-op)。 - 每类资源只在对应 flag 打开时加载:
factory.ListEnabledMCPServers(db)与factory.ListEnabledSkills(db),均按 name 升序。 - 工作区级与节点级的禁用机制:配置键
disabledAgentResourceIds(按资源 ID 整体剔除)与disabledAgentResourceTools(按资源 ID 禁用具体工具)在disabledAgentResourceIDs/disabledAgentResourceTools中解析,rejectDisabledAgentResources做剔除。 attachWorkspaceMCPServers:逐行调用assembleWorkspaceMCPServer——header 认证从ctx.Secrets.GetKey解析值;OAuth 认证走mcp.MintFactoryAgentResourceAccessToken;保留名superplane或 URL 为空直接跳过。最终序列化为{"servers":[...]}写入workspace_mcp.json(mode 0644),并追加环境变量SUPERPLANE_WORKSPACE_MCP_CONFIG=$SUPERPLANE_TASK_DIR/workspace_mcp.json。appendWorkspaceSkillFiles:跳过空 markdown、保留名与校验失败的技能,把同一份 markdown 同时写入.claude/skills/<name>/SKILL.md和.agents/skills/<name>/SKILL.md。appendWorkspaceAgentResourcesHint:把一段提示文本("You can use these resources. MCP servers: ... / Skills: ...")追加到prompts/*.txt提示文件末尾,让模型知道本次任务可用的资源。
调用位置:每个 runner 组件构建 broker 任务时统一调用。例如 pkg/components/runner/superplane/component.go 中environment, files = runner.AttachWorkspaceAgentResources(ctx, environment, files),claude / codex / openrouter 等组件的 component.go 同样接入。
7.2 各 CLI 的合并方式
| CLI | 合并机制 |
|---|---|
| Claude Code | 写mcp.runtime.json,条目形如{ type: "http", url, headers };只要存在工作区 MCP 就每次运行都写该文件;planning allowlist 包含mcp__<name>;禁用工具以mcp__<server>__<tool>传给--disallowedTools;技能从.claude/skills加载 |
| Codex | TOML 的mcp_servers.<name>字段:url、headers、disabled_tools;技能从.agents/skills加载 |
| OpenCode | config.mcp.<name>记为type: "remote";用permission.<server>_<tool>拒绝禁用工具;技能从.agents/skills加载 |
以 Claude 为例,pkg/components/runner/claude/run.js 中workspaceMCPConfigPath会展开$SUPERPLANE_TASK_DIR并从候选路径查找workspace_mcp.json(候选含SUPERPLANE_WORKSPACE_MCP_CONFIG展开值、原值、taskDir/workspace_mcp.json兜底);workspaceMCPServers解析 JSON 并跳过名为superplane的保留服务器;writeClaudeMCPConfig把远端服务器与(planning 开启时的)SuperPlane stdio MCP 一起写进mcp.runtime.json。Codex 与 OpenCode 的 run.js 也有同样的候选路径逻辑(pkg/components/runner/codex/run.js、pkg/components/runner/openrouter/run.js)。
安全边界:playbook 特别提醒——自定义 HTTP MCP 工具可能在细化过程中改变外部系统,而仓库保持只读,这一点必须在 helper text 中写明。
8. Skills 后续演进(GitHub 包)
GitHub 技能包不在 v1 create 中,但 Storybook 中保留SkillsGitHub作为后续布局。当 GitHub 包落地时:
- 在添加时把 GitHub tree 快照进 SuperPlane blob storage,按 SHA 固定版本。
- 在 runner 的共享 skills 根目录解包,拷贝到 Claude 的
.claude/skills/<name>/与 Codex/OpenCode 的.agents/skills/<name>/。 - 不重写 canvas YAML。
- 不运行 vendor 安装器(如
uipro或npx skills add)。
基础设施前提:fleet runner 镜像必须包含python3(供跑搜索脚本的技能使用);优先公共仓库,私有 GitHub 技能将来需要 workspace VCS token。
9. Out of scope(v1 明确不做)
- runner 上的 stdio /
npxMCP - SuperPlane MCP proxy 或运行中 token 刷新
- Canvas AI chat 自定义工具
- Anthropic Managed Agent vault MCP
- 按步骤单独 opt-out 与组织级共享
- 交互式 MCP Apps UIs
- 第一方 vendor connector 注册
- 技能包安装与快照
- SKILL.md 之外的技能脚本、引用与额外文件
这些边界与第 1 节的锁定决策互相印证——例如"不做 SuperPlane MCP proxy"正是第 3 条"不写 refresh token 到 runner"的自然延伸。
10. 测试计划与 Storybook 覆盖
playbook 给出了 14 条验收测试,覆盖三层:数据层(创建 header 连接并列表)、注入层(启用后 runner 任务产出workspace_mcp.json;Claude/Codex/OpenCode 都能合并远端服务器;禁用工具出现在 JSON 与三个 CLI 的 denylist;planning 会话仍附加 SuperPlane stdio MCP)、OAuth 层(mock 授权服务器完成回调;vendor allowlist 失败显示 Reconnect 与错误文本)、校验层(拒绝私有 URL 与httpURL)、技能层(内联技能落盘到两个技能目录;空 markdown 与 GitHub source 被拒绝)、UI 层(Storybook 全状态走查)。
仓库中已存在对应测试,可直接对照验收:
- pkg/components/runner/workspace_agent_resources_test.go:
TestAttachWorkspaceAgentResourcesSkipsNonFactoryCanvas(非 factory 画布不产出任何文件)、TestAttachWorkspaceAgentResourcesWritesHeaderServers(启用后只写启用的服务器,环境变量为$SUPERPLANE_TASK_DIR/workspace_mcp.json,header 值正确解析)、TestAttachWorkspaceAgentResourcesWritesPublicServersWithoutHeaders(无认证的公共服务器不带 headers)等。 - 三个 CLI 的 run_test.go(如 claude/run_test.go、codex/run_test.go、openrouter/run_test.go)都直接写入
workspace_mcp.json并断言SUPERPLANE_WORKSPACE_MCP_CONFIG的注入行为。 - 模型层 pkg/models/factory_agent_resource_test.go 与 gRPC 层 pkg/grpc/actions/factories/factory_agent_resources_test.go 覆盖目录 CRUD、容量上限与 URL 唯一性。
Storybook 目录(FactorySettingsAgentResources.stories.tsx):
- MCP servers 页:
MCPEmpty、MCPCatalog、HeaderAuth、OAuthNotConnected、ConnectedGreenDot、OAuthNeedsReconnect、OAuthVendorRejected、Mixed。 - Skills 页:
SkillsEmpty、SkillsInline、SkillsGitHub(mocknextlevelbuilder/ui-ux-pro-max-skill)、SkillEditor。 - 另保留
Factories/Pages/Settings/MCP catalog、MCP status、MCP tools(对应 picker、绿点、工具排序与8/12计数),且页面必须能从Settings.stories.tsx的 sidebar 触达。
11. 维护清单:已上线表面与后续演进约束
已上线的表面(shipped surfaces,playbook 明确列出,均已在仓库中确认存在):
- MCP 页:FactorySettingsMCPPage.tsx
- Skills 页:FactorySettingsSkillsPage.tsx
- Skill 编辑器:FactorySettingsSkillEditorPage.tsx
- 路由:
/{org}/workspaces/{key}/settings/workspace/mcp与.../skills - Stories:FactorySettingsAgentResources.stories.tsx
- Catalog RPCs:
List/Create/Update/DeleteFactoryAgentResource,定义于 protos/factories.proto,实现于 pkg/grpc/actions/factories/factory_agent_resources.go - OAuth:
StartFactoryAgentResourceOAuth与/api/v1/mcp-oauth/callback(pkg/public/mcp_oauth.go) - Inject:pkg/components/runner/workspace_agent_resources.go
当接入 GitHubkind=skill包时的六条约束(playbook 收尾):
- 更新本 playbook,保持锁定决策 1、3、5 不变。
- 保留 Skills 页,不新增第二张目录表。
- 只扩展
AttachWorkspaceAgentResources,不新增第二条注入路径。 - 为 fetch 失败与就绪的 GitHub skill 行新增 stories,保留
SkillsEmpty与SkillsInline。 make pb.gen后保持 proto 字段号连续。- 以 GitHub
repository、ref、path作为包来源,不引入npx skills安装。
12. 结语:一张表、一个注入函数、三类 CLI
回顾整份 playbook,Workspace Agent Resources 的设计可以用"一、二、三"概括:一张目录表(factory_agent_resources)承载 MCP 与技能两类资源;一个注入函数(AttachWorkspaceAgentResources)在任务构建时统一发货;三个 CLI(Claude Code、Codex、OpenCode)各自把远端 MCP 服务器合并进自己的配置格式。管理员在设置页配置一次,所有 factory runner 步骤(含任务细化)即可自动使用这些资源——这正是把"每步都能用 Agent 能力"这个目标落到工程实现的关键路径。若要在 SuperPlane 上扩展第三方技能或新增 CLI 支持,本文第 11 节的约束清单就是必须遵守的扩展契约。
【免费下载链接】superplane
Open source factory for one-shot engineering
相关推荐
终极指南:用NetDXF掌握DWG文件处理的艺术
在当今数字化设计领域,CAD工程师和.NET开发者经常面临一个共同的挑战:如何在应用程序中高效处理DWG文件格式。传统的解决方案要么过于复杂,要么功能有限,让开
人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音深入解析 VoltAgent SKILL.md:用 Workspace 技能文件为 Agent 注入数据洞察能力
深入解析 VoltAgent SKILL.md:用 Workspace 技能文件为 Agent 注入数据洞察能力 导读 本文以 VoltAgent 仓库中 ex
人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音mcp-use 实战:用 SKILL.md 为 MCP 服务器发布 Agent Skills(Skills over MCP 指南)
mcp use 实战:用 SKILL.md 为 MCP 服务器发布 Agent Skills(Skills over MCP 指南) 本篇技术指南以 mcp u
后端MCP 服务MCP ClientsAI Agent人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考