@josephyan/qingflow-app-user-mcp 1.0.9 → 1.1.2
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 -2
- package/npm/bin/qingflow-app-user-mcp.mjs +33 -2
- package/npm/lib/runtime.mjs +386 -15
- package/npm/scripts/postinstall.mjs +7 -2
- package/package.json +1 -1
- package/pyproject.toml +2 -1
- package/skills/qingflow-app-builder/SKILL.md +276 -0
- package/skills/qingflow-app-builder/agents/openai.yaml +4 -0
- package/skills/qingflow-app-builder/references/build-complete-system.md +428 -0
- package/skills/qingflow-app-builder/references/build-single-app.md +530 -0
- package/skills/qingflow-app-builder/references/create-app.md +149 -0
- package/skills/qingflow-app-builder/references/environments.md +63 -0
- package/skills/qingflow-app-builder/references/flow-actors-and-permissions.md +123 -0
- package/skills/qingflow-app-builder/references/gotchas.md +108 -0
- package/skills/qingflow-app-builder/references/match-rules.md +114 -0
- package/skills/qingflow-app-builder/references/public-surface-sync.md +75 -0
- package/skills/qingflow-app-builder/references/solution-playbooks.md +52 -0
- package/skills/qingflow-app-builder/references/tool-selection.md +107 -0
- package/skills/qingflow-app-builder/references/update-flow.md +186 -0
- package/skills/qingflow-app-builder/references/update-layout.md +68 -0
- package/skills/qingflow-app-builder/references/update-schema.md +72 -0
- package/skills/qingflow-app-builder/references/update-views.md +291 -0
- package/skills/qingflow-app-builder-code-integrations/SKILL.md +137 -0
- package/skills/qingflow-app-builder-code-integrations/agents/openai.yaml +4 -0
- package/skills/qingflow-app-builder-code-integrations/references/code-block.md +66 -0
- package/skills/qingflow-app-builder-code-integrations/references/q-linker.md +77 -0
- package/skills/qingflow-app-user/SKILL.md +2 -1
- package/skills/qingflow-app-user/references/data-gotchas.md +5 -3
- package/skills/qingflow-app-user/references/public-surface-sync.md +6 -3
- package/skills/qingflow-app-user/references/record-patterns.md +14 -4
- 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-record-analysis/SKILL.md +94 -186
- package/skills/qingflow-record-analysis/agents/openai.yaml +2 -2
- package/skills/qingflow-record-analysis/references/analysis-gotchas.md +54 -113
- package/skills/qingflow-record-analysis/references/analysis-patterns.md +95 -134
- package/skills/qingflow-record-analysis/references/business-context.md +74 -0
- package/skills/qingflow-record-analysis/references/confidence-reporting.md +47 -74
- package/skills/qingflow-record-analysis/references/data-access-playbook.md +106 -0
- package/skills/qingflow-record-analysis/references/pandas-recipes.md +172 -0
- package/skills/qingflow-record-analysis/references/report-format.md +76 -0
- package/skills/qingflow-record-insert/SKILL.md +28 -7
- package/skills/qingflow-record-update/SKILL.md +3 -1
- 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/backend_client.py +55 -1
- package/src/qingflow_mcp/builder_facade/models.py +532 -48
- package/src/qingflow_mcp/builder_facade/service.py +9194 -2384
- package/src/qingflow_mcp/builder_facade/workflow_spec.py +111 -0
- package/src/qingflow_mcp/cli/commands/app.py +3 -16
- package/src/qingflow_mcp/cli/commands/builder.py +354 -56
- package/src/qingflow_mcp/cli/commands/record.py +112 -6
- package/src/qingflow_mcp/cli/formatters.py +102 -2
- package/src/qingflow_mcp/cli/main.py +245 -3
- package/src/qingflow_mcp/public_surface.py +12 -9
- package/src/qingflow_mcp/response_trim.py +287 -22
- package/src/qingflow_mcp/server.py +29 -20
- package/src/qingflow_mcp/server_app_builder.py +108 -30
- package/src/qingflow_mcp/server_app_user.py +28 -23
- package/src/qingflow_mcp/solution/compiler/__init__.py +1 -3
- package/src/qingflow_mcp/solution/compiler/icon_utils.py +294 -0
- package/src/qingflow_mcp/solution/executor.py +3 -133
- package/src/qingflow_mcp/tools/ai_builder_tools.py +2617 -440
- package/src/qingflow_mcp/tools/app_tools.py +53 -8
- package/src/qingflow_mcp/tools/package_tools.py +16 -2
- package/src/qingflow_mcp/tools/record_tools.py +14283 -9162
- package/src/qingflow_mcp/tools/resource_read_tools.py +3 -0
- package/src/qingflow_mcp/tools/solution_tools.py +30 -2
- package/src/qingflow_mcp/tools/workflow_tools.py +3 -31
- package/src/qingflow_mcp/version.py +110 -0
- package/skills/qingflow-record-analysis/references/dsl-templates.md +0 -93
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +0 -173
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
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. Use after MCP is connected and authenticated, especially for CRM-style scoring, lookup, and enrichment forms.
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: Configure Qingflow code blocks and Q-Linkers safely
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Qingflow App Builder Code Integrations
|
|
9
|
+
|
|
10
|
+
Use this skill when the user wants to build or repair:
|
|
11
|
+
- `code_block` fields
|
|
12
|
+
- `q_linker` fields
|
|
13
|
+
- output alias parsing
|
|
14
|
+
- target field binding
|
|
15
|
+
- form configurations that depend on code block or Q-Linker relations
|
|
16
|
+
|
|
17
|
+
Do not use this skill for MCP setup, generic field CRUD, or runtime execution debugging unless those are strictly supporting code block or Q-Linker configuration work.
|
|
18
|
+
|
|
19
|
+
## Core Rule
|
|
20
|
+
|
|
21
|
+
Treat code blocks and Q-Linkers as **integration fields**, not ordinary fields.
|
|
22
|
+
|
|
23
|
+
For both of them, the public builder request may look like one step, but the real backend form structure has multiple layers. Never invent a new backend meaning. Only compile into the backend structures that already exist.
|
|
24
|
+
|
|
25
|
+
## Mental Model
|
|
26
|
+
|
|
27
|
+
### Code block
|
|
28
|
+
|
|
29
|
+
There are three conceptual layers:
|
|
30
|
+
|
|
31
|
+
1. Code block field itself
|
|
32
|
+
2. Parsed output aliases
|
|
33
|
+
3. Target field bindings
|
|
34
|
+
|
|
35
|
+
Current builder support:
|
|
36
|
+
- configure the code block field itself
|
|
37
|
+
- configure input insertion into code content
|
|
38
|
+
- configure alias parsing
|
|
39
|
+
|
|
40
|
+
Important:
|
|
41
|
+
- keep `qf_output = {...}` as a plain assignment
|
|
42
|
+
- do not emit `const qf_output =` or `let qf_output =`
|
|
43
|
+
|
|
44
|
+
### Q-Linker
|
|
45
|
+
|
|
46
|
+
There are two conceptual layers:
|
|
47
|
+
|
|
48
|
+
1. Q-Linker field itself via `remoteLookupConfig`
|
|
49
|
+
2. Target field bindings via relation-default + `questionRelations(relationType=Q_LINKER)`
|
|
50
|
+
|
|
51
|
+
Current builder support:
|
|
52
|
+
- one-step high-level config through `q_linker_binding`
|
|
53
|
+
- internal compilation into existing backend payloads
|
|
54
|
+
|
|
55
|
+
## Operating Order
|
|
56
|
+
|
|
57
|
+
For code block or Q-Linker work, use this order:
|
|
58
|
+
|
|
59
|
+
1. Resolve the app and read fields:
|
|
60
|
+
- `app_resolve`
|
|
61
|
+
- `app_read_fields`
|
|
62
|
+
2. Confirm the target field set already exists.
|
|
63
|
+
3. Apply schema updates with `app_schema_apply`.
|
|
64
|
+
4. Read fields again and verify:
|
|
65
|
+
- field type
|
|
66
|
+
- alias config
|
|
67
|
+
- target field binding shape
|
|
68
|
+
5. For page-safety checks, use user-side schema or insert checks:
|
|
69
|
+
- `record_insert_schema_get`
|
|
70
|
+
- optional safe `record_insert`
|
|
71
|
+
|
|
72
|
+
Do not treat raw apply success as enough. Always re-read the field config.
|
|
73
|
+
|
|
74
|
+
## Code Block Rules
|
|
75
|
+
|
|
76
|
+
Read [references/code-block.md](references/code-block.md) before changing a code block field.
|
|
77
|
+
|
|
78
|
+
Use builder high-level config only for:
|
|
79
|
+
- input field insertion
|
|
80
|
+
- code content
|
|
81
|
+
- alias parsing
|
|
82
|
+
- auto trigger
|
|
83
|
+
- custom button text
|
|
84
|
+
|
|
85
|
+
When binding outputs to target fields, do not guess payload shape from memory. Follow the current builder implementation and the readback shape.
|
|
86
|
+
|
|
87
|
+
Hard rules:
|
|
88
|
+
- target fields must already exist
|
|
89
|
+
- keep target field types business-compatible
|
|
90
|
+
- if a page starts hanging on “关联中”, inspect whether the target field default type or relation config was written incorrectly
|
|
91
|
+
|
|
92
|
+
## Q-Linker Rules
|
|
93
|
+
|
|
94
|
+
Read [references/q-linker.md](references/q-linker.md) before changing a Q-Linker field.
|
|
95
|
+
|
|
96
|
+
First-stage stable support is only:
|
|
97
|
+
- custom mode
|
|
98
|
+
- request config
|
|
99
|
+
- alias parsing
|
|
100
|
+
- target field binding
|
|
101
|
+
- auto trigger / button text
|
|
102
|
+
|
|
103
|
+
Do not generate:
|
|
104
|
+
- template mode
|
|
105
|
+
- openApp/light-wing branches
|
|
106
|
+
- subtable table-match bindings
|
|
107
|
+
|
|
108
|
+
Hard rules:
|
|
109
|
+
- `outputs[*].target_field` is required
|
|
110
|
+
- use only supported target field types
|
|
111
|
+
- on rebinding, old target fields must be restored from relation-default to safe default type
|
|
112
|
+
- `resultFormatPath` must preserve backend-required alias metadata
|
|
113
|
+
|
|
114
|
+
## Verification Checklist
|
|
115
|
+
|
|
116
|
+
After each code block or Q-Linker change, verify all of these:
|
|
117
|
+
|
|
118
|
+
- `app_read_fields` shows the intended field type
|
|
119
|
+
- the high-level config is readable and stable
|
|
120
|
+
- target fields still have valid types
|
|
121
|
+
- insert schema can be opened
|
|
122
|
+
- record insert does not get blocked by malformed integration config
|
|
123
|
+
|
|
124
|
+
If the task explicitly includes runtime verification, keep it separate from configuration verification.
|
|
125
|
+
|
|
126
|
+
## Common Pitfalls
|
|
127
|
+
|
|
128
|
+
- Writing code block code with `const qf_output =`
|
|
129
|
+
- Treating a Q-Linker or code block binding as a plain field default
|
|
130
|
+
- Forgetting to restore old target fields after unbinding
|
|
131
|
+
- Using unsupported target field types
|
|
132
|
+
- Assuming apply success means the form page can open
|
|
133
|
+
|
|
134
|
+
## References
|
|
135
|
+
|
|
136
|
+
- Code block details: [references/code-block.md](references/code-block.md)
|
|
137
|
+
- Q-Linker details: [references/q-linker.md](references/q-linker.md)
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Qingflow Code Integrations"
|
|
3
|
+
short_description: "Configure Qingflow code block and Q-Linker fields safely"
|
|
4
|
+
default_prompt: "Use $qingflow-app-builder-code-integrations when configuring Qingflow code block or Q-Linker fields, especially when input insertion, alias parsing, target field binding, or page-safety verification matter."
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Code Block Builder Notes
|
|
2
|
+
|
|
3
|
+
## What Builder Should Configure
|
|
4
|
+
|
|
5
|
+
- code block field type
|
|
6
|
+
- code content
|
|
7
|
+
- inserted input fields inside code content
|
|
8
|
+
- alias parsing
|
|
9
|
+
- auto trigger
|
|
10
|
+
- custom button text
|
|
11
|
+
|
|
12
|
+
## Stable Writing Rules
|
|
13
|
+
|
|
14
|
+
- Always emit `qf_output = {...}`
|
|
15
|
+
- Never emit `const qf_output = {...}`
|
|
16
|
+
- Never emit `let qf_output = {...}`
|
|
17
|
+
|
|
18
|
+
## Useful CRM Pattern
|
|
19
|
+
|
|
20
|
+
Inputs:
|
|
21
|
+
- customer name
|
|
22
|
+
- source
|
|
23
|
+
- budget
|
|
24
|
+
- timing
|
|
25
|
+
- decision-maker flag
|
|
26
|
+
|
|
27
|
+
Outputs:
|
|
28
|
+
- score
|
|
29
|
+
- level
|
|
30
|
+
- priority
|
|
31
|
+
- summary
|
|
32
|
+
- next follow date
|
|
33
|
+
|
|
34
|
+
## Target Field Rules
|
|
35
|
+
|
|
36
|
+
Required:
|
|
37
|
+
- every `outputs[*].target_field` must point to an existing field
|
|
38
|
+
|
|
39
|
+
Allowed target field types:
|
|
40
|
+
- text
|
|
41
|
+
- long text
|
|
42
|
+
- number
|
|
43
|
+
- amount
|
|
44
|
+
- date
|
|
45
|
+
- datetime
|
|
46
|
+
- single select
|
|
47
|
+
- multi select
|
|
48
|
+
- boolean
|
|
49
|
+
|
|
50
|
+
Do not bind code block outputs to:
|
|
51
|
+
- q_linker
|
|
52
|
+
- code_block
|
|
53
|
+
- relation
|
|
54
|
+
- subtable
|
|
55
|
+
- attachment
|
|
56
|
+
- member
|
|
57
|
+
- department
|
|
58
|
+
- address
|
|
59
|
+
|
|
60
|
+
## Safe Verification
|
|
61
|
+
|
|
62
|
+
- `app_read_fields`
|
|
63
|
+
- `record_insert_schema_get`
|
|
64
|
+
- optional `record_code_block_run`
|
|
65
|
+
|
|
66
|
+
Treat configuration verification and runtime verification as separate checks.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Q-Linker Builder Notes
|
|
2
|
+
|
|
3
|
+
## What Builder Should Configure
|
|
4
|
+
|
|
5
|
+
- `remoteLookupConfig`
|
|
6
|
+
- alias parsing
|
|
7
|
+
- target field binding
|
|
8
|
+
- auto trigger
|
|
9
|
+
- custom button text
|
|
10
|
+
|
|
11
|
+
## Current Supported Scope
|
|
12
|
+
|
|
13
|
+
- custom mode only
|
|
14
|
+
- standard request fields
|
|
15
|
+
- alias path parsing
|
|
16
|
+
- target field binding to existing ordinary fields
|
|
17
|
+
|
|
18
|
+
## Recommended Public APIs For Samples
|
|
19
|
+
|
|
20
|
+
### Httpbin
|
|
21
|
+
|
|
22
|
+
- URL: `https://httpbin.org/get`
|
|
23
|
+
- Good for:
|
|
24
|
+
- query echo
|
|
25
|
+
- request URL echo
|
|
26
|
+
|
|
27
|
+
Useful paths:
|
|
28
|
+
- `$.args.keyword`
|
|
29
|
+
- `$.url`
|
|
30
|
+
|
|
31
|
+
### Open-Meteo Geocoding
|
|
32
|
+
|
|
33
|
+
- URL: `https://geocoding-api.open-meteo.com/v1/search`
|
|
34
|
+
- Good for:
|
|
35
|
+
- place normalization
|
|
36
|
+
- country
|
|
37
|
+
- lat/lng summary
|
|
38
|
+
|
|
39
|
+
Useful paths:
|
|
40
|
+
- `$.results[0].name`
|
|
41
|
+
- `$.results[0].country`
|
|
42
|
+
- `$.results[0].latitude`
|
|
43
|
+
- `$.results[0].longitude`
|
|
44
|
+
|
|
45
|
+
## Target Field Rules
|
|
46
|
+
|
|
47
|
+
Required:
|
|
48
|
+
- every `outputs[*].target_field` must point to an existing field
|
|
49
|
+
|
|
50
|
+
Prefer:
|
|
51
|
+
- text
|
|
52
|
+
- long text
|
|
53
|
+
- number
|
|
54
|
+
- amount
|
|
55
|
+
- date
|
|
56
|
+
- datetime
|
|
57
|
+
- single select
|
|
58
|
+
- multi select
|
|
59
|
+
- boolean
|
|
60
|
+
|
|
61
|
+
Avoid:
|
|
62
|
+
- q_linker
|
|
63
|
+
- code_block
|
|
64
|
+
- relation
|
|
65
|
+
- subtable
|
|
66
|
+
- attachment
|
|
67
|
+
- member
|
|
68
|
+
- department
|
|
69
|
+
- address
|
|
70
|
+
|
|
71
|
+
## Safe Verification
|
|
72
|
+
|
|
73
|
+
- `app_read_fields`
|
|
74
|
+
- `record_insert_schema_get`
|
|
75
|
+
- `record_insert`
|
|
76
|
+
|
|
77
|
+
This verifies that the configuration does not break the form page, even before runtime execution is tested.
|
|
@@ -54,7 +54,7 @@ Route to exactly one of these specialized paths:
|
|
|
54
54
|
- If the task involves member, department, or relation fields and the user only has natural names/titles, keep the same route; direct write now supports backend-native auto resolution and may return `needs_confirmation` with candidates instead of failing blind
|
|
55
55
|
- If the task involves linked visibility, upstream/downstream field dependencies, reference-driven auto fill, or formula-driven defaulting, keep the same insert/update route and read field-level `linkage` from the schema before composing payloads
|
|
56
56
|
- If the task is about subtable writes, still route to the matching insert/update skill, but shape the payload as parent subtable field -> row array; do not route users toward top-level leaf selectors
|
|
57
|
-
- If the task is insert-focused and readback
|
|
57
|
+
- If the task is insert-focused and readback/detail context matters, keep the same route and prefer the single-record detail readback after the write; use normalized list readback only when batch row shape is needed
|
|
58
58
|
- If the user sounds like an ordinary workflow assignee rather than a system operator, prefer `$qingflow-task-ops` over direct record mutation whenever both paths could fit
|
|
59
59
|
- If the task is about task discovery by natural language query, still route to `$qingflow-task-ops`; `task_list --query` now uses backend search first and only falls back to local matching when backend returns zero rows
|
|
60
60
|
- If the task is about grouped distributions, ratios, rankings, trends, insights, or any final statistical conclusion, switch to `$qingflow-record-analysis`
|
|
@@ -68,6 +68,7 @@ Route to exactly one of these specialized paths:
|
|
|
68
68
|
- if the task can stay read-only, do not write or act
|
|
69
69
|
- if the task involves a user-uploaded import file, do not modify the file unless the user explicitly authorizes repair or normalization
|
|
70
70
|
- if the task involves record import, call `app_get` first and inspect `data.import_capability` before template download, file repair, or import start
|
|
71
|
+
- if a record detail includes images or attachments, prefer the single-record detail tool's local paths: images from `media_assets.items[].local_path`, documents/tables from `file_assets.items[].local_path` and `extraction.text_path`; remote Qingflow file URLs are not stable direct-read targets
|
|
71
72
|
- if the current MCP capability is unsupported, the workflow is awkward, or the user's need still cannot be satisfied after reasonable use, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation
|
|
72
73
|
|
|
73
74
|
## Shared Helper
|
|
@@ -6,17 +6,18 @@ For final statistics, grouped distributions, rankings, trends, or insight-style
|
|
|
6
6
|
|
|
7
7
|
- For analysis-style reads, use `record_access` through [$qingflow-record-analysis](../../qingflow-record-analysis/SKILL.md)
|
|
8
8
|
- `record_list` is for browsing and sample inspection only
|
|
9
|
-
- `record_get` is for one exact record
|
|
9
|
+
- `record_get` is for one exact record and downloads readable detail-page images into `media_assets.items[].local_path` plus attachments/documents/tables into `file_assets.items[].local_path`
|
|
10
10
|
- Use `record_browse_schema_get` when field titles are uncertain instead of guessing ids
|
|
11
11
|
- Do not present paged browse output as if it were a grouped or full-population conclusion
|
|
12
12
|
- Use `record_export_direct` only when the user explicitly asks for export/download/Excel output
|
|
13
13
|
|
|
14
14
|
## Direct Writes
|
|
15
15
|
|
|
16
|
-
- `record_insert` is schema-first through `record_insert_schema_get`
|
|
16
|
+
- `record_insert` is schema-first through `record_insert_schema_get`; default to `items=[{"fields": {...}}]`
|
|
17
17
|
- `record_update` is schema-first through `record_update_schema_get`
|
|
18
18
|
- `record_delete` does not need a schema-get step
|
|
19
|
-
-
|
|
19
|
+
- For batch insert, `partial_success` means some rows were created; use `created_record_ids`, failed `row_number`, and `failed_fields` to repair only failed rows
|
|
20
|
+
- If a direct-write tool returns `write_executed=false`, the write was blocked and not executed for that item
|
|
20
21
|
- Prefer `verify_write=true` for complex, relation-heavy, subtable, or production writes
|
|
21
22
|
|
|
22
23
|
## Lookup Fields
|
|
@@ -29,3 +30,4 @@ For final statistics, grouped distributions, rankings, trends, or insight-style
|
|
|
29
30
|
|
|
30
31
|
- Subtable payloads stay under the parent table field as a row array
|
|
31
32
|
- Attachment fields are two-step: upload first, then write the returned upload payload
|
|
33
|
+
- For reads, attachment/rich-text images returned by `record_get` should be opened from local `media_assets` paths, and non-image files should be read from `file_assets` local paths or `extraction.text_path`, instead of remote file URLs
|
|
@@ -8,12 +8,12 @@ It is not a user-facing product spec. It exists to prevent skill drift.
|
|
|
8
8
|
### User data
|
|
9
9
|
|
|
10
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 `
|
|
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
12
|
- Standard flows:
|
|
13
13
|
- analyze: `app_get -> record_browse_schema_get -> record_access -> Python`
|
|
14
14
|
- browse detail: `app_get -> record_browse_schema_get -> record_list / record_get`
|
|
15
15
|
- explicit export/download/Excel: `view_get -> record_export_*` or `record_export_direct`
|
|
16
|
-
- insert: `record_insert_schema_get -> record_insert`
|
|
16
|
+
- insert: `record_insert_schema_get -> record_insert(items)`
|
|
17
17
|
- update: `record_update_schema_get -> record_update`
|
|
18
18
|
|
|
19
19
|
### Tasks
|
|
@@ -39,11 +39,14 @@ It is not a user-facing product spec. It exists to prevent skill drift.
|
|
|
39
39
|
- `app_layout_apply`
|
|
40
40
|
- `app_flow_apply`
|
|
41
41
|
- `app_views_apply`
|
|
42
|
+
- `app_custom_buttons_apply`
|
|
43
|
+
- `app_associated_resources_apply`
|
|
42
44
|
- `app_charts_apply`
|
|
43
45
|
- `portal_apply`
|
|
44
46
|
- `app_publish_verify`
|
|
45
47
|
- `portal_apply` edit mode may omit `sections` for base-info-only updates
|
|
46
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
|
|
47
50
|
- `app_get.editability` uses:
|
|
48
51
|
- `can_edit_app_base`
|
|
49
52
|
- `can_edit_form`
|
|
@@ -57,7 +60,7 @@ It is not a user-facing product spec. It exists to prevent skill drift.
|
|
|
57
60
|
- Package public tools: do not regress to `package_create` / `package_attach_app` as the public default story
|
|
58
61
|
- App editability: do not let `can_edit_form` imply app base-info writes
|
|
59
62
|
- Portal and chart visibility: keep the public story on `portal_apply` / `app_charts_apply`, not low-level internal writes
|
|
60
|
-
- Analysis path: standard path stays `record_access -> Python
|
|
63
|
+
- Analysis path: standard path stays `record_access -> Python`
|
|
61
64
|
|
|
62
65
|
## Release Checklist For Skill Maintenance
|
|
63
66
|
|
|
@@ -10,6 +10,14 @@ Use `record_browse_schema_get -> record_list` when:
|
|
|
10
10
|
- the target `record_id` is unknown
|
|
11
11
|
- a delete target still needs confirmation
|
|
12
12
|
- the user needs sample rows or a small export
|
|
13
|
+
- the user gives fuzzy text such as a company, project, bug, or contract name
|
|
14
|
+
|
|
15
|
+
For fuzzy lookup, pass `query` and optional `query_fields`. `record_list` returns at most 10 `data.items`, plus `data.pagination.total_count` and `lookup.next_action`.
|
|
16
|
+
|
|
17
|
+
- `lookup.next_action="record_get"`: read the single returned item with `record_get`
|
|
18
|
+
- `lookup.next_action="ask_user"`: ask the user to choose from returned `data.items`
|
|
19
|
+
- `lookup.next_action="refine_query"`: ask for a narrower keyword or add `query_fields`
|
|
20
|
+
- `lookup.next_action="broaden_query"`: remove overly narrow fields or ask for another clue
|
|
13
21
|
|
|
14
22
|
## Detail Pattern
|
|
15
23
|
|
|
@@ -18,16 +26,18 @@ Use `record_browse_schema_get -> record_get` when:
|
|
|
18
26
|
- the exact `record_id` is known
|
|
19
27
|
- the user needs one record in detail
|
|
20
28
|
- a write target needs verification before action
|
|
29
|
+
- the user needs images or attachments shown on the detail page; read downloaded images from `media_assets.items[].local_path`, and read documents/tables from `file_assets.items[].local_path` or `extraction.text_path`
|
|
21
30
|
|
|
22
31
|
## Insert Pattern
|
|
23
32
|
|
|
24
|
-
Use `record_insert_schema_get -> record_insert`.
|
|
33
|
+
Use `record_insert_schema_get -> record_insert(items)`.
|
|
25
34
|
|
|
26
35
|
1. Confirm the target app
|
|
27
36
|
2. Read `required_fields`, `optional_fields`, `runtime_linked_required_fields`, and `payload_template`
|
|
28
|
-
3. Build
|
|
29
|
-
4.
|
|
30
|
-
5.
|
|
37
|
+
3. Build `items` as `[{"fields": {...}}]`; a single record is one item
|
|
38
|
+
4. Write member, department, and relation fields with natural strings first when the user provided names
|
|
39
|
+
5. If lookup fields are ambiguous, stop and ask for confirmation
|
|
40
|
+
6. On `partial_success`, keep `created_record_ids` and only repair failed `row_number` / `failed_fields`
|
|
31
41
|
|
|
32
42
|
## Update Pattern
|
|
33
43
|
|
|
@@ -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
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Environment Switching
|
|
2
|
+
|
|
3
|
+
Use this reference before any setup, authentication, or live validation flow.
|
|
4
|
+
|
|
5
|
+
## Step 1: Resolve the active environment
|
|
6
|
+
|
|
7
|
+
Decide explicitly whether the user is targeting:
|
|
8
|
+
|
|
9
|
+
- `test`: for smoke tests, trial setup, DSL validation, mock data, and integration debugging
|
|
10
|
+
- `prod`: for real business usage in the formal environment
|
|
11
|
+
|
|
12
|
+
If the user did not specify an environment, default to `prod`.
|
|
13
|
+
|
|
14
|
+
## Test Environment
|
|
15
|
+
|
|
16
|
+
Default characteristics:
|
|
17
|
+
|
|
18
|
+
- preferred for first-time setup and local MCP validation
|
|
19
|
+
- mock or smoke data is acceptable when the user asks for it
|
|
20
|
+
- use read/write verification freely inside the intended test workspace
|
|
21
|
+
|
|
22
|
+
Known values in the current workspace:
|
|
23
|
+
|
|
24
|
+
- use an explicitly provided non-production backend
|
|
25
|
+
- common test workspace example: `ws_id=2`
|
|
26
|
+
- `qf_version`: usually unset unless the user explicitly needs a routed version
|
|
27
|
+
|
|
28
|
+
Setup behavior:
|
|
29
|
+
|
|
30
|
+
- prefer this environment for Claude Desktop or local MCP client onboarding
|
|
31
|
+
- use `auth_use_token` or `auth_login`, then `workspace_list`, then `workspace_select`
|
|
32
|
+
- if the user asks to verify installation, a real read-only smoke path is acceptable
|
|
33
|
+
|
|
34
|
+
## Production Environment
|
|
35
|
+
|
|
36
|
+
Production is the default environment when the user does not specify one. If the user explicitly says `test`, switch to the dedicated non-production backend they provide.
|
|
37
|
+
|
|
38
|
+
Expected behavior:
|
|
39
|
+
|
|
40
|
+
- default `base_url`: `https://qingflow.com/api`
|
|
41
|
+
- confirm the production `qf_version` explicitly when browser traffic depends on routed versions such as `canary`
|
|
42
|
+
- confirm the exact workspace before any live validation
|
|
43
|
+
- prefer read-only checks first
|
|
44
|
+
- avoid mock data, smoke writes, or destructive tests unless the user explicitly asks for them
|
|
45
|
+
|
|
46
|
+
Production guardrails:
|
|
47
|
+
|
|
48
|
+
- do not store credentials in skill files or examples
|
|
49
|
+
- do not assume the same workspace ids as test
|
|
50
|
+
- treat startup verification and auth verification as separate steps
|
|
51
|
+
- when sharing snippets, label them as `prod` and `test` clearly
|
|
52
|
+
- when MCP and browser results diverge, compare `request_route` with the browser route before blaming the query logic
|
|
53
|
+
|
|
54
|
+
## Reporting Rule
|
|
55
|
+
|
|
56
|
+
When you give setup instructions, always state:
|
|
57
|
+
|
|
58
|
+
- active environment
|
|
59
|
+
- selected `base_url`
|
|
60
|
+
- selected `qf_version` when relevant
|
|
61
|
+
- whether the next step is read-only or write-impacting
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generic Stdio MCP Clients
|
|
2
|
+
|
|
3
|
+
Use this for any local AI client that supports MCP over stdio.
|
|
4
|
+
|
|
5
|
+
## Required mapping
|
|
6
|
+
|
|
7
|
+
- `command`: `<ABSOLUTE_PATH_TO_REPO>/qingflow-support/mcp-server/qingflow-mcp`
|
|
8
|
+
- `args`: `[]`
|
|
9
|
+
- `env.QINGFLOW_MCP_DEFAULT_BASE_URL`: backend base URL for the active environment
|
|
10
|
+
|
|
11
|
+
Environment examples:
|
|
12
|
+
|
|
13
|
+
- `prod` (default): `https://qingflow.com/api`
|
|
14
|
+
- `test`: use the explicitly provided non-production backend
|
|
15
|
+
|
|
16
|
+
Keep separate client entries or separate config snippets for `test` and `prod`.
|
|
17
|
+
|
|
18
|
+
## Validation sequence
|
|
19
|
+
|
|
20
|
+
1. Start the client
|
|
21
|
+
2. Confirm the `qingflow` MCP server is visible
|
|
22
|
+
3. Run `auth_use_token`
|
|
23
|
+
4. Run `workspace_list`
|
|
24
|
+
5. Run `workspace_select`
|
|
25
|
+
6. Run a read-only tool such as `app_list`
|
|
26
|
+
|
|
27
|
+
## Common failures
|
|
28
|
+
|
|
29
|
+
- Launch failure: bad `command` path or missing `.venv`
|
|
30
|
+
- Auth failure: invalid or expired token
|
|
31
|
+
- Business tool failure before setup: workspace not selected
|