@josephyan/qingflow-app-builder-mcp 1.1.25 → 1.1.27
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 +6 -6
- package/docs/local-agent-install.md +6 -57
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-app-builder-mcp.mjs +33 -2
- package/npm/lib/runtime.mjs +101 -21
- package/npm/scripts/postinstall.mjs +10 -1
- package/package.json +2 -3
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +51 -164
- package/skills/qingflow-app-builder/references/build-complete-system.md +234 -0
- package/skills/qingflow-app-builder/references/build-single-app.md +138 -0
- package/skills/qingflow-app-builder/references/create-app.md +24 -31
- package/skills/qingflow-app-builder/references/environments.md +1 -1
- package/skills/qingflow-app-builder/references/gotchas.md +13 -39
- package/skills/qingflow-app-builder/references/match-rules.md +18 -29
- package/skills/qingflow-app-builder/references/public-surface-sync.md +2 -2
- package/skills/qingflow-app-builder/references/solution-playbooks.md +0 -10
- package/skills/qingflow-app-builder/references/tool-selection.md +25 -42
- package/skills/qingflow-app-builder/references/update-flow.md +38 -22
- package/skills/qingflow-app-builder/references/update-schema.md +0 -14
- package/skills/qingflow-app-builder/references/update-views.md +14 -83
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +3 -5
- package/skills/qingflow-app-builder-code-integrations/references/code-block.md +1 -1
- package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +1 -1
- package/skills/qingflow-mcp-setup/SKILL.md +111 -0
- package/skills/qingflow-mcp-setup/agents/openai.yaml +4 -0
- package/skills/qingflow-mcp-setup/references/claude-desktop.md +34 -0
- package/skills/qingflow-mcp-setup/references/environments.md +61 -0
- package/skills/qingflow-mcp-setup/references/generic-stdio.md +31 -0
- package/skills/qingflow-mcp-setup/scripts/check_local_server.sh +38 -0
- package/skills/qingflow-workflow-builder/SKILL.md +96 -0
- package/skills/qingflow-workflow-builder/manifest.yaml +8 -0
- package/skills/qingflow-workflow-builder/references/01-overview.md +45 -0
- package/skills/qingflow-workflow-builder/references/02-update-mode.md +53 -0
- package/skills/qingflow-workflow-builder/references/03-flow-patterns.md +57 -0
- package/skills/qingflow-workflow-builder/references/04-stage1-business-modeling.md +131 -0
- package/skills/qingflow-workflow-builder/references/05-stage2-members-roles.md +29 -0
- package/skills/qingflow-workflow-builder/references/06-stage3-build-spec.md +165 -0
- package/skills/qingflow-workflow-builder/references/07-stage4-validate-spec.md +33 -0
- package/skills/qingflow-workflow-builder/references/08-stage5-apply-verify.md +51 -0
- package/skills/qingflow-workflow-builder/references/09-stage6-summary.md +88 -0
- package/skills/qingflow-workflow-builder/references/10-node-config-reference.md +93 -0
- package/skills/qingflow-workflow-builder/references/11-troubleshooting.md +15 -0
- package/skills/qingflow-workflow-builder/scripts/diff_flow_spec.py +275 -0
- package/skills/qingflow-workflow-builder/scripts/validate_flow_spec.py +605 -0
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/__main__.py +2 -6
- package/src/qingflow_mcp/builder_facade/models.py +49 -330
- package/src/qingflow_mcp/builder_facade/service.py +1621 -6149
- package/src/qingflow_mcp/cli/commands/builder.py +366 -322
- package/src/qingflow_mcp/cli/commands/chart.py +1 -1
- package/src/qingflow_mcp/cli/commands/common.py +3 -12
- 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 +27 -101
- package/src/qingflow_mcp/cli/commands/task.py +47 -28
- package/src/qingflow_mcp/cli/commands/view.py +1 -1
- package/src/qingflow_mcp/cli/context.py +3 -0
- package/src/qingflow_mcp/cli/formatters.py +16 -784
- package/src/qingflow_mcp/cli/main.py +41 -120
- package/src/qingflow_mcp/errors.py +2 -43
- package/src/qingflow_mcp/public_surface.py +17 -26
- package/src/qingflow_mcp/response_trim.py +17 -81
- package/src/qingflow_mcp/server.py +12 -14
- package/src/qingflow_mcp/server_app_builder.py +39 -81
- package/src/qingflow_mcp/server_app_user.py +16 -22
- package/src/qingflow_mcp/session_store.py +7 -11
- package/src/qingflow_mcp/solution/compiler/__init__.py +1 -3
- package/src/qingflow_mcp/solution/executor.py +18 -245
- package/src/qingflow_mcp/tools/ai_builder_tools.py +1483 -3139
- package/src/qingflow_mcp/tools/app_tools.py +43 -184
- package/src/qingflow_mcp/tools/approval_tools.py +35 -197
- package/src/qingflow_mcp/tools/auth_tools.py +16 -92
- package/src/qingflow_mcp/tools/code_block_tools.py +40 -298
- package/src/qingflow_mcp/tools/custom_button_tools.py +10 -64
- package/src/qingflow_mcp/tools/directory_tools.py +72 -236
- package/src/qingflow_mcp/tools/export_tools.py +34 -244
- package/src/qingflow_mcp/tools/feedback_tools.py +0 -9
- package/src/qingflow_mcp/tools/file_tools.py +3 -9
- package/src/qingflow_mcp/tools/import_tools.py +49 -336
- package/src/qingflow_mcp/tools/navigation_tools.py +12 -91
- package/src/qingflow_mcp/tools/package_tools.py +6 -118
- package/src/qingflow_mcp/tools/portal_tools.py +3 -39
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +7 -116
- package/src/qingflow_mcp/tools/record_tools.py +360 -1145
- package/src/qingflow_mcp/tools/resource_read_tools.py +39 -188
- package/src/qingflow_mcp/tools/role_tools.py +9 -80
- package/src/qingflow_mcp/tools/solution_tools.py +45 -59
- package/src/qingflow_mcp/tools/task_context_tools.py +158 -662
- package/src/qingflow_mcp/tools/task_tools.py +29 -113
- package/src/qingflow_mcp/tools/view_tools.py +3 -106
- package/src/qingflow_mcp/tools/workflow_tools.py +4 -48
- package/src/qingflow_mcp/tools/workspace_tools.py +3 -71
- package/src/qingflow_mcp/version.py +2 -0
- package/npm/bin/qingflow-skills.mjs +0 -5
- package/skills/qingflow-app-builder/references/complete-system-development-guide.md +0 -172
- package/skills/qingflow-app-builder/references/single-app-development-guide.md +0 -87
- package/skills/qingflow-app-builder/scripts/validate_system_build_summary.py +0 -124
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +0 -173
|
@@ -19,40 +19,27 @@ Before picking tools, decide which layer the request targets:
|
|
|
19
19
|
|
|
20
20
|
If the user asks for multiple forms/modules that relate to each other, this is a package-level multi-app task, not a single-app create.
|
|
21
21
|
|
|
22
|
-
Use this split consistently:
|
|
23
|
-
|
|
24
|
-
- Complete system/package: `package_apply` first, then one `app_schema_apply(package_id=..., apps=[...])`.
|
|
25
|
-
- Single app: `app_resolve/app_get` first, then app-scoped apply tools.
|
|
26
|
-
- Record/task/data operation: leave builder and use record/task skills.
|
|
27
|
-
|
|
28
|
-
Decision gate before writing:
|
|
29
|
-
|
|
30
|
-
| Evidence | Action |
|
|
31
|
-
| --- | --- |
|
|
32
|
-
| User gives an `app_key`, `view_key`, `chart_id`, `dash_key`, or exact `package_id` | Treat the task as an update to that existing target unless the user explicitly asks for a new one |
|
|
33
|
-
| User names several forms/modules or asks for a system/package | Use the complete-system path; do not compress them into one app |
|
|
34
|
-
| Same or very similar package/app already exists and the user did not say extend/replace/new | Stop and ask whether to extend existing, repair missing parts, or create a new target |
|
|
35
|
-
| Existing readback already contains part of the requested system | List verified existing resources, identify gaps, and patch only missing or incorrect slices |
|
|
36
|
-
| A write is uncertain: timeout, `partial_success`, `write_executed=true`, or `safe_to_retry=false` | Read back before retrying; do not create `V2`, `测试`, timestamp, or random-suffix resources |
|
|
37
|
-
|
|
38
22
|
## Resolve
|
|
39
23
|
|
|
40
|
-
- `package_get`: read one known package by `package_id
|
|
41
|
-
- `package_apply`: create or update one package;
|
|
24
|
+
- `package_get`: read one known package by `package_id`
|
|
25
|
+
- `package_apply`: create or update one package; use `create_if_missing=true` only after explicit user intent
|
|
42
26
|
- `member_search`: resolve named people from the directory
|
|
43
27
|
- `role_search`: resolve reusable roles from the directory
|
|
44
28
|
- `role_create`: create a reusable role when the business owner wants role-based routing
|
|
45
|
-
- `app_resolve`: locate an existing app by exactly one selector mode: `app_key`, or `app_name + package_id
|
|
29
|
+
- `app_resolve`: locate an existing app by exactly one selector mode: `app_key`, or `app_name + package_id`
|
|
46
30
|
|
|
47
31
|
## Summary reads
|
|
48
32
|
|
|
33
|
+
All `app_get_*` tools accept either `app_key` (single) or `app_keys[]` (batch). Batch returns `{status, apps[], errors[]}` — prefer batch when reading multiple apps in one step.
|
|
34
|
+
|
|
49
35
|
- `app_get`: overall app config health, publish state, counts, and builder editability
|
|
50
36
|
- `app_get_fields`: field names, types, required flags, section ids
|
|
51
37
|
- `app_get_layout`: sections, rows, unplaced fields
|
|
52
38
|
- `app_get_views`: current view names, types, columns, group-by
|
|
53
|
-
- `app_get_flow`: workflow enabled state, nodes
|
|
39
|
+
- `app_get_flow`: workflow enabled state, full spec (nodes + transitions)
|
|
54
40
|
- `app_get_charts`: current chart ids, names, types, order
|
|
55
|
-
- `
|
|
41
|
+
- `app_get_associated_resources`: current associated resource pool (draft state)
|
|
42
|
+
- `app_publish_verify`: publish state and package tag verification — accepts `app_keys[]` for multi-app batch
|
|
56
43
|
- `portal_get`: current portal config detail and component inventory
|
|
57
44
|
|
|
58
45
|
## Apply tools
|
|
@@ -60,15 +47,14 @@ Decision gate before writing:
|
|
|
60
47
|
These execute normalized patches. Some app apply tools publish by default and still accept `publish=false`; custom button and associated-resource apply publish after at least one write succeeds and do not expose that switch.
|
|
61
48
|
|
|
62
49
|
- `app_schema_apply`: create app shell or change fields
|
|
63
|
-
- `app_layout_apply`:
|
|
64
|
-
- `app_flow_apply`: replace workflow
|
|
65
|
-
- `app_views_apply`: use
|
|
66
|
-
- `
|
|
67
|
-
- `
|
|
68
|
-
- `
|
|
69
|
-
- `portal_apply`: create or replace-update portal pages; use `dash_key` for update mode or `package_id + dash_name` for create mode; create mode only prechecks package add_app, matching backend portal creation; edit mode may omit `sections` for base-info-only updates; when sections are supplied they still use replace semantics. Build portals only after referenced apps, raw `view_key`s, and chart ids/keys are known. PC layout uses 24 columns: components with the same `y` must have the same `rows`, same-row `cols` should sum to 24, metric cards use `rows=5`, BI charts use `rows=7`, data views use `rows=11`, and business-entry grids must include real `config.items[]`. Use business entry -> metrics -> BI charts -> concrete data views; do not use platform default views or raw `source_type: "filter"` as the main path.
|
|
50
|
+
- `app_layout_apply`: layout-only maintenance for existing apps; new app layout belongs in `app_schema_apply` `form.sections`
|
|
51
|
+
- `app_flow_apply`: replace full workflow spec; use `patch_nodes[]` (`{id, set, unset}`) to update specific nodes without rewriting the full spec
|
|
52
|
+
- `app_views_apply`: use top-level `views[]` for same-app/cross-app batch create, patch, and remove; view business actions belong in each view item's `action_buttons`
|
|
53
|
+
- `app_associated_resources_apply`: attach existing BI reports/views to the Qingflow app associated-resource pool and per-view display area; it does not create or edit QingBI report bodies/configs. Use `patch_resources` for existing associated-resource parameter replacement; use `upsert_resources` for creation or full target config; `view_configs`, remove, and reorder may reference existing resources by internal `associated_item_id` or by `chart_id`/`chart_key`/`view_key`; use `match_mappings` for associated view/report filters; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only to attach an existing BI dataset report. Before `upsert_resources`, read `app_get.associated_resources` and reuse an existing matching `target_app_key + view_key/chart_key`; repeated upsert can create duplicates because `client_key` is only valid inside one apply call. Use `apps[]` for multi-app batch.
|
|
54
|
+
- `app_charts_apply`: create/edit/remove/reorder app-source QingBI report bodies/configs with `dataSourceType=qingflow`; it does not create/edit dataset BI reports and does not attach reports to Qingflow app associated-resource display. Use `patch_charts` for existing-chart parameter replacement; use `upsert_charts` for creation or full target config; supports `target/table` aliases plus QingBI chart types such as `summary`, `columnar`, `area`, `funnel`, `radar`, `scatter`, `dualaxes`, and `map`; charts are immediate-live and do not publish; use `chart_id` when names are not unique; use `apps[]` for multi-app batch
|
|
55
|
+
- `portal_apply`: create or replace-update portal pages; use `dash_key` for update mode or `package_id + dash_name` for create mode; edit mode may omit `sections` for base-info-only updates; when sections are supplied they still use replace semantics; sections use a 24-column PC grid — all components in the same row (same `y`) must share the same `rows` value and their `cols` must sum to exactly 24; mismatched `rows` causes height misalignment, `cols` under 24 leaves trailing blank space; use `patch_sections[]` (`{chart/view_ref/order, set, unset}`) to update individual sections without replacing all
|
|
70
56
|
|
|
71
|
-
For object-level updates, the safe partial syntax is `patch_*` with the object's real selector field plus `set` and optional `unset`. `selector` is only a concept, not a literal key. Examples: `patch_views: [{"view_key": "VIEW_KEY", "set": {...}}]`, `
|
|
57
|
+
For object-level updates, the safe partial syntax is `patch_*` with the object's real selector field plus `set` and optional `unset`. `selector` is only a concept, not a literal key. Examples: `patch_views: [{"view_key": "VIEW_KEY", "set": {...}}]`, `patch_resources: [{"associated_item_id": 123, "set": {...}}]`, `patch_charts: [{"chart_id": 456, "set": {...}}]`, `patch_nodes: [{"id": "approve_1", "set": {...}}]`, `patch_sections: [{"chart": {"chart_key": "ck_001"}, "set": {"title": "新标题"}}]`. The tool reads the current backend config, merges the patch, then submits the full backend payload internally. Do not send a partial `upsert_*` and expect missing required fields to be preserved.
|
|
72
58
|
|
|
73
59
|
## Explicit post-apply tools
|
|
74
60
|
|
|
@@ -79,29 +65,27 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
|
|
|
79
65
|
- Create one app inside an existing package:
|
|
80
66
|
`package_get -> app_resolve -> app_schema_apply`
|
|
81
67
|
- Create a brand new package, then create one app in it:
|
|
82
|
-
`package_apply(
|
|
68
|
+
`package_apply(create_if_missing=true) -> app_schema_apply`
|
|
83
69
|
- Create a brand new multi-app system/package:
|
|
84
|
-
`package_apply(
|
|
70
|
+
`package_apply(create_if_missing=true) -> app_schema_apply(apps[] with form.sections)`
|
|
85
71
|
- Update fields on an existing app:
|
|
86
72
|
`app_resolve -> app_get_fields -> app_schema_apply`
|
|
87
73
|
- Tidy layout:
|
|
88
|
-
`app_get_fields -> app_get_layout ->
|
|
74
|
+
`app_get_fields -> app_get_layout -> app_layout_apply`
|
|
89
75
|
- Add workflow:
|
|
90
76
|
`builder_tool_contract -> app_get_fields -> app_get_flow -> role_search/member_search -> app_flow_apply -> app_get_flow`
|
|
77
|
+
- Update specific flow nodes:
|
|
78
|
+
`app_get_flow -> app_flow_apply.patch_nodes[]`
|
|
91
79
|
- Add views:
|
|
92
|
-
`
|
|
93
|
-
- Add
|
|
94
|
-
`
|
|
95
|
-
- Maintain advanced custom buttons:
|
|
96
|
-
`app_get -> app_custom_buttons_apply.patch_buttons/upsert_buttons + view_configs -> app_get_views`
|
|
97
|
-
- Add QingBI charts:
|
|
98
|
-
`builder_tool_contract -> app_get_fields -> app_get_charts -> app_charts_apply.patch_charts/upsert_charts -> app_get_charts`
|
|
80
|
+
`app_get_fields -> app_get_views -> app_views_apply.views[] -> app_get_views`
|
|
81
|
+
- Add QingBI charts for a portal:
|
|
82
|
+
`portal_apply.sections[].chart`
|
|
99
83
|
- Show an existing QingBI chart inside a Qingflow app/view:
|
|
100
84
|
`app_get -> app_associated_resources_apply.upsert_resources/patch_resources + view_configs -> app_get`
|
|
101
85
|
- Create or update a portal:
|
|
102
86
|
`builder_tool_contract -> portal_get -> portal_apply -> portal_get`
|
|
103
|
-
-
|
|
104
|
-
`portal_get -> portal_apply.patch_sections[]
|
|
87
|
+
- Update portal section(s) without replacing all:
|
|
88
|
+
`portal_get -> portal_apply.patch_sections[]`
|
|
105
89
|
|
|
106
90
|
## Avoid
|
|
107
91
|
|
|
@@ -119,4 +103,3 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
|
|
|
119
103
|
- Do not omit assignees on approval/fill/copy nodes
|
|
120
104
|
- Do not patch preset flows with brand new approval/fill node ids unless you are intentionally replacing the skeleton; reuse preset ids like `approve_1` and `fill_1`
|
|
121
105
|
- Do not guess role ids, member ids, or editable field ids; resolve names first
|
|
122
|
-
- Do not force agent-authored schema into backend-internal names when public keys exist: write icons as `icon + color` first; `icon_config` / `icon:{name,color}` are compatibility aliases only. Options may use `{label,value}`, and same-call relation targets may use `target_app_ref` / `target_app`.
|
|
@@ -6,19 +6,18 @@ Use this when the app already exists and the task is only about workflow.
|
|
|
6
6
|
|
|
7
7
|
1. `builder_tool_contract(tool_name="app_flow_apply")`
|
|
8
8
|
2. `app_get_fields`
|
|
9
|
-
3.
|
|
10
|
-
4. `
|
|
11
|
-
5. `
|
|
12
|
-
6.
|
|
13
|
-
7.
|
|
14
|
-
8.
|
|
15
|
-
9. reuse preset node ids when patching:
|
|
9
|
+
3. `app_get_flow`
|
|
10
|
+
4. `role_search` or `member_search`
|
|
11
|
+
5. `role_create` if the user wants a reusable directory role and no good role exists
|
|
12
|
+
6. start from a canonical preset when possible
|
|
13
|
+
7. patch the skeleton instead of freehanding a full graph
|
|
14
|
+
8. reuse preset node ids when patching:
|
|
16
15
|
- `basic_approval` -> patch `approve_1`
|
|
17
16
|
- `basic_fill_then_approve` -> patch `fill_1` and `approve_1`
|
|
18
17
|
Do not add a second approval/fill node with a new id unless you are intentionally replacing the skeleton.
|
|
19
18
|
The MCP now auto-aligns the simplest single-node preset overrides, but still prefer explicit preset ids so the merged graph stays predictable.
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
9. `app_flow_apply`
|
|
20
|
+
10. `app_get_flow` when apply returns `partial_success` or the user asked for verification
|
|
22
21
|
|
|
23
22
|
If you are unsure about presets or node shapes, call `builder_tool_contract(tool_name="app_flow_apply")` before guessing.
|
|
24
23
|
|
|
@@ -62,6 +61,34 @@ For flexible business requirements, do not jump straight to a full custom graph.
|
|
|
62
61
|
2. identify the business-specific changes
|
|
63
62
|
3. patch nodes/transitions explicitly
|
|
64
63
|
|
|
64
|
+
## Targeted node updates
|
|
65
|
+
|
|
66
|
+
To change one or a few nodes without rewriting the full spec, use `patch_nodes[]` instead of `spec`:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"tool_name": "app_flow_apply",
|
|
71
|
+
"arguments": {
|
|
72
|
+
"profile": "default",
|
|
73
|
+
"app_key": "APP_123",
|
|
74
|
+
"publish": true,
|
|
75
|
+
"patch_nodes": [
|
|
76
|
+
{
|
|
77
|
+
"id": "approve_1",
|
|
78
|
+
"set": {
|
|
79
|
+
"name": "总监审批",
|
|
80
|
+
"assignees": {"role_names": ["总监"]}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`patch_nodes[]` reads the current flow, merges `set` keys and removes `unset` keys on the matched node, then writes the full spec back. It returns `FLOW_NODE_NOT_FOUND` if the `id` does not match any existing node — call `app_get_flow` first to confirm ids.
|
|
89
|
+
|
|
90
|
+
Do NOT use `patch_nodes` and `spec` together in the same call.
|
|
91
|
+
|
|
65
92
|
Public flow building is intentionally limited to linear workflows. Use only:
|
|
66
93
|
|
|
67
94
|
- `start`
|
|
@@ -97,18 +124,7 @@ Preferred fix order:
|
|
|
97
124
|
|
|
98
125
|
### `FLOW_DEPENDENCY_MISSING`
|
|
99
126
|
|
|
100
|
-
The workflow depends on fields that do not exist yet, usually
|
|
101
|
-
|
|
102
|
-
Do:
|
|
103
|
-
|
|
104
|
-
- add a business field such as `状态`, `处理状态`, `审批状态`, `工单状态`, or `流程阶段`
|
|
105
|
-
- use type `select` / `single_select`
|
|
106
|
-
- use business options such as `草稿`, `进行中`, `已完成`
|
|
107
|
-
|
|
108
|
-
Do not:
|
|
109
|
-
|
|
110
|
-
- create platform workflow system fields such as `当前流程状态`, `当前处理人`, `当前处理节点`, or `流程标题`
|
|
111
|
-
- skip the flow and still report workflow completion
|
|
127
|
+
The workflow depends on fields that do not exist yet, usually `status`. Fix schema first.
|
|
112
128
|
|
|
113
129
|
Preferred recovery:
|
|
114
130
|
|
|
@@ -161,7 +177,7 @@ Do not copy internal keys from old plan outputs or logs, including:
|
|
|
161
177
|
|
|
162
178
|
## Notes
|
|
163
179
|
|
|
164
|
-
- `mode=replace` is the only supported flow apply mode
|
|
180
|
+
- `mode=replace` is the only supported flow apply mode when using `spec`; `patch_nodes[]` does not require a `mode`
|
|
165
181
|
- `app_flow_apply` publishes by default
|
|
166
182
|
- Prefer roles over explicit members unless the user explicitly asks for named members
|
|
167
183
|
- `basic_approval` and `basic_fill_then_approve` are skeletons, not complete business workflows
|
|
@@ -10,18 +10,6 @@ Use this when the app already exists and the task is only about fields.
|
|
|
10
10
|
|
|
11
11
|
## Example
|
|
12
12
|
|
|
13
|
-
Do not add platform system fields as form controls: `数据ID`, `编号`, `申请人`, `申请时间`, `创建人`, `创建时间`, `提交人`, `提交时间`, `更新时间`, `更新人`, `当前流程状态`, `当前处理人`, `当前处理节点`, `流程标题`. They are generated by Qingflow; use readback/list fields when you need them.
|
|
14
|
-
|
|
15
|
-
Field patch rules:
|
|
16
|
-
|
|
17
|
-
- Re-read fields first, then choose `add_fields`, `update_fields`, or `remove_fields`. If a field already exists, use `update_fields` instead of adding a duplicate.
|
|
18
|
-
- Drafts may use intuitive type aliases: `multiline -> long_text`, `select -> single_select`, `checkbox -> multi_select`, `currency -> amount`, `mobile -> phone`. Readback canonical types are normal and do not prove a failed update.
|
|
19
|
-
- `title` and `label` are accepted aliases for `name`, but the preferred public key is `name`.
|
|
20
|
-
- Keep exactly one top-level data title field after the patch. `as_data_cover` is optional and only valid on top-level `attachment`.
|
|
21
|
-
- Select fields must keep a clear `options` set. Sample data and filters should use those option labels or ids.
|
|
22
|
-
- Relation fields must use `target_app_key` for existing apps, or `target_app_ref` only in same-batch app creation. `display_field` and `visible_fields` are selector objects such as `{"name": "客户名称"}`, not bare strings.
|
|
23
|
-
- Do not impose a one-relation-field limit when updating schema; add the relation fields the business needs and rely on backend validation/readback.
|
|
24
|
-
|
|
25
13
|
Read current fields first:
|
|
26
14
|
|
|
27
15
|
```json
|
|
@@ -76,11 +64,9 @@ Treat it as uncertain write state. Read back with `app_get_fields` before retryi
|
|
|
76
64
|
|
|
77
65
|
- `title` and `label` are accepted aliases for `name`
|
|
78
66
|
- `textarea -> long_text`
|
|
79
|
-
- `multiline` / `multiline_text -> long_text`
|
|
80
67
|
- `currency -> amount`
|
|
81
68
|
- `mobile -> phone`
|
|
82
69
|
- `select/radio -> single_select`
|
|
83
70
|
- `checkbox -> multi_select`
|
|
84
71
|
- `as_data_title: true` marks the app data title; the final form must have exactly one top-level data title field
|
|
85
72
|
- `as_data_cover: true` marks the app data cover; the cover is optional and must be a top-level `attachment` field
|
|
86
|
-
- `数据ID`, `编号`, applicant/creation/update time, and workflow status fields are system-generated and must not appear in `add_fields`
|
|
@@ -28,25 +28,17 @@ Canonical rules before any example:
|
|
|
28
28
|
- Always use `columns`
|
|
29
29
|
- Do not emit `column_names`
|
|
30
30
|
- Treat `fields` only as a legacy alias the MCP may normalize, not as the preferred shape
|
|
31
|
-
- Use `filters` with
|
|
31
|
+
- Use `filters` with canonical keys `field_name`, `operator`, `value`/`values`
|
|
32
32
|
- Use `query_conditions` for the frontend query panel. Do not put query-panel fields into `filters`.
|
|
33
|
-
-
|
|
34
|
-
- To change a built-in default/system view, first read the existing raw `view_key` from `app_get.views` or `app_get_views`, then use `patch_views` or a full `upsert_views` item with that `view_key`.
|
|
33
|
+
- When creating any new table or card view, always include `query_conditions` with `enabled: true`. In `rows`, list the fields users would most commonly search by — typically the data-title field, any status/type select fields, date fields, and member fields. Do not omit `query_conditions` or leave `rows` empty on a new view.
|
|
35
34
|
- New views created by `app_views_apply` default the frontend associated report/view area to visible with `limit_type="all"`. Existing views preserve their current associated-resource display unless `associated_resources` is explicitly patched.
|
|
36
|
-
- Use `app_associated_resources_apply` for the associated report/view resource pool, selected resources, and match rules.
|
|
35
|
+
- Use `app_associated_resources_apply` for the associated report/view resource pool, selected resources, and match rules. `associated_item_id` is the internal associated-resource id from `app_get.associated_resources`; `view_configs`, remove, and reorder may also pass an existing resource's `chart_id`/`chart_key`/`view_key`, which the tool resolves to the internal id. Do not write backend raw `sourceType`; reports default to BI app reports, and dataset reports use `report_source="dataset"`. Use `match_mappings` for associated view/report filters; read `match-rules.md` if field type compatibility is unclear.
|
|
37
36
|
- For gantt, use `start_field`, `end_field`, and optionally `title_field`
|
|
38
37
|
- If `app_get.views` or `app_get_views` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
|
|
39
38
|
- Builder view writes always use the raw `view_key` from `app_get.views[].view_key`, such as `emsrao25rs02`. Do not pass `custom:emsrao25rs02`; that prefixed form is only for record-data `view_id`.
|
|
40
39
|
- For an existing view, prefer `patch_views` for parameter replacement. Do not send a partial `upsert_views` object such as only `name/type/query_conditions`; backend view saves require other type-specific fields, and the patch path preserves them for you.
|
|
41
|
-
- For ordinary view-specific business buttons, declare `action_buttons` inside `upsert_views[]` or `patch_views[].set`. Use `app_custom_buttons_apply` only for style/icon changes, cross-view reuse, deleting button bodies, bulk binding reorder, or exact qRobot/wings configs.
|
|
42
|
-
- Choose the button by user intent before choosing a trigger type:
|
|
43
|
-
- current record -> downstream/related record: `add_data` with `target_app_key + field_mappings`
|
|
44
|
-
- global independent entry: `add_data` on `header` without current-record `source_field`
|
|
45
|
-
- URL/SOP/help page: `link` with `url`
|
|
46
|
-
- approval/status transition/close task: do not fake it with a normal button; use workflow/task action or exact existing automation config
|
|
47
|
-
- Button placement choice: `header` is global and has no current-row context; `list` is row/list action; `detail` is the safest current-record context action. Do not use current-record `field_mappings` on `header`.
|
|
48
40
|
|
|
49
|
-
Apply a
|
|
41
|
+
Apply a default table view:
|
|
50
42
|
|
|
51
43
|
```json
|
|
52
44
|
{
|
|
@@ -57,10 +49,16 @@ Apply a business table view:
|
|
|
57
49
|
"publish": true,
|
|
58
50
|
"upsert_views": [
|
|
59
51
|
{
|
|
60
|
-
"name": "
|
|
52
|
+
"name": "全部订单",
|
|
61
53
|
"view_key": "VIEW_KEY_IF_DUPLICATE_NAMES_EXIST",
|
|
62
54
|
"type": "table",
|
|
63
|
-
"columns": ["订单编号", "客户名称", "订单金额", "状态"]
|
|
55
|
+
"columns": ["订单编号", "客户名称", "订单金额", "状态", "负责人", "创建时间"],
|
|
56
|
+
"query_conditions": {
|
|
57
|
+
"enabled": true,
|
|
58
|
+
"exact": false,
|
|
59
|
+
"hide_before_query": false,
|
|
60
|
+
"rows": [["订单编号", "客户名称"], ["状态", "负责人"], ["创建时间"]]
|
|
61
|
+
}
|
|
64
62
|
}
|
|
65
63
|
],
|
|
66
64
|
"remove_views": []
|
|
@@ -69,48 +67,6 @@ Apply a business table view:
|
|
|
69
67
|
```
|
|
70
68
|
After `app_views_apply` returns canonical arguments or blocking issues, prefer reusing its `suggested_next_call.arguments` directly. Do not rewrite aliases back into non-canonical keys such as `column_names`.
|
|
71
69
|
|
|
72
|
-
Create a table view with ordinary business buttons:
|
|
73
|
-
|
|
74
|
-
```json
|
|
75
|
-
{
|
|
76
|
-
"tool_name": "app_views_apply",
|
|
77
|
-
"arguments": {
|
|
78
|
-
"profile": "default",
|
|
79
|
-
"app_key": "APP_123",
|
|
80
|
-
"publish": true,
|
|
81
|
-
"upsert_views": [
|
|
82
|
-
{
|
|
83
|
-
"name": "工单执行视图",
|
|
84
|
-
"type": "table",
|
|
85
|
-
"columns": ["工单编号", "产品", "状态", "负责人"],
|
|
86
|
-
"action_buttons": [
|
|
87
|
-
{
|
|
88
|
-
"text": "创建质检单",
|
|
89
|
-
"action": "add_data",
|
|
90
|
-
"target_app_key": "QUALITY_APP",
|
|
91
|
-
"field_mappings": [
|
|
92
|
-
{"source_field": "数据ID", "target_field": "关联工单"}
|
|
93
|
-
],
|
|
94
|
-
"default_values": {"处理状态": "待处理"},
|
|
95
|
-
"placement": "detail",
|
|
96
|
-
"visible_when": [
|
|
97
|
-
{"field_name": "状态", "operator": "eq", "value": "已完工"}
|
|
98
|
-
]
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
"text": "查看作业说明",
|
|
102
|
-
"action": "link",
|
|
103
|
-
"url": "https://example.com/sop",
|
|
104
|
-
"placement": "header"
|
|
105
|
-
}
|
|
106
|
-
]
|
|
107
|
-
}
|
|
108
|
-
],
|
|
109
|
-
"remove_views": []
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
70
|
Existing table view: replace only frontend query conditions:
|
|
115
71
|
|
|
116
72
|
```json
|
|
@@ -321,32 +277,7 @@ At least one `query_conditions.rows` field does not exist on the app.
|
|
|
321
277
|
|
|
322
278
|
### `INVALID_QUERY_CONDITION_FIELD`
|
|
323
279
|
|
|
324
|
-
The field exists but cannot be used in the frontend query-condition panel.
|
|
325
|
-
|
|
326
|
-
Supported `query_conditions.rows` fields are query-panel fields:
|
|
327
|
-
|
|
328
|
-
- text / long text
|
|
329
|
-
- number / amount
|
|
330
|
-
- date / datetime
|
|
331
|
-
- single select / multi select
|
|
332
|
-
- member / department
|
|
333
|
-
- phone / email
|
|
334
|
-
- boolean
|
|
335
|
-
|
|
336
|
-
Do not use these fields in `query_conditions`:
|
|
337
|
-
|
|
338
|
-
- relation
|
|
339
|
-
- attachment
|
|
340
|
-
- subtable or subtable subfield
|
|
341
|
-
- address/location
|
|
342
|
-
- Q-Linker
|
|
343
|
-
- code block
|
|
344
|
-
|
|
345
|
-
Fix path:
|
|
346
|
-
|
|
347
|
-
- If you wanted a saved filter that opens with the view, use `filters`.
|
|
348
|
-
- If you wanted a related report/view to match the current record, use `app_associated_resources_apply.match_mappings`.
|
|
349
|
-
- If you only need frontend search fields, remove unsupported fields from `query_conditions.rows` and keep query-panel supported fields only.
|
|
280
|
+
The field exists but cannot be used in the frontend query-condition panel, such as attachment, relation, Q-Linker, code block, location/address, or subtable/subfield selections.
|
|
350
281
|
|
|
351
282
|
## Notes
|
|
352
283
|
|
|
@@ -355,6 +286,6 @@ Fix path:
|
|
|
355
286
|
- `app_get_views` should be treated as canonical readback and now returns `columns`
|
|
356
287
|
- If `app_views_apply` returns `AMBIGUOUS_VIEW`, stop and re-run `app_get_views`; then retry with the exact `view_key`
|
|
357
288
|
- `filters` are ANDed together as one flat condition group
|
|
358
|
-
- `query_conditions.rows` does not mean OR; it controls frontend query-field layout
|
|
289
|
+
- `query_conditions.rows` does not mean OR; it controls frontend query-field layout
|
|
359
290
|
- `app_views_apply` publishes by default
|
|
360
291
|
- For select-style filters, success means the backend preserved the option value in readback, not just that the view name now exists
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qingflow-app-builder-code-integrations
|
|
3
|
-
description: Configure Qingflow code block and Q-Linker fields through the builder surface when the task involves input field insertion, alias parsing, target field binding, or troubleshooting broken code/q-linker form configurations.
|
|
3
|
+
description: Configure Qingflow code block and Q-Linker fields through the builder surface when the task involves input field insertion, alias parsing, target field binding, or troubleshooting broken code/q-linker form configurations. Use after MCP is connected and authenticated, especially for CRM-style scoring, lookup, and enrichment forms.
|
|
4
4
|
metadata:
|
|
5
5
|
short-description: Configure Qingflow code blocks and Q-Linkers safely
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Qingflow App Builder Code Integrations
|
|
9
9
|
|
|
10
|
-
> **Skill 版本**:`qingflow-skills-2026.06.24.2`(入口文档版本;如需确认 CLI 包版本,使用 `qingflow --version` 或 `qingflow --json version`)。
|
|
11
|
-
|
|
12
10
|
Use this skill when the user wants to build or repair:
|
|
13
11
|
- `code_block` fields
|
|
14
12
|
- `q_linker` fields
|
|
@@ -60,7 +58,7 @@ For code block or Q-Linker work, use this order:
|
|
|
60
58
|
|
|
61
59
|
1. Resolve the app and read fields:
|
|
62
60
|
- `app_resolve`
|
|
63
|
-
- `
|
|
61
|
+
- `app_read_fields`
|
|
64
62
|
2. Confirm the target field set already exists.
|
|
65
63
|
3. Apply schema updates with `app_schema_apply`.
|
|
66
64
|
4. Read fields again and verify:
|
|
@@ -117,7 +115,7 @@ Hard rules:
|
|
|
117
115
|
|
|
118
116
|
After each code block or Q-Linker change, verify all of these:
|
|
119
117
|
|
|
120
|
-
- `
|
|
118
|
+
- `app_read_fields` shows the intended field type
|
|
121
119
|
- the high-level config is readable and stable
|
|
122
120
|
- target fields still have valid types
|
|
123
121
|
- insert schema can be opened
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qingflow-mcp-setup
|
|
3
|
+
description: Install, connect, authenticate, and troubleshoot the Qingflow MCP server in local AI clients such as Claude Desktop or any stdio-compatible MCP client. Use when the user wants to configure the MCP, verify local startup, log in with token/password, select a workspace, or fix connection/authentication issues.
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: Install and connect the Qingflow MCP locally
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Qingflow MCP Setup
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
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.
|
|
13
|
+
|
|
14
|
+
## Workflow
|
|
15
|
+
|
|
16
|
+
Follow these steps in order.
|
|
17
|
+
|
|
18
|
+
`feedback_submit` is also available as a cross-cutting helper when setup or MCP capability gaps still block the user after reasonable troubleshooting. It does not require Qingflow login or workspace selection, and should be called only after explicit user confirmation.
|
|
19
|
+
|
|
20
|
+
Before configuration or live calls, identify the target environment explicitly as `test` or `prod`, then read [references/environments.md](references/environments.md). If the user did not specify one, default to `prod`.
|
|
21
|
+
|
|
22
|
+
### Step 1: Verify the local project path
|
|
23
|
+
|
|
24
|
+
Resolve the repository root first. In this repo, the MCP server should live at:
|
|
25
|
+
|
|
26
|
+
- `<repo_root>/qingflow-support/mcp-server`
|
|
27
|
+
|
|
28
|
+
Key entrypoint:
|
|
29
|
+
|
|
30
|
+
- `<repo_root>/qingflow-support/mcp-server/qingflow-mcp`
|
|
31
|
+
|
|
32
|
+
If the path differs, stop and update all client config snippets before proceeding.
|
|
33
|
+
If the skill is installed under `$CODEX_HOME/skills` instead of the repo-local `.codex/skills`, set `QINGFLOW_MCP_ROOT=<repo_root>/qingflow-support/mcp-server` before running `scripts/check_local_server.sh`.
|
|
34
|
+
|
|
35
|
+
### Step 2: Install local dependencies
|
|
36
|
+
|
|
37
|
+
Run:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd <repo_root>/qingflow-support/mcp-server
|
|
41
|
+
python3 -m venv .venv
|
|
42
|
+
./.venv/bin/pip install -e '.[dev]'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Use `scripts/check_local_server.sh` to verify the entrypoint and virtualenv. The script will first try `QINGFLOW_MCP_ROOT`, then the current git repo, then a repo-local `.codex/skills` layout.
|
|
46
|
+
|
|
47
|
+
### Step 3: Configure the local AI client
|
|
48
|
+
|
|
49
|
+
For any stdio-compatible MCP client, map these values:
|
|
50
|
+
|
|
51
|
+
- `command`: `<repo_root>/qingflow-support/mcp-server/qingflow-mcp`
|
|
52
|
+
- `args`: `[]`
|
|
53
|
+
- `env.QINGFLOW_MCP_DEFAULT_BASE_URL`: the target backend URL for the active environment
|
|
54
|
+
- `env.QINGFLOW_MCP_DEFAULT_QF_VERSION`: set this when the environment must route to a specific version such as `canary`
|
|
55
|
+
|
|
56
|
+
Client-specific snippets:
|
|
57
|
+
|
|
58
|
+
- Claude Desktop: read [references/claude-desktop.md](references/claude-desktop.md)
|
|
59
|
+
- Generic stdio MCP clients: read [references/generic-stdio.md](references/generic-stdio.md)
|
|
60
|
+
|
|
61
|
+
When both test and production are in play, keep separate config snippets or clearly labeled `env` blocks so the user can switch without ambiguity.
|
|
62
|
+
|
|
63
|
+
### Step 4: Validate startup
|
|
64
|
+
|
|
65
|
+
The server is a stdio MCP process. A direct terminal launch may print nothing and wait for a client. That is normal.
|
|
66
|
+
|
|
67
|
+
Manual startup command:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cd <repo_root>/qingflow-support/mcp-server
|
|
71
|
+
./qingflow-mcp
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Prefer validating through the client after config is added.
|
|
75
|
+
|
|
76
|
+
### Step 5: Authenticate and select workspace
|
|
77
|
+
|
|
78
|
+
Recommended order inside the client:
|
|
79
|
+
|
|
80
|
+
1. `auth_use_token` or `auth_login`
|
|
81
|
+
2. `workspace_list`
|
|
82
|
+
3. `workspace_select`
|
|
83
|
+
4. Only then use business tools
|
|
84
|
+
|
|
85
|
+
If the user already knows the target workspace, prefer `auth_use_token(..., ws_id=<id>)`.
|
|
86
|
+
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
|
+
`auth_use_token` is a tool call, not a custom HTTP header. The runtime injects `token`, `wsId`, and when needed `Cookie: qfVersion=...` after the session is established.
|
|
88
|
+
Do not skip `workspace_select` on production paths. If `/user` does not return a version lane, the session now falls back to the workspace `systemVersion`.
|
|
89
|
+
|
|
90
|
+
### Step 6: Troubleshoot in the right layer
|
|
91
|
+
|
|
92
|
+
- If the client cannot launch the server, check path, execute permission, and `.venv`
|
|
93
|
+
- If tools return `auth required`, re-run `auth_use_token` or `auth_login`
|
|
94
|
+
- If tools return `workspace not selected`, call `workspace_list` and `workspace_select`
|
|
95
|
+
- If calls fail after a working session, assume token expiry and re-authenticate
|
|
96
|
+
- If the browser shows data but MCP does not, compare `request_route` against the browser environment and check whether `qf_version` should be `canary`
|
|
97
|
+
|
|
98
|
+
## Guardrails
|
|
99
|
+
|
|
100
|
+
- Never write tokens into the skill files
|
|
101
|
+
- Never assume a workspace is selected until `auth_whoami` or `workspace_select` confirms it
|
|
102
|
+
- When debugging, distinguish server startup issues from Qingflow auth issues
|
|
103
|
+
- When the user mentions production, restate the exact `base_url`, `qf_version`, and workspace before any live validation
|
|
104
|
+
- 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
|
|
105
|
+
|
|
106
|
+
## Resources
|
|
107
|
+
|
|
108
|
+
- Environment switching: [references/environments.md](references/environments.md)
|
|
109
|
+
- Claude Desktop config: [references/claude-desktop.md](references/claude-desktop.md)
|
|
110
|
+
- Generic stdio config: [references/generic-stdio.md](references/generic-stdio.md)
|
|
111
|
+
- Local checks: [scripts/check_local_server.sh](scripts/check_local_server.sh)
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Qingflow MCP Setup"
|
|
3
|
+
short_description: "Install and connect the Qingflow MCP locally"
|
|
4
|
+
default_prompt: "Use $qingflow-mcp-setup to install and connect the Qingflow MCP in a local AI client, and to verify the active base_url, qf_version, auth state, and workspace selection."
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Claude Desktop
|
|
2
|
+
|
|
3
|
+
Use this when the user wants to install Qingflow MCP in Claude Desktop.
|
|
4
|
+
|
|
5
|
+
## Config snippet
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"mcpServers": {
|
|
10
|
+
"qingflow": {
|
|
11
|
+
"command": "<ABSOLUTE_PATH_TO_REPO>/qingflow-support/mcp-server/qingflow-mcp",
|
|
12
|
+
"args": [],
|
|
13
|
+
"env": {
|
|
14
|
+
"QINGFLOW_MCP_DEFAULT_BASE_URL": "<QINGFLOW_BASE_URL>"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Environment examples
|
|
22
|
+
|
|
23
|
+
- `prod` (default): set `QINGFLOW_MCP_DEFAULT_BASE_URL` to `https://qingflow.com/api`
|
|
24
|
+
- `test`: if needed, set `QINGFLOW_MCP_DEFAULT_BASE_URL` to the explicitly provided non-production backend
|
|
25
|
+
|
|
26
|
+
Keep separate snippets for `test` and `prod` so switching environments does not require editing values in-place under pressure.
|
|
27
|
+
|
|
28
|
+
## Notes
|
|
29
|
+
|
|
30
|
+
- After updating the config, restart Claude Desktop
|
|
31
|
+
- Replace `<ABSOLUTE_PATH_TO_REPO>` with the real checkout path on the current machine
|
|
32
|
+
- If the server path changes, update the `command` field
|
|
33
|
+
- The server is local stdio MCP, so no remote URL is required
|
|
34
|
+
- Do not store Qingflow token in Claude Desktop config; pass it through `auth_use_token` inside the chat
|