@qingflow-tech/qingflow-cli 1.1.39 → 1.1.41

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 (32) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/pyproject.toml +1 -1
  4. package/src/qingflow_mcp/builder_facade/service.py +8 -8
  5. package/src/qingflow_mcp/server_cloud.py +89 -3
  6. package/src/qingflow_mcp/session_store.py +7 -1
  7. package/src/qingflow_mcp/tools/ai_builder_tools.py +1 -59
  8. package/src/qingflow_mcp/tools/app_tools.py +15 -29
  9. package/src/qingflow_mcp/tools/approval_tools.py +16 -40
  10. package/src/qingflow_mcp/tools/auth_tools.py +18 -13
  11. package/src/qingflow_mcp/tools/base.py +114 -74
  12. package/src/qingflow_mcp/tools/code_block_tools.py +2 -5
  13. package/src/qingflow_mcp/tools/custom_button_tools.py +6 -11
  14. package/src/qingflow_mcp/tools/directory_tools.py +9 -16
  15. package/src/qingflow_mcp/tools/export_tools.py +5 -9
  16. package/src/qingflow_mcp/tools/feedback_tools.py +0 -2
  17. package/src/qingflow_mcp/tools/file_tools.py +3 -5
  18. package/src/qingflow_mcp/tools/import_tools.py +7 -13
  19. package/src/qingflow_mcp/tools/navigation_tools.py +12 -23
  20. package/src/qingflow_mcp/tools/package_tools.py +11 -21
  21. package/src/qingflow_mcp/tools/portal_tools.py +9 -17
  22. package/src/qingflow_mcp/tools/qingbi_report_tools.py +18 -23
  23. package/src/qingflow_mcp/tools/record_tools.py +97 -53
  24. package/src/qingflow_mcp/tools/repository_dev_tools.py +4 -7
  25. package/src/qingflow_mcp/tools/resource_read_tools.py +6 -9
  26. package/src/qingflow_mcp/tools/role_tools.py +5 -9
  27. package/src/qingflow_mcp/tools/solution_tools.py +4 -16
  28. package/src/qingflow_mcp/tools/task_context_tools.py +6 -12
  29. package/src/qingflow_mcp/tools/task_tools.py +12 -29
  30. package/src/qingflow_mcp/tools/view_tools.py +23 -32
  31. package/src/qingflow_mcp/tools/workflow_tools.py +30 -47
  32. package/src/qingflow_mcp/tools/workspace_tools.py +5 -9
@@ -5,7 +5,7 @@ from mcp.server.fastmcp import FastMCP
5
5
  from ..config import DEFAULT_PROFILE
6
6
  from ..errors import QingflowApiError, backend_code_int, is_auth_like_error, raise_tool_error
7
7
  from ..json_types import JSONObject
8
- from .base import ToolBase, tool_cn_name
8
+ from .base import ToolBase
9
9
 
10
10
 
11
11
  class PortalTools(ToolBase):
@@ -52,16 +52,14 @@ class PortalTools(ToolBase):
52
52
  def portal_publish(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> JSONObject:
53
53
  return self.portal_publish(profile=profile, dash_key=dash_key)
54
54
 
55
- @tool_cn_name("门户列表")
56
55
  def portal_list(self, *, profile: str) -> JSONObject:
57
56
  """执行门户相关逻辑。"""
58
57
  def runner(session_profile, context):
59
58
  result = self.backend.request("GET", context, "/dash")
60
59
  return {"profile": profile, "ws_id": session_profile.selected_ws_id, "items": result}
61
60
 
62
- return self._run(profile, runner)
61
+ return self._run(profile, runner, tool_name='门户列表')
63
62
 
64
- @tool_cn_name("门户详情")
65
63
  def portal_get(self, *, profile: str, dash_key: str, being_draft: bool = False) -> JSONObject:
66
64
  """执行门户相关逻辑。"""
67
65
  self._require_dash_key(dash_key)
@@ -70,9 +68,8 @@ class PortalTools(ToolBase):
70
68
  result = self.backend.request("GET", context, f"/dash/{dash_key}", params={"beingDraft": being_draft})
71
69
  return {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result}
72
70
 
73
- return self._run(profile, runner)
71
+ return self._run(profile, runner, tool_name='门户详情')
74
72
 
75
- @tool_cn_name("创建门户")
76
73
  def portal_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
77
74
  """执行门户相关逻辑。"""
78
75
  body = self._require_dict(payload)
@@ -81,9 +78,8 @@ class PortalTools(ToolBase):
81
78
  result = self.backend.request("POST", context, "/dash", json_body=body)
82
79
  return {"profile": profile, "ws_id": session_profile.selected_ws_id, "result": result}
83
80
 
84
- return self._run(profile, runner)
81
+ return self._run(profile, runner, tool_name='创建门户')
85
82
 
86
- @tool_cn_name("门户基础信息")
87
83
  def portal_get_base_info(self, *, profile: str, dash_key: str) -> JSONObject:
88
84
  """执行门户相关逻辑。"""
89
85
  self._require_dash_key(dash_key)
@@ -121,9 +117,8 @@ class PortalTools(ToolBase):
121
117
  "verification": verification,
122
118
  }
