@qingflow-tech/qingflow-app-builder-mcp 1.0.8 → 1.0.10

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 CHANGED
@@ -3,13 +3,13 @@
3
3
  Install:
4
4
 
5
5
  ```bash
6
- npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.8
6
+ npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.10
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.8 qingflow-app-builder-mcp
12
+ npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.10 qingflow-app-builder-mcp
13
13
  ```
14
14
 
15
15
  Environment:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qingflow-tech/qingflow-app-builder-mcp",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Builder MCP for Qingflow app/package/system design and staged solution workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "1.0.8"
7
+ version = "1.0.10"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -49,6 +49,9 @@ Treat these as the official surface. Do not default to `package_create`, `packag
49
49
  - Package work:
50
50
  - use `package_get(package_id=...)` to read one known package
51
51
  - use `package_apply(...)` for package creation, rename, icon, visibility, grouping, ordering, and app/portal layout
52
+ - Multi-app schema work:
53
+ - use one `app_schema_apply(apps=[...])` / CLI `builder schema apply --apps-file` when creating several apps in one package
54
+ - same-call relation fields may use `target_app_ref` to point at another `apps[].client_key`
52
55
  - App base permissions:
53
56
  - trust `app_get.editability.can_edit_app_base` for app base-info writes like app name, icon, and visibility
54
57
  - `can_edit_form` only means schema/form-route capability; it no longer implies app base-info write capability
@@ -61,7 +64,10 @@ Treat these as the official surface. Do not default to `package_create`, `packag
61
64
  - in edit mode, omitting `sections` means “preserve existing layout and update base info only”
62
65
  - supplying `sections` means full replace semantics for sections
63
66
  - Chart work:
64
- - `app_charts_apply` is the public write path
67
+ - `app_charts_apply` is the public write path for app-source QingBI report bodies/configs; it creates/updates reports with `dataSourceType=qingflow`
68
+ - dataset BI reports are not created or edited by `app_charts_apply` yet; create them in QingBI first, then attach the existing report with `app_associated_resources_apply` and `report_source="dataset"`
69
+ - it does not attach the report to the Qingflow app associated-resource display; use `app_associated_resources_apply` for that
70
+ - supported `chart_type` values include legacy public aliases `target`, `table` and QingBI types such as `summary`, `columnar`, `area`, `stacked_area`, `funnel`, `waterfall`, `gauge`, `heatmap`, `histogram`, `treemap`, `radar`, `stacked_bar`, `stacked_column`, `scatter`, `ring`, `rose`, `dualaxes`, `map`, and `timeline`
65
71
  - use `patch_charts` for changing a chart name, visibility, filters, or one config fragment on an existing chart
66
72
  - `visibility` is a public capability and should be treated as a base-only permission update
67
73
  - do not model chart visibility changes as raw config rewrites
@@ -79,12 +85,13 @@ Treat these as the official surface. Do not default to `package_create`, `packag
79
85
  - `placement=list` configures row/list buttons and maps to the backend `INSIDE` button position
80
86
  - advanced bindings may use `button_limit`, `button_formula`, `button_formula_type`, and `print_tpls` only when visibility or print-template behavior is required
81
87
  - Associated resources:
82
- - `app_associated_resources_apply` is the public write path for the app-level associated report/view pool and per-view display config
88
+ - `app_associated_resources_apply` is the public write path for the Qingflow app-level associated report/view pool and per-view display config
89
+ - it attaches existing BI reports/views for in-app display; it does not create or edit QingBI report bodies/configs, including dataset reports
83
90
  - use `patch_resources` for changing match rules or other existing associated-resource parameters; the tool preserves backend-required raw fields internally
84
- - `associated_item_id` must come from `app_get.associated_resources[].associated_item_id`; it is not `chart_id`, `chart_key`, or `view_key`
91
+ - `associated_item_id` is the backend internal associated-resource id; for `view_configs`, `remove_associated_item_ids`, and `reorder_associated_item_ids`, you may pass `associated_item_id` or an existing resource's `chart_id`/`chart_key`/`view_key`, and the tool resolves it to the internal id
85
92
  - before creating a resource, check `app_get.associated_resources` for the same `target_app_key + view_key/chart_key`; if it already exists, use `patch_resources` with that `associated_item_id`
86
93
  - `client_key` is only a same-call reference for `view_configs[].associated_item_refs`; it is not saved and cannot deduplicate later calls
87
- - do not pass backend raw `sourceType`; view resources infer the internal Qingflow view source, report/chart resources default to BI app reports, and dataset reports use `report_source="dataset"`
94
+ - do not pass backend raw `sourceType`; view resources infer the internal Qingflow view source, report/chart resources default to BI app reports, and existing dataset reports use `report_source="dataset"`
88
95
  - use `match_mappings` for associated view/report filters; dynamic conditions use `source_field`, static conditions use `value`
89
96
  - if field type compatibility is unclear, read [references/match-rules.md](references/match-rules.md)
90
97
  - Views and flows:
@@ -93,6 +100,7 @@ Treat these as the official surface. Do not default to `package_create`, `packag
93
100
  - builder view writes use raw `view_key` values from `app_get.views`; `custom:<viewKey>` is a record-data `view_id` form, not a builder `view_key`
