@qingflow-tech/qingflow-app-builder-mcp 1.0.11 → 1.0.13
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 -3
- package/docs/local-agent-install.md +54 -3
- package/entry_point.py +1 -1
- package/npm/bin/qingflow-skills.mjs +5 -0
- package/npm/lib/runtime.mjs +304 -13
- package/npm/scripts/postinstall.mjs +1 -5
- package/package.json +3 -2
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-builder/SKILL.md +12 -12
- package/skills/qingflow-app-builder/references/create-app.md +3 -3
- package/skills/qingflow-app-builder/references/environments.md +1 -1
- package/skills/qingflow-app-builder/references/gotchas.md +1 -1
- package/skills/qingflow-app-builder/references/public-surface-sync.md +75 -0
- package/skills/qingflow-app-builder/references/tool-selection.md +6 -5
- package/skills/qingflow-app-builder/references/update-views.md +1 -1
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +3 -3
- 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/src/qingflow_mcp/__main__.py +6 -2
- package/src/qingflow_mcp/builder_facade/models.py +11 -0
- package/src/qingflow_mcp/builder_facade/service.py +1488 -288
- package/src/qingflow_mcp/cli/commands/builder.py +2 -2
- package/src/qingflow_mcp/cli/commands/exports.py +2 -2
- package/src/qingflow_mcp/cli/commands/imports.py +1 -1
- package/src/qingflow_mcp/cli/commands/record.py +91 -19
- package/src/qingflow_mcp/cli/context.py +0 -3
- package/src/qingflow_mcp/cli/formatters.py +206 -7
- package/src/qingflow_mcp/cli/main.py +47 -3
- package/src/qingflow_mcp/errors.py +43 -2
- package/src/qingflow_mcp/public_surface.py +21 -15
- package/src/qingflow_mcp/response_trim.py +74 -13
- package/src/qingflow_mcp/server.py +11 -9
- package/src/qingflow_mcp/server_app_builder.py +3 -2
- package/src/qingflow_mcp/server_app_user.py +19 -13
- package/src/qingflow_mcp/session_store.py +11 -7
- package/src/qingflow_mcp/solution/executor.py +112 -15
- package/src/qingflow_mcp/tools/ai_builder_tools.py +36 -11
- package/src/qingflow_mcp/tools/app_tools.py +184 -43
- package/src/qingflow_mcp/tools/approval_tools.py +196 -34
- 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/file_tools.py +7 -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 +1067 -349
- 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 +569 -119
- 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
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Qingflow Core Public Surface Sync
|
|
2
|
+
|
|
3
|
+
Use this file as the maintenance baseline for the core Qingflow skills.
|
|
4
|
+
It is not a user-facing product spec. It exists to prevent skill drift.
|
|
5
|
+
|
|
6
|
+
## Current Public Defaults
|
|
7
|
+
|
|
8
|
+
### User data
|
|
9
|
+
|
|
10
|
+
- Read range first with `app_get`, then `record_browse_schema_get(view_id=...)`
|
|
11
|
+
- Treat `record_browse_schema_get.fields` as the selected Qingflow table view header schema; `record_access.fields` and `record_list` field selectors must stay aligned with it.
|
|
12
|
+
- Standard flows:
|
|
13
|
+
- analyze: `app_get -> record_browse_schema_get -> record_access -> Python`
|
|
14
|
+
- browse detail: `app_get -> record_browse_schema_get -> record_list / record_get`
|
|
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
|
+
- insert: `record_insert_schema_get -> record_insert(items)`
|
|
17
|
+
- update: `record_get -> record_update`; use `record_update_schema_get` only for failure diagnosis or ambiguous writable-field routing
|
|
18
|
+
|
|
19
|
+
### Tasks
|
|
20
|
+
|
|
21
|
+
- Discovery stays on `task_list`
|
|
22
|
+
- `task_list --query` uses backend search first and only applies local fallback when backend returns zero rows
|
|
23
|
+
- Public actions are:
|
|
24
|
+
- `approve`
|
|
25
|
+
- `reject`
|
|
26
|
+
- `rollback`
|
|
27
|
+
- `transfer`
|
|
28
|
+
- `urge`
|
|
29
|
+
- `save_only`
|
|
30
|
+
- `reject` requires `payload.audit_feedback`
|
|
31
|
+
- `save_only` requires non-empty `fields`
|
|
32
|
+
- `TASK_RUNTIME_CONSUMED_AFTER_ACTION` is a normal post-success warning when the current node runtime is consumed and `46001` appears on re-read
|
|
33
|
+
|
|
34
|
+
### Builder
|
|
35
|
+
|
|
36
|
+
- Official package entry: `package_get`, `package_apply`
|
|
37
|
+
- Official builder writes:
|
|
38
|
+
- `app_schema_apply`
|
|
39
|
+
- `app_layout_apply`
|
|
40
|
+
- `app_flow_apply`
|
|
41
|
+
- `app_views_apply`
|
|
42
|
+
- `app_custom_buttons_apply`
|
|
43
|
+
- `app_associated_resources_apply`
|
|
44
|
+
- `app_charts_apply`
|
|
45
|
+
- `portal_apply`
|
|
46
|
+
- `app_publish_verify`
|
|
47
|
+
- `portal_apply` edit mode may omit `sections` for base-info-only updates
|
|
48
|
+
- `app_charts_apply.visibility` is a public capability and should be treated as a base-only visibility update
|
|
49
|
+
- Existing object parameter replacement should use `patch_views`, `patch_buttons`, `patch_resources`, and `patch_charts`; `upsert_*` is for creation or full target config
|
|
50
|
+
- `app_get.editability` uses:
|
|
51
|
+
- `can_edit_app_base`
|
|
52
|
+
- `can_edit_form`
|
|
53
|
+
- `can_edit_flow`
|
|
54
|
+
- `can_edit_views`
|
|
55
|
+
- `can_edit_charts`
|
|
56
|
+
|
|
57
|
+
## Known High-Drift Areas
|
|
58
|
+
|
|
59
|
+
- Task actions, especially `save_only`, reject payload requirements, and `46001` post-action interpretation
|
|
60
|
+
- Package public tools: do not regress to `package_create` / `package_attach_app` as the public default story
|
|
61
|
+
- App editability: do not let `can_edit_form` imply app base-info writes
|
|
62
|
+
- Portal and chart visibility: keep the public story on `portal_apply` / `app_charts_apply`, not low-level internal writes
|
|
63
|
+
- Analysis path: standard path stays `record_access -> Python`
|
|
64
|
+
|
|
65
|
+
## Release Checklist For Skill Maintenance
|
|
66
|
+
|
|
67
|
+
After each beta that changes public behavior, re-check:
|
|
68
|
+
|
|
69
|
+
1. `public_surface.py`
|
|
70
|
+
2. `README.md`
|
|
71
|
+
3. `server_app_builder.py` and `server.py` top-level guidance
|
|
72
|
+
4. CLI help for `task`, `builder package`, `builder portal`, `builder charts`
|
|
73
|
+
5. Whether new warnings or verification fields need to be explained in skills
|
|
74
|
+
|
|
75
|
+
If a tool behavior changed but the public surface did not, prefer updating the relevant skill section instead of expanding this file.
|
|
@@ -21,12 +21,12 @@ If the user asks for multiple forms/modules that relate to each other, this is a
|
|
|
21
21
|
|
|
22
22
|
## Resolve
|
|
23
23
|
|
|
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
|
|
24
|
+
- `package_get`: read one known package by `package_id`; it reads package `baseInfo` first and may warn `PACKAGE_DETAIL_READ_DEGRADED` when the richer detail endpoint needs package edit/add-app permission. Treat that warning as degraded detail, not as package-read failure.
|
|
25
|
+
- `package_apply`: create or update one package; use `create_if_missing=true` only after explicit user intent; layout/group/order changes require package edit permission because they call the backend package ordering route
|
|
26
26
|
- `member_search`: resolve named people from the directory
|
|
27
27
|
- `role_search`: resolve reusable roles from the directory
|
|
28
28
|
- `role_create`: create a reusable role when the business owner wants role-based routing
|
|
29
|
-
- `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`; by-name resolution checks package detail/current visible apps before using broader admin-style app search, so a `/app/item` permission miss is not a frontend-visible-app failure
|
|
30
30
|
|
|
31
31
|
## Summary reads
|
|
32
32
|
|
|
@@ -36,6 +36,7 @@ If the user asks for multiple forms/modules that relate to each other, this is a
|
|
|
36
36
|
- `app_get_views`: current view names, types, columns, group-by
|
|
37
37
|
- `app_get_flow`: workflow enabled state, nodes, transitions
|
|
38
38
|
- `app_get_charts`: current chart ids, names, types, order
|
|
39
|
+
- `chart_get`: one chart's base/config detail; base info is read through the Qingflow/qflow visible route first, and config may degrade from chart data when the CHART_SEE config endpoint is unavailable. Treat degraded config as a read-mode warning, not as proof the user cannot see the chart.
|
|
39
40
|
- `portal_get`: current portal config detail and component inventory
|
|
40
41
|
|
|
41
42
|
## Apply tools
|
|
@@ -47,9 +48,9 @@ These execute normalized patches. Some app apply tools publish by default and st
|
|
|
47
48
|
- `app_flow_apply`: replace workflow
|
|
48
49
|
- `app_views_apply`: use `patch_views` for existing-view parameter replacement; use `upsert_views` for creation or full target config; remove views by key; new views default associated report/view display to visible with `limit_type="all"`
|
|
49
50
|
- `app_custom_buttons_apply`: use `patch_buttons` for existing-button parameter replacement; use `upsert_buttons` for creation or full target config; configure add-data field mappings/default values; bind buttons to header/detail/list view positions; `placement=list` maps to the backend `INSIDE` row/list button position; merge-mode view configs require `buttons`; use `view_configs[].mode="replace"` or `buttons=[]` to clear a view's custom button bindings. For child-record creation linked to the current source record, map `source_field: "数据ID"` to the target relation field.
|
|
50
|
-
- `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.
|
|
51
|
+
- `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. Permission is split like the backend: resource pool writes use EditAppAuth, while `view_configs` uses the view config/DataManageAuth path. 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.
|
|
51
52
|
- `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
|
|
52
|
-
- `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
|
|
53
|
+
- `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
|
|
53
54
|
|
|
54
55
|
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_buttons: [{"button_id": 1001, "set": {...}}]`, `patch_resources: [{"associated_item_id": 123, "set": {...}}]`, `patch_charts: [{"chart_id": 456, "set": {...}}]`. 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.
|
|
55
56
|
|
|
@@ -31,7 +31,7 @@ Canonical rules before any example:
|
|
|
31
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
33
|
- 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.
|
|
34
|
-
- 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.
|
|
34
|
+
- Use `app_associated_resources_apply` for the associated report/view resource pool, selected resources, and match rules. Permission is split like the backend: resource pool writes use EditAppAuth, while `view_configs` uses the view config/DataManageAuth path. `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.
|
|
35
35
|
- For gantt, use `start_field`, `end_field`, and optionally `title_field`
|
|
36
36
|
- If `app_get.views` or `app_get_views` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
|
|
37
37
|
- 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`.
|
|
@@ -1,6 +1,6 @@
|
|
|
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. In Wingent Momo runtime, use the injected MCP session and recover auth/workspace only after a tool error.
|
|
4
4
|
metadata:
|
|
5
5
|
short-description: Configure Qingflow code blocks and Q-Linkers safely
|
|
6
6
|
---
|
|
@@ -58,7 +58,7 @@ For code block or Q-Linker work, use this order:
|
|
|
58
58
|
|
|
59
59
|
1. Resolve the app and read fields:
|
|
60
60
|
- `app_resolve`
|
|
61
|
-
- `
|
|
61
|
+
- `app_get_fields`
|
|
62
62
|
2. Confirm the target field set already exists.
|
|
63
63
|
3. Apply schema updates with `app_schema_apply`.
|
|
64
64
|
4. Read fields again and verify:
|
|
@@ -115,7 +115,7 @@ Hard rules:
|
|
|
115
115
|
|
|
116
116
|
After each code block or Q-Linker change, verify all of these:
|
|
117
117
|
|
|
118
|
-
- `
|
|
118
|
+
- `app_get_fields` shows the intended field type
|
|
119
119
|
- the high-level config is readable and stable
|
|
120
120
|
- target fields still have valid types
|
|
121
121
|
- insert schema can be opened
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
"""Entry point for running qingflow_mcp as a module.
|
|
2
|
-
|
|
1
|
+
"""Entry point for running qingflow_mcp as a module.
|
|
2
|
+
|
|
3
|
+
Default to the curated user-facing MCP surface. Split package and console
|
|
4
|
+
entrypoints can still start the builder server explicitly.
|
|
5
|
+
"""
|
|
6
|
+
from qingflow_mcp.server_app_user import main
|
|
3
7
|
|
|
4
8
|
if __name__ == "__main__":
|
|
5
9
|
main()
|
|
@@ -1610,6 +1610,7 @@ class AssociatedResourcesApplyRequest(StrictModel):
|
|
|
1610
1610
|
if not isinstance(value, dict):
|
|
1611
1611
|
return value
|
|
1612
1612
|
payload = dict(value)
|
|
1613
|
+
default_target_app_key = str(payload.get("app_key", payload.get("appKey", "")) or "").strip()
|
|
1613
1614
|
if "upsertResources" in payload and "upsert_resources" not in payload:
|
|
1614
1615
|
payload["upsert_resources"] = payload.pop("upsertResources")
|
|
1615
1616
|
if "patchResources" in payload and "patch_resources" not in payload:
|
|
@@ -1622,6 +1623,16 @@ class AssociatedResourcesApplyRequest(StrictModel):
|
|
|
1622
1623
|
payload["reorder_associated_item_ids"] = payload.pop("reorderAssociatedItemIds")
|
|
1623
1624
|
if "viewConfigs" in payload and "view_configs" not in payload:
|
|
1624
1625
|
payload["view_configs"] = payload.pop("viewConfigs")
|
|
1626
|
+
if default_target_app_key and isinstance(payload.get("upsert_resources"), list):
|
|
1627
|
+
normalized_resources = []
|
|
1628
|
+
for item in payload["upsert_resources"]:
|
|
1629
|
+
if isinstance(item, dict) and not any(
|
|
1630
|
+
str(item.get(key) or "").strip()
|
|
1631
|
+
for key in ("target_app_key", "targetAppKey", "app_key", "appKey")
|
|
1632
|
+
):
|
|
1633
|
+
item = {**item, "target_app_key": default_target_app_key}
|
|
1634
|
+
normalized_resources.append(item)
|
|
1635
|
+
payload["upsert_resources"] = normalized_resources
|
|
1625
1636
|
return payload
|
|
1626
1637
|
|
|
1627
1638
|
@model_validator(mode="after")
|