123
119
 
124
- return self._run(profile, runner)
120
+ return self._run(profile, runner, tool_name='门户基础信息')
125
121
 
126
- @tool_cn_name("更新门户基础信息")
127
122
  def portal_update_base_info(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
128
123
  """执行门户相关逻辑。"""
129
124
  self._require_dash_key(dash_key)
@@ -137,9 +132,8 @@ class PortalTools(ToolBase):
137
132
  target="portal base settings",
138
133
  )
139
134
 
140
- return self._run(profile, runner)
135
+ return self._run(profile, runner, tool_name='更新门户基础信息')
141
136
 
142
- @tool_cn_name("更新门户配置")
143
137
  def portal_update(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
144
138
  """执行门户相关逻辑。"""
145
139
  self._require_dash_key(dash_key)
@@ -153,9 +147,8 @@ class PortalTools(ToolBase):
153
147
  target="portal configuration",
154
148
  )
155
149
 
156
- return self._run(profile, runner)
150
+ return self._run(profile, runner, tool_name='更新门户配置')
157
151
 
158
- @tool_cn_name("删除门户")
159
152
  def portal_delete(self, *, profile: str, dash_key: str) -> JSONObject:
160
153
  """执行门户相关逻辑。"""
161
154
  self._require_dash_key(dash_key)
@@ -168,9 +161,8 @@ class PortalTools(ToolBase):
168
161
  target="portal configuration",
169
162
  )
170
163
 
171
- return self._run(profile, runner)
164
+ return self._run(profile, runner, tool_name='删除门户')
172
165
 
173
- @tool_cn_name("发布门户")
174
166
  def portal_publish(self, *, profile: str, dash_key: str) -> JSONObject:
175
167
  """执行门户相关逻辑。"""
176
168
  self._require_dash_key(dash_key)
@@ -179,7 +171,7 @@ class PortalTools(ToolBase):
179
171
  result = self.backend.request("POST", context, f"/dash/{dash_key}/publish")
180
172
  return {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result}
181
173
 
182
- return self._run(profile, runner)
174
+ return self._run(profile, runner, tool_name='发布门户')
183
175
 
184
176
  def _require_dash_key(self, dash_key: str) -> None:
185
177
  """执行内部辅助逻辑。"""
@@ -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, backend_code_int, is_auth_like_error, raise_tool_error
11
11
  from ..json_types import JSONObject, JSONValue
12
- from .base import ToolBase, tool_cn_name
12
+ from .base import ToolBase
13
13
 
14
14
 
15
15
  def _qingbi_base_url(base_url: str) -> str:
@@ -147,13 +147,11 @@ class QingbiReportTools(ToolBase):
147
147
  ) -> JSONObject:
148
148
  return self.qingbi_report_list_field_options(profile=profile, field_id=field_id, chart_id=chart_id)
149
149
 
150
- @tool_cn_name("报表列表")
151
150
  def qingbi_report_list(self, *, profile: str, app_key: str) -> JSONObject:
152
151
  """执行工具方法逻辑。"""
153
152
  self._require_app_key(app_key)
154
- return self._request(profile, "GET", f"/qingbi/charts/data/bichart/{app_key}", app_key=app_key, items_key="items")
153
+ return self._request(profile, "GET", f"/qingbi/charts/data/bichart/{app_key}", app_key=app_key, items_key="items", tool_name="报表列表")
155
154
 