94
101
  - use `builder_tool_contract` whenever the minimal legal shape is unclear
95
102
  - keep view `filters` and `query_conditions` separate: `filters` are fixed saved filters; `query_conditions` configure the frontend query panel fields and only take effect after users enter query values
103
+ - new views default the associated report/view display area to visible with `limit_type="all"`; existing views preserve their current associated-resource display unless `associated_resources` is explicitly patched
96
104
  - configure associated reports/views through `app_associated_resources_apply`, not through `app_views_apply`
97
105
 
98
106
  ## Standard Operating Order
@@ -141,6 +149,10 @@ Treat these as the official surface. Do not default to `package_create`, `packag
141
149
 
142
150
  ## Response Interpretation
143
151
 
152
+ - All builder apply/write tools return a standard UI envelope in addition to legacy fields:
153
+ `schema_version`, `operation`, `summary`, and `resources[]`.
154
+ - For UI cards or quick narration, read `resources[]` first. Each resource has `resource_type`, `operation`, `status`, `id`, `key`, `name`, typed `ids`, and `parent`.
155
+ - Use legacy fields such as `field_diff`, `views_diff`, `chart_results`, `created/updated/removed`, and `verification` only for compatibility and troubleshooting.
144
156
  - Treat post-write readback as the source of truth, not just write status codes.
145
157
  - `success` means write and verification completed; `partial_success` means the write landed but verification is incomplete.
146
158
  - For portals, distinguish clearly between:
@@ -37,8 +37,8 @@ then do not treat that as one app.
37
37
  Use this pattern instead:
38
38
 
39
39
  1. `package_get` or `package_apply(create_if_missing=true, package_name=...)`
40
- 2. for each app name, run `app_schema_apply`
41
- 3. once the apps exist, add `relation` fields between them
40
+ 2. for a multi-app system, run one `app_schema_apply` with `apps[]`
41
+ 3. use `apps[].client_key` plus relation field `target_app_ref` when one new app references another new app
42
42
 
43
43
  ## Example
44
44
 
@@ -91,6 +91,43 @@ Apply schema for a new app:
91
91
  }
92
92
  ```
93
93
 
94
+ Apply schema for multiple apps in one call:
95
+
96
+ ```json
97
+ {
98
+ "tool_name": "app_schema_apply",
99
+ "arguments": {
100
+ "profile": "default",
101
+ "package_id": 1218950,
102
+ "create_if_missing": true,
103
+ "publish": true,
104
+ "apps": [
105
+ {
106
+ "client_key": "customer",
107
+ "app_name": "客户",
108
+ "add_fields": [
109
+ {"name": "客户名称", "type": "text", "required": true, "as_data_title": true}
110
+ ]
111
+ },
112
+ {
113
+ "client_key": "order",
114
+ "app_name": "订单",
115
+ "add_fields": [
116
+ {"name": "订单编号", "type": "text", "required": true, "as_data_title": true},
117
+ {
118
+ "name": "关联客户",
119
+ "type": "relation",
120
+ "target_app_ref": "customer",
121
+ "display_field": {"name": "客户名称"},
122
+ "visible_fields": [{"name": "客户名称"}]
123
+ }
124
+ ]
125
+ }
126
+ ]
127
+ }
128
+ }
129
+ ```
130
+
94
131
  Data title is required: mark exactly one top-level field with `as_data_title: true`. Data cover is optional and only valid on a top-level `attachment` field.
95
132
 
96
133
  ## Common failures
@@ -25,6 +25,14 @@
25
25
  - `app_custom_buttons_apply` and `app_associated_resources_apply` publish after at least one write succeeds and do not accept `publish=false`
26
26
  - `app_publish_verify` is for explicit final verification, not the default next step after every write
27
27
 
28
+ ## BI Reports
29
+
30
+ - Use `app_charts_apply` for QingBI report body/config creation or updates.
31
+ - Use `app_associated_resources_apply` only when an existing BI report or view needs to appear in the Qingflow app associated-resource area or a specific view.
32
+ - `app_charts_apply` currently creates/updates app-source BI reports only (`dataSourceType=qingflow`); dataset BI reports can only be attached when they already exist.
33
+ - Creating a chart with `app_charts_apply` does not automatically show it in the Qingflow app UI; attach it separately if display is required.
34
+ - `target` and `table` remain compatibility aliases for QingBI `indicator` and `detail`; use the real QingBI chart type when you need a specific type such as `summary`, `columnar`, `stacked_bar`, `scatter`, or `dualaxes`.
35
+
28
36
  ## Custom buttons
