@josephyan/qingflow-app-user-mcp 1.1.30 → 1.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/docs/local-agent-install.md +57 -6
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-app-user-mcp.mjs +1 -1
- package/npm/bin/qingflow-skills.mjs +5 -0
- package/npm/lib/runtime.mjs +20 -59
- package/npm/scripts/postinstall.mjs +1 -10
- package/package.json +3 -2
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-user/SKILL.md +16 -15
- package/skills/qingflow-app-user/references/data-gotchas.md +2 -2
- package/skills/qingflow-app-user/references/public-surface-sync.md +5 -7
- package/skills/qingflow-app-user/references/record-patterns.md +5 -5
- package/skills/qingflow-app-user/references/workflow-usage.md +4 -5
- package/skills/qingflow-mcp-setup/SKILL.md +13 -9
- package/skills/qingflow-mcp-setup/references/claude-desktop.md +1 -1
- package/skills/qingflow-mcp-setup/references/environments.md +2 -1
- package/skills/qingflow-mcp-setup/references/generic-stdio.md +6 -5
- package/skills/qingflow-record-analysis/SKILL.md +9 -8
- package/skills/qingflow-record-analysis/manifest.yaml +10 -0
- package/skills/qingflow-record-delete/SKILL.md +7 -3
- package/skills/qingflow-record-import/SKILL.md +35 -2
- package/skills/qingflow-record-insert/SKILL.md +78 -6
- package/skills/qingflow-record-insert/manifest.yaml +6 -0
- package/skills/qingflow-record-update/SKILL.md +39 -24
- package/skills/qingflow-task-ops/SKILL.md +30 -27
- package/skills/qingflow-task-ops/references/environments.md +0 -1
- package/skills/qingflow-task-ops/references/workflow-usage.md +4 -6
- package/src/qingflow_mcp/__main__.py +6 -2
- package/src/qingflow_mcp/builder_facade/models.py +473 -138
- package/src/qingflow_mcp/builder_facade/service.py +6356 -1866
- package/src/qingflow_mcp/cli/commands/builder.py +358 -355
- package/src/qingflow_mcp/cli/commands/chart.py +1 -1
- package/src/qingflow_mcp/cli/commands/common.py +12 -3
- package/src/qingflow_mcp/cli/commands/exports.py +2 -2
- package/src/qingflow_mcp/cli/commands/imports.py +3 -3
- package/src/qingflow_mcp/cli/commands/portal.py +2 -2
- package/src/qingflow_mcp/cli/commands/record.py +101 -27
- package/src/qingflow_mcp/cli/commands/task.py +28 -47
- package/src/qingflow_mcp/cli/commands/view.py +1 -1
- package/src/qingflow_mcp/cli/context.py +0 -3
- package/src/qingflow_mcp/cli/formatters.py +784 -16
- package/src/qingflow_mcp/cli/main.py +120 -41
- package/src/qingflow_mcp/errors.py +43 -2
- package/src/qingflow_mcp/public_surface.py +26 -17
- package/src/qingflow_mcp/response_trim.py +81 -17
- package/src/qingflow_mcp/server.py +14 -12
- package/src/qingflow_mcp/server_app_builder.py +83 -39
- package/src/qingflow_mcp/server_app_user.py +22 -16
- package/src/qingflow_mcp/session_store.py +11 -7
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +173 -0
- package/src/qingflow_mcp/solution/executor.py +114 -15
- package/src/qingflow_mcp/tools/ai_builder_tools.py +3571 -1473
- package/src/qingflow_mcp/tools/app_tools.py +184 -43
- package/src/qingflow_mcp/tools/approval_tools.py +197 -35
- package/src/qingflow_mcp/tools/auth_tools.py +92 -16
- package/src/qingflow_mcp/tools/code_block_tools.py +298 -40
- package/src/qingflow_mcp/tools/custom_button_tools.py +64 -10
- package/src/qingflow_mcp/tools/directory_tools.py +236 -72
- package/src/qingflow_mcp/tools/export_tools.py +244 -34
- package/src/qingflow_mcp/tools/feedback_tools.py +9 -0
- package/src/qingflow_mcp/tools/file_tools.py +9 -3
- package/src/qingflow_mcp/tools/import_tools.py +336 -49
- package/src/qingflow_mcp/tools/navigation_tools.py +91 -12
- package/src/qingflow_mcp/tools/package_tools.py +118 -6
- package/src/qingflow_mcp/tools/portal_tools.py +39 -3
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +116 -7
- package/src/qingflow_mcp/tools/record_tools.py +1141 -356
- package/src/qingflow_mcp/tools/resource_read_tools.py +188 -39
- package/src/qingflow_mcp/tools/role_tools.py +80 -9
- package/src/qingflow_mcp/tools/solution_tools.py +57 -15
- package/src/qingflow_mcp/tools/task_context_tools.py +687 -159
- package/src/qingflow_mcp/tools/task_tools.py +113 -29
- package/src/qingflow_mcp/tools/view_tools.py +106 -3
- package/src/qingflow_mcp/tools/workflow_tools.py +17 -1
- package/src/qingflow_mcp/tools/workspace_tools.py +71 -3
- package/src/qingflow_mcp/version.py +0 -2
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @josephyan/qingflow-app-user-mcp@1.1.
|
|
6
|
+
npm install @josephyan/qingflow-app-user-mcp@1.1.33
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @josephyan/qingflow-app-user-mcp@1.1.
|
|
12
|
+
npx -y -p @josephyan/qingflow-app-user-mcp@1.1.33 qingflow-app-user-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
|
@@ -23,17 +23,19 @@ This package bootstraps a local Python runtime on first install and then starts
|
|
|
23
23
|
Bundled skills:
|
|
24
24
|
|
|
25
25
|
- `skills/qingflow-app-user`
|
|
26
|
+
- `skills/qingflow-mcp-setup`
|
|
26
27
|
- `skills/qingflow-record-insert`
|
|
27
28
|
- `skills/qingflow-record-update`
|
|
28
29
|
- `skills/qingflow-record-delete`
|
|
29
30
|
- `skills/qingflow-record-import`
|
|
30
31
|
- `skills/qingflow-task-ops`
|
|
31
32
|
- `skills/qingflow-record-analysis`
|
|
32
|
-
- `skills/qingflow-mcp-setup`
|
|
33
33
|
|
|
34
34
|
Note:
|
|
35
35
|
|
|
36
36
|
- The skill files are included in the npm package.
|
|
37
|
-
-
|
|
38
|
-
-
|
|
37
|
+
- Installing the npm package does not overwrite agent skills automatically.
|
|
38
|
+
- To mount bundled skills from an installed package, run `qingflow-app-user-mcp-skills install --agent codex --scope user`.
|
|
39
|
+
- For one-shot `npx -p` installs, prefer `--copy` because symlinks would point into the npm execution cache.
|
|
40
|
+
- Use `qingflow-app-user-mcp-skills list` to inspect bundled skills. The installer defaults to symlinks for stable package installs and refuses to overwrite existing skills unless `--force` is provided.
|
|
39
41
|
- If a stdio MCP client reports `Transport closed`, delete `.npm-python`, reinstall the package, and make sure CLI/user/builder packages are on the same version. The stdio entrypoints refuse runtime bootstrap so install logs never corrupt MCP stdout.
|
|
@@ -101,7 +101,51 @@ npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-app-builder-mcp-<v
|
|
|
101
101
|
1. 创建 `.npm-python/`
|
|
102
102
|
2. 在其中建立 Python 虚拟环境
|
|
103
103
|
3. 执行 `pip install .`
|
|
104
|
-
4.
|
|
104
|
+
4. 在安装位置暴露对应入口:CLI 包暴露 `qingflow` / `qingflow-skills`;app-user 包暴露 `qingflow-app-user-mcp` / `qingflow-app-user-mcp-skills`;app-builder 包暴露 `qingflow-app-builder-mcp` / `qingflow-app-builder-mcp-skills`
|
|
105
|
+
5. 携带 `skills/<skill-name>/SKILL.md`,但不在 `postinstall` 阶段自动覆盖本机 agent skills
|
|
106
|
+
|
|
107
|
+
## Skills 挂载
|
|
108
|
+
|
|
109
|
+
显式查看包内 skills:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
qingflow-skills list
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
独立 MCP split 包使用包专属 skills 命令,避免全局安装多个包时发生 bin 覆盖:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
qingflow-app-user-mcp-skills list
|
|
119
|
+
qingflow-app-builder-mcp-skills list
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
显式挂载到 Codex 用户目录:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
qingflow-skills install --agent codex --scope user
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
如果通过一次性 `npx -p <package>` 执行安装,请加 `--copy`,避免 symlink 指向 npm 临时执行缓存:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx -y -p @qingflow-tech/qingflow-cli qingflow-skills install --agent codex --scope user --copy
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
也可以挂载到项目级 agent 目录:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
qingflow-skills install --agent claude-code --scope project
|
|
138
|
+
qingflow-skills install --agent cursor --scope project --copy
|
|
139
|
+
qingflow-skills install --agent all --scope project
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
默认行为:
|
|
143
|
+
|
|
144
|
+
- `--mode symlink`:使用 symlink,让 npm 包版本成为单一来源
|
|
145
|
+
- `--scope user`:安装到用户级 agent skills 目录
|
|
146
|
+
- `--agent codex`:目标 agent 为 Codex
|
|
147
|
+
- 不覆盖已有同名 skill;需要替换时显式加 `--force`
|
|
148
|
+
- 每次安装会在目标 skills 目录下写入 `.qingflow-skill-sources/<skill>.json`,记录 package、version、source、destination、agent、scope、mode
|
|
105
149
|
|
|
106
150
|
## 本地验证
|
|
107
151
|
|
|
@@ -110,24 +154,31 @@ npm install /absolute/path/to/dist/npm/qingflow-tech-qingflow-app-builder-mcp-<v
|
|
|
110
154
|
```bash
|
|
111
155
|
cd qingflow-support/mcp-server
|
|
112
156
|
node ./npm/bin/qingflow.mjs --help
|
|
157
|
+
node ./npm/bin/qingflow-skills.mjs list
|
|
113
158
|
node ./npm/bin/qingflow-app-user-mcp.mjs
|
|
114
159
|
node ./npm/bin/qingflow-app-builder-mcp.mjs
|
|
115
160
|
```
|
|
116
161
|
|
|
117
|
-
|
|
162
|
+
如果你是全局安装对应包:
|
|
118
163
|
|
|
119
164
|
```bash
|
|
120
165
|
qingflow --help
|
|
166
|
+
qingflow-skills list
|
|
121
167
|
qingflow-app-user-mcp
|
|
168
|
+
qingflow-app-user-mcp-skills list
|
|
122
169
|
qingflow-app-builder-mcp
|
|
170
|
+
qingflow-app-builder-mcp-skills list
|
|
123
171
|
```
|
|
124
172
|
|
|
125
|
-
如果你是把包安装到了某个本地 agent workspace
|
|
173
|
+
如果你是把包安装到了某个本地 agent workspace,安装对应包后命令通常位于:
|
|
126
174
|
|
|
127
175
|
```bash
|
|
128
176
|
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow
|
|
177
|
+
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-skills
|
|
129
178
|
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-user-mcp
|
|
179
|
+
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-user-mcp-skills
|
|
130
180
|
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-builder-mcp
|
|
181
|
+
/absolute/path/to/agent-workspace/node_modules/.bin/qingflow-app-builder-mcp-skills
|
|
131
182
|
```
|
|
132
183
|
|
|
133
184
|
如果你是从 tgz 安装到某个空目录,命令通常位于:
|
|
@@ -217,7 +268,7 @@ qingflow-app-builder-mcp
|
|
|
217
268
|
"command": "npx",
|
|
218
269
|
"args": [
|
|
219
270
|
"-y",
|
|
220
|
-
"@
|
|
271
|
+
"@qingflow-tech/qingflow-app-user-mcp"
|
|
221
272
|
],
|
|
222
273
|
"env": {
|
|
223
274
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
@@ -230,7 +281,7 @@ qingflow-app-builder-mcp
|
|
|
230
281
|
"command": "npx",
|
|
231
282
|
"args": [
|
|
232
283
|
"-y",
|
|
233
|
-
"@
|
|
284
|
+
"@qingflow-tech/qingflow-app-builder-mcp"
|
|
234
285
|
],
|
|
235
286
|
"env": {
|
|
236
287
|
"QINGFLOW_MCP_DEFAULT_BASE_URL": "https://qingflow.com/api",
|
|
@@ -272,7 +323,7 @@ npm install
|
|
|
272
323
|
|
|
273
324
|
如果 MCP 客户端一调用工具就报 `Transport closed`,优先检查这几件事:
|
|
274
325
|
|
|
275
|
-
1. 不要混用不同版本的 `@
|
|
326
|
+
1. 不要混用不同版本的 `@qingflow-tech/qingflow-cli`、`@qingflow-tech/qingflow-app-user-mcp`、`@qingflow-tech/qingflow-app-builder-mcp`
|
|
276
327
|
2. 删除安装目录下的 `.npm-python`
|
|
277
328
|
3. 重新执行 `npm install` 或重新安装对应 tgz/npm 包
|
|
278
329
|
4. 再启动 MCP 客户端
|
package/entry_point.py
CHANGED
|
@@ -7,7 +7,7 @@ src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "src"))
|
|
|
7
7
|
if src_path not in sys.path:
|
|
8
8
|
sys.path.insert(0, src_path)
|
|
9
9
|
|
|
10
|
-
from qingflow_mcp.
|
|
10
|
+
from qingflow_mcp.server_app_user import main
|
|
11
11
|
|
|
12
12
|
if __name__ == "__main__":
|
|
13
13
|
main()
|
|
@@ -24,7 +24,7 @@ function resolvePackageModule(metaUrl, ...segments) {
|
|
|
24
24
|
if (!pkgName) {
|
|
25
25
|
throw new Error(`Unknown qingflow command: ${binName}`);
|
|
26
26
|
}
|
|
27
|
-
const scope = process.env.QINGFLOW_NPM_SCOPE || "@
|
|
27
|
+
const scope = process.env.QINGFLOW_NPM_SCOPE || "@qingflow-tech";
|
|
28
28
|
const fromBin = path.join(scriptDir, "..", scope, pkgName, "npm", ...segments);
|
|
29
29
|
if (fs.existsSync(fromBin)) {
|
|
30
30
|
return pathToFileURL(fromBin).href;
|
package/npm/lib/runtime.mjs
CHANGED
|
@@ -42,7 +42,7 @@ export function getPackageRoot(metaUrl) {
|
|
|
42
42
|
if (!pkgName) {
|
|
43
43
|
throw new Error(`Unknown qingflow command: ${binName}`);
|
|
44
44
|
}
|
|
45
|
-
const scope = process.env.QINGFLOW_NPM_SCOPE || "@
|
|
45
|
+
const scope = process.env.QINGFLOW_NPM_SCOPE || "@qingflow-tech";
|
|
46
46
|
return path.join(scriptDir, "..", scope, pkgName);
|
|
47
47
|
}
|
|
48
48
|
return path.resolve(scriptDir, "..", "..");
|
|
@@ -154,43 +154,6 @@ function writeSkillProvenance(skillsDestRoot, skillName, payload) {
|
|
|
154
154
|
fs.writeFileSync(path.join(provenanceRoot, `${skillName}.json`), `${JSON.stringify(payload, null, 2)}\n`);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
function sleepMs(ms) {
|
|
158
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function withSkillInstallLock(skillsDestRoot, callback) {
|
|
162
|
-
const lockDir = path.join(skillsDestRoot, ".qingflow-skill-install.lock");
|
|
163
|
-
const startedAt = Date.now();
|
|
164
|
-
while (true) {
|
|
165
|
-
try {
|
|
166
|
-
fs.mkdirSync(lockDir);
|
|
167
|
-
break;
|
|
168
|
-
} catch (error) {
|
|
169
|
-
if (error.code !== "EEXIST") {
|
|
170
|
-
throw error;
|
|
171
|
-
}
|
|
172
|
-
try {
|
|
173
|
-
const stat = fs.statSync(lockDir);
|
|
174
|
-
if (Date.now() - stat.mtimeMs > 300_000) {
|
|
175
|
-
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
} catch {
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (Date.now() - startedAt > 30_000) {
|
|
182
|
-
throw new Error(`Timed out waiting for skill install lock: ${lockDir}`);
|
|
183
|
-
}
|
|
184
|
-
sleepMs(100);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
try {
|
|
188
|
-
return callback();
|
|
189
|
-
} finally {
|
|
190
|
-
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
157
|
export function installBundledSkills(
|
|
195
158
|
packageRoot,
|
|
196
159
|
{
|
|
@@ -234,29 +197,27 @@ export function installBundledSkills(
|
|
|
234
197
|
mode,
|
|
235
198
|
};
|
|
236
199
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
});
|
|
255
|
-
}
|
|
200
|
+
for (const skillName of wanted) {
|
|
201
|
+
const src = path.join(skillsSrc, skillName);
|
|
202
|
+
const dest = path.join(skillsDestRoot, skillName);
|
|
203
|
+
const installResult = installOneSkill(src, dest, { force, mode });
|
|
204
|
+
result[installResult.status === "conflict" ? "conflicts" : installResult.status].push(skillName);
|
|
205
|
+
if (installResult.status !== "conflict") {
|
|
206
|
+
writeSkillProvenance(skillsDestRoot, skillName, {
|
|
207
|
+
package: packageJson.name ?? null,
|
|
208
|
+
version: packageJson.version ?? null,
|
|
209
|
+
skill: skillName,
|
|
210
|
+
source: src,
|
|
211
|
+
destination: dest,
|
|
212
|
+
agent,
|
|
213
|
+
scope,
|
|
214
|
+
mode,
|
|
215
|
+
installed_at: new Date().toISOString(),
|
|
216
|
+
});
|
|
256
217
|
}
|
|
218
|
+
}
|
|
257
219
|
|
|
258
|
-
|
|
259
|
-
});
|
|
220
|
+
return result;
|
|
260
221
|
}
|
|
261
222
|
|
|
262
223
|
function parseSkillsCliArgs(args) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensurePythonEnv, getPackageRoot
|
|
1
|
+
import { ensurePythonEnv, getPackageRoot } from "../lib/runtime.mjs";
|
|
2
2
|
|
|
3
3
|
const packageRoot = getPackageRoot(import.meta.url);
|
|
4
4
|
|
|
@@ -6,15 +6,6 @@ try {
|
|
|
6
6
|
console.log("[qingflow-mcp] Bootstrapping Python runtime...");
|
|
7
7
|
ensurePythonEnv(packageRoot, { commandName: "qingflow-app-user-mcp" });
|
|
8
8
|
console.log("[qingflow-mcp] Python runtime is ready.");
|
|
9
|
-
const skills = installBundledSkills(packageRoot, { force: true });
|
|
10
|
-
if (!skills.skipped) {
|
|
11
|
-
const changed = [
|
|
12
|
-
skills.installed.length ? `installed=${skills.installed.join(",")}` : "",
|
|
13
|
-
skills.unchanged.length ? `unchanged=${skills.unchanged.join(",")}` : "",
|
|
14
|
-
skills.conflicts.length ? `conflicts=${skills.conflicts.join(",")}` : "",
|
|
15
|
-
].filter(Boolean).join(" ");
|
|
16
|
-
console.log(`[qingflow-mcp] Installed skills to ${skills.destination}: ${changed || "none"}`);
|
|
17
|
-
}
|
|
18
9
|
} catch (error) {
|
|
19
10
|
console.error(`[qingflow-mcp] postinstall failed: ${error.message}`);
|
|
20
11
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@josephyan/qingflow-app-user-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.33",
|
|
4
4
|
"description": "Operational end-user MCP for Qingflow records, tasks, comments, and directory workflows.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"qingflow-app-user-mcp": "./npm/bin/qingflow-app-user-mcp.mjs"
|
|
8
|
+
"qingflow-app-user-mcp": "./npm/bin/qingflow-app-user-mcp.mjs",
|
|
9
|
+
"qingflow-app-user-mcp-skills": "./npm/bin/qingflow-skills.mjs"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
12
|
"postinstall": "node ./npm/scripts/postinstall.mjs"
|
package/pyproject.toml
CHANGED
|
@@ -1,66 +1,67 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qingflow-app-user
|
|
3
|
-
description: Route Qingflow end-user requests to the right specialized operational skill
|
|
3
|
+
description: Route Qingflow end-user requests to the right specialized operational skill using the current Wingent Momo runtime MCP session. Use when the task is operational but it is not yet clear whether it is record CRUD or final analysis.
|
|
4
4
|
metadata:
|
|
5
5
|
short-description: Router for Qingflow operational skills
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Qingflow App User
|
|
9
9
|
|
|
10
|
-
> **Skill 版本**:`qingflow-skills-2026.06.
|
|
10
|
+
> **Skill 版本**:`qingflow-skills-2026.06.24.2`(入口文档版本;如需确认 CLI 包版本,使用 `qingflow --version` 或 `qingflow --json version`)。
|
|
11
11
|
|
|
12
12
|
## Overview
|
|
13
13
|
|
|
14
14
|
This skill is a lightweight router for operational Qingflow work.
|
|
15
|
-
|
|
15
|
+
In Wingent Momo runtime, trust injected MCP credentials, workspace, and route context until a business tool explicitly reports otherwise.
|
|
16
16
|
Before routing, skim the shared maintenance baseline: [public-surface-sync.md](references/public-surface-sync.md).
|
|
17
17
|
|
|
18
18
|
## Default Paths
|
|
19
19
|
|
|
20
20
|
Route to exactly one of these specialized paths:
|
|
21
21
|
|
|
22
|
-
1. Record insert
|
|
22
|
+
1. Record insert
|
|
23
23
|
Switch to [$qingflow-record-insert](../qingflow-record-insert/SKILL.md)
|
|
24
24
|
|
|
25
|
-
2. Record update
|
|
25
|
+
2. Record update
|
|
26
26
|
Switch to [$qingflow-record-update](../qingflow-record-update/SKILL.md)
|
|
27
27
|
|
|
28
|
-
3. Record delete
|
|
28
|
+
3. Record delete
|
|
29
29
|
Switch to [$qingflow-record-delete](../qingflow-record-delete/SKILL.md)
|
|
30
30
|
|
|
31
|
-
4. Record import
|
|
31
|
+
4. Record import
|
|
32
32
|
Switch to [$qingflow-record-import](../qingflow-record-import/SKILL.md)
|
|
33
33
|
|
|
34
|
-
5. Task workflow operations
|
|
34
|
+
5. Task workflow operations
|
|
35
35
|
Switch to [$qingflow-task-ops](../qingflow-task-ops/SKILL.md)
|
|
36
36
|
|
|
37
|
-
6. Analysis
|
|
37
|
+
6. Analysis
|
|
38
38
|
Switch to [$qingflow-record-analysis](../qingflow-record-analysis/SKILL.md)
|
|
39
39
|
|
|
40
|
-
7. MCP
|
|
40
|
+
7. Standalone MCP setup or explicit auth/workspace recovery
|
|
41
41
|
Switch to [$qingflow-mcp-setup](../qingflow-mcp-setup/SKILL.md)
|
|
42
42
|
|
|
43
43
|
8. App / view / workflow / chart / portal / package configuration
|
|
44
|
-
This is
|
|
44
|
+
This is outside the App User MCP tool surface. Use the separate `qingflow-app-builder` skill/MCP package when that builder surface is installed; otherwise ask the user to enable the builder MCP.
|
|
45
45
|
|
|
46
46
|
## Routing Rules
|
|
47
47
|
|
|
48
|
-
- If the user does not know the target `app_key`, discover apps first with `app_list`
|
|
48
|
+
- If the user does not know the target `app_key`, discover apps first with `app_list` / `app list --query` over current-user visible apps, then route to the specialized skill; do not use the legacy app search path for ordinary members
|
|
49
49
|
- If the app is known but the available data range is unclear, call `app_get` first and inspect `accessible_views`
|
|
50
50
|
- If the task is about creating or new record entry, switch to `$qingflow-record-insert`
|
|
51
51
|
- If the task is about editing an existing record directly, switch to `$qingflow-record-update`
|
|
52
52
|
- If the task is about deleting records directly, switch to `$qingflow-record-delete`
|
|
53
53
|
- If the task is about import templates, import capability discovery, import-file verification, authorized local file repair, import execution, or import status, switch to `$qingflow-record-import`
|
|
54
54
|
- If the task is about todo discovery, task context, approval actions, rollback or transfer, associated report review, or workflow log review, switch to `$qingflow-task-ops`
|
|
55
|
-
- If the task is about package, app, field, layout, workflow, view, chart, portal, visibility, icon, or app base configuration,
|
|
55
|
+
- If the task is about package, app, field, layout, workflow, view, chart, portal, visibility, icon, or app base configuration, do not continue with App User MCP tools. Use the separate `qingflow-app-builder` skill/MCP package when available, or ask the user to enable the builder MCP.
|
|
56
56
|
- If the task involves member, department, or relation fields and the user only has natural names/titles, keep the same route; direct write now supports backend-native auto resolution and may return `needs_confirmation` with candidates instead of failing blind
|
|
57
|
+
- For member/department field ambiguity, keep the record insert/update route and use `record_member_candidates` / `record_department_candidates`; do not switch to `directory_*`, builder member search, external-contact lookup, or contact-directory management queries. App User MCP only exposes `directory_search` for member-visible keyword search, not directory tree/list management.
|
|
57
58
|
- If the task involves linked visibility, upstream/downstream field dependencies, reference-driven auto fill, or formula-driven defaulting, keep the same insert/update route and read field-level `linkage` from the schema before composing payloads
|
|
58
59
|
- If the task is about subtable writes, still route to the matching insert/update skill, but shape the payload as parent subtable field -> row array; do not route users toward top-level leaf selectors
|
|
59
60
|
- If the task is insert-focused and readback/detail context matters, keep the same route and prefer the single-record detail readback after the write; use normalized list readback only when batch row shape is needed
|
|
60
61
|
- If the user sounds like an ordinary workflow assignee rather than a system operator, prefer `$qingflow-task-ops` over direct record mutation whenever both paths could fit
|
|
61
62
|
- If the task is about task discovery by natural language query, still route to `$qingflow-task-ops`; `task_list --query` now uses backend search first and only falls back to local matching when backend returns zero rows
|
|
62
63
|
- If the task is about grouped distributions, ratios, rankings, trends, insights, or any final statistical conclusion, switch to `$qingflow-record-analysis`
|
|
63
|
-
-
|
|
64
|
+
- In Wingent Momo runtime, do not route to `$qingflow-mcp-setup` as a preflight. Switch there only when a business tool explicitly reports missing auth, invalid session, or wrong/missing workspace, or when the user asks to configure a standalone MCP client.
|
|
64
65
|
|
|
65
66
|
## Shared Preconditions
|
|
66
67
|
|
|
@@ -88,4 +89,4 @@ Route to exactly one of these specialized paths:
|
|
|
88
89
|
- Record import: [$qingflow-record-import](../qingflow-record-import/SKILL.md)
|
|
89
90
|
- Task workflow operations: [$qingflow-task-ops](../qingflow-task-ops/SKILL.md)
|
|
90
91
|
- Dedicated analysis workflow: [$qingflow-record-analysis](../qingflow-record-analysis/SKILL.md)
|
|
91
|
-
- Builder workflow
|
|
92
|
+
- Builder workflow requires the separate `qingflow-app-builder` skill/MCP package.
|
|
@@ -9,12 +9,12 @@ For final statistics, grouped distributions, rankings, trends, or insight-style
|
|
|
9
9
|
- `record_get` is for one exact record and downloads readable detail-page images into `media_assets.items[].local_path` plus attachments/documents/tables into `file_assets.items[].local_path`
|
|
10
10
|
- Use `record_browse_schema_get` when field titles are uncertain instead of guessing ids
|
|
11
11
|
- Do not present paged browse output as if it were a grouped or full-population conclusion
|
|
12
|
-
- Use `record_export_direct` only when the user explicitly asks for export/download/Excel output
|
|
12
|
+
- Use `record_export_direct` only when the user explicitly asks for export/download/Excel output, and always pass an explicit `view_id` from `app_get.accessible_views` or the frontend URL
|
|
13
13
|
|
|
14
14
|
## Direct Writes
|
|
15
15
|
|
|
16
16
|
- `record_insert` is schema-first through `record_insert_schema_get`; default to `items=[{"fields": {...}}]`
|
|
17
|
-
- `record_update` is
|
|
17
|
+
- `record_update` is detail-first: read `record_get`, compose the requested title-keyed `fields` map, then write directly; use `record_update_schema_get` only after update failure or ambiguity
|
|
18
18
|
- `record_delete` does not need a schema-get step
|
|
19
19
|
- For batch insert, `partial_success` means some rows were created; use `created_record_ids`, failed `row_number`, and `failed_fields` to repair only failed rows
|
|
20
20
|
- If a direct-write tool returns `write_executed=false`, the write was blocked and not executed for that item
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Qingflow Core Public Surface Sync
|
|
2
2
|
|
|
3
|
-
Use this file as the maintenance baseline for the core Qingflow skills.
|
|
3
|
+
Use this file as the maintenance baseline for the core Qingflow skills.
|
|
4
4
|
It is not a user-facing product spec. It exists to prevent skill drift.
|
|
5
5
|
|
|
6
6
|
## Current Public Defaults
|
|
@@ -12,9 +12,9 @@ It is not a user-facing product spec. It exists to prevent skill drift.
|
|
|
12
12
|
- Standard flows:
|
|
13
13
|
- analyze: `app_get -> record_browse_schema_get -> record_access -> Python`
|
|
14
14
|
- browse detail: `app_get -> record_browse_schema_get -> record_list / record_get`
|
|
15
|
-
- explicit export/download/Excel: `view_get -> record_export_*` or `record_export_direct`
|
|
15
|
+
- explicit export/download/Excel: `app_get -> choose view_id -> view_get -> record_export_*` or `record_export_direct`; export tools require explicit `view_id`
|
|
16
16
|
- insert: `record_insert_schema_get -> record_insert(items)`
|
|
17
|
-
- update: `
|
|
17
|
+
- update: `record_get -> record_update`; use `record_update_schema_get` only for failure diagnosis or ambiguous writable-field routing
|
|
18
18
|
|
|
19
19
|
### Tasks
|
|
20
20
|
|
|
@@ -33,22 +33,20 @@ It is not a user-facing product spec. It exists to prevent skill drift.
|
|
|
33
33
|
|
|
34
34
|
### Builder
|
|
35
35
|
|
|
36
|
-
- Builder work belongs to the `qingflow-cli` skill or the `qingflow-app-builder` package; this app-user package only records the boundary to prevent routing drift.
|
|
37
36
|
- Official package entry: `package_get`, `package_apply`
|
|
38
37
|
- Official builder writes:
|
|
39
38
|
- `app_schema_apply`
|
|
40
39
|
- `app_layout_apply`
|
|
41
40
|
- `app_flow_apply`
|
|
42
41
|
- `app_views_apply`
|
|
42
|
+
- `app_custom_buttons_apply`
|
|
43
43
|
- `app_associated_resources_apply`
|
|
44
44
|
- `app_charts_apply`
|
|
45
45
|
- `portal_apply`
|
|
46
46
|
- `app_publish_verify`
|
|
47
|
-
- Complete-system main path: package -> schema apps with `form.sections` and `target_app_ref` -> views with `action_buttons` -> portal with inline `sections[].chart`
|
|
48
|
-
- Single-app main path: resolve/get -> schema with `form.sections` -> views with `action_buttons`; do not default to portal
|
|
49
47
|
- `portal_apply` edit mode may omit `sections` for base-info-only updates
|
|
50
48
|
- `app_charts_apply.visibility` is a public capability and should be treated as a base-only visibility update
|
|
51
|
-
- Existing object parameter replacement should use `patch_views`, `patch_resources`, and `patch_charts`; `upsert_*` is for creation or full target config
|
|
49
|
+
- Existing object parameter replacement should use `patch_views`, `patch_buttons`, `patch_resources`, and `patch_charts`; `upsert_*` is for creation or full target config
|
|
52
50
|
- `app_get.editability` uses:
|
|
53
51
|
- `can_edit_app_base`
|
|
54
52
|
- `can_edit_form`
|
|
@@ -41,13 +41,13 @@ Use `record_insert_schema_get -> record_insert(items)`.
|
|
|
41
41
|
|
|
42
42
|
## Update Pattern
|
|
43
43
|
|
|
44
|
-
Use `
|
|
44
|
+
Use `record_get -> record_update`.
|
|
45
45
|
|
|
46
46
|
1. Confirm the target app and `record_id`
|
|
47
|
-
2. Read `
|
|
48
|
-
3.
|
|
49
|
-
4.
|
|
50
|
-
5.
|
|
47
|
+
2. Read `record_get` in the same view/context the user is using when a `view_id` is known
|
|
48
|
+
3. Build a field-title keyed `fields` map from `record_get.fields[]` and the user's requested changes
|
|
49
|
+
4. Run `record_update` directly; let MCP auto-select the executable update route
|
|
50
|
+
5. If `record_update` fails because fields/routes are ambiguous or unavailable, then use `record_update_schema_get` as a diagnostic tool
|
|
51
51
|
|
|
52
52
|
## Delete Pattern
|
|
53
53
|
|
|
@@ -14,13 +14,12 @@ Examples:
|
|
|
14
14
|
|
|
15
15
|
Rules:
|
|
16
16
|
|
|
17
|
-
- if the user starts from inbox, todo, workload, cc, or bottleneck language, use
|
|
18
|
-
- use `
|
|
19
|
-
- use `
|
|
20
|
-
- use `task_facets` when worksheet or workflow-node buckets matter
|
|
17
|
+
- if the user starts from inbox, todo, workload, cc, or bottleneck language, use the public task tools first
|
|
18
|
+
- use `task_list` for headline counts and flat browsing; group locally by app or workflow node when buckets matter
|
|
19
|
+
- use `task_get`, `task_workflow_log_get`, and `task_associated_report_detail_get` only after locating the exact task
|
|
21
20
|
- treat task counts as task-center counts, not record counts
|
|
22
21
|
- switch to `record_*` only after locating the exact business record behind a task
|
|
23
22
|
- identify the exact target first
|
|
24
|
-
- for approve or reject, identify the exact
|
|
23
|
+
- for approve or reject, identify the exact target first; prefer `task_id` from task-center results, then use `task_action_execute` with action `approve` or `reject`
|
|
25
24
|
- avoid usage-side workflow actions on ambiguous records
|
|
26
25
|
- summarize the final action and target task ids or record ids
|
|
@@ -7,6 +7,8 @@ metadata:
|
|
|
7
7
|
|
|
8
8
|
# Qingflow MCP Setup
|
|
9
9
|
|
|
10
|
+
> **Skill 版本**:`qingflow-skills-2026.06.24.2`(入口文档版本;如需确认 CLI 包版本,使用 `qingflow --version` 或 `qingflow --json version`)。
|
|
11
|
+
|
|
10
12
|
## Overview
|
|
11
13
|
|
|
12
14
|
This skill sets up the local Qingflow MCP server, connects it to a local AI client, and verifies authentication and workspace selection. Use it for installation, client configuration, token login, and connection troubleshooting.
|
|
@@ -73,24 +75,26 @@ cd <repo_root>/qingflow-support/mcp-server
|
|
|
73
75
|
|
|
74
76
|
Prefer validating through the client after config is added.
|
|
75
77
|
|
|
76
|
-
### Step 5:
|
|
78
|
+
### Step 5: Use injected session first; authenticate only for setup or recovery
|
|
79
|
+
|
|
80
|
+
For Wingent Momo runtime conversations, the session normally already carries the credential-derived token, workspace, and route context. Do not run `auth_use_credential`, `auth_login`, `workspace_list`, or `workspace_select` before ordinary business tools. Start with the smallest read-only business call that fits the task; if it succeeds, continue.
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
For a standalone local MCP client that has no injected session, use this setup order:
|
|
79
83
|
|
|
80
|
-
1. `
|
|
84
|
+
1. `auth_use_credential` or `auth_login`
|
|
81
85
|
2. `workspace_list`
|
|
82
86
|
3. `workspace_select`
|
|
83
|
-
4.
|
|
87
|
+
4. Run a small read-only business tool
|
|
84
88
|
|
|
85
|
-
If the user
|
|
89
|
+
`auth_use_credential` gets the selected workspace from the credential context. If the user needs a different workspace after authentication, use `workspace_list` and then `workspace_select`.
|
|
86
90
|
After auth, prefer one read-only tool call that returns `request_route` so you can confirm the live `base_url` and `qf_version` before proceeding.
|
|
87
|
-
`
|
|
88
|
-
Do not
|
|
91
|
+
`auth_use_credential` is a tool call, not a custom HTTP header. It exchanges the createClaw credential for a Qingflow token, `wsId`, and when needed `Cookie: qfVersion=...` after the session is established.
|
|
92
|
+
Do not run `workspace_select` on production paths unless the user explicitly asks to switch workspace or a business tool clearly reports that no workspace is selected. If `/user` does not return a version lane, the session now falls back to the workspace `systemVersion`.
|
|
89
93
|
|
|
90
94
|
### Step 6: Troubleshoot in the right layer
|
|
91
95
|
|
|
92
96
|
- If the client cannot launch the server, check path, execute permission, and `.venv`
|
|
93
|
-
- If tools return `auth required`, re-run `
|
|
97
|
+
- If tools return `auth required`, re-run `auth_use_credential` or `auth_login`
|
|
94
98
|
- If tools return `workspace not selected`, call `workspace_list` and `workspace_select`
|
|
95
99
|
- If calls fail after a working session, assume token expiry and re-authenticate
|
|
96
100
|
- If the browser shows data but MCP does not, compare `request_route` against the browser environment and check whether `qf_version` should be `canary`
|
|
@@ -98,7 +102,7 @@ Do not skip `workspace_select` on production paths. If `/user` does not return a
|
|
|
98
102
|
## Guardrails
|
|
99
103
|
|
|
100
104
|
- Never write tokens into the skill files
|
|
101
|
-
-
|
|
105
|
+
- In Wingent Momo runtime, trust injected workspace context until a business tool proves otherwise; for standalone clients, confirm workspace with `auth_whoami`, `workspace_select`, or a successful read-only business call.
|
|
102
106
|
- When debugging, distinguish server startup issues from Qingflow auth issues
|
|
103
107
|
- When the user mentions production, restate the exact `base_url`, `qf_version`, and workspace before any live validation
|
|
104
108
|
- If setup is complete but the current MCP capability is still unsupported or the user's need still cannot be satisfied, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation
|
|
@@ -31,4 +31,4 @@ Keep separate snippets for `test` and `prod` so switching environments does not
|
|
|
31
31
|
- Replace `<ABSOLUTE_PATH_TO_REPO>` with the real checkout path on the current machine
|
|
32
32
|
- If the server path changes, update the `command` field
|
|
33
33
|
- The server is local stdio MCP, so no remote URL is required
|
|
34
|
-
- Do not store Qingflow
|
|
34
|
+
- Do not store Qingflow credentials in Claude Desktop config; pass the createClaw credential through `auth_use_credential` inside the chat, or use `auth_login` when credential exchange is unavailable
|
|
@@ -28,7 +28,8 @@ Known values in the current workspace:
|
|
|
28
28
|
Setup behavior:
|
|
29
29
|
|
|
30
30
|
- prefer this environment for Claude Desktop or local MCP client onboarding
|
|
31
|
-
- use
|
|
31
|
+
- for Wingent Momo runtime, use the injected session and skip auth/workspace preflight
|
|
32
|
+
- for standalone MCP client setup, use `auth_use_credential` or `auth_login`, then `workspace_list`, then `workspace_select`
|
|
32
33
|
- if the user asks to verify installation, a real read-only smoke path is acceptable
|
|
33
34
|
|
|
34
35
|
## Production Environment
|
|
@@ -19,13 +19,14 @@ Keep separate client entries or separate config snippets for `test` and `prod`.
|
|
|
19
19
|
|
|
20
20
|
1. Start the client
|
|
21
21
|
2. Confirm the `qingflow` MCP server is visible
|
|
22
|
-
3.
|
|
23
|
-
4.
|
|
24
|
-
5.
|
|
25
|
-
6.
|
|
22
|
+
3. In Wingent Momo runtime, skip auth/workspace preflight and run a read-only tool such as `app_list`
|
|
23
|
+
4. In a standalone client without injected credentials, run `auth_use_credential` or `auth_login`
|
|
24
|
+
5. Then run `workspace_list`
|
|
25
|
+
6. Then run `workspace_select`
|
|
26
|
+
7. Run a read-only tool such as `app_list`
|
|
26
27
|
|
|
27
28
|
## Common failures
|
|
28
29
|
|
|
29
30
|
- Launch failure: bad `command` path or missing `.venv`
|
|
30
|
-
- Auth failure: invalid or expired token
|
|
31
|
+
- Auth failure: invalid or expired credential/token
|
|
31
32
|
- Business tool failure before setup: workspace not selected
|