@costrict/cosworkflow
v0.1.6
Published
CosWorkflow MCP server — query and track CSC work items (IPD) over the Model Context Protocol.
Readme
cosworkflow-mcp
Implementation Notes
This project follows the standard MCP TypeScript server layout: tsc → dist/, exposed via bin, consumed through npx. Dev uses tsx for instant transpile; releases ship the compiled dist/. Runs on Node.js + npm (Bun not required).
开发
npm install # SDK(runtime)+ tsx/typescript/shx(dev/build)
npm start # tsx 即时转译跑 src/index.ts(改代码即时生效)
npm run build # tsc → dist/(含拷贝 ipd-api.cjs / ipd-token-logic.cjs)
npm run typecheck # tsc --noEmit
npm run watch # tsc --watch作为 MCP server 消费(发布后)
发布到 npm 后,客户端 .mcp.json:
{
"mcpServers": {
"cosworkflow": {
"command": "npx",
"args": ["-y", "@costrict/cosworkflow@latest"]
}
}
}不要在仓库内 .mcp.json 使用不带版本/标签的包规格:
{
"command": "npx",
"args": ["-y", "@costrict/cosworkflow"]
}在本仓库根目录等同名 package 场景下,npm 会把 @costrict/cosworkflow 当作当前项目自引用,但不会为当前项目创建 _npx 临时安装包的 cosworkflow bin shim,最终报 cosworkflow 找不到。使用 @costrict/cosworkflow@latest 会强制走 registry 包解析,可稳定启动。
Windows 客户端:
"command": "cmd","args": ["/c", "npx", "-y", "@costrict/cosworkflow@latest"]。npx -y首次运行自动从 npm 拉取本包及依赖,消费者无需手动安装(公共 scoped 包,免认证)。本地 dogfood 编译产物(不经 npx):"command": "node","args": ["dist/index.js"]。
发布(维护者)
发布由 GitHub Actions 自动完成(.github/workflows/release.yml):推 v* tag → npm ci → typecheck → build → npm publish 到 npmjs.org。
一次性准备:
- 在 npm 创建组织
costrict(对应 scope@costrict),并确认@costrict/cosworkflow未被占用。 - 生成 npm 发布 token(npm → Access Tokens → Classic/Granular,给 publish 权限)。
- 在 GitHub 仓库
zgsm-sangfor/cosworkflow-mcp→ Settings → Secrets and variables → Actions → 加仓库 secretNPM_TOKEN。
发版:
npm version patch # 0.1.0 → 0.1.1,自动改 package.json + 打 tag v0.1.1
git push --follow-tags # 推送 → Actions 自动构建并发布到 npm
publishConfig.access: "public"让 scoped 包以公共可见发布。想先演练:Actions 页手动触发 "Release" workflow,勾选dry-run。prepare钩子会在 publish 前npm run build,tarball 始终带最新dist/;files: ["dist"]只发布编译产物。
Multica integration is implemented through HTTP APIs, not the Multica CLI.
Key environment variables. The Multica mirror is mandatory: the server resolves credentials as ENV → ~/.costrict/share/auth.json → throw (see "复用 csc 的 CoStrict 登录" below). Placeholder values (e.g. __PASTE_MULTICA_JWT__) are treated as "not configured" and fall through to the file; if neither source yields both a token and a base URL, the server refuses to start.
| Variable | Purpose |
|---|---|
| COSTRICT_BASE_URL | Multica base URL. Its source decides URL construction (see "URL 拼接" below): set via ENV → bare base; fallback to ~/.costrict/share/auth.json → deployment prefixes applied. Missing both sources → startup error |
| COSTRICT_TOKEN | Multica API token (falls back to ~/.costrict/share/auth.json; placeholder/missing → startup error) |
复用 csc 的 CoStrict 登录(~/.costrict/share/auth.json)
若你已通过 csc(CoStrict CLI)登录,COSTRICT_TOKEN 与 COSTRICT_BASE_URL 可不配:未设(或为占位符)时,自动回退读 csc 的 ~/.costrict/share/auth.json 里的 access_token 与 base_url。优先级:环境变量 > auth.json。
- 必需:Multica 镜像为强制项——env 与 auth.json 两级都解析不到(或只到其一)时,server 启动即抛错,不再静默降级为 IPD-only。
COSTRICT_AUTH_JSON_PATH:可选,覆盖凭证文件路径(默认~/.costrict/share/auth.json)。- 不查过期:
access_token过期后 Multica 会回 401,重新csc登录刷新即可。 base_url为 CoStrict 平台根地址(裸 host)即可;csc 登录来源会自动套/workflow-backend(API)//cloud/workflow(协作页)前缀(见下「URL 拼接」)。如需切到非 csc 部署形态,改用COSTRICT_BASE_URL(ENV)覆盖。
URL 拼接(按 BASE_URL 来源分流)
Multica 接口不返回页面 URL;协作页面 issueUrl 与 Multica API 请求地址均在本地拼接,规则取决于 COSTRICT_BASE_URL 的来源:
- ENV 来源(设了
COSTRICT_BASE_URL):裸 base。- API 请求:
{BASE_URL}/api/xxxxx - 协作页面:
{BASE_URL}/{workspace}/issues/{issue_id}
- API 请求:
- auth.json 来源(回退
~/.costrict/share/auth.json的base_url,即 csc 登录态):自动套部署前缀。- API 请求:
{BASE_URL}/workflow-backend/api/xxxxx - 协作页面:
{BASE_URL}/cloud/workflow/{workspace}/issues/{issue_id}
- API 请求:
COSTRICT_WEB_BASE_URL已移除:协作页面地址完全由来源推导,不再支持单独覆盖。
Current behavior:
list_issues: read-only IPD query over server-side search. It supports type/status/assignedToMe/projectId/projectName pagination;projectNameis resolved to a unique project ID before issue search; fuzzy or duplicate matches return a normal candidate list instead of guessing or failing.get_issue_detail: read-only IPD detail query, returning node content, parent chain, direct children, attachments, and related links when present.create_subissue: creates Tech/task children under allowed parents, deduplicates by title, and supports item-leveldescriptionFormat: "markdown". Top-leveldescriptionFormatis rejected.update_subissue: reassigns an existing task owner only. It does not create tasks, transition status, edit content, or upload artifacts.transition_state: moves epic/feature/story/tech/task towardin_progress/done/blocked/todousing the IPD transition flow. IPD success is required before any best-effort mirror sync.upload_artifacts: uploads files, links, and comments to a target work item. It does not transition status, create tasks, or edit node body content.download_attachment: downloads an attachment URL, typically fromget_issue_detail, into a local file path.upload_deliverable: uploads a local file as a fixed-name requirement deliverable and marks that deliverable submitted.
Multica 镜像字段同步
写工具(create_subissue / update_subissue / transition_state / upload_artifacts)在触达镜像时,会按 IPD 为源回填字段到已存在的 Multica 镜像 issue(公共入口 src/mirror-reconcile.ts 的 reconcileMirror):
- 原生字段:
title/description/priority(IPD 改动后下次触达即更新)。 - metadata:
ipd_assignee_id/ipd_assignee_name/ipd_url/ipd_update_at(责任人只入 metadata,不改 Multicaassignee)。 - 不改动:
assignee_type/assignee_id、status(由transition_state单独管)。 - 变更检测:
ipd_update_at未变则跳过写。
list_issues 为纯读,不产生 Multica 读写。get_issue_detail 为只读查询,只在需要回填相关链接等信息时读取已有镜像数据,不外显镜像 ID 或协作页面地址。二者均展示 IPD 负责人。
自包含 MCP Server:IPD 客户端已内置于项目(src/ipd-api.cjs),无需外部依赖即可运行,为 CSC Agent 提供「以 feature 进入系统需求 → 拉取用户需求 → 推回 IPD」的工作流原语。
src/ipd-api.cjs是从qianliu-ipd/scripts/ipd_api.js集成进来的 IPD HTTP 客户端(仅依赖 Node 内置模块)。凭证优先级:环境变量 > 配置文件;支持IPD_TOKEN/IPD_PRODUCT/IPD_BASE_URL/QIANLIU_CONFIG_PATH环境变量。配置文件(默认~/.qianliu/config.json)可选——env 齐全时无需该文件。
工具
| 工具 | 读写 | 用途 | 底层 IPD 接口 |
|---|---|---|---|
| list_issues | 读 | 查询工作项清单;支持名下、项目 ID、项目名称、状态和分页过滤 | getCurrentUser / searchIssues / searchProjectsByName |
| get_issue_detail | 读 | 按 ID 查询工作项正文、父链、直接子节点、附件和相关链接 | getIssueDetail / getSubIssues / getIssueAttachments |
| create_subissue | 写 | 在父节点下创建 Tech/task,按标题去重;支持 item 级 Markdown 正文 | getIssue / createIssue / createTask / getSubIssues |
| update_subissue | 写 | 改派已有 task 负责人;不创建、不流转、不改正文 | getIssue / updateIssueAssigner |
| transition_state | 写 | 将工作项推进到 in_progress / done / blocked / todo | getIssue / getIssueTransitions / doTransition |
| upload_artifacts | 写 | 上传文件、外链和归档评论到指定工作项 | uploadIssueAttachment |
| download_attachment | 读/写本地 | 下载附件直链到本地路径,不修改工作项 | HTTP download |
| upload_deliverable | 写 | 上传固定枚举名称的需求交付物附件 | uploadDeliverableByName |
工具定义以
src/index.ts暴露的 MCP schema 为准;本 README 只保留运行、交付和常用行为摘要。create_subissue/update_subissue/transition_state/upload_artifacts的镜像同步均为后台 best-effort,不扩大用户可见返回契约。
典型流程(系统需求入口 ↔ 推回 IPD)
list_issues({ type: "feature", projectName: "完整项目名" }) # 先解析项目 ID,再查项目内 feature
list_issues({ type: "feature", projectName: "不完整项目名" }) # 返回候选 projectId,不执行工作项搜索
→ get_issue_detail(featureId) # 拉取正文、父子链和附件上下文
→ upload_artifacts(featureId, 系统需求文档/设计文档) # 归档文件、外链和评论,不推进状态
→ create_subissue(featureId, [{ kind: "tech" }, { kind: "task", descriptionFormat: "markdown" }])
→ update_subissue(taskId, assignee) # 可选:改派已有 task 负责人
→ transition_state(featureId, done) # 显式推进状态运行
npm start默认使用内置 IPD 客户端 src/ipd-api.cjs,只需 ~/.qianliu/config.json 配好 ipd.token(创建需求还需 ipd.product)。
如需改用外部实现,可设 COSWORKFLOW_IPD_API_PATH 覆盖:
# 可选:覆盖为外部 IPD 客户端
COSWORKFLOW_IPD_API_PATH="/abs/path/to/ipd_api.js" npm start错误码
工具失败时返回带错误码前缀的文本,常见包括 INVALID_INPUT / NOT_FOUND / INVALID_TRANSITION / AUTH_EXPIRED / UPSTREAM_TIMEOUT / UPSTREAM_ERROR / PARTIAL。项目名模糊匹配或重名会正常返回候选列表,不作为错误处理。