29
37
 
30
38
  - Use `app_custom_buttons_apply` for button creation/update/removal and view placement; do not split placement into `app_views_apply.buttons` unless you are maintaining a legacy patch.
@@ -45,6 +53,7 @@
45
53
 
46
54
  - Before creating an associated view/report, check `app_get.associated_resources` for the same `target_app_key + view_key/chart_key`.
47
55
  - If the resource already exists, use `patch_resources` with its `associated_item_id`; do not call `upsert_resources` again.
56
+ - For per-view display, remove, and reorder, existing associated reports/views may be referenced by `associated_item_id`, `chart_id`/`chart_key`, or `view_key`; the tool resolves these to the internal id before writing.
48
57
  - `client_key` is only a same-call alias for `view_configs[].associated_item_refs`. It is not stored by Qingflow and cannot prevent duplicates in later calls.
49
58
  - Repeated `upsert_resources` without `associated_item_id` can create multiple app-level associated items pointing to the same view/report.
50
59
 
@@ -45,10 +45,10 @@ These execute normalized patches. Some app apply tools publish by default and st
45
45
  - `app_schema_apply`: create app shell or change fields
46
46
  - `app_layout_apply`: merge or replace layout
47
47
  - `app_flow_apply`: replace workflow
48
- - `app_views_apply`: use `patch_views` for existing-view parameter replacement; use `upsert_views` for creation or full target config; remove views by key
48
+ - `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
49
  - `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`: use `patch_resources` for existing associated-resource parameter replacement; use `upsert_resources` for creation or full target config; use `match_mappings` for associated view/report filters; manage per-view display config; publishes after successful writes; omit raw `sourceType`, and use `report_source="dataset"` only for BI dataset reports. 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_charts_apply`: use `patch_charts` for existing-chart parameter replacement; use `upsert_charts` for creation or full target config; remove/reorder QingBI charts; charts are immediate-live and do not publish; use `chart_id` when names are not unique
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_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
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
53
 
54
54
  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.
@@ -64,7 +64,7 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
64
64
  - Create a brand new package, then create one app in it:
65
65
  `package_apply(create_if_missing=true) -> app_schema_apply`
66
66
  - Create a brand new multi-app system/package:
67
- `package_apply(create_if_missing=true) -> per-app app_schema_apply -> relation field patches`
67
+ `package_apply(create_if_missing=true) -> app_schema_apply(apps[])`
68
68
  - Update fields on an existing app:
69
69
  `app_resolve -> app_get_fields -> app_schema_apply`
70
70
  - Tidy layout:
@@ -75,6 +75,8 @@ For object-level updates, the safe partial syntax is `patch_*` with the object's
75
75
  `builder_tool_contract -> app_get_fields -> app_get_views -> app_views_apply.patch_views/upsert_views -> app_get_views`
76
76
  - Add QingBI charts:
77
77
  `builder_tool_contract -> app_get_fields -> app_get_charts -> app_charts_apply.patch_charts/upsert_charts -> app_get_charts`
78
+ - Show an existing QingBI chart inside a Qingflow app/view:
79
+ `app_get -> app_associated_resources_apply.upsert_resources/patch_resources + view_configs -> app_get`
78
80
  - Create or update a portal:
79
81
  `builder_tool_contract -> portal_get -> portal_apply -> portal_get`
80
82
 
@@ -30,7 +30,8 @@ Canonical rules before any example:
30
30
  - Treat `fields` only as a legacy alias the MCP may normalize, not as the preferred shape
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
- - Use `app_associated_resources_apply` for the frontend associated report/view area. `associated_item_id` must be copied from `app_get.associated_resources[].associated_item_id`; it is not `chart_id` or `chart_key`. 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.
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
35
  - For gantt, use `start_field`, `end_field`, and optionally `title_field`
35
36
  - If `app_get.views` or `app_get_views` shows duplicate view names, include `view_key` in `upsert_views[]` and update that exact target
36
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`.
@@ -116,7 +117,7 @@ View associated resources example:
116
117
  }
117
118
  ```
118
119
 
