@josephyan/qingflow-cli 0.2.0-beta.55 → 0.2.0-beta.57

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.
@@ -4,12 +4,9 @@ from mcp.server.fastmcp import FastMCP
4
4
 
5
5
  from .backend_client import BackendClient
6
6
  from .config import DEFAULT_PROFILE
7
+ from .ops.base import mcp_result_from_operation
8
+ from .ops.context import build_operations_runtime
7
9
  from .session_store import SessionStore
8
- from .tools.ai_builder_tools import AiBuilderTools
9
- from .tools.auth_tools import AuthTools
10
- from .tools.feedback_tools import FeedbackTools
11
- from .tools.file_tools import FileTools
12
- from .tools.workspace_tools import WorkspaceTools
13
10
 
14
11
 
15
12
  def build_builder_server() -> FastMCP:
@@ -33,11 +30,7 @@ def build_builder_server() -> FastMCP:
33
30
  )
34
31
  sessions = SessionStore()
35
32
  backend = BackendClient()
36
- auth = AuthTools(sessions, backend)
37
- workspace = WorkspaceTools(sessions, backend)
38
- files = FileTools(sessions, backend)
39
- ai_builder = AiBuilderTools(sessions, backend)
40
- feedback = FeedbackTools(backend, mcp_side="App Builder MCP")
33
+ runtime = build_operations_runtime(sessions=sessions, backend=backend, feedback_mcp_side="App Builder MCP")
41
34
 
42
35
  @server.tool()
43
36
  def auth_login(
@@ -48,13 +41,15 @@ def build_builder_server() -> FastMCP:
48
41
  password: str = "",
49
42
  persist: bool = True,
50
43
  ) -> dict:
51
- return auth.auth_login(
52
- profile=profile,
53
- base_url=base_url,
54
- qf_version=qf_version,
55
- email=email,
56
- password=password,
57
- persist=persist,
44
+ return mcp_result_from_operation(
45
+ runtime.auth.login(
46
+ profile=profile,
47
+ base_url=base_url,
48
+ qf_version=qf_version,
49
+ email=email,
50
+ password=password,
51
+ persist=persist,
52
+ )
58
53
  )
59
54
 
60
55
  @server.tool()
@@ -66,22 +61,24 @@ def build_builder_server() -> FastMCP:
66
61
  ws_id: int | None = None,
67
62
  persist: bool = False,
68
63
  ) -> dict:
69
- return auth.auth_use_token(
70
- profile=profile,
71
- base_url=base_url,
72
- qf_version=qf_version,
73
- token=token,
74
- ws_id=ws_id,
75
- persist=persist,
64
+ return mcp_result_from_operation(
65
+ runtime.auth.use_token(
66
+ profile=profile,
67
+ base_url=base_url,
68
+ qf_version=qf_version,
69
+ token=token,
70
+ ws_id=ws_id,
71
+ persist=persist,
72
+ )
76
73
  )
77
74
 
78
75
  @server.tool()
79
76
  def auth_whoami(profile: str = DEFAULT_PROFILE) -> dict:
80
- return auth.auth_whoami(profile=profile)
77
+ return mcp_result_from_operation(runtime.auth.me(profile=profile))
81
78
 
82
79
  @server.tool()
83
80
  def auth_logout(profile: str = DEFAULT_PROFILE, forget_persisted: bool = False) -> dict:
84
- return auth.auth_logout(profile=profile, forget_persisted=forget_persisted)
81
+ return mcp_result_from_operation(runtime.auth.logout(profile=profile, forget_persisted=forget_persisted))
85
82
 
86
83
  @server.tool()
87
84
  def workspace_list(
@@ -90,16 +87,18 @@ def build_builder_server() -> FastMCP:
90
87
  page_size: int = 20,
91
88
  include_external: bool = False,
92
89
  ) -> dict:
93
- return workspace.workspace_list(
94
- profile=profile,
95
- page_num=page_num,
96
- page_size=page_size,
97
- include_external=include_external,
90
+ return mcp_result_from_operation(
91
+ runtime.workspace.list(
92
+ profile=profile,
93
+ page_num=page_num,
94
+ page_size=page_size,
95
+ include_external=include_external,
96
+ )
98
97
  )
99
98
 
100
99
  @server.tool()
101
100
  def workspace_select(profile: str = DEFAULT_PROFILE, ws_id: int = 0) -> dict:
102
- return workspace.workspace_select(profile=profile, ws_id=ws_id)
101
+ return mcp_result_from_operation(runtime.workspace.use(profile=profile, ws_id=ws_id))
103
102
 
104
103
  @server.tool()
105
104
  def file_upload_local(
@@ -112,34 +111,64 @@ def build_builder_server() -> FastMCP:
112
111
  path_id: int | None = None,
113
112
  file_related_url: str | None = None,
114
113
  ) -> dict:
115
- return files.file_upload_local(
116
- profile=profile,
117
- upload_kind=upload_kind,
118
- file_path=file_path,
119
- upload_mark=upload_mark,
120
- content_type=content_type,
121
- bucket_type=bucket_type,
122
- path_id=path_id,
123
- file_related_url=file_related_url,
114
+ return mcp_result_from_operation(
115
+ runtime.files.upload_local(
116
+ profile=profile,
117
+ upload_kind=upload_kind,
118
+ file_path=file_path,
119
+ upload_mark=upload_mark,
120
+ content_type=content_type,
121
+ bucket_type=bucket_type,
122
+ path_id=path_id,
123
+ file_related_url=file_related_url,
124
+ )
124
125
  )
125
126
 
126
- feedback.register(server)
127
+ @server.tool()
128
+ def feedback_submit(
129
+ category: str = "",
130
+ title: str = "",
131
+ description: str = "",
132
+ expected_behavior: str | None = None,
133
+ actual_behavior: str | None = None,
134
+ impact_scope: str | None = None,
135
+ tool_name: str | None = None,
136
+ app_key: str | None = None,
137
+ record_id: str | int | None = None,
138
+ workflow_node_id: str | int | None = None,
139
+ note: str | None = None,
140
+ ) -> dict:
141
+ return mcp_result_from_operation(
142
+ runtime.feedback.submit(
143
+ category=category,
144
+ title=title,
145
+ description=description,
146
+ expected_behavior=expected_behavior,
147
+ actual_behavior=actual_behavior,
148
+ impact_scope=impact_scope,
149
+ tool_name=tool_name,
150
+ app_key=app_key,
151
+ record_id=record_id,
152
+ workflow_node_id=workflow_node_id,
153
+ note=note,
154
+ )
155
+ )
127
156
 
128
157
  @server.tool()
129
158
  def package_list(profile: str = DEFAULT_PROFILE, trial_status: str = "all") -> dict:
130
- return ai_builder.package_list(profile=profile, trial_status=trial_status)
159
+ return mcp_result_from_operation(runtime.builder.package_list(profile=profile, trial_status=trial_status))
131
160
 
132
161
  @server.tool()
133
162
  def package_resolve(profile: str = DEFAULT_PROFILE, package_name: str = "") -> dict:
134
- return ai_builder.package_resolve(profile=profile, package_name=package_name)
163
+ return mcp_result_from_operation(runtime.builder.package_resolve(profile=profile, package_name=package_name))
135
164
 
136
165
  @server.tool()
137
166
  def builder_tool_contract(tool_name: str = "") -> dict:
138
- return ai_builder.builder_tool_contract(tool_name=tool_name)
167
+ return mcp_result_from_operation(runtime.builder.builder_tool_contract(tool_name=tool_name))
139
168
 
140
169
  @server.tool()
141
170
  def package_create(profile: str = DEFAULT_PROFILE, package_name: str = "") -> dict:
142
- return ai_builder.package_create(profile=profile, package_name=package_name)
171
+ return mcp_result_from_operation(runtime.builder.package_create(profile=profile, package_name=package_name))
143
172
 
144
173
  @server.tool()
145
174
  def member_search(
@@ -149,12 +178,14 @@ def build_builder_server() -> FastMCP:
149
178
  page_size: int = 20,
150
179
  contain_disable: bool = False,
151
180
  ) -> dict:
152
- return ai_builder.member_search(
153
- profile=profile,
154
- query=query,
155
- page_num=page_num,
156
- page_size=page_size,
157
- contain_disable=contain_disable,
181
+ return mcp_result_from_operation(
182
+ runtime.builder.member_search(
183
+ profile=profile,
184
+ query=query,
185
+ page_num=page_num,
186
+ page_size=page_size,
187
+ contain_disable=contain_disable,
188
+ )
158
189
  )
159
190
 
160
191
  @server.tool()
@@ -164,7 +195,9 @@ def build_builder_server() -> FastMCP:
164
195
  page_num: int = 1,
165
196
  page_size: int = 20,
166
197
  ) -> dict:
167
- return ai_builder.role_search(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
198
+ return mcp_result_from_operation(
199
+ runtime.builder.role_search(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
200
+ )
168
201
 
169
202
  @server.tool()
170
203
  def role_create(
@@ -175,13 +208,15 @@ def build_builder_server() -> FastMCP:
175
208
  member_names: list[str] | None = None,
176
209
  role_icon: str = "ex-user-outlined",
177
210
  ) -> dict:
178
- return ai_builder.role_create(
179
- profile=profile,
180
- role_name=role_name,
181
- member_uids=member_uids or [],
182
- member_emails=member_emails or [],
183
- member_names=member_names or [],
184
- role_icon=role_icon,
211
+ return mcp_result_from_operation(
212
+ runtime.builder.role_create(
213
+ profile=profile,
214
+ role_name=role_name,
215
+ member_uids=member_uids or [],
216
+ member_emails=member_emails or [],
217
+ member_names=member_names or [],
218
+ role_icon=role_icon,
219
+ )
185
220
  )
186
221
 
187
222
  @server.tool()
@@ -191,7 +226,9 @@ def build_builder_server() -> FastMCP:
191
226
  app_key: str = "",
192
227
  app_title: str = "",
193
228
  ) -> dict:
194
- return ai_builder.package_attach_app(profile=profile, tag_id=tag_id, app_key=app_key, app_title=app_title)
229
+ return mcp_result_from_operation(
230
+ runtime.builder.package_attach_app(profile=profile, tag_id=tag_id, app_key=app_key, app_title=app_title)
231
+ )
195
232
 
196
233
  @server.tool()
197
234
  def app_release_edit_lock_if_mine(
@@ -200,11 +237,13 @@ def build_builder_server() -> FastMCP:
200
237
  lock_owner_email: str = "",
201
238
  lock_owner_name: str = "",
202
239
  ) -> dict:
203
- return ai_builder.app_release_edit_lock_if_mine(
204
- profile=profile,
205
- app_key=app_key,
206
- lock_owner_email=lock_owner_email,
207
- lock_owner_name=lock_owner_name,
240
+ return mcp_result_from_operation(
241
+ runtime.builder.release_edit_lock_if_mine(
242
+ profile=profile,
243
+ app_key=app_key,
244
+ lock_owner_email=lock_owner_email,
245
+ lock_owner_name=lock_owner_name,
246
+ )
208
247
  )
209
248
 
210
249
  @server.tool()
@@ -214,31 +253,38 @@ def build_builder_server() -> FastMCP:
214
253
  app_name: str = "",
215
254
  package_tag_id: int | None = None,
216
255
  ) -> dict:
217
- return ai_builder.app_resolve(profile=profile, app_key=app_key, app_name=app_name, package_tag_id=package_tag_id)
256
+ return mcp_result_from_operation(
257
+ runtime.builder.app_resolve(
258
+ profile=profile,
259
+ app_key=app_key,
260
+ app_name=app_name,
261
+ package_tag_id=package_tag_id,
262
+ )
263
+ )
218
264
 
219
265
  @server.tool()
220
266
  def app_read_summary(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
221
- return ai_builder.app_read_summary(profile=profile, app_key=app_key)
267
+ return mcp_result_from_operation(runtime.builder.app_show(profile=profile, app_key=app_key))
222
268
 
223
269
  @server.tool()
224
270
  def app_read_fields(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
225
- return ai_builder.app_read_fields(profile=profile, app_key=app_key)
271
+ return mcp_result_from_operation(runtime.builder.fields_show(profile=profile, app_key=app_key))
226
272
 
227
273
  @server.tool()
228
274
  def app_read_layout_summary(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
229
- return ai_builder.app_read_layout_summary(profile=profile, app_key=app_key)
275
+ return mcp_result_from_operation(runtime.builder.layout_show(profile=profile, app_key=app_key))
230
276
 
231
277
  @server.tool()
232
278
  def app_read_views_summary(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
233
- return ai_builder.app_read_views_summary(profile=profile, app_key=app_key)
279
+ return mcp_result_from_operation(runtime.builder.views_show(profile=profile, app_key=app_key))
234
280
 
235
281
  @server.tool()
236
282
  def app_read_flow_summary(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
237
- return ai_builder.app_read_flow_summary(profile=profile, app_key=app_key)
283
+ return mcp_result_from_operation(runtime.builder.flow_show(profile=profile, app_key=app_key))
238
284
 
239
285
  @server.tool()
240
286
  def app_read_charts_summary(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
241
- return ai_builder.app_read_charts_summary(profile=profile, app_key=app_key)
287
+ return mcp_result_from_operation(runtime.builder.charts_show(profile=profile, app_key=app_key))
242
288
 
243
289
  @server.tool()
244
290
  def portal_read_summary(
@@ -246,7 +292,9 @@ def build_builder_server() -> FastMCP:
246
292
  dash_key: str = "",
247
293
  being_draft: bool = True,
248
294
  ) -> dict:
249
- return ai_builder.portal_read_summary(profile=profile, dash_key=dash_key, being_draft=being_draft)
295
+ return mcp_result_from_operation(
296
+ runtime.builder.portal_show(profile=profile, dash_key=dash_key, being_draft=being_draft)
297
+ )
250
298
 
251
299
  @server.tool()
252
300
  def app_schema_apply(
@@ -261,17 +309,19 @@ def build_builder_server() -> FastMCP:
261
309
  update_fields: list[dict] | None = None,
262
310
  remove_fields: list[dict] | None = None,
263
311
  ) -> dict:
264
- return ai_builder.app_schema_apply(
265
- profile=profile,
266
- app_key=app_key,
267
- package_tag_id=package_tag_id,
268
- app_name=app_name,
269
- app_title=app_title,
270
- create_if_missing=create_if_missing,
271
- publish=publish,
272
- add_fields=add_fields or [],
273
- update_fields=update_fields or [],
274
- remove_fields=remove_fields or [],
312
+ return mcp_result_from_operation(
313
+ runtime.builder.fields_apply(
314
+ profile=profile,
315
+ app_key=app_key,
316
+ package_tag_id=package_tag_id,
317
+ app_name=app_name,
318
+ app_title=app_title,
319
+ create_if_missing=create_if_missing,
320
+ publish=publish,
321
+ add_fields=add_fields or [],
322
+ update_fields=update_fields or [],
323
+ remove_fields=remove_fields or [],
324
+ )
275
325
  )
276
326
 
277
327
  @server.tool()
@@ -282,7 +332,15 @@ def build_builder_server() -> FastMCP:
282
332
  publish: bool = True,
283
333
  sections: list[dict] | None = None,
284
334
  ) -> dict:
285
- return ai_builder.app_layout_apply(profile=profile, app_key=app_key, mode=mode, publish=publish, sections=sections or [])
335
+ return mcp_result_from_operation(
336
+ runtime.builder.layout_apply(
337
+ profile=profile,
338
+ app_key=app_key,
339
+ mode=mode,
340
+ publish=publish,
341
+ sections=sections or [],
342
+ )
343
+ )
286
344
 
287
345
  @server.tool()
288
346
  def app_flow_apply(
@@ -293,13 +351,15 @@ def build_builder_server() -> FastMCP:
293
351
  nodes: list[dict] | None = None,
294
352
  transitions: list[dict] | None = None,
295
353
  ) -> dict:
296
- return ai_builder.app_flow_apply(
297
- profile=profile,
298
- app_key=app_key,
299
- mode=mode,
300
- publish=publish,
301
- nodes=nodes or [],
302
- transitions=transitions or [],
354
+ return mcp_result_from_operation(
355
+ runtime.builder.flow_apply(
356
+ profile=profile,
357
+ app_key=app_key,
358
+ mode=mode,
359
+ publish=publish,
360
+ nodes=nodes or [],
361
+ transitions=transitions or [],
362
+ )
303
363
  )
304
364
 
305
365
  @server.tool()
@@ -310,12 +370,14 @@ def build_builder_server() -> FastMCP:
310
370
  upsert_views: list[dict] | None = None,
311
371
  remove_views: list[str] | None = None,
312
372
  ) -> dict:
313
- return ai_builder.app_views_apply(
314
- profile=profile,
315
- app_key=app_key,
316
- publish=publish,
317
- upsert_views=upsert_views or [],
318
- remove_views=remove_views or [],
373
+ return mcp_result_from_operation(
374
+ runtime.builder.views_apply(
375
+ profile=profile,
376
+ app_key=app_key,
377
+ publish=publish,
378
+ upsert_views=upsert_views or [],
379
+ remove_views=remove_views or [],
380
+ )
319
381
  )
320
382
 
321
383
  @server.tool()
@@ -326,12 +388,14 @@ def build_builder_server() -> FastMCP:
326
388
  remove_chart_ids: list[str] | None = None,
327
389
  reorder_chart_ids: list[str] | None = None,
328
390
  ) -> dict:
329
- return ai_builder.app_charts_apply(
330
- profile=profile,
331
- app_key=app_key,
332
- upsert_charts=upsert_charts or [],
333
- remove_chart_ids=remove_chart_ids or [],
334
- reorder_chart_ids=reorder_chart_ids or [],
391
+ return mcp_result_from_operation(
392
+ runtime.builder.charts_apply(
393
+ profile=profile,
394
+ app_key=app_key,
395
+ upsert_charts=upsert_charts or [],
396
+ remove_chart_ids=remove_chart_ids or [],
397
+ reorder_chart_ids=reorder_chart_ids or [],
398
+ )
335
399
  )
336
400
 
337
401
  @server.tool()
@@ -349,19 +413,21 @@ def build_builder_server() -> FastMCP:
349
413
  dash_global_config: dict | None = None,
350
414
  config: dict | None = None,
351
415
  ) -> dict:
352
- return ai_builder.portal_apply(
353
- profile=profile,
354
- dash_key=dash_key,
355
- dash_name=dash_name,
356
- package_tag_id=package_tag_id,
357
- publish=publish,
358
- sections=sections or [],
359
- auth=auth,
360
- icon=icon,
361
- color=color,
362
- hide_copyright=hide_copyright,
363
- dash_global_config=dash_global_config,
364
- config=config or {},
416
+ return mcp_result_from_operation(
417
+ runtime.builder.portal_apply(
418
+ profile=profile,
419
+ dash_key=dash_key,
420
+ dash_name=dash_name,
421
+ package_tag_id=package_tag_id,
422
+ publish=publish,
423
+ sections=sections or [],
424
+ auth=auth,
425
+ icon=icon,
426
+ color=color,
427
+ hide_copyright=hide_copyright,
428
+ dash_global_config=dash_global_config,
429
+ config=config or {},
430
+ )
365
431
  )
366
432
 
367
433
  @server.tool()
@@ -370,10 +436,12 @@ def build_builder_server() -> FastMCP:
370
436
  app_key: str = "",
371
437
  expected_package_tag_id: int | None = None,
372
438
  ) -> dict:
373
- return ai_builder.app_publish_verify(
374
- profile=profile,
375
- app_key=app_key,
376
- expected_package_tag_id=expected_package_tag_id,
439
+ return mcp_result_from_operation(
440
+ runtime.builder.publish_verify(
441
+ profile=profile,
442
+ app_key=app_key,
443
+ expected_package_tag_id=expected_package_tag_id,
444
+ )
377
445
  )
378
446
 
379
447
  return server