@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.
- package/README.md +2 -2
- package/docs/local-agent-install.md +70 -11
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/builder_facade/service.py +47 -21
- package/src/qingflow_mcp/cli/commands/auth.py +14 -43
- package/src/qingflow_mcp/cli/commands/task.py +4 -1
- package/src/qingflow_mcp/cli/commands/workspace.py +0 -8
- package/src/qingflow_mcp/cli/formatters.py +0 -21
- package/src/qingflow_mcp/config.py +39 -0
- package/src/qingflow_mcp/errors.py +2 -2
- package/src/qingflow_mcp/public_surface.py +2 -6
- package/src/qingflow_mcp/response_trim.py +1 -8
- package/src/qingflow_mcp/server.py +1 -1
- package/src/qingflow_mcp/server_app_builder.py +4 -28
- package/src/qingflow_mcp/server_app_user.py +4 -28
- package/src/qingflow_mcp/session_store.py +31 -5
- package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
- package/src/qingflow_mcp/tools/app_tools.py +51 -1
- package/src/qingflow_mcp/tools/approval_tools.py +82 -1
- package/src/qingflow_mcp/tools/auth_tools.py +258 -288
- package/src/qingflow_mcp/tools/base.py +204 -4
- package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
- package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
- package/src/qingflow_mcp/tools/directory_tools.py +28 -1
- package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
- package/src/qingflow_mcp/tools/file_tools.py +25 -1
- package/src/qingflow_mcp/tools/import_tools.py +40 -1
- package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
- package/src/qingflow_mcp/tools/package_tools.py +37 -1
- package/src/qingflow_mcp/tools/portal_tools.py +28 -1
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
- package/src/qingflow_mcp/tools/record_tools.py +255 -2
- package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
- package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
- package/src/qingflow_mcp/tools/role_tools.py +19 -1
- package/src/qingflow_mcp/tools/solution_tools.py +56 -1
- package/src/qingflow_mcp/tools/task_context_tools.py +205 -6
- package/src/qingflow_mcp/tools/task_tools.py +49 -3
- package/src/qingflow_mcp/tools/view_tools.py +56 -1
- package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
- 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
|
|