@josephyan/qingflow-app-builder-mcp 0.2.0-beta.26 → 0.2.0-beta.28

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 @josephyan/qingflow-app-builder-mcp@0.2.0-beta.26
6
+ npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.28
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.26 qingflow-app-builder-mcp
12
+ npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.28 qingflow-app-builder-mcp
13
13
  ```
14
14
 
15
15
  Environment:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyan/qingflow-app-builder-mcp",
3
- "version": "0.2.0-beta.26",
3
+ "version": "0.2.0-beta.28",
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 = "0.2.0b26"
7
+ version = "0.2.0b28"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -2,4 +2,4 @@ from __future__ import annotations
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.2.0b26"
5
+ __version__ = "0.2.0b28"
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from datetime import date
4
+
3
5
  from mcp.server.fastmcp import FastMCP
4
6
 
5
7
  from .backend_client import BackendClient
@@ -23,25 +25,91 @@ from .tools.workspace_tools import WorkspaceTools
23
25
 
24
26
 
25
27
  def build_server() -> FastMCP:
28
+ today = date.today()
29
+ current_year = today.year
26
30
  server = FastMCP(
27
31
  "Qingflow MCP",
28
- instructions=(
29
- "Use auth_login first, then workspace_list and workspace_select. "
30
- "All resource tools operate with the logged-in user's Qingflow permissions.\n\n"
31
- "If app_key is unknown, use app_list or app_search first to discover current-user visible apps in the selected workspace. "
32
- "For analytics, use record_schema_get first, let the model build field_id-based DSL, "
33
- "then call record_analyze. record_analyze returns compact business-first output as query/result/ranking/ratios/completeness/presentation; use verbose only for route/debug details. "
34
- "record_schema_get returns the current user's applicant-node visible schema only; hidden fields are omitted and missing fields should be treated as not visible in the current permission scope. "
35
- "For operational record reads, use record_schema_get first, then record_list or record_get. "
36
- "For writes, use record_schema_get and then call record_write once; it performs internal preflight before any apply and refuses fields outside the applicant-node writable schema.\n\n"
37
- "Task Center (待办/已办) handling:\n"
38
- "- Use task_summary to get headline counts.\n"
39
- "- Use task_list for flat task browsing with task_box and flow_status.\n"
40
- "- Use task_facets when worksheet or workflow-node buckets matter.\n"
41
- "- Use task_mark_read to mark a specific task as read.\n"
42
- "- Use task_urge to send an urgent reminder for a pending task.\n"
43
- "- After identifying the exact task node and record, use task_approve, task_reject, task_rollback, or task_transfer as needed."
44
- ),
32
+ instructions=f"""Use this server for Qingflow operational workflows. Current date: `{today.isoformat()}`.
33
+
34
+ ## Authentication
35
+
36
+ Use `auth_login` first, then `workspace_list` and `workspace_select`.
37
+ All resource tools operate with the logged-in user's Qingflow permissions.
38
+
39
+ ## App Discovery
40
+
41
+ If `app_key` is unknown, use `app_list` or `app_search` first.
42
+
43
+ ## Schema-First Rule
44
+
45
+ Always call `record_schema_get` before `record_list`, `record_get`, `record_write`, or `record_analyze`.
46
+
47
+ - All `field_id` values must come from the schema response.
48
+ - Never guess field names or ids.
49
+
50
+ ## Schema Scope
51
+
52
+ `record_schema_get` returns the current user's applicant-node visible fields only.
53
+
54
+ - Hidden fields are omitted.
55
+ - Missing fields mean the field is not visible in the current permission scope.
56
+ - Read `fields` and `suggested_*` from the top level of the schema response.
57
+
58
+ ## Analytics Path
59
+
60
+ `record_schema_get -> record_analyze`
61
+
62
+ Use this DSL shape:
63
+
64
+ - `dimensions`: `{{field_id, alias, bucket}}`
65
+ - `metrics`: `{{op, field_id, alias}}`
66
+ - `filters`: `{{field_id, op, value}}`
67
+ - `sort`: `{{by, order}}`
68
+
69
+ Important key rules:
70
+
71
+ - Use `op`
72
+ - Do **not** use `type`
73
+ - Do **not** use `agg`
74
+ - Do **not** use `aggregation`
75
+ - Do **not** use `operator`
76
+
77
+ Analysis answers must include concrete numbers. When applicable, include percentages based on the returned totals.
78
+
79
+ ## Record CRUD Path
80
+
81
+ `record_schema_get -> record_list / record_get / record_write`
82
+
83
+ - For `columns`, prefer `[{{field_id}}]`; bare integer field ids remain supported for compatibility.
84
+
85
+ `record_write` uses SQL-like JSON clauses:
86
+
87
+ - `insert` -> `values`
88
+ - `update` -> `record_id + set`
89
+ - `delete` -> `record_id` or `record_ids`
90
+
91
+ - Read relation targets from `record_schema_get.target_app_key` / `target_app_name` before preparing relation writes.
92
+ - If a member or department field id is known but candidate ids are not, use `record_member_candidates` or `record_department_candidates` before `record_write`.
93
+
94
+ ## Task Center Path
95
+
96
+ `task_summary -> task_list / task_facets -> task action`
97
+
98
+ ## Time Handling
99
+
100
+ Normalize relative dates before building DSL.
101
+
102
+ - If the user says `3月` without a year, use the current year: `{current_year}`
103
+ - Convert month-only phrases into explicit legal date ranges
104
+ - Never send impossible dates such as `2026-02-29`
105
+
106
+ ## Environment
107
+
108
+ Default to `prod` unless the user explicitly specifies `test`.
109
+
110
+ ## Constraints
111
+
112
+ Avoid builder-side app or schema changes here.""",
45
113
  )
46
114
  sessions = SessionStore()
47
115
  backend = BackendClient()
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from datetime import date
4
+
3
5
  from mcp.server.fastmcp import FastMCP
4
6
 
5
7
  from .backend_client import BackendClient
@@ -16,17 +18,86 @@ from .tools.workspace_tools import WorkspaceTools
16
18
 
17
19
 
18
20
  def build_user_server() -> FastMCP:
21
+ today = date.today()
22
+ current_year = today.year
19
23
  server = FastMCP(
20
24
  "Qingflow App User MCP",
21
- instructions=(
22
- "Use this server for Qingflow operational workflows with a schema-first path. "
23
- "If app_key is unknown, use app_list or app_search first to discover current-user visible apps in the selected workspace. "
24
- "For records, start with record_schema_get, then choose record_list, record_get, or record_write. "
25
- "record_schema_get returns the current user's applicant-node visible schema only; hidden fields are omitted and missing fields should be treated as not visible in the current permission scope. "
26
- "For analytics, switch to record_schema_get and record_analyze; its default output is compact query/result/ranking/ratios/completeness/presentation, with route/debug only in verbose mode. "
27
- "For task center, use task_summary, task_list, and task_facets before any explicit task action. "
28
- "Avoid builder-side app or schema changes here."
29
- ),
25
+ instructions=f"""Use this server for Qingflow operational workflows. Current date: `{today.isoformat()}`.
26
+
27
+ ## App Discovery
28
+
29
+ If `app_key` is unknown, use `app_list` or `app_search` first.
30
+
31
+ ## Schema-First Rule
32
+
33
+ Always call `record_schema_get` before `record_list`, `record_get`, `record_write`, or `record_analyze`.
34
+
35
+ - All `field_id` values must come from the schema response.
36
+ - Never guess field names or ids.
37
+
38
+ ## Schema Scope
39
+
40
+ `record_schema_get` returns the current user's applicant-node visible fields only.
41
+
42
+ - Hidden fields are omitted.
43
+ - Missing fields mean the field is not visible in the current permission scope.
44
+ - Read `fields` and `suggested_*` from the top level of the schema response.
45
+
46
+ ## Analytics Path
47
+
48
+ `record_schema_get -> record_analyze`
49
+
50
+ Use this DSL shape:
51
+
52
+ - `dimensions`: `{{field_id, alias, bucket}}`
53
+ - `metrics`: `{{op, field_id, alias}}`
54
+ - `filters`: `{{field_id, op, value}}`
55
+ - `sort`: `{{by, order}}`
56
+
57
+ Important key rules:
58
+
59
+ - Use `op`
60
+ - Do **not** use `type`
61
+ - Do **not** use `agg`
62
+ - Do **not** use `aggregation`
63
+ - Do **not** use `operator`
64
+
65
+ Analysis answers must include concrete numbers. When applicable, include percentages based on the returned totals.
66
+
67
+ ## Record CRUD Path
68
+
69
+ `record_schema_get -> record_list / record_get / record_write`
70
+
71
+ - For `columns`, prefer `[{{field_id}}]`; bare integer field ids remain supported for compatibility.
72
+
73
+ `record_write` uses SQL-like JSON clauses:
74
+
75
+ - `insert` -> `values`
76
+ - `update` -> `record_id + set`
77
+ - `delete` -> `record_id` or `record_ids`
78
+
79
+ - Read relation targets from `record_schema_get.target_app_key` / `target_app_name` before preparing relation writes.
80
+ - If a member or department field id is known but candidate ids are not, use `record_member_candidates` or `record_department_candidates` before `record_write`.
81
+
82
+ ## Task Center Path
83
+
84
+ `task_summary -> task_list / task_facets -> task action`
85
+
86
+ ## Time Handling
87
+
88
+ Normalize relative dates before building DSL.
89
+
90
+ - If the user says `3月` without a year, use the current year: `{current_year}`
91
+ - Convert month-only phrases into explicit legal date ranges
92
+ - Never send impossible dates such as `2026-02-29`
93
+
94
+ ## Environment
95
+
96
+ Default to `prod` unless the user explicitly specifies `test`.
97
+
98
+ ## Constraints
99
+
100
+ Avoid builder-side app or schema changes here.""",
30
101
  )
31
102
  sessions = SessionStore()
32
103
  backend = BackendClient()