156
- @tool_cn_name("报表排序列表")
157
155
  def qingbi_report_list_sorted(
158
156
  self,
159
157
  *,
@@ -179,28 +177,27 @@ class QingbiReportTools(ToolBase):
179
177
  items_key="items",
180
178
  result_transform=_extract_sorted_chart_items,
181
179
  json_body=body,
180
+ tool_name="报表排序列表",
182
181
  )
183
182
 
184
- @tool_cn_name("创建报表")
185
183
  def qingbi_report_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
186
184
  """执行工具方法逻辑。"""
187
185
  body = self._require_dict(payload)
188
- return self._request(profile, "POST", "/qingbi/charts", json_body=body)
186
+ return self._request(profile, "POST", "/qingbi/charts", json_body=body, tool_name="创建报表")
189
187
 
190
- @tool_cn_name("报表基础信息")
191
188
  def qingbi_report_get_base(self, *, profile: str, chart_id: str) -> JSONObject:
192
189
  """执行工具方法逻辑。"""
193
190
  self._require_chart_id(chart_id)
194
191
  source_error: QingflowApiError | None = None
195
192
  try:
196
- return self._request(profile, "GET", f"/qingbi/charts/qflow/baseinfo/{chart_id}", chart_id=chart_id)
193
+ return self._request(profile, "GET", f"/qingbi/charts/qflow/baseinfo/{chart_id}", chart_id=chart_id, tool_name="报表基础信息")
197
194
  except (QingflowApiError, RuntimeError) as raw_error:
198
195
  error = _coerce_tool_error(raw_error)
199
196
  if error is None or not _should_retry_qflow_base(error):
200
197
  raise
201
198
  source_error = error
202
199
  try:
203
- fallback = self._request(profile, "GET", f"/qingbi/charts/baseinfo/{chart_id}", chart_id=chart_id)
200
+ fallback = self._request(profile, "GET", f"/qingbi/charts/baseinfo/{chart_id}", chart_id=chart_id, tool_name="报表基础信息")
204
201
  except (QingflowApiError, RuntimeError):
205
202
  raise
206
203
  if not _has_chart_base_identity(fallback.get("result"), chart_id=chart_id):
@@ -223,20 +220,18 @@ class QingbiReportTools(ToolBase):
223
220
  )
224
221
  return fallback
225
222
 
226
- @tool_cn_name("更新报表基础信息")
227
223
  def qingbi_report_update_base(self, *, profile: str, chart_id: str, payload: JSONObject) -> JSONObject:
228
224
  """执行工具方法逻辑。"""
229
225
  self._require_chart_id(chart_id)
230
226
  body = self._require_dict(payload)
231
- 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")
227
+ 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", tool_name="更新报表基础信息")
232
228
 
233
- @tool_cn_name("报表配置")
234
229
  def qingbi_report_get_config(self, *, profile: str, chart_id: str) -> JSONObject:
235
230
  """执行工具方法逻辑。"""
236
231
  self._require_chart_id(chart_id)
237
232
  original_error: QingflowApiError | RuntimeError | None = None
238
233
  try:
239
- return self._request(profile, "GET", f"/qingbi/charts/{chart_id}/configs", chart_id=chart_id)
234
+ return self._request(profile, "GET", f"/qingbi/charts/{chart_id}/configs", chart_id=chart_id, tool_name="报表配置")
240
235
  except (QingflowApiError, RuntimeError) as raw_error:
241
236
  original_error = raw_error
242
237
  error = _coerce_tool_error(raw_error)
@@ -274,14 +269,12 @@ class QingbiReportTools(ToolBase):
274
269
  raise original_error
275
270
  raise_tool_error(QingflowApiError.config_error("chart config fallback did not return config"))
276
271
 
277
- @tool_cn_name("更新报表配置")
278
272
  def qingbi_report_update_config(self, *, profile: str, chart_id: str, payload: JSONObject) -> JSONObject:
279
273
  """执行工具方法逻辑。"""
280
274
  self._require_chart_id(chart_id)
281
275
  body = self._require_dict(payload)
282
- 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")
276
+ 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", tool_name="更新报表配置")
283
277
 
284
- @tool_cn_name("报表数据")
285
278
  def qingbi_report_get_data(
286
279
  self,
287
280
  *,
@@ -315,6 +308,7 @@ class QingbiReportTools(ToolBase):
315
308
  chart_id=chart_id,
316
309
  params=params,
317
310
  json_body=payload,
311
+ tool_name="报表数据",
318
312
  )
