@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.
@@ -1,21 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import date
4
+ from typing import Any
4
5
 
5
6
  from mcp.server.fastmcp import FastMCP
6
7
 
7
8
  from .backend_client import BackendClient
8
9
  from .config import DEFAULT_PROFILE
10
+ from .ops.base import mcp_result_from_operation
11
+ from .ops.context import build_operations_runtime
9
12
  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
17
13
  from .tools.task_context_tools import TaskContextTools
18
- from .tools.workspace_tools import WorkspaceTools
19
14
 
20
15
 
21
16
  def build_user_server() -> FastMCP:
@@ -169,12 +164,11 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
169
164
  )
170
165
  sessions = SessionStore()
171
166
  backend = BackendClient()
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")
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
+ )
178
172
 
179
173
  @server.tool()
180
174
  def auth_login(
@@ -185,13 +179,15 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
185
179
  password: str = "",
186
180
  persist: bool = True,
187
181
  ) -> dict:
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,
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
+ )
195
191
  )
196
192
 
197
193
  @server.tool()
@@ -203,22 +199,24 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
203
199
  ws_id: int | None = None,
204
200
  persist: bool = False,
205
201
  ) -> dict:
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,
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
+ )
213
211
  )
214
212
 
215
213
  @server.tool()
216
214
  def auth_whoami(profile: str = DEFAULT_PROFILE) -> dict:
217
- return auth.auth_whoami(profile=profile)
215
+ return mcp_result_from_operation(runtime.auth.me(profile=profile))
218
216
 
219
217
  @server.tool()
220
218
  def auth_logout(profile: str = DEFAULT_PROFILE, forget_persisted: bool = False) -> dict:
221
- return auth.auth_logout(profile=profile, forget_persisted=forget_persisted)
219
+ return mcp_result_from_operation(runtime.auth.logout(profile=profile, forget_persisted=forget_persisted))
222
220
 
223
221
  @server.tool()
224
222
  def workspace_list(
@@ -227,28 +225,32 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
227
225
  page_size: int = 20,
228
226
  include_external: bool = False,
229
227
  ) -> dict:
230
- return workspace.workspace_list(
231
- profile=profile,
232
- page_num=page_num,
233
- page_size=page_size,
234
- include_external=include_external,
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
+ )
235
235
  )
236
236
 
237
237
  @server.tool()
238
238
  def workspace_select(profile: str = DEFAULT_PROFILE, ws_id: int = 0) -> dict:
239
- return workspace.workspace_select(profile=profile, ws_id=ws_id)
239
+ return mcp_result_from_operation(runtime.workspace.use(profile=profile, ws_id=ws_id))
240
240
 
241
241
  @server.tool()
242
242
  def app_list(profile: str = DEFAULT_PROFILE) -> dict:
243
- return apps.app_list(profile=profile)
243
+ return mcp_result_from_operation(runtime.apps.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 apps.app_search(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
247
+ return mcp_result_from_operation(
248
+ runtime.apps.find(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
249
+ )
248
250
 
249
251
  @server.tool()
250
252
  def app_get(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
251
- return apps.app_get(profile=profile, app_key=app_key)
253
+ return mcp_result_from_operation(runtime.apps.show(profile=profile, app_key=app_key))
252
254
 
253
255
  @server.tool()
254
256
  def file_get_upload_info(
@@ -262,16 +264,18 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
262
264
  path_id: int | None = None,
263
265
  file_related_url: str | None = None,
264
266
  ) -> dict:
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,
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
+ )
275
279
  )
276
280
 
277
281
  @server.tool()
@@ -285,23 +289,618 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
285
289
  path_id: int | None = None,
286
290
  file_related_url: str | None = None,
287
291
  ) -> dict:
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,
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
+ )
297
819
  )
298
820
 
299
- imports.register(server)
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
+ )
300
842
 
301
- feedback.register(server)
302
- CodeBlockTools(sessions, backend).register(server)
303
- TaskContextTools(sessions, backend).register(server)
304
- DirectoryTools(sessions, backend).register(server)
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
+ )
305
904
 
306
905
  return server
307
906