119
- Use `{"visible": true, "limit_type": "all"}` to show all app-level associated resources, and `{"visible": false}` to hide the area. The ids above must come from `app_get.associated_resources`. Before creating a resource, check whether the same `target_app_key + view_key/chart_key` already exists; if it does, use `patch_resources` with that `associated_item_id`. If you create a new associated item in the same call, give it a `client_key` and reference it from `view_configs[].associated_item_refs`; `client_key` is not persisted and cannot deduplicate a later call.
120
+ Use `{"visible": true, "limit_type": "all"}` to show all app-level associated resources, and `{"visible": false}` to hide the area. The ids above can be internal `associated_item_id` values or existing resource `chart_id`/`chart_key`/`view_key` values from `app_get.associated_resources`. Before creating a resource, check whether the same `target_app_key + view_key/chart_key` already exists; if it does, use `patch_resources` with that `associated_item_id`. Dataset BI reports must already exist in QingBI and should be attached with `report_source="dataset"`; do not try to create them through `app_charts_apply`. If you create a new associated item in the same call, give it a `client_key` and reference it from `view_configs[].associated_item_refs`; `client_key` is not persisted and cannot deduplicate a later call.
120
121
 
121
122
  Create and show a BI indicator-card report in the same call:
122
123
 
@@ -142,10 +142,34 @@ class PublicButtonPlacement(str, Enum):
142
142
 
143
143
  class PublicChartType(str, Enum):
144
144
  target = "target"
145
+ indicator = "indicator"
146
+ summary = "summary"
145
147
  pie = "pie"
146
148
  bar = "bar"
149
+ columnar = "columnar"
147
150
  line = "line"
148
151
  table = "table"
152
+ detail = "detail"
153
+ area = "area"
154
+ stacked_area = "stacked_area"
155
+ pct_stack_area = "pct_stack_area"
156
+ funnel = "funnel"
157
+ waterfall = "waterfall"
158
+ gauge = "gauge"
159
+ heatmap = "heatmap"
160
+ histogram = "histogram"
161
+ treemap = "treemap"
162
+ radar = "radar"
163
+ stacked_bar = "stacked_bar"
164
+ pct_stack_bar = "pct_stack_bar"
165
+ stacked_column = "stacked_column"
166
+ pct_stack_col = "pct_stack_col"
167
+ scatter = "scatter"
168
+ ring = "ring"
169
+ rose = "rose"
170
+ dualaxes = "dualaxes"
171
+ map = "map"
172
+ timeline = "timeline"
149
173
 
150
174
 
151
175
  class LayoutApplyMode(str, Enum):
@@ -1576,8 +1600,8 @@ class AssociatedResourcesApplyRequest(StrictModel):
1576
1600
  app_key: str
1577
1601
  upsert_resources: list[AssociatedResourceUpsertPatch] = Field(default_factory=list)
1578
1602
  patch_resources: list[AssociatedResourcePartialPatch] = Field(default_factory=list)
1579
- remove_associated_item_ids: list[int] = Field(default_factory=list)
1580
- reorder_associated_item_ids: list[int] = Field(default_factory=list)
1603
+ remove_associated_item_ids: list[Any] = Field(default_factory=list)
1604
+ reorder_associated_item_ids: list[Any] = Field(default_factory=list)
1581
1605
  view_configs: list[AssociatedResourceViewConfigPatch] = Field(default_factory=list)
1582
1606
 
1583
1607
  @model_validator(mode="before")
@@ -1775,10 +1799,18 @@ class ChartUpsertPatch(StrictModel):
1775
1799
  normalized = raw_type.strip().lower()
1776
1800
  aliases = {
1777
1801
  "targetchart": PublicChartType.target.value,
1802
+ "indicatorchart": PublicChartType.indicator.value,
1803
+ "summarychart": PublicChartType.summary.value,
1778
1804
  "piechart": PublicChartType.pie.value,
1779
1805
  "barchart": PublicChartType.bar.value,
1806
+ "columnchart": PublicChartType.columnar.value,
1807
+ "columnarchart": PublicChartType.columnar.value,
1780
1808
  "linechart": PublicChartType.line.value,
1781
1809
  "tablechart": PublicChartType.table.value,
1810
+ "detailchart": PublicChartType.detail.value,
1811
+ "percent_stacked_column": PublicChartType.pct_stack_col.value,
1812
+ "percent_stacked_bar": PublicChartType.pct_stack_bar.value,
1813
+ "percent_stacked_area": PublicChartType.pct_stack_area.value,
1782
1814
  }
1783
1815
  if normalized in aliases:
1784
1816
  payload["chart_type"] = aliases[normalized]
@@ -2002,6 +2034,8 @@ FieldUpdatePatch.model_rebuild()
2002
2034
 
2003
2035
  class AppGetResponse(StrictModel):
2004
2036
  app_key: str
2037
+ app_name: str | None = None
2038
+ name: str | None = None
2005
2039
  title: str | None = None
2006
2040
  app_icon: str | None = None
2007
2041
  visibility: dict[str, Any] = Field(default_factory=dict)