@josephyan/qingflow-cli 0.2.0-beta.58 → 0.2.0-beta.60

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 (35) hide show
  1. package/README.md +3 -2
  2. package/docs/local-agent-install.md +9 -0
  3. package/npm/bin/qingflow.mjs +1 -1
  4. package/npm/lib/runtime.mjs +156 -21
  5. package/package.json +1 -1
  6. package/pyproject.toml +1 -1
  7. package/src/qingflow_mcp/builder_facade/service.py +670 -191
  8. package/src/qingflow_mcp/cli/commands/app.py +16 -16
  9. package/src/qingflow_mcp/cli/commands/auth.py +19 -16
  10. package/src/qingflow_mcp/cli/commands/builder.py +124 -162
  11. package/src/qingflow_mcp/cli/commands/common.py +21 -95
  12. package/src/qingflow_mcp/cli/commands/imports.py +42 -34
  13. package/src/qingflow_mcp/cli/commands/record.py +131 -133
  14. package/src/qingflow_mcp/cli/commands/task.py +43 -44
  15. package/src/qingflow_mcp/cli/commands/workspace.py +10 -10
  16. package/src/qingflow_mcp/cli/context.py +35 -32
  17. package/src/qingflow_mcp/cli/formatters.py +124 -121
  18. package/src/qingflow_mcp/cli/main.py +52 -17
  19. package/src/qingflow_mcp/server_app_builder.py +122 -190
  20. package/src/qingflow_mcp/server_app_user.py +63 -662
  21. package/src/qingflow_mcp/solution/executor.py +63 -4
  22. package/src/qingflow_mcp/tools/solution_tools.py +115 -3
  23. package/src/qingflow_mcp/ops/__init__.py +0 -3
  24. package/src/qingflow_mcp/ops/apps.py +0 -64
  25. package/src/qingflow_mcp/ops/auth.py +0 -121
  26. package/src/qingflow_mcp/ops/base.py +0 -290
  27. package/src/qingflow_mcp/ops/builder.py +0 -357
  28. package/src/qingflow_mcp/ops/context.py +0 -120
  29. package/src/qingflow_mcp/ops/directory.py +0 -171
  30. package/src/qingflow_mcp/ops/feedback.py +0 -49
  31. package/src/qingflow_mcp/ops/files.py +0 -78
  32. package/src/qingflow_mcp/ops/imports.py +0 -140
  33. package/src/qingflow_mcp/ops/records.py +0 -415
  34. package/src/qingflow_mcp/ops/tasks.py +0 -171
  35. package/src/qingflow_mcp/ops/workspace.py +0 -76
@@ -1,16 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import date
4
- from typing import Any
5
4
 
6
5
  from mcp.server.fastmcp import FastMCP
7
6
 
8
7
  from .backend_client import BackendClient
9
8
  from .config import DEFAULT_PROFILE
10
- from .ops.base import mcp_result_from_operation
11
- from .ops.context import build_operations_runtime
12
9
  from .session_store import SessionStore
10
+ from .tools.app_tools import AppTools
11
+ from .tools.auth_tools import AuthTools
12
+ from .tools.code_block_tools import CodeBlockTools
13
+ from .tools.directory_tools import DirectoryTools
14
+ from .tools.feedback_tools import FeedbackTools
15
+ from .tools.file_tools import FileTools
16
+ from .tools.import_tools import ImportTools
13
17
  from .tools.task_context_tools import TaskContextTools
18
+ from .tools.workspace_tools import WorkspaceTools
14
19
 
15
20
 
16
21
  def build_user_server() -> FastMCP:
@@ -164,11 +169,12 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
164
169
  )
165
170
  sessions = SessionStore()
166
171
  backend = BackendClient()
167
- runtime = build_operations_runtime(sessions=sessions, backend=backend, feedback_mcp_side="App User MCP")
168
- high_risk_desc = TaskContextTools(sessions, backend)._high_risk_tool_description(
169
- operation="execute",
170
- target="workflow task action",
171
- )
172
+ auth = AuthTools(sessions, backend)
173
+ apps = AppTools(sessions, backend)
174
+ workspace = WorkspaceTools(sessions, backend)
175
+ files = FileTools(sessions, backend)
176
+ imports = ImportTools(sessions, backend)
177
+ feedback = FeedbackTools(backend, mcp_side="App User MCP")
172
178
 
