feishu-user-plugin 1.3.0 → 1.3.1
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 +103 -39
- package/package.json +5 -3
- package/scripts/confirm-version.js +28 -0
- package/scripts/mcp_stdio_bridge.js +97 -0
- package/skills/feishu-user-plugin/references/CLAUDE.md +76 -34
- package/src/cli.js +12 -7
- package/src/config.js +202 -27
- package/src/index.js +124 -237
- package/src/oauth.js +2 -1
- package/src/official.js +103 -109
- package/src/setup.js +19 -3
package/src/index.js
CHANGED
|
@@ -541,49 +541,9 @@ const TOOLS = [
|
|
|
541
541
|
required: ['app_token', 'table_id'],
|
|
542
542
|
},
|
|
543
543
|
},
|
|
544
|
-
{
|
|
545
|
-
name: 'create_bitable_record',
|
|
546
|
-
description: '[Official API] Create a new record (row) in a Bitable table.',
|
|
547
|
-
inputSchema: {
|
|
548
|
-
type: 'object',
|
|
549
|
-
properties: {
|
|
550
|
-
app_token: { type: 'string', description: 'Bitable app token' },
|
|
551
|
-
table_id: { type: 'string', description: 'Table ID' },
|
|
552
|
-
fields: { type: 'object', description: 'Field name → value mapping' },
|
|
553
|
-
},
|
|
554
|
-
required: ['app_token', 'table_id', 'fields'],
|
|
555
|
-
},
|
|
556
|
-
},
|
|
557
|
-
{
|
|
558
|
-
name: 'update_bitable_record',
|
|
559
|
-
description: '[Official API] Update an existing record in a Bitable table.',
|
|
560
|
-
inputSchema: {
|
|
561
|
-
type: 'object',
|
|
562
|
-
properties: {
|
|
563
|
-
app_token: { type: 'string', description: 'Bitable app token' },
|
|
564
|
-
table_id: { type: 'string', description: 'Table ID' },
|
|
565
|
-
record_id: { type: 'string', description: 'Record ID to update' },
|
|
566
|
-
fields: { type: 'object', description: 'Field name → new value mapping' },
|
|
567
|
-
},
|
|
568
|
-
required: ['app_token', 'table_id', 'record_id', 'fields'],
|
|
569
|
-
},
|
|
570
|
-
},
|
|
571
|
-
{
|
|
572
|
-
name: 'delete_bitable_record',
|
|
573
|
-
description: '[Official API] Delete a record (row) from a Bitable table.',
|
|
574
|
-
inputSchema: {
|
|
575
|
-
type: 'object',
|
|
576
|
-
properties: {
|
|
577
|
-
app_token: { type: 'string', description: 'Bitable app token' },
|
|
578
|
-
table_id: { type: 'string', description: 'Table ID' },
|
|
579
|
-
record_id: { type: 'string', description: 'Record ID to delete' },
|
|
580
|
-
},
|
|
581
|
-
required: ['app_token', 'table_id', 'record_id'],
|
|
582
|
-
},
|
|
583
|
-
},
|
|
584
544
|
{
|
|
585
545
|
name: 'batch_create_bitable_records',
|
|
586
|
-
description: '[Official API]
|
|
546
|
+
description: '[Official API] Create one or more records (rows) in a Bitable table. Pass a single record or up to 500.',
|
|
587
547
|
inputSchema: {
|
|
588
548
|
type: 'object',
|
|
589
549
|
properties: {
|
|
@@ -596,7 +556,7 @@ const TOOLS = [
|
|
|
596
556
|
},
|
|
597
557
|
{
|
|
598
558
|
name: 'batch_update_bitable_records',
|
|
599
|
-
description: '[Official API]
|
|
559
|
+
description: '[Official API] Update one or more records in a Bitable table. Pass a single record or up to 500.',
|
|
600
560
|
inputSchema: {
|
|
601
561
|
type: 'object',
|
|
602
562
|
properties: {
|
|
@@ -609,7 +569,7 @@ const TOOLS = [
|
|
|
609
569
|
},
|
|
610
570
|
{
|
|
611
571
|
name: 'batch_delete_bitable_records',
|
|
612
|
-
description: '[Official API]
|
|
572
|
+
description: '[Official API] Delete one or more records from a Bitable table. Pass a single ID or up to 500.',
|
|
613
573
|
inputSchema: {
|
|
614
574
|
type: 'object',
|
|
615
575
|
properties: {
|
|
@@ -777,19 +737,13 @@ const TOOLS = [
|
|
|
777
737
|
// ========== IM — Pin Messages ==========
|
|
778
738
|
{
|
|
779
739
|
name: 'pin_message',
|
|
780
|
-
description: '[Official API] Pin a message in a chat.',
|
|
781
|
-
inputSchema: {
|
|
782
|
-
type: 'object',
|
|
783
|
-
properties: { message_id: { type: 'string', description: 'Message ID to pin' } },
|
|
784
|
-
required: ['message_id'],
|
|
785
|
-
},
|
|
786
|
-
},
|
|
787
|
-
{
|
|
788
|
-
name: 'unpin_message',
|
|
789
|
-
description: '[Official API] Unpin a message from a chat.',
|
|
740
|
+
description: '[Official API] Pin or unpin a message in a chat.',
|
|
790
741
|
inputSchema: {
|
|
791
742
|
type: 'object',
|
|
792
|
-
properties: {
|
|
743
|
+
properties: {
|
|
744
|
+
message_id: { type: 'string', description: 'Message ID' },
|
|
745
|
+
pinned: { type: 'boolean', description: 'true to pin, false to unpin', default: true },
|
|
746
|
+
},
|
|
793
747
|
required: ['message_id'],
|
|
794
748
|
},
|
|
795
749
|
},
|
|
@@ -835,27 +789,16 @@ const TOOLS = [
|
|
|
835
789
|
},
|
|
836
790
|
},
|
|
837
791
|
{
|
|
838
|
-
name: '
|
|
839
|
-
description: '[Official API] Add
|
|
792
|
+
name: 'manage_members',
|
|
793
|
+
description: '[Official API] Add or remove members from a group chat.',
|
|
840
794
|
inputSchema: {
|
|
841
795
|
type: 'object',
|
|
842
796
|
properties: {
|
|
843
|
-
chat_id: { type: 'string', description: '
|
|
844
|
-
|
|
797
|
+
chat_id: { type: 'string', description: 'Group chat ID (oc_xxx)' },
|
|
798
|
+
member_ids: { type: 'array', items: { type: 'string' }, description: 'Array of user open_ids' },
|
|
799
|
+
action: { type: 'string', enum: ['add', 'remove'], description: 'Action to perform' },
|
|
845
800
|
},
|
|
846
|
-
required: ['chat_id', '
|
|
847
|
-
},
|
|
848
|
-
},
|
|
849
|
-
{
|
|
850
|
-
name: 'remove_members',
|
|
851
|
-
description: '[Official API] Remove users from a group chat.',
|
|
852
|
-
inputSchema: {
|
|
853
|
-
type: 'object',
|
|
854
|
-
properties: {
|
|
855
|
-
chat_id: { type: 'string', description: 'Chat ID (oc_xxx)' },
|
|
856
|
-
user_ids: { type: 'array', items: { type: 'string' }, description: 'Array of user open_ids to remove' },
|
|
857
|
-
},
|
|
858
|
-
required: ['chat_id', 'user_ids'],
|
|
801
|
+
required: ['chat_id', 'member_ids', 'action'],
|
|
859
802
|
},
|
|
860
803
|
},
|
|
861
804
|
|
|
@@ -929,165 +872,111 @@ const TOOLS = [
|
|
|
929
872
|
},
|
|
930
873
|
},
|
|
931
874
|
|
|
932
|
-
// ========== Drive — File Operations ==========
|
|
933
875
|
{
|
|
934
|
-
name: '
|
|
935
|
-
description: '[Official API]
|
|
876
|
+
name: 'get_bitable_meta',
|
|
877
|
+
description: '[Official API] Get metadata of a Bitable app (name, revision, etc.).',
|
|
936
878
|
inputSchema: {
|
|
937
879
|
type: 'object',
|
|
938
880
|
properties: {
|
|
939
|
-
|
|
940
|
-
name: { type: 'string', description: 'New file name' },
|
|
941
|
-
folder_token: { type: 'string', description: 'Destination folder token (optional)' },
|
|
942
|
-
type: { type: 'string', description: 'File type: file, doc, sheet, bitable, docx, mindnote, slides (optional)' },
|
|
943
|
-
},
|
|
944
|
-
required: ['file_token', 'name'],
|
|
945
|
-
},
|
|
946
|
-
},
|
|
947
|
-
{
|
|
948
|
-
name: 'move_file',
|
|
949
|
-
description: '[Official API] Move a file to another folder in Drive.',
|
|
950
|
-
inputSchema: {
|
|
951
|
-
type: 'object',
|
|
952
|
-
properties: {
|
|
953
|
-
file_token: { type: 'string', description: 'File token to move' },
|
|
954
|
-
folder_token: { type: 'string', description: 'Destination folder token' },
|
|
955
|
-
},
|
|
956
|
-
required: ['file_token', 'folder_token'],
|
|
957
|
-
},
|
|
958
|
-
},
|
|
959
|
-
{
|
|
960
|
-
name: 'delete_file',
|
|
961
|
-
description: '[Official API] Delete a file/folder from Drive.',
|
|
962
|
-
inputSchema: {
|
|
963
|
-
type: 'object',
|
|
964
|
-
properties: {
|
|
965
|
-
file_token: { type: 'string', description: 'File token to delete' },
|
|
966
|
-
type: { type: 'string', description: 'Type: file, folder, doc, sheet, bitable, docx, mindnote, slides' },
|
|
881
|
+
app_token: { type: 'string', description: 'Bitable app token' },
|
|
967
882
|
},
|
|
968
|
-
required: ['
|
|
883
|
+
required: ['app_token'],
|
|
969
884
|
},
|
|
970
885
|
},
|
|
971
|
-
|
|
972
|
-
// ========== Calendar ==========
|
|
973
|
-
{
|
|
974
|
-
name: 'list_calendars',
|
|
975
|
-
description: '[Official API] List all calendars accessible by the bot.',
|
|
976
|
-
inputSchema: { type: 'object', properties: {} },
|
|
977
|
-
},
|
|
978
886
|
{
|
|
979
|
-
name: '
|
|
980
|
-
description: '[Official API]
|
|
887
|
+
name: 'update_bitable_table',
|
|
888
|
+
description: '[Official API] Rename a data table in a Bitable app.',
|
|
981
889
|
inputSchema: {
|
|
982
890
|
type: 'object',
|
|
983
891
|
properties: {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
end_time: { type: 'string', description: 'End time (RFC3339 or Unix timestamp string)' },
|
|
988
|
-
description: { type: 'string', description: 'Event description (optional)' },
|
|
989
|
-
location: { type: 'string', description: 'Event location (optional)' },
|
|
892
|
+
app_token: { type: 'string', description: 'Bitable app token' },
|
|
893
|
+
table_id: { type: 'string', description: 'Table ID' },
|
|
894
|
+
name: { type: 'string', description: 'New table name' },
|
|
990
895
|
},
|
|
991
|
-
required: ['
|
|
896
|
+
required: ['app_token', 'table_id', 'name'],
|
|
992
897
|
},
|
|
993
898
|
},
|
|
994
899
|
{
|
|
995
|
-
name: '
|
|
996
|
-
description: '[Official API]
|
|
900
|
+
name: 'create_bitable_view',
|
|
901
|
+
description: '[Official API] Create a new view in a Bitable table.',
|
|
997
902
|
inputSchema: {
|
|
998
903
|
type: 'object',
|
|
999
904
|
properties: {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
905
|
+
app_token: { type: 'string', description: 'Bitable app token' },
|
|
906
|
+
table_id: { type: 'string', description: 'Table ID' },
|
|
907
|
+
view_name: { type: 'string', description: 'View name' },
|
|
908
|
+
view_type: { type: 'string', description: 'View type: grid (default), kanban, gallery, form, gantt, calendar', default: 'grid' },
|
|
1004
909
|
},
|
|
1005
|
-
required: ['
|
|
910
|
+
required: ['app_token', 'table_id', 'view_name'],
|
|
1006
911
|
},
|
|
1007
912
|
},
|
|
1008
913
|
{
|
|
1009
|
-
name: '
|
|
1010
|
-
description: '[Official API] Delete a
|
|
914
|
+
name: 'delete_bitable_view',
|
|
915
|
+
description: '[Official API] Delete a view from a Bitable table.',
|
|
1011
916
|
inputSchema: {
|
|
1012
917
|
type: 'object',
|
|
1013
918
|
properties: {
|
|
1014
|
-
|
|
1015
|
-
|
|
919
|
+
app_token: { type: 'string', description: 'Bitable app token' },
|
|
920
|
+
table_id: { type: 'string', description: 'Table ID' },
|
|
921
|
+
view_id: { type: 'string', description: 'View ID to delete' },
|
|
1016
922
|
},
|
|
1017
|
-
required: ['
|
|
923
|
+
required: ['app_token', 'table_id', 'view_id'],
|
|
1018
924
|
},
|
|
1019
925
|
},
|
|
1020
926
|
{
|
|
1021
|
-
name: '
|
|
1022
|
-
description: '[Official API]
|
|
927
|
+
name: 'copy_bitable',
|
|
928
|
+
description: '[Official API] Copy a Bitable app to create a new one.',
|
|
1023
929
|
inputSchema: {
|
|
1024
930
|
type: 'object',
|
|
1025
931
|
properties: {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
932
|
+
app_token: { type: 'string', description: 'Bitable app token to copy' },
|
|
933
|
+
name: { type: 'string', description: 'New Bitable name' },
|
|
934
|
+
folder_id: { type: 'string', description: 'Destination folder token (optional)' },
|
|
1029
935
|
},
|
|
1030
|
-
required: ['
|
|
936
|
+
required: ['app_token', 'name'],
|
|
1031
937
|
},
|
|
1032
938
|
},
|
|
1033
939
|
|
|
1034
|
-
// ==========
|
|
940
|
+
// ========== Drive — File Operations ==========
|
|
1035
941
|
{
|
|
1036
|
-
name: '
|
|
1037
|
-
description: '[Official API]
|
|
942
|
+
name: 'copy_file',
|
|
943
|
+
description: '[Official API] Copy a file/doc in Drive.',
|
|
1038
944
|
inputSchema: {
|
|
1039
945
|
type: 'object',
|
|
1040
946
|
properties: {
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
947
|
+
file_token: { type: 'string', description: 'File token to copy' },
|
|
948
|
+
name: { type: 'string', description: 'New file name' },
|
|
949
|
+
folder_token: { type: 'string', description: 'Destination folder token (optional)' },
|
|
950
|
+
type: { type: 'string', description: 'File type: file, doc, sheet, bitable, docx, mindnote, slides (optional)' },
|
|
1044
951
|
},
|
|
1045
|
-
required: ['
|
|
1046
|
-
},
|
|
1047
|
-
},
|
|
1048
|
-
{
|
|
1049
|
-
name: 'get_task',
|
|
1050
|
-
description: '[Official API] Get task details by ID.',
|
|
1051
|
-
inputSchema: {
|
|
1052
|
-
type: 'object',
|
|
1053
|
-
properties: { task_id: { type: 'string', description: 'Task ID' } },
|
|
1054
|
-
required: ['task_id'],
|
|
952
|
+
required: ['file_token', 'name'],
|
|
1055
953
|
},
|
|
1056
954
|
},
|
|
1057
955
|
{
|
|
1058
|
-
name: '
|
|
1059
|
-
description: '[Official API]
|
|
956
|
+
name: 'move_file',
|
|
957
|
+
description: '[Official API] Move a file to another folder in Drive.',
|
|
1060
958
|
inputSchema: {
|
|
1061
959
|
type: 'object',
|
|
1062
960
|
properties: {
|
|
1063
|
-
|
|
1064
|
-
|
|
961
|
+
file_token: { type: 'string', description: 'File token to move' },
|
|
962
|
+
folder_token: { type: 'string', description: 'Destination folder token' },
|
|
1065
963
|
},
|
|
964
|
+
required: ['file_token', 'folder_token'],
|
|
1066
965
|
},
|
|
1067
966
|
},
|
|
1068
967
|
{
|
|
1069
|
-
name: '
|
|
1070
|
-
description: '[Official API]
|
|
968
|
+
name: 'delete_file',
|
|
969
|
+
description: '[Official API] Delete a file/folder from Drive.',
|
|
1071
970
|
inputSchema: {
|
|
1072
971
|
type: 'object',
|
|
1073
972
|
properties: {
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
description: { type: 'string', description: 'New description (optional)' },
|
|
1077
|
-
due: { type: 'string', description: 'New due date (optional)' },
|
|
973
|
+
file_token: { type: 'string', description: 'File token to delete' },
|
|
974
|
+
type: { type: 'string', description: 'Type: file, folder, doc, sheet, bitable, docx, mindnote, slides' },
|
|
1078
975
|
},
|
|
1079
|
-
required: ['
|
|
1080
|
-
},
|
|
1081
|
-
},
|
|
1082
|
-
{
|
|
1083
|
-
name: 'complete_task',
|
|
1084
|
-
description: '[Official API] Mark a task as complete.',
|
|
1085
|
-
inputSchema: {
|
|
1086
|
-
type: 'object',
|
|
1087
|
-
properties: { task_id: { type: 'string', description: 'Task ID to complete' } },
|
|
1088
|
-
required: ['task_id'],
|
|
976
|
+
required: ['file_token'],
|
|
1089
977
|
},
|
|
1090
978
|
},
|
|
979
|
+
|
|
1091
980
|
];
|
|
1092
981
|
|
|
1093
982
|
// --- Server ---
|
|
@@ -1331,14 +1220,33 @@ async function handleTool(name, args) {
|
|
|
1331
1220
|
return json(await getOfficialClient().readDoc(args.document_id));
|
|
1332
1221
|
case 'get_doc_blocks':
|
|
1333
1222
|
return json(await getOfficialClient().getDocBlocks(args.document_id));
|
|
1334
|
-
case 'create_doc':
|
|
1335
|
-
|
|
1223
|
+
case 'create_doc': {
|
|
1224
|
+
const official = getOfficialClient();
|
|
1225
|
+
if (official.hasUAT) {
|
|
1226
|
+
try {
|
|
1227
|
+
const result = await official.createDocAsUser(args.title, args.folder_id);
|
|
1228
|
+
return text(`Document created (as user): ${result.documentId}`);
|
|
1229
|
+
} catch (e) {
|
|
1230
|
+
console.error(`[feishu-user-plugin] UAT createDoc failed, falling back to app: ${e.message}`);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
return text(`Document created: ${(await official.createDoc(args.title, args.folder_id)).documentId}`);
|
|
1234
|
+
}
|
|
1336
1235
|
|
|
1337
1236
|
// --- Official API: Bitable ---
|
|
1338
1237
|
|
|
1339
1238
|
case 'create_bitable': {
|
|
1340
|
-
const
|
|
1341
|
-
|
|
1239
|
+
const official = getOfficialClient();
|
|
1240
|
+
if (official.hasUAT) {
|
|
1241
|
+
try {
|
|
1242
|
+
const r = await official.createBitableAsUser(args.name, args.folder_id);
|
|
1243
|
+
return text(`Bitable created (as user): ${r.appToken}\nURL: ${r.url || ''}`);
|
|
1244
|
+
} catch (e) {
|
|
1245
|
+
console.error(`[feishu-user-plugin] UAT createBitable failed, falling back to app: ${e.message}`);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
const r = await official.createBitable(args.name, args.folder_id);
|
|
1249
|
+
return text(`Bitable created: ${r.appToken}\nURL: ${r.url || ''}`);
|
|
1342
1250
|
}
|
|
1343
1251
|
case 'list_bitable_tables':
|
|
1344
1252
|
return json(await getOfficialClient().listBitableTables(args.app_token));
|
|
@@ -1368,12 +1276,6 @@ async function handleTool(name, args) {
|
|
|
1368
1276
|
return json(await getOfficialClient().searchBitableRecords(args.app_token, args.table_id, {
|
|
1369
1277
|
filter: args.filter, sort: args.sort, pageSize: args.page_size,
|
|
1370
1278
|
}));
|
|
1371
|
-
case 'create_bitable_record':
|
|
1372
|
-
return text(`Record created: ${(await getOfficialClient().createBitableRecord(args.app_token, args.table_id, args.fields)).recordId}`);
|
|
1373
|
-
case 'update_bitable_record':
|
|
1374
|
-
return text(`Record updated: ${(await getOfficialClient().updateBitableRecord(args.app_token, args.table_id, args.record_id, args.fields)).recordId}`);
|
|
1375
|
-
case 'delete_bitable_record':
|
|
1376
|
-
return text(`Record deleted: ${(await getOfficialClient().deleteBitableRecord(args.app_token, args.table_id, args.record_id)).deleted}`);
|
|
1377
1279
|
case 'batch_create_bitable_records':
|
|
1378
1280
|
return json(await getOfficialClient().batchCreateBitableRecords(args.app_token, args.table_id, args.records));
|
|
1379
1281
|
case 'batch_update_bitable_records':
|
|
@@ -1394,8 +1296,17 @@ async function handleTool(name, args) {
|
|
|
1394
1296
|
|
|
1395
1297
|
case 'list_files':
|
|
1396
1298
|
return json(await getOfficialClient().listFiles(args.folder_token));
|
|
1397
|
-
case 'create_folder':
|
|
1398
|
-
|
|
1299
|
+
case 'create_folder': {
|
|
1300
|
+
const official = getOfficialClient();
|
|
1301
|
+
if (official.hasUAT) {
|
|
1302
|
+
try {
|
|
1303
|
+
return text(`Folder created (as user): ${(await official.createFolderAsUser(args.name, args.parent_token)).token}`);
|
|
1304
|
+
} catch (e) {
|
|
1305
|
+
console.error(`[feishu-user-plugin] UAT createFolder failed, falling back to app: ${e.message}`);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
return text(`Folder created: ${(await official.createFolder(args.name, args.parent_token)).token}`);
|
|
1309
|
+
}
|
|
1399
1310
|
|
|
1400
1311
|
// --- Official API: Contact ---
|
|
1401
1312
|
|
|
@@ -1434,9 +1345,7 @@ async function handleTool(name, args) {
|
|
|
1434
1345
|
// --- Official API: Pins ---
|
|
1435
1346
|
|
|
1436
1347
|
case 'pin_message':
|
|
1437
|
-
return json(await getOfficialClient().pinMessage(args.message_id));
|
|
1438
|
-
case 'unpin_message':
|
|
1439
|
-
return text(`Unpinned: ${(await getOfficialClient().unpinMessage(args.message_id)).deleted}`);
|
|
1348
|
+
return json(await getOfficialClient().pinMessage(args.message_id, args.pinned !== false));
|
|
1440
1349
|
|
|
1441
1350
|
// --- Official API: Chat Management ---
|
|
1442
1351
|
|
|
@@ -1446,13 +1355,12 @@ async function handleTool(name, args) {
|
|
|
1446
1355
|
return text(`Group updated: ${(await getOfficialClient().updateChat(args.chat_id, { name: args.name, description: args.description })).updated}`);
|
|
1447
1356
|
case 'list_members':
|
|
1448
1357
|
return json(await getOfficialClient().listChatMembers(args.chat_id, { pageSize: args.page_size, pageToken: args.page_token }));
|
|
1449
|
-
case '
|
|
1450
|
-
const
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
return text(r.invalidIds.length ? `Removed (invalid IDs: ${r.invalidIds.join(', ')})` : 'Members removed');
|
|
1358
|
+
case 'manage_members': {
|
|
1359
|
+
const official = getOfficialClient();
|
|
1360
|
+
if (args.action === 'remove') {
|
|
1361
|
+
return json(await official.removeChatMembers(args.chat_id, args.member_ids));
|
|
1362
|
+
}
|
|
1363
|
+
return json(await official.addChatMembers(args.chat_id, args.member_ids));
|
|
1456
1364
|
}
|
|
1457
1365
|
|
|
1458
1366
|
// --- Official API: Doc Block Editing ---
|
|
@@ -1470,6 +1378,16 @@ async function handleTool(name, args) {
|
|
|
1470
1378
|
return json(await getOfficialClient().getBitableRecord(args.app_token, args.table_id, args.record_id));
|
|
1471
1379
|
case 'delete_bitable_table':
|
|
1472
1380
|
return text(`Table deleted: ${(await getOfficialClient().deleteBitableTable(args.app_token, args.table_id)).deleted}`);
|
|
1381
|
+
case 'get_bitable_meta':
|
|
1382
|
+
return json(await getOfficialClient().getBitableMeta(args.app_token));
|
|
1383
|
+
case 'update_bitable_table':
|
|
1384
|
+
return text(`Table renamed: ${(await getOfficialClient().updateBitableTable(args.app_token, args.table_id, args.name)).name}`);
|
|
1385
|
+
case 'create_bitable_view':
|
|
1386
|
+
return json(await getOfficialClient().createBitableView(args.app_token, args.table_id, args.view_name, args.view_type));
|
|
1387
|
+
case 'delete_bitable_view':
|
|
1388
|
+
return text(`View deleted: ${(await getOfficialClient().deleteBitableView(args.app_token, args.table_id, args.view_id)).deleted}`);
|
|
1389
|
+
case 'copy_bitable':
|
|
1390
|
+
return json(await getOfficialClient().copyBitable(args.app_token, args.name, args.folder_id));
|
|
1473
1391
|
|
|
1474
1392
|
// --- Official API: Drive File Operations ---
|
|
1475
1393
|
|
|
@@ -1480,53 +1398,22 @@ async function handleTool(name, args) {
|
|
|
1480
1398
|
case 'delete_file':
|
|
1481
1399
|
return text(`File deleted: task=${(await getOfficialClient().deleteFile(args.file_token, args.type)).taskId}`);
|
|
1482
1400
|
|
|
1483
|
-
// --- Official API: Calendar ---
|
|
1484
|
-
|
|
1485
|
-
case 'list_calendars':
|
|
1486
|
-
return json(await getOfficialClient().listCalendars());
|
|
1487
|
-
case 'create_calendar_event': {
|
|
1488
|
-
const event = { summary: args.summary, description: args.description || '' };
|
|
1489
|
-
event.start_time = { timestamp: args.start_time };
|
|
1490
|
-
event.end_time = { timestamp: args.end_time };
|
|
1491
|
-
if (args.location) event.location = { name: args.location };
|
|
1492
|
-
return json(await getOfficialClient().createCalendarEvent(args.calendar_id, event));
|
|
1493
|
-
}
|
|
1494
|
-
case 'list_calendar_events':
|
|
1495
|
-
return json(await getOfficialClient().listCalendarEvents(args.calendar_id, {
|
|
1496
|
-
startTime: args.start_time, endTime: args.end_time, pageSize: args.page_size,
|
|
1497
|
-
}));
|
|
1498
|
-
case 'delete_calendar_event':
|
|
1499
|
-
return text(`Event deleted: ${(await getOfficialClient().deleteCalendarEvent(args.calendar_id, args.event_id)).deleted}`);
|
|
1500
|
-
case 'get_freebusy':
|
|
1501
|
-
return json(await getOfficialClient().getFreeBusy(args.user_ids, args.start_time, args.end_time));
|
|
1502
|
-
|
|
1503
|
-
// --- Official API: Tasks ---
|
|
1504
|
-
|
|
1505
|
-
case 'create_task': {
|
|
1506
|
-
const task = { summary: args.summary };
|
|
1507
|
-
if (args.description) task.description = args.description;
|
|
1508
|
-
if (args.due) task.due = { timestamp: args.due };
|
|
1509
|
-
return json(await getOfficialClient().createTask(task));
|
|
1510
|
-
}
|
|
1511
|
-
case 'get_task':
|
|
1512
|
-
return json(await getOfficialClient().getTask(args.task_id));
|
|
1513
|
-
case 'list_tasks':
|
|
1514
|
-
return json(await getOfficialClient().listTasks({ pageSize: args.page_size, pageToken: args.page_token }));
|
|
1515
|
-
case 'update_task': {
|
|
1516
|
-
const task = {};
|
|
1517
|
-
if (args.summary) task.summary = args.summary;
|
|
1518
|
-
if (args.description) task.description = args.description;
|
|
1519
|
-
if (args.due) task.due = { timestamp: args.due };
|
|
1520
|
-
return json(await getOfficialClient().updateTask(args.task_id, task));
|
|
1521
|
-
}
|
|
1522
|
-
case 'complete_task':
|
|
1523
|
-
return text(`Task completed: ${(await getOfficialClient().completeTask(args.task_id)).completed}`);
|
|
1524
|
-
|
|
1525
1401
|
default:
|
|
1526
1402
|
return text(`Unknown tool: ${name}`);
|
|
1527
1403
|
}
|
|
1528
1404
|
}
|
|
1529
1405
|
|
|
1406
|
+
// --- Process-level error handlers ---
|
|
1407
|
+
// Prevent stray promise rejections or uncaught exceptions from killing the MCP server.
|
|
1408
|
+
process.on('uncaughtException', (err) => {
|
|
1409
|
+
console.error('[feishu-user-plugin] Uncaught exception:', err.message);
|
|
1410
|
+
console.error(err.stack);
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
process.on('unhandledRejection', (reason) => {
|
|
1414
|
+
console.error('[feishu-user-plugin] Unhandled rejection:', reason);
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1530
1417
|
async function main() {
|
|
1531
1418
|
const transport = new StdioServerTransport();
|
|
1532
1419
|
await server.connect(transport);
|
package/src/oauth.js
CHANGED
|
@@ -22,7 +22,8 @@ const APP_SECRET = creds.LARK_APP_SECRET;
|
|
|
22
22
|
const PORT = 9997;
|
|
23
23
|
const REDIRECT_URI = `http://127.0.0.1:${PORT}/callback`;
|
|
24
24
|
// offline_access is required to get refresh_token for auto-renewal
|
|
25
|
-
|
|
25
|
+
// Write scopes (docx:document, drive:drive, bitable:app) allow creating resources as the user, not the app
|
|
26
|
+
const SCOPES = 'offline_access auth:user.id:read im:message im:message:readonly im:chat im:chat:readonly contact:user.base:readonly contact:user.id:readonly docx:document drive:drive bitable:app wiki:wiki:readonly';
|
|
26
27
|
|
|
27
28
|
if (!APP_ID || !APP_SECRET) {
|
|
28
29
|
console.error('Missing LARK_APP_ID or LARK_APP_SECRET.');
|