@josephyan/qingflow-app-builder-mcp 0.2.0-beta.39 → 0.2.0-beta.40
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 +2 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +17 -8
- package/skills/qingflow-app-builder/references/tool-selection.md +6 -4
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/builder_facade/models.py +19 -0
- package/src/qingflow_mcp/builder_facade/service.py +544 -49
- package/src/qingflow_mcp/server_app_builder.py +16 -4
- package/src/qingflow_mcp/tools/ai_builder_tools.py +151 -14
- package/src/qingflow_mcp/tools/record_tools.py +249 -3
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.
|
|
6
|
+
npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.40
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.
|
|
12
|
+
npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.40 qingflow-app-builder-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -48,8 +48,8 @@ Default modeling rules:
|
|
|
48
48
|
|
|
49
49
|
- Authentication and workspace: `auth_*`, `workspace_*`
|
|
50
50
|
- File upload: `file_upload_local`
|
|
51
|
-
- Resource resolve/read: `package_list`, `package_resolve`, `package_create`, `builder_tool_contract`, `member_search`, `role_search`, `app_resolve`, `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`
|
|
52
|
-
- Resource patch: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `
|
|
51
|
+
- Resource resolve/read: `package_list`, `package_resolve`, `package_create`, `builder_tool_contract`, `member_search`, `role_search`, `app_resolve`, `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`, `app_read_charts_summary`, `portal_read_summary`
|
|
52
|
+
- Resource patch: `app_schema_apply`, `app_layout_apply`, `app_flow_apply`, `app_views_apply`, `app_charts_apply`, `portal_apply`, `package_attach_app`, `app_release_edit_lock_if_mine`, `role_create`
|
|
53
53
|
- Publish and verify: `app_publish_verify`
|
|
54
54
|
|
|
55
55
|
Note:
|
|
@@ -57,8 +57,10 @@ Note:
|
|
|
57
57
|
- Do not rely on low-level `view_*`, `workflow_*`, `qingbi_report_*`, or `portal_*` write payloads from public builder flows.
|
|
58
58
|
- Public builder work should stay on the resource path: `resolve -> summary read -> apply -> attach -> publish_verify`.
|
|
59
59
|
- `app_schema_apply` / `app_layout_apply` / `app_flow_apply` / `app_views_apply` publish by default; pass `publish=false` only when you intentionally want to leave changes in draft.
|
|
60
|
-
- `
|
|
61
|
-
- `portal_apply` uses replace semantics for sections; remove a section by omitting it from the next full sections list.
|
|
60
|
+
- `app_charts_apply` is immediate-live and does not publish; it resolves targets by `chart_id` first and then exact unique chart name.
|
|
61
|
+
- `portal_apply` uses replace semantics for sections; remove a section by omitting it from the next full sections list. `publish=false` only guarantees draft/base-info updates, and `chart_ref/view_ref` resolve by `id/key` first and exact unique name second.
|
|
62
|
+
- `app_read_charts_summary` is the compact discovery path for current chart inventory; use it before `app_charts_apply` when you need exact `chart_id` values.
|
|
63
|
+
- `portal_read_summary` is the compact discovery path for portal draft/live summaries; it returns section summaries, not the raw dash payload.
|
|
62
64
|
- `app_schema_apply` / `app_layout_apply` / `app_flow_apply` / `app_views_apply` now perform planning, normalization, and dependency checks internally; when prechecks block, read the returned blocking issues and `suggested_next_call` directly from the apply result.
|
|
63
65
|
- If you are unsure about a public builder tool's keys, aliases, presets, or minimal legal shape, call `builder_tool_contract` instead of guessing.
|
|
64
66
|
- For views, always write the canonical key `columns`. Do not emit `column_names`; treat `fields` only as a tolerated legacy alias, not the preferred shape.
|
|
@@ -94,7 +96,7 @@ For builder work:
|
|
|
94
96
|
- one app: continue with `app_resolve`
|
|
95
97
|
- multi-app package/system: create or resolve the package, then create each app separately before adding relations
|
|
96
98
|
3. Resolve the target app with `app_resolve` if the request is an update.
|
|
97
|
-
4. Read only the smallest summary you need: `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`.
|
|
99
|
+
4. Read only the smallest summary you need: `app_read_summary`, `app_read_fields`, `app_read_layout_summary`, `app_read_views_summary`, `app_read_flow_summary`, `app_read_charts_summary`, `portal_read_summary`.
|
|
98
100
|
5. Use `app_schema_apply` for create/upsert/remove field work. It publishes by default after the patch lands; noop schema requests do not publish.
|
|
99
101
|
6. If the app must belong to a package, use `package_attach_app` explicitly after schema work unless readback already shows the target `tag_id`.
|
|
100
102
|
7. Use `app_layout_apply` only when the user is explicitly changing layout. Prefer the default `mode=merge`; use `mode=replace` only when you intend to place every field explicitly. It publishes by default after the patch lands; noop layout requests do not publish.
|
|
@@ -130,8 +132,10 @@ For flow work, keep the order strict:
|
|
|
130
132
|
10. When a node must edit specific fields, declare `permissions.editable_fields`
|
|
131
133
|
11. `app_flow_apply`
|
|
132
134
|
12. `app_read_flow_summary` after apply whenever the user asked for verification or apply returns `partial_success`
|
|
133
|
-
13. Use `
|
|
134
|
-
14. Use `
|
|
135
|
+
13. Use `app_read_charts_summary` before chart work whenever exact current `chart_id` values matter
|
|
136
|
+
14. Use `app_charts_apply` for QingBI chart creation and updates, not raw `qingbi_report_*` writes
|
|
137
|
+
15. Use `portal_read_summary` before portal work whenever exact current draft/live section inventory matters
|
|
138
|
+
16. Use `portal_apply` for builder-side portal work; treat sections as a full replacement list
|
|
135
139
|
|
|
136
140
|
For additive work on existing systems:
|
|
137
141
|
|
|
@@ -174,6 +178,9 @@ For additive work on existing systems:
|
|
|
174
178
|
|
|
175
179
|
- low-level list totals from the backend may report `0` while rows are present; prefer summary or aggregate readbacks for final conclusions
|
|
176
180
|
- `app_publish_verify` is the publish source of truth.
|
|
181
|
+
- All public builder tools expose top-level `warnings`, `verification`, and `verified`. Read them before deciding whether a run is fully done.
|
|
182
|
+
- For read tools, `status=success` can still pair with `verified=false` when some optional readback is unavailable; in that case prefer `warnings` and `verification` over the bare status code.
|
|
183
|
+
- For `app_charts_apply`, `portal_apply`, and `app_publish_verify`, treat `success` as “write and verification completed” and `partial_success` as “write executed but verification is incomplete”.
|
|
177
184
|
- If readback mismatches the UI, compare `request_route` and do not assume the builder hit the same `qf_version` as the browser
|
|
178
185
|
- Treat post-write readback as the source of truth, not just write status codes
|
|
179
186
|
- For views, a top-level `VIEW_APPLY_FAILED` does not prove all requested views failed. Read back the view list and verify which views actually landed.
|
|
@@ -200,6 +207,8 @@ For additive work on existing systems:
|
|
|
200
207
|
- Read layout summary: `app_read_layout_summary`
|
|
201
208
|
- Read views summary: `app_read_views_summary`
|
|
202
209
|
- Read flow summary: `app_read_flow_summary`
|
|
210
|
+
- Read chart summary: `app_read_charts_summary`
|
|
211
|
+
- Read portal summary: `portal_read_summary`
|
|
203
212
|
- Search members for workflow assignees: `member_search`
|
|
204
213
|
- Search roles for workflow assignees: `role_search`
|
|
205
214
|
- Create reusable workflow role: `role_create`
|
|
@@ -207,7 +216,7 @@ For additive work on existing systems:
|
|
|
207
216
|
- Merge or replace layout: `app_layout_apply`
|
|
208
217
|
- Replace workflow: `app_flow_apply`
|
|
209
218
|
- Upsert/remove views: `app_views_apply`
|
|
210
|
-
- Upsert/remove/reorder QingBI charts: `
|
|
219
|
+
- Upsert/remove/reorder QingBI charts: `app_charts_apply`
|
|
211
220
|
- Create or replace-update portal pages: `portal_apply`
|
|
212
221
|
- Attach one app to a package: `package_attach_app`
|
|
213
222
|
- Release your own stale edit lock: `app_release_edit_lock_if_mine`
|
|
@@ -36,6 +36,8 @@ If the user asks for multiple forms/modules that relate to each other, this is a
|
|
|
36
36
|
- `app_read_layout_summary`: sections, rows, unplaced fields
|
|
37
37
|
- `app_read_views_summary`: current view names, types, columns, group-by
|
|
38
38
|
- `app_read_flow_summary`: workflow enabled state, nodes, transitions
|
|
39
|
+
- `app_read_charts_summary`: current chart ids, names, types, order
|
|
40
|
+
- `portal_read_summary`: current draft/live portal metadata and compact section inventory
|
|
39
41
|
|
|
40
42
|
## Apply tools
|
|
41
43
|
|
|
@@ -45,8 +47,8 @@ These execute normalized patches and publish by default unless `publish=false`.
|
|
|
45
47
|
- `app_layout_apply`: merge or replace layout
|
|
46
48
|
- `app_flow_apply`: replace workflow
|
|
47
49
|
- `app_views_apply`: upsert or remove views
|
|
48
|
-
- `
|
|
49
|
-
- `portal_apply`: create or replace-update portal pages; sections are replace-only and omission deletes old sections
|
|
50
|
+
- `app_charts_apply`: upsert/remove/reorder QingBI charts; charts are immediate-live and do not publish; use `chart_id` when names are not unique
|
|
51
|
+
- `portal_apply`: create or replace-update portal pages; sections are replace-only and omission deletes old sections; `publish=false` only guarantees draft/base-info updates
|
|
50
52
|
|
|
51
53
|
## Explicit post-apply tools
|
|
52
54
|
|
|
@@ -70,9 +72,9 @@ These execute normalized patches and publish by default unless `publish=false`.
|
|
|
70
72
|
- Add views:
|
|
71
73
|
`builder_tool_contract -> app_read_fields -> app_read_views_summary -> app_views_apply -> app_read_views_summary`
|
|
72
74
|
- Add QingBI charts:
|
|
73
|
-
`builder_tool_contract -> app_read_fields ->
|
|
75
|
+
`builder_tool_contract -> app_read_fields -> app_read_charts_summary -> app_charts_apply -> app_read_charts_summary`
|
|
74
76
|
- Create or update a portal:
|
|
75
|
-
`builder_tool_contract -> portal_apply`
|
|
77
|
+
`builder_tool_contract -> portal_read_summary -> portal_apply -> portal_read_summary`
|
|
76
78
|
|
|
77
79
|
## Avoid
|
|
78
80
|
|
|
@@ -794,6 +794,25 @@ class AppFlowReadResponse(StrictModel):
|
|
|
794
794
|
transitions: list[dict[str, Any]] = Field(default_factory=list)
|
|
795
795
|
|
|
796
796
|
|
|
797
|
+
class AppChartsReadResponse(StrictModel):
|
|
798
|
+
app_key: str
|
|
799
|
+
charts: list[dict[str, Any]] = Field(default_factory=list)
|
|
800
|
+
chart_count: int = 0
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
class PortalReadSummaryResponse(StrictModel):
|
|
804
|
+
dash_key: str
|
|
805
|
+
being_draft: bool = True
|
|
806
|
+
dash_name: str | None = None
|
|
807
|
+
package_tag_ids: list[int] = Field(default_factory=list)
|
|
808
|
+
dash_icon: str | None = None
|
|
809
|
+
hide_copyright: bool | None = None
|
|
810
|
+
config_keys: list[str] = Field(default_factory=list)
|
|
811
|
+
dash_global_config_keys: list[str] = Field(default_factory=list)
|
|
812
|
+
section_count: int = 0
|
|
813
|
+
sections: list[dict[str, Any]] = Field(default_factory=list)
|
|
814
|
+
|
|
815
|
+
|
|
797
816
|
class SchemaPlanRequest(StrictModel):
|
|
798
817
|
app_key: str = ""
|
|
799
818
|
package_tag_id: int | None = None
|