319
313
  return self._request(
320
314
  profile,
@@ -322,6 +316,7 @@ class QingbiReportTools(ToolBase):
322
316
  f"/qingbi/charts/data/qflow/{chart_id}",
323
317
  chart_id=chart_id,
324
318
  params=params,
319
+ tool_name="报表数据",
325
320
  )
326
321
  except (QingflowApiError, RuntimeError) as raw_error:
327
322
  error = _coerce_tool_error(raw_error)
@@ -349,15 +344,14 @@ class QingbiReportTools(ToolBase):
349
344
  "qflow_data_route_loaded": False,
350
345
  "asos_data_route_loaded": True,
351
346
  },
347
+ tool_name="报表数据",
352
348
  )
353
349
 
354
- @tool_cn_name("删除报表")
355
350
  def qingbi_report_delete(self, *, profile: str, chart_id: str) -> JSONObject:
356
351
  """执行工具方法逻辑。"""
357
352
  self._require_chart_id(chart_id)
358
- return self._request(profile, "DELETE", f"/qingbi/charts/{chart_id}", chart_id=chart_id, risk_operation="delete", risk_target="report chart")
353
+ return self._request(profile, "DELETE", f"/qingbi/charts/{chart_id}", chart_id=chart_id, risk_operation="delete", risk_target="report chart", tool_name="删除报表")
359
354
 
360
- @tool_cn_name("报表排序")
361
355
  def qingbi_report_reorder(self, *, profile: str, app_key: str, chart_ids: list[str]) -> JSONObject:
362
356
  """执行工具方法逻辑。"""
363
357
  self._require_app_key(app_key)
@@ -372,9 +366,9 @@ class QingbiReportTools(ToolBase):
372
366
  app_key=app_key,
373
367
  chart_ids=chart_ids,
374
368
  json_body={"appKey": app_key, "sortChartIdList": chart_ids},
369
+ tool_name="报表排序",
375
370
  )
376
371
 
377
- @tool_cn_name("报表字段列表")
378
372
  def qingbi_report_list_fields(self, *, profile: str, app_key: str) -> JSONObject:
379
373
  """执行工具方法逻辑。"""
380
374
  self._require_app_key(app_key)
@@ -386,9 +380,9 @@ class QingbiReportTools(ToolBase):
386
380
  params={"dataSourceId": app_key, "dataSourceType": "qingflow"},
387
381
  items_key="items",
388
382
  result_transform=_extract_dataset_fields,
383
+ tool_name="报表字段列表",
389
384
  )
390
385
 
391
- @tool_cn_name("报表字段选项")
392
386
  def qingbi_report_list_field_options(self, *, profile: str, field_id: str, chart_id: str) -> JSONObject:
393
387
  """执行工具方法逻辑。"""
394
388
  if not field_id:
@@ -397,7 +391,7 @@ class QingbiReportTools(ToolBase):
397
391
  params = {"fieldId": field_id}
398
392
  if chart_id:
399
393
  self._require_chart_id(chart_id)
400
- return self._request(profile, "GET", path, chart_id=chart_id or None, field_id=field_id, params=params, items_key="items")
394
+ return self._request(profile, "GET", path, chart_id=chart_id or None, field_id=field_id, params=params, items_key="items", tool_name="报表字段选项")
401
395
 
402
396
  def _request(
403
397
  self,
@@ -411,6 +405,7 @@ class QingbiReportTools(ToolBase):
411
405
  result_transform: object | None = None,
412
406
  risk_operation: str | None = None,
413
407
  risk_target: str | None = None,
408
+ tool_name: str,
414
409
  **extra: JSONValue,
415
410
  ) -> JSONObject:
416
411
  """执行内部辅助逻辑。"""
@@ -436,7 +431,7 @@ class QingbiReportTools(ToolBase):
436
431
  return self._attach_human_review_notice(payload, operation=risk_operation, target=risk_target)
437
432
  return payload
438
433
 
439
- return self._run(profile, runner)
434
+ return self._run(profile, runner, tool_name=tool_name)
440
435
 
441
436
  def _require_app_key(self, app_key: str) -> None:
442
437
  """执行内部辅助逻辑。"""