@josephyan/qingflow-cli 0.2.0-beta.984 → 0.2.0-beta.986

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.
Files changed (43) hide show
  1. package/README.md +2 -2
  2. package/docs/local-agent-install.md +70 -11
  3. package/package.json +1 -1
  4. package/pyproject.toml +1 -1
  5. package/src/qingflow_mcp/__init__.py +1 -1
  6. package/src/qingflow_mcp/builder_facade/service.py +47 -21
  7. package/src/qingflow_mcp/cli/commands/auth.py +14 -43
  8. package/src/qingflow_mcp/cli/commands/task.py +4 -1
  9. package/src/qingflow_mcp/cli/commands/workspace.py +0 -8
  10. package/src/qingflow_mcp/cli/formatters.py +0 -21
  11. package/src/qingflow_mcp/config.py +39 -0
  12. package/src/qingflow_mcp/errors.py +2 -2
  13. package/src/qingflow_mcp/public_surface.py +2 -6
  14. package/src/qingflow_mcp/response_trim.py +1 -8
  15. package/src/qingflow_mcp/server.py +1 -1
  16. package/src/qingflow_mcp/server_app_builder.py +4 -28
  17. package/src/qingflow_mcp/server_app_user.py +4 -28
  18. package/src/qingflow_mcp/session_store.py +31 -5
  19. package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
  20. package/src/qingflow_mcp/tools/app_tools.py +51 -1
  21. package/src/qingflow_mcp/tools/approval_tools.py +82 -1
  22. package/src/qingflow_mcp/tools/auth_tools.py +258 -288
  23. package/src/qingflow_mcp/tools/base.py +204 -4
  24. package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
  25. package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
  26. package/src/qingflow_mcp/tools/directory_tools.py +28 -1
  27. package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
  28. package/src/qingflow_mcp/tools/file_tools.py +25 -1
  29. package/src/qingflow_mcp/tools/import_tools.py +40 -1
  30. package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
  31. package/src/qingflow_mcp/tools/package_tools.py +37 -1
  32. package/src/qingflow_mcp/tools/portal_tools.py +28 -1
  33. package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
  34. package/src/qingflow_mcp/tools/record_tools.py +255 -2
  35. package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
  36. package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
  37. package/src/qingflow_mcp/tools/role_tools.py +19 -1
  38. package/src/qingflow_mcp/tools/solution_tools.py +56 -1
  39. package/src/qingflow_mcp/tools/task_context_tools.py +205 -6
  40. package/src/qingflow_mcp/tools/task_tools.py +49 -3
  41. package/src/qingflow_mcp/tools/view_tools.py +56 -1
  42. package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
  43. package/src/qingflow_mcp/tools/workspace_tools.py +14 -225
@@ -5,11 +5,21 @@ from mcp.server.fastmcp import FastMCP
5
5
  from ..config import DEFAULT_PROFILE
6
6
  from ..errors import QingflowApiError, raise_tool_error
7
7
  from ..json_types import JSONObject
8
- from .base import ToolBase
8
+ from .base import ToolBase, tool_cn_name
9
9
 
10
10
 
11
11
  class PortalTools(ToolBase):
12
+ """门户工具(中文名:门户页管理)。
13
+
14
+ 类型:门户配置工具。
15
+ 主要职责:
16
+ 1. 查询门户列表与详情;
17
+ 2. 维护门户基础信息与配置;
18
+ 3. 执行门户发布与删除操作。
19
+ """
20
+
12
21
  def register(self, mcp: FastMCP) -> None:
22
+ """注册当前工具到 MCP 服务。"""
13
23
  @mcp.tool()
14
24
  def portal_list(profile: str = DEFAULT_PROFILE) -> JSONObject:
15
25
  return self.portal_list(profile=profile)