173
179
  @server.tool()
174
180
  def auth_login(
@@ -179,15 +185,13 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
179
185
  password: str = "",
180
186
  persist: bool = True,
181
187
  ) -> dict:
182
- return mcp_result_from_operation(
183
- runtime.auth.login(
184
- profile=profile,
185
- base_url=base_url,
186
- qf_version=qf_version,
187
- email=email,
188
- password=password,
189
- persist=persist,
190
- )
188
+ return auth.auth_login(
189
+ profile=profile,
190
+ base_url=base_url,
191
+ qf_version=qf_version,
192
+ email=email,
193
+ password=password,
194
+ persist=persist,
191
195
  )
192
196
 
193
197
  @server.tool()
@@ -199,24 +203,22 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
199
203
  ws_id: int | None = None,
200
204
  persist: bool = False,
201
205
  ) -> dict:
202
- return mcp_result_from_operation(
203
- runtime.auth.use_token(
204
- profile=profile,
205
- base_url=base_url,
206
- qf_version=qf_version,
207
- token=token,
208
- ws_id=ws_id,
209
- persist=persist,
210
- )
206
+ return auth.auth_use_token(
207
+ profile=profile,
208
+ base_url=base_url,
209
+ qf_version=qf_version,
210
+ token=token,
211
+ ws_id=ws_id,
212
+ persist=persist,
211
213
  )
212
214
 
213
215
  @server.tool()
214
216
  def auth_whoami(profile: str = DEFAULT_PROFILE) -> dict:
215
- return mcp_result_from_operation(runtime.auth.me(profile=profile))
217
+ return auth.auth_whoami(profile=profile)
216
218
 
217
219
  @server.tool()
218
220
  def auth_logout(profile: str = DEFAULT_PROFILE, forget_persisted: bool = False) -> dict:
219
- return mcp_result_from_operation(runtime.auth.logout(profile=profile, forget_persisted=forget_persisted))
221
+ return auth.auth_logout(profile=profile, forget_persisted=forget_persisted)
220
222
 
221
223
  @server.tool()
222
224
  def workspace_list(
@@ -225,32 +227,28 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
225
227
  page_size: int = 20,
226
228
  include_external: bool = False,
227
229
  ) -> dict:
228
- return mcp_result_from_operation(
229
- runtime.workspace.list(
230
- profile=profile,
231
- page_num=page_num,
232
- page_size=page_size,
233
- include_external=include_external,
234
- )
230
+ return workspace.workspace_list(
231
+ profile=profile,
232
+ page_num=page_num,
233
+ page_size=page_size,
234
+ include_external=include_external,
235
235
  )
236
236
 
237
237
  @server.tool()
238
238
  def workspace_select(profile: str = DEFAULT_PROFILE, ws_id: int = 0) -> dict:
239
- return mcp_result_from_operation(runtime.workspace.use(profile=profile, ws_id=ws_id))
239
+ return workspace.workspace_select(profile=profile, ws_id=ws_id)
240
240
 
241
241
  @server.tool()
242
242
  def app_list(profile: str = DEFAULT_PROFILE) -> dict:
243
- return mcp_result_from_operation(runtime.apps.list(profile=profile))
243
+ return apps.app_list(profile=profile)
244
244
 
245
245
  @server.tool()
246
246
  def app_search(profile: str = DEFAULT_PROFILE, keyword: str = "", page_num: int = 1, page_size: int = 50) -> dict:
247
- return mcp_result_from_operation(
248
- runtime.apps.find(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
249
- )
247
+ return apps.app_search(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
250
248
 
251
249
  @server.tool()
252
250
  def app_get(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
253
- return mcp_result_from_operation(runtime.apps.show(profile=profile, app_key=app_key))
251
+ return apps.app_get(profile=profile, app_key=app_key)
254
252
 
255
253
  @server.tool()
256
254
  def file_get_upload_info(
@@ -264,18 +262,16 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
264
262
  path_id: int | None = None,
265
263
  file_related_url: str | None = None,
266
264
  ) -> dict:
267
- return mcp_result_from_operation(
268
- runtime.files.get_upload_info(
269
- profile=profile,
270
- upload_kind=upload_kind,
271
- file_name=file_name,
272
- file_size=file_size,
273
- upload_mark=upload_mark,
274
- content_type=content_type,
275
- bucket_type=bucket_type,
276
- path_id=path_id,
277
- file_related_url=file_related_url,
278
- )
265
+ return files.file_get_upload_info(
266
+ profile=profile,
267
+ upload_kind=upload_kind,
268
+ file_name=file_name,
269
+ file_size=file_size,
270
+ upload_mark=upload_mark,
271
+ content_type=content_type,
272
+ bucket_type=bucket_type,
273
+ path_id=path_id,
274
+ file_related_url=file_related_url,
279
275
  )
280
276
 
281
277
  @server.tool()
@@ -289,618 +285,23 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
289
285
  path_id: int | None = None,
290
286
  file_related_url: str | None = None,
291
287
  ) -> dict:
292
- return mcp_result_from_operation(
293
- runtime.files.upload_local(
294
- profile=profile,
295
- upload_kind=upload_kind,
296
- file_path=file_path,
297
- upload_mark=upload_mark,
298
- content_type=content_type,
299
- bucket_type=bucket_type,
300
- path_id=path_id,
301
- file_related_url=file_related_url,
302
- )
303
- )
304
-
305
- @server.tool()
306
- def feedback_submit(
307
- category: str = "",
308
- title: str = "",
309
- description: str = "",
310
- expected_behavior: str | None = None,
311
- actual_behavior: str | None = None,
312
- impact_scope: str | None = None,
313
- tool_name: str | None = None,
314
- app_key: str | None = None,
315
- record_id: str | int | None = None,
316
- workflow_node_id: str | int | None = None,
317
- note: str | None = None,
318
- ) -> dict:
319
- return mcp_result_from_operation(
320
- runtime.feedback.submit(
321
- category=category,
322
- title=title,
323
- description=description,
324
- expected_behavior=expected_behavior,
325
- actual_behavior=actual_behavior,
326
- impact_scope=impact_scope,
327
- tool_name=tool_name,
328
- app_key=app_key,
329
- record_id=record_id,
330
- workflow_node_id=workflow_node_id,
331
- note=note,
332
- )
333
- )
334
-
335
- @server.tool()
336
- def record_import_schema_get(
337
- app_key: str = "",
338
- output_profile: str = "normal",
339
- ) -> dict:
340
- return mcp_result_from_operation(
341
- runtime.imports.schema(profile=DEFAULT_PROFILE, app_key=app_key, output_profile=output_profile)
342
- )
343
-
344
- @server.tool(description="Get the official app import template and the expected applicant import columns.")
345
- def record_import_template_get(
346
- profile: str = DEFAULT_PROFILE,
347
- app_key: str = "",
348
- download_to_path: str | None = None,
349
- ) -> dict:
350
- return mcp_result_from_operation(
351
- runtime.imports.template(profile=profile, app_key=app_key, download_to_path=download_to_path)
352
- )
353
-
354
- @server.tool(description="Verify a local Excel import file and produce the only verification_id allowed for import start.")
355
- def record_import_verify(
356
- profile: str = DEFAULT_PROFILE,
357
- app_key: str = "",
358
- file_path: str = "",
359
- ) -> dict:
360
- return mcp_result_from_operation(runtime.imports.verify(profile=profile, app_key=app_key, file_path=file_path))
361
-
362
- @server.tool(description="Repair a local .xlsx import file after explicit user authorization, then re-verify it.")
363
- def record_import_repair_local(
364
- profile: str = DEFAULT_PROFILE,
365
- verification_id: str = "",
366
- authorized_file_modification: bool = False,
367
- output_path: str | None = None,
368
- selected_repairs: list[str] | None = None,
369
- ) -> dict:
370
- return mcp_result_from_operation(
371
- runtime.imports.repair(
372
- profile=profile,
373
- verification_id=verification_id,
374
- authorized_file_modification=authorized_file_modification,
375
- output_path=output_path,
376
- selected_repairs=selected_repairs or [],
377
- )
378
- )
379
-
380
- @server.tool(description="Start import from a successful verification_id. being_enter_auditing must be passed explicitly.")
381
- def record_import_start(
382
- profile: str = DEFAULT_PROFILE,
383
- app_key: str = "",
384
- verification_id: str = "",
385
- being_enter_auditing: bool | None = None,
386
- view_key: str | None = None,
387
- ) -> dict:
388
- return mcp_result_from_operation(
389
- runtime.imports.start(
390
- profile=profile,
391
- app_key=app_key,
392
- verification_id=verification_id,
393
- being_enter_auditing=being_enter_auditing,
394
- view_key=view_key,
395
- )
396
- )
397
-
398
- @server.tool()
399
- def record_import_status_get(
400
- profile: str = DEFAULT_PROFILE,
401
- app_key: str = "",
402
- import_id: str | None = None,
403
- process_id_str: str | None = None,
404
- ) -> dict:
405
- return mcp_result_from_operation(
406
- runtime.imports.status(
407
- profile=profile,
408
- app_key=app_key,
409
- import_id=import_id,
410
- process_id_str=process_id_str,
411
- )
412
- )
413
-
414
- @server.tool()
415
- def record_insert_schema_get(app_key: str = "", output_profile: str = "normal") -> dict:
416
- return mcp_result_from_operation(
417
- runtime.records.schema(
418
- profile=DEFAULT_PROFILE,
419
- app_key=app_key,
420
- mode="insert",
421
- view_id=None,
422
- record_id=None,
423
- output_profile=output_profile,
424
- )
425
- )
426
-
427
- @server.tool()
428
- def record_update_schema_get(app_key: str = "", record_id: int = 0, output_profile: str = "normal") -> dict:
429
- return mcp_result_from_operation(
430
- runtime.records.schema(
431
- profile=DEFAULT_PROFILE,
432
- app_key=app_key,
433
- mode="update",
434
- view_id=None,
435
- record_id=record_id,
436
- output_profile=output_profile,
437
- )
438
- )
439
-
440
- @server.tool()
441
- def record_browse_schema_get(app_key: str = "", view_id: str = "", output_profile: str = "normal") -> dict:
442
- return mcp_result_from_operation(
443
- runtime.records.schema(
444
- profile=DEFAULT_PROFILE,
445
- app_key=app_key,
446
- mode="browse",
447
- view_id=view_id,
448
- record_id=None,
449
- output_profile=output_profile,
450
- )
451
- )
452
-
453
- @server.tool()
454
- def record_member_candidates(
455
- profile: str = DEFAULT_PROFILE,
456
- app_key: str = "",
457
- field_id: int = 0,
458
- keyword: str = "",
459
- page_num: int = 1,
460
- page_size: int = 20,
461
- ) -> dict:
462
- return mcp_result_from_operation(
463
- runtime.records.member_candidates(
464
- profile=profile,
465
- app_key=app_key,
466
- field_id=field_id,
467
- keyword=keyword,
468
- page_num=page_num,
469
- page_size=page_size,
470
- )
471
- )
472
-
473
- @server.tool()
474
- def record_department_candidates(
475
- profile: str = DEFAULT_PROFILE,
476
- app_key: str = "",
477
- field_id: int = 0,
478
- keyword: str = "",
479
- page_num: int = 1,
480
- page_size: int = 20,
481
- ) -> dict:
482
- return mcp_result_from_operation(
483
- runtime.records.department_candidates(
484
- profile=profile,
485
- app_key=app_key,
486
- field_id=field_id,
487
- keyword=keyword,
488
- page_num=page_num,
489
- page_size=page_size,
490
- )
491
- )
492
-
493
- @server.tool()
494
- def record_analyze(
495
- profile: str = DEFAULT_PROFILE,
496
- app_key: str = "",
497
- dimensions: list[dict[str, Any]] | None = None,
498
- metrics: list[dict[str, Any]] | None = None,
499
- filters: list[dict[str, Any]] | None = None,
500
- sort: list[dict[str, Any]] | None = None,
501
- limit: int = 50,
502
- strict_full: bool = True,
503
- view_id: str | None = None,
504
- list_type: int | None = None,
505
- view_key: str | None = None,
506
- view_name: str | None = None,
507
- output_profile: str = "normal",
508
- ) -> dict:
509
- return mcp_result_from_operation(
510
- runtime.records.analyze(
511
- profile=profile,
512
- app_key=app_key,
513
- dimensions=dimensions or [],
514
- metrics=metrics or [],
515
- filters=filters or [],
516
- sort=sort or [],
517
- limit=limit,
518
- strict_full=strict_full,
519
- view_id=view_id,
520
- list_type=list_type,
521
- view_key=view_key,
522
- view_name=view_name,
523
- output_profile=output_profile,
524
- )
525
- )
526
-
527
- @server.tool()
528
- def record_list(
529
- profile: str = DEFAULT_PROFILE,
530
- app_key: str = "",
531
- columns: list[dict[str, Any] | int] | None = None,
532
- where: list[dict[str, Any]] | None = None,
533
- order_by: list[dict[str, Any]] | None = None,
534
- limit: int = 50,
535
- page: int = 1,
536
- view_id: str | None = None,
537
- list_type: int | None = None,
538
- view_key: str | None = None,
539
- view_name: str | None = None,
540
- output_profile: str = "normal",
541
- ) -> dict:
542
- return mcp_result_from_operation(
543
- runtime.records.list(
544
- profile=profile,
545
- app_key=app_key,
546
- columns=columns or [],
547
- where=where or [],
548
- order_by=order_by or [],
549
- limit=limit,
550
- page=page,
551
- view_id=view_id,
552
- list_type=list_type,
553
- view_key=view_key,
554
- view_name=view_name,
555
- output_profile=output_profile,
556
- )
557
- )
558
-
559
- @server.tool()
560
- def record_get(
561
- profile: str = DEFAULT_PROFILE,
562
- app_key: str = "",
563
- record_id: int = 0,
564
- columns: list[dict[str, Any] | int] | None = None,
565
- view_id: str | None = None,
566
- workflow_node_id: int | None = None,
567
- output_profile: str = "normal",
568
- ) -> dict:
569
- return mcp_result_from_operation(
570
- runtime.records.get(
571
- profile=profile,
572
- app_key=app_key,
573
- record_id=record_id,
574
- columns=columns or [],
575
- view_id=view_id,
576
- workflow_node_id=workflow_node_id,
577
- output_profile=output_profile,
578
- )
579
- )
580
-
581
- @server.tool()
582
- def record_insert(
583
- app_key: str = "",
584
- fields: dict[str, Any] | None = None,
585
- verify_write: bool = True,
586
- output_profile: str = "normal",
587
- ) -> dict:
588
- return mcp_result_from_operation(
589
- runtime.records.create(
590
- profile=DEFAULT_PROFILE,
591
- app_key=app_key,
592
- fields=fields or {},
593
- verify_write=verify_write,
594
- output_profile=output_profile,
595
- )
596
- )
597
-
598
- @server.tool()
599
- def record_update(
600
- app_key: str = "",
601
- record_id: int | None = None,
602
- fields: dict[str, Any] | None = None,
603
- verify_write: bool = True,
604
- output_profile: str = "normal",
605
- ) -> dict:
606
- return mcp_result_from_operation(
607
- runtime.records.update(
608
- profile=DEFAULT_PROFILE,
609
- app_key=app_key,
610
- record_id=record_id,
611
- fields=fields or {},
612
- verify_write=verify_write,
613
- output_profile=output_profile,
614
- )
615
- )
616
-
617
- @server.tool()
618
- def record_delete(
619
- app_key: str = "",
620
- record_id: int | None = None,
621
- record_ids: list[int] | None = None,
622
- output_profile: str = "normal",
623
- ) -> dict:
624
- return mcp_result_from_operation(
625
- runtime.records.delete(
626
- profile=DEFAULT_PROFILE,
627
- app_key=app_key,
628
- record_id=record_id,
629
- record_ids=record_ids or [],
630
- output_profile=output_profile,
631
- )
632
- )
633
-
634
- @server.tool()
635
- def record_code_block_schema_get(app_key: str = "", output_profile: str = "normal") -> dict:
636
- return mcp_result_from_operation(
637
- runtime.records.schema(
638
- profile=DEFAULT_PROFILE,
639
- app_key=app_key,
640
- mode="code-block",
641
- view_id=None,
642
- record_id=None,
643
- output_profile=output_profile,
644
- )
645
- )
646
-
647
- @server.tool()
648
- def record_code_block_run(
649
- profile: str = DEFAULT_PROFILE,
650
- app_key: str = "",
651
- record_id: int = 0,
652
- code_block_field: str = "",
653
- role: int = 1,
654
- workflow_node_id: int | None = None,
655
- answers: list[dict[str, Any]] | None = None,
656
- fields: dict[str, Any] | None = None,
657
- manual: bool = True,
658
- verify_writeback: bool = True,
659
- force_refresh_form: bool = False,
660
- output_profile: str = "normal",
661
- ) -> dict:
662
- return mcp_result_from_operation(
663
- runtime.records.run_code(
664
- profile=profile,
665
- app_key=app_key,
666
- record_id=record_id,
667
- code_block_field=code_block_field,
668
- role=role,
669
- workflow_node_id=workflow_node_id,
670
- answers=answers or [],
671
- fields=fields or {},
672
- manual=manual,
673
- verify_writeback=verify_writeback,
674
- force_refresh_form=force_refresh_form,
675
- output_profile=output_profile,
676
- )
677
- )
678
-
679
- @server.tool()
680
- def task_list(
681
- profile: str = DEFAULT_PROFILE,
682
- task_box: str = "todo",
683
- flow_status: str = "all",
684
- app_key: str | None = None,
685
- workflow_node_id: int | None = None,
686
- query: str | None = None,
687
- page: int = 1,
688
- page_size: int = 20,
689
- ) -> dict:
690
- return mcp_result_from_operation(
691
- runtime.tasks.list(
692
- profile=profile,
693
- task_box=task_box,
694
- flow_status=flow_status,
695
- app_key=app_key,
696
- workflow_node_id=workflow_node_id,
697
- query=query,
698
- page=page,
699
- page_size=page_size,
700
- )
701
- )
702
-
703
- @server.tool()
704
- def task_get(
705
- profile: str = DEFAULT_PROFILE,
706
- app_key: str = "",
707
- record_id: int = 0,
708
- workflow_node_id: int = 0,
709
- include_candidates: bool = True,
710
- include_associated_reports: bool = True,
711
- ) -> dict:
712
- return mcp_result_from_operation(
713
- runtime.tasks.show(
714
- profile=profile,
715
- app_key=app_key,
716
- record_id=record_id,
717
- workflow_node_id=workflow_node_id,
718
- include_candidates=include_candidates,
719
- include_associated_reports=include_associated_reports,
720
- )
721
- )
722
-
723
- @server.tool(description=high_risk_desc)
724
- def task_action_execute(
725
- profile: str = DEFAULT_PROFILE,
726
- app_key: str = "",
727
- record_id: int = 0,
728
- workflow_node_id: int = 0,
729
- action: str = "",
730
- payload: dict[str, Any] | None = None,
731
- ) -> dict:
732
- return mcp_result_from_operation(
733
- runtime.tasks.act(
734
- profile=profile,
735
- app_key=app_key,
736
- record_id=record_id,
737
- workflow_node_id=workflow_node_id,
738
- action=action,
739
- payload=payload or {},
740
- )
741
- )
742
-
743
- @server.tool()
744
- def task_associated_report_detail_get(
745
- profile: str = DEFAULT_PROFILE,
746
- app_key: str = "",
747
- record_id: int = 0,
748
- workflow_node_id: int = 0,
749
- report_id: int = 0,
750
- page: int = 1,
751
- page_size: int = 20,
752
- ) -> dict:
753
- return mcp_result_from_operation(
754
- runtime.tasks.associated_report_detail(
755
- profile=profile,
756
- app_key=app_key,
757
- record_id=record_id,
758
- workflow_node_id=workflow_node_id,
759
- report_id=report_id,
760
- page=page,
761
- page_size=page_size,
762
- )
763
- )
764
-
765
- @server.tool()
766
- def task_workflow_log_get(
767
- profile: str = DEFAULT_PROFILE,
768
- app_key: str = "",
769
- record_id: int = 0,
770
- workflow_node_id: int = 0,
771
- ) -> dict:
772
- return mcp_result_from_operation(
773
- runtime.tasks.log(
774
- profile=profile,
775
- app_key=app_key,
776
- record_id=record_id,
777
- workflow_node_id=workflow_node_id,
778
- )
779
- )
780
-
781
- @server.tool()
782
- def directory_search(
783
- profile: str = DEFAULT_PROFILE,
784
- query: str = "",
785
- scopes: list[str] | None = None,
786
- page_num: int = 1,
787
- page_size: int = 20,
788
- ) -> dict:
789
- return mcp_result_from_operation(
790
- runtime.directory.search(
791
- profile=profile,
792
- query=query,
793
- scopes=scopes,
794
- page_num=page_num,
795
- page_size=page_size,
796
- )
797
- )
798
-
799
- @server.tool()
800
- def directory_list_internal_users(
801
- profile: str = DEFAULT_PROFILE,
802
- keyword: str | None = None,
803
- department_id: int | None = None,
804
- role_id: int | None = None,
805
- page_num: int = 1,
806
- page_size: int = 20,
807
- include_disabled: bool = False,
808
- ) -> dict:
809
- return mcp_result_from_operation(
810
- runtime.directory.list_internal_users(
811
- profile=profile,
812
- keyword=keyword,
813
- department_id=department_id,
814
- role_id=role_id,
815
- page_num=page_num,
816
- page_size=page_size,
817
- include_disabled=include_disabled,
818
- )
288
+ return files.file_upload_local(
289
+ profile=profile,
290
+ upload_kind=upload_kind,
291
+ file_path=file_path,
292
+ upload_mark=upload_mark,
293
+ content_type=content_type,
294
+ bucket_type=bucket_type,
295
+ path_id=path_id,
296
+ file_related_url=file_related_url,
819
297
  )
820
298
 
821
- @server.tool()
822
- def directory_list_all_internal_users(
823
- profile: str = DEFAULT_PROFILE,
824
- keyword: str | None = None,
825
- department_id: int | None = None,
826
- role_id: int | None = None,
827
- page_size: int = 200,
828
- include_disabled: bool = False,
829
- max_pages: int = 100,
830
- ) -> dict:
831
- return mcp_result_from_operation(
832
- runtime.directory.list_all_internal_users(
833
- profile=profile,
834
- keyword=keyword,
835
- department_id=department_id,
836
- role_id=role_id,
837
- page_size=page_size,
838
- include_disabled=include_disabled,
839
- max_pages=max_pages,
840
- )
841
- )
299
+ imports.register(server)
842
300
 
843
- @server.tool()
844
- def directory_list_internal_departments(
845
- profile: str = DEFAULT_PROFILE,
846
- keyword: str = "",
847
- page_num: int = 1,
848
- page_size: int = 20,
849
- ) -> dict:
850
- return mcp_result_from_operation(
851
- runtime.directory.list_internal_departments(
852
- profile=profile,
853
- keyword=keyword,
854
- page_num=page_num,
855
- page_size=page_size,
856
- )
857
- )
858
-
859
- @server.tool()
860
- def directory_list_all_departments(
861
- profile: str = DEFAULT_PROFILE,
862
- parent_department_id: int | None = None,
863
- max_depth: int = 20,
864
- max_items: int = 2000,
865
- ) -> dict:
866
- return mcp_result_from_operation(
867
- runtime.directory.list_all_departments(
868
- profile=profile,
869
- parent_department_id=parent_department_id,
870
- max_depth=max_depth,
871
- max_items=max_items,
872
- )
873
- )
874
-
875
- @server.tool()
876
- def directory_list_sub_departments(
877
- profile: str = DEFAULT_PROFILE,
878
- parent_department_id: int | None = None,
879
- ) -> dict:
880
- return mcp_result_from_operation(
881
- runtime.directory.list_sub_departments(
882
- profile=profile,
883
- parent_department_id=parent_department_id,
884
- )
885
- )
886
-
887
- @server.tool()
888
- def directory_list_external_members(
889
- profile: str = DEFAULT_PROFILE,
890
- keyword: str | None = None,
891
- page_num: int = 1,
892
- page_size: int = 20,
893
- simple: bool = False,
894
- ) -> dict:
895
- return mcp_result_from_operation(
896
- runtime.directory.list_external_members(
897
- profile=profile,
898
- keyword=keyword,
899
- page_num=page_num,
900
- page_size=page_size,
901
- simple=simple,
902
- )
903
- )
301
+ feedback.register(server)
302
+ CodeBlockTools(sessions, backend).register(server)
303
+ TaskContextTools(sessions, backend).register(server)
304
+ DirectoryTools(sessions, backend).register(server)
904
305
 
905
306
  return server
906
307