@@ -42,14 +52,18 @@ class PortalTools(ToolBase):
42
52
  def portal_publish(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> JSONObject:
43
53
  return self.portal_publish(profile=profile, dash_key=dash_key)
44
54
 
55
+ @tool_cn_name("门户列表")
45
56
  def portal_list(self, *, profile: str) -> JSONObject:
57
+ """执行门户相关逻辑。"""
46
58
  def runner(session_profile, context):
47
59
  result = self.backend.request("GET", context, "/dash")
48
60
  return {"profile": profile, "ws_id": session_profile.selected_ws_id, "items": result}
49
61
 
50
62
  return self._run(profile, runner)
51
63
 
64
+ @tool_cn_name("门户详情")
52
65
  def portal_get(self, *, profile: str, dash_key: str, being_draft: bool = False) -> JSONObject:
66
+ """执行门户相关逻辑。"""
53
67
  self._require_dash_key(dash_key)
54
68
 
55
69
  def runner(session_profile, context):
@@ -58,7 +72,9 @@ class PortalTools(ToolBase):
58
72
 
59
73
  return self._run(profile, runner)
60
74
 
75
+ @tool_cn_name("创建门户")
61
76
  def portal_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
77
+ """执行门户相关逻辑。"""
62
78
  body = self._require_dict(payload)
63
79
 
64
80
  def runner(session_profile, context):
@@ -67,7 +83,9 @@ class PortalTools(ToolBase):
67
83
 
68
84
  return self._run(profile, runner)
69
85
 
86
+ @tool_cn_name("门户基础信息")
70
87
  def portal_get_base_info(self, *, profile: str, dash_key: str) -> JSONObject:
88
+ """执行门户相关逻辑。"""
71
89
  self._require_dash_key(dash_key)
72
90
 
73
91
  def runner(session_profile, context):
@@ -76,7 +94,9 @@ class PortalTools(ToolBase):
76
94
 
77
95
  return self._run(profile, runner)
78
96
 
97
+ @tool_cn_name("更新门户基础信息")
79
98
  def portal_update_base_info(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
99
+ """执行门户相关逻辑。"""
80
100
  self._require_dash_key(dash_key)
81
101
  body = self._require_dict(payload)
82
102
 
@@ -90,7 +110,9 @@ class PortalTools(ToolBase):
90
110
 
91
111
  return self._run(profile, runner)
92
112
 
113
+ @tool_cn_name("更新门户配置")
93
114
  def portal_update(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
115
+ """执行门户相关逻辑。"""
94
116
  self._require_dash_key(dash_key)
95
117
  body = self._require_dict(payload)
96
118
 
@@ -104,7 +126,9 @@ class PortalTools(ToolBase):
104
126
 
105
127
  return self._run(profile, runner)
106
128
 
129
+ @tool_cn_name("删除门户")
107
130
  def portal_delete(self, *, profile: str, dash_key: str) -> JSONObject:
131
+ """执行门户相关逻辑。"""
108
132
  self._require_dash_key(dash_key)
109
133
 
110
134
  def runner(session_profile, context):
@@ -117,7 +141,9 @@ class PortalTools(ToolBase):
117
141
 
118
142
  return self._run(profile, runner)
119
143
 
144
+ @tool_cn_name("发布门户")
120
145
  def portal_publish(self, *, profile: str, dash_key: str) -> JSONObject:
146
+ """执行门户相关逻辑。"""
121
147
  self._require_dash_key(dash_key)
122
148
 
123
149
  def runner(session_profile, context):
@@ -127,5 +153,6 @@ class PortalTools(ToolBase):
127
153
  return self._run(profile, runner)
128
154
 
129
155
  def _require_dash_key(self, dash_key: str) -> None:
156
+ """执行内部辅助逻辑。"""
130
157
  if not dash_key:
131
158
  raise_tool_error(QingflowApiError.config_error("dash_key is required"))
@@ -9,7 +9,7 @@ from ..backend_client import BackendRequestContext
9
9
  from ..config import DEFAULT_PROFILE, normalize_base_url
10
10
  from ..errors import QingflowApiError, raise_tool_error
11
11
  from ..json_types import JSONObject, JSONValue
12
- from .base import ToolBase
12
+ from .base import ToolBase, tool_cn_name
13
13
 
14
14
 
15
15
  def _qingbi_base_url(base_url: str) -> str:
@@ -51,7 +51,17 @@ def _coerce_tool_error(error: RuntimeError | QingflowApiError) -> QingflowApiErr
51
51
 
52
52
 
53
53
  class QingbiReportTools(ToolBase):
54
+ """轻报表工具(中文名:图表与报表读取)。
55
+
56
+ 类型:报表分析工具。
57
+ 主要职责:
58
+ 1. 查询报表列表与基础信息;
59
+ 2. 获取报表配置与图表数据;
60
+ 3. 为门户与任务上下文提供报表侧读取能力。
61
+ """
62
+
54
63
  def register(self, mcp: FastMCP) -> None:
64
+ """注册当前工具到 MCP 服务。"""
55
65
  @mcp.tool()
56
66
  def qingbi_report_list(
57
67
  profile: str = DEFAULT_PROFILE,
@@ -123,10 +133,13 @@ class QingbiReportTools(ToolBase):
123
133
  ) -> JSONObject:
124
134
  return self.qingbi_report_list_field_options(profile=profile, field_id=field_id, chart_id=chart_id)
125
135
 
136
+ @tool_cn_name("报表列表")
126
137
  def qingbi_report_list(self, *, profile: str, app_key: str) -> JSONObject:
138
+ """执行工具方法逻辑。"""
127
139
  self._require_app_key(app_key)
128
140
  return self._request(profile, "GET", f"/qingbi/charts/data/bichart/{app_key}", app_key=app_key, items_key="items")
129
141
 
142
+ @tool_cn_name("报表排序列表")
130
143
  def qingbi_report_list_sorted(
131
144
  self,
132
145
  *,
@@ -136,6 +149,7 @@ class QingbiReportTools(ToolBase):
136
149
  page_size: int = 500,
137
150
  search_key: str | None = None,
138
151
  ) -> JSONObject:
152
+ """执行工具方法逻辑。"""
139
153
  self._require_app_key(app_key)
140
154
  body: JSONObject = {"appKey": app_key, "pageNum": page_num, "pageSize": page_size}
141
155
  if search_key:
@@ -153,11 +167,15 @@ class QingbiReportTools(ToolBase):
153
167
  json_body=body,
154
168
  )
155
169
 
170
+ @tool_cn_name("创建报表")
156
171
  def qingbi_report_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
172
+ """执行工具方法逻辑。"""
157
173
  body = self._require_dict(payload)
158
174
  return self._request(profile, "POST", "/qingbi/charts", json_body=body)
159
175
 
176
+ @tool_cn_name("报表基础信息")
160
177
  def qingbi_report_get_base(self, *, profile: str, chart_id: str) -> JSONObject:
178
+ """执行工具方法逻辑。"""
161
179
  self._require_chart_id(chart_id)
162
180
  try:
163
181
  return self._request(profile, "GET", f"/qingbi/charts/baseinfo/{chart_id}", chart_id=chart_id)
@@ -167,20 +185,27 @@ class QingbiReportTools(ToolBase):
167
185
  raise
168
186
  return self._request(profile, "GET", f"/qingbi/charts/qflow/baseinfo/{chart_id}", chart_id=chart_id)
169
187
 
188
+ @tool_cn_name("更新报表基础信息")
170
189
  def qingbi_report_update_base(self, *, profile: str, chart_id: str, payload: JSONObject) -> JSONObject:
190
+ """执行工具方法逻辑。"""
171
191
  self._require_chart_id(chart_id)
172
192
  body = self._require_dict(payload)
173
193
  return self._request(profile, "PUT", f"/qingbi/charts/baseinfo/{chart_id}", chart_id=chart_id, json_body=body, risk_operation="update", risk_target="report base settings")
174
194
 
195
+ @tool_cn_name("报表配置")
175
196
  def qingbi_report_get_config(self, *, profile: str, chart_id: str) -> JSONObject:
197
+ """执行工具方法逻辑。"""
176
198
  self._require_chart_id(chart_id)
177
199
  return self._request(profile, "GET", f"/qingbi/charts/{chart_id}/configs", chart_id=chart_id)
178
200
 
201
+ @tool_cn_name("更新报表配置")
179
202
  def qingbi_report_update_config(self, *, profile: str, chart_id: str, payload: JSONObject) -> JSONObject:
203
+ """执行工具方法逻辑。"""
180
204
  self._require_chart_id(chart_id)
181
205
  body = self._require_dict(payload)
182
206
  return self._request(profile, "PUT", f"/qingbi/charts/{chart_id}/configs", chart_id=chart_id, json_body=body, risk_operation="update", risk_target="report chart config")
183
207
 
208
+ @tool_cn_name("报表数据")
184
209
  def qingbi_report_get_data(
185
210
  self,
186
211
  *,
@@ -192,6 +217,7 @@ class QingbiReportTools(ToolBase):
192
217
  page_num_y: int | None = None,
193
218
  page_size_y: int | None = None,
194
219
  ) -> JSONObject:
220
+ """执行工具方法逻辑。"""
195
221
  self._require_chart_id(chart_id)
196
222
  params = {
197
223
  "qfUUID": uuid4().hex,
@@ -234,11 +260,15 @@ class QingbiReportTools(ToolBase):
234
260
  json_body=payload or {},
235
261
  )
236
262
 
263
+ @tool_cn_name("删除报表")
237
264
  def qingbi_report_delete(self, *, profile: str, chart_id: str) -> JSONObject:
265
+ """执行工具方法逻辑。"""
238
266
  self._require_chart_id(chart_id)
239
267
  return self._request(profile, "DELETE", f"/qingbi/charts/{chart_id}", chart_id=chart_id, risk_operation="delete", risk_target="report chart")
240
268
 
269
+ @tool_cn_name("报表排序")
241
270
  def qingbi_report_reorder(self, *, profile: str, app_key: str, chart_ids: list[str]) -> JSONObject:
271
+ """执行工具方法逻辑。"""
242
272
  self._require_app_key(app_key)
243
273
  if not isinstance(chart_ids, list) or not chart_ids:
244
274
  raise_tool_error(QingflowApiError.config_error("chart_ids must be a non-empty array"))
@@ -253,7 +283,9 @@ class QingbiReportTools(ToolBase):
253
283
  json_body={"appKey": app_key, "sortChartIdList": chart_ids},
254
284
  )
255
285
 
286
+ @tool_cn_name("报表字段列表")
256
287
  def qingbi_report_list_fields(self, *, profile: str, app_key: str) -> JSONObject:
288
+ """执行工具方法逻辑。"""
257
289
  self._require_app_key(app_key)
258
290
  return self._request(
259
291
  profile,
@@ -265,7 +297,9 @@ class QingbiReportTools(ToolBase):
265
297
  result_transform=_extract_dataset_fields,
266
298
  )
267
299
 
300
+ @tool_cn_name("报表字段选项")
268
301
  def qingbi_report_list_field_options(self, *, profile: str, field_id: str, chart_id: str) -> JSONObject:
302
+ """执行工具方法逻辑。"""
269
303
  if not field_id:
270
304
  raise_tool_error(QingflowApiError.config_error("field_id is required"))
271
305
  path = f"/qingbi/charts/datasource/{chart_id}/question/option" if chart_id else "/qingbi/charts/datasource/question/option"
@@ -288,6 +322,7 @@ class QingbiReportTools(ToolBase):
288
322
  risk_target: str | None = None,
289
323
  **extra: JSONValue,
290
324
  ) -> JSONObject:
325
+ """执行内部辅助逻辑。"""
291
326
  def runner(session_profile, context):
292
327
  qingbi_context = BackendRequestContext(
293
328
  base_url=_qingbi_base_url(context.base_url),
@@ -313,10 +348,12 @@ class QingbiReportTools(ToolBase):
313
348
  return self._run(profile, runner)
314
349
 
315
350
  def _require_app_key(self, app_key: str) -> None:
351
+ """执行内部辅助逻辑。"""
316
352
  if not app_key:
317
353
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
318
354
 
319
355
  def _require_chart_id(self, chart_id: str) -> None:
356
+ """执行内部辅助逻辑。"""
320
357
  if not chart_id:
321
358
  raise_tool_error(QingflowApiError.config_error("chart_id is required"))
322
359