@t4dhg/mcp-factorial 4.0.0 → 6.0.0
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 +1 -1
- package/dist/api.d.ts +8 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +213 -285
- package/dist/api.js.map +1 -1
- package/dist/endpoints.d.ts +51 -0
- package/dist/endpoints.d.ts.map +1 -0
- package/dist/endpoints.js +63 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +22 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.js +95 -253
- package/dist/index.js.map +1 -1
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +2 -1
- package/dist/pagination.js.map +1 -1
- package/dist/schemas.d.ts +3 -3
- package/dist/schemas.js +1 -1
- package/dist/schemas.js.map +1 -1
- package/dist/tool-utils.d.ts +59 -0
- package/dist/tool-utils.d.ts.map +1 -0
- package/dist/tool-utils.js +71 -0
- package/dist/tool-utils.js.map +1 -0
- package/dist/utils.d.ts +33 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +48 -0
- package/dist/utils.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ loadEnv();
|
|
|
21
21
|
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
22
22
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
23
23
|
import * as z from 'zod';
|
|
24
|
+
import { cache } from './cache.js';
|
|
24
25
|
import {
|
|
25
26
|
// Employees - Read
|
|
26
27
|
listEmployees, getEmployee, searchEmployees,
|
|
@@ -65,6 +66,7 @@ createJobPosting, updateJobPosting, deleteJobPosting, createCandidate, updateCan
|
|
|
65
66
|
// Payroll (Read-only)
|
|
66
67
|
listPayrollSupplements, getPayrollSupplement, listTaxIdentifiers, getTaxIdentifier, listFamilySituations, getFamilySituation, } from './api.js';
|
|
67
68
|
import { formatPaginationInfo } from './pagination.js';
|
|
69
|
+
import { wrapHighRiskToolHandler, textResponse } from './tool-utils.js';
|
|
68
70
|
const server = new McpServer({
|
|
69
71
|
name: 'factorial-hr',
|
|
70
72
|
version: '3.0.0',
|
|
@@ -272,36 +274,17 @@ server.registerTool('update_employee', {
|
|
|
272
274
|
});
|
|
273
275
|
server.registerTool('terminate_employee', {
|
|
274
276
|
title: 'Terminate Employee',
|
|
275
|
-
description: 'Terminate an employee (soft delete). This is a
|
|
277
|
+
description: 'Terminate an employee (soft delete). This is a HIGH-RISK operation that requires confirmation.',
|
|
276
278
|
inputSchema: {
|
|
277
279
|
id: z.number().describe('The employee ID to terminate'),
|
|
278
280
|
terminated_on: z.string().describe('Termination date (YYYY-MM-DD)'),
|
|
279
281
|
reason: z.string().max(500).optional().describe('Termination reason'),
|
|
282
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
280
283
|
},
|
|
281
|
-
}, async ({ id, terminated_on, reason }) => {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
content: [
|
|
286
|
-
{
|
|
287
|
-
type: 'text',
|
|
288
|
-
text: `Employee terminated successfully. Termination date: ${terminated_on}\n\n${JSON.stringify(employee, null, 2)}`,
|
|
289
|
-
},
|
|
290
|
-
],
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
return {
|
|
295
|
-
content: [
|
|
296
|
-
{
|
|
297
|
-
type: 'text',
|
|
298
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
299
|
-
},
|
|
300
|
-
],
|
|
301
|
-
isError: true,
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
});
|
|
284
|
+
}, wrapHighRiskToolHandler('terminate_employee', async ({ id, terminated_on, reason }) => {
|
|
285
|
+
const employee = await terminateEmployee(id, terminated_on, reason);
|
|
286
|
+
return textResponse(`Employee terminated successfully. Termination date: ${terminated_on}\n\n${JSON.stringify(employee, null, 2)}`);
|
|
287
|
+
}));
|
|
305
288
|
// ============================================================================
|
|
306
289
|
// Team Tools
|
|
307
290
|
// ============================================================================
|
|
@@ -441,34 +424,15 @@ server.registerTool('update_team', {
|
|
|
441
424
|
});
|
|
442
425
|
server.registerTool('delete_team', {
|
|
443
426
|
title: 'Delete Team',
|
|
444
|
-
description: 'Delete a team. This is a
|
|
427
|
+
description: 'Delete a team. This is a HIGH-RISK operation that requires confirmation.',
|
|
445
428
|
inputSchema: {
|
|
446
429
|
id: z.number().describe('The team ID to delete'),
|
|
430
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
447
431
|
},
|
|
448
|
-
}, async ({ id }) => {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
content: [
|
|
453
|
-
{
|
|
454
|
-
type: 'text',
|
|
455
|
-
text: `Team ${id} deleted successfully.`,
|
|
456
|
-
},
|
|
457
|
-
],
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
catch (error) {
|
|
461
|
-
return {
|
|
462
|
-
content: [
|
|
463
|
-
{
|
|
464
|
-
type: 'text',
|
|
465
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
466
|
-
},
|
|
467
|
-
],
|
|
468
|
-
isError: true,
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
});
|
|
432
|
+
}, wrapHighRiskToolHandler('delete_team', async ({ id }) => {
|
|
433
|
+
await deleteTeam(id);
|
|
434
|
+
return textResponse(`Team ${id} deleted successfully.`);
|
|
435
|
+
}));
|
|
472
436
|
// ============================================================================
|
|
473
437
|
// Location Tools
|
|
474
438
|
// ============================================================================
|
|
@@ -616,34 +580,15 @@ server.registerTool('update_location', {
|
|
|
616
580
|
});
|
|
617
581
|
server.registerTool('delete_location', {
|
|
618
582
|
title: 'Delete Location',
|
|
619
|
-
description: 'Delete a location. This is a
|
|
583
|
+
description: 'Delete a location. This is a HIGH-RISK operation that requires confirmation.',
|
|
620
584
|
inputSchema: {
|
|
621
585
|
id: z.number().describe('The location ID to delete'),
|
|
586
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
622
587
|
},
|
|
623
|
-
}, async ({ id }) => {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
content: [
|
|
628
|
-
{
|
|
629
|
-
type: 'text',
|
|
630
|
-
text: `Location ${id} deleted successfully.`,
|
|
631
|
-
},
|
|
632
|
-
],
|
|
633
|
-
};
|
|
634
|
-
}
|
|
635
|
-
catch (error) {
|
|
636
|
-
return {
|
|
637
|
-
content: [
|
|
638
|
-
{
|
|
639
|
-
type: 'text',
|
|
640
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
641
|
-
},
|
|
642
|
-
],
|
|
643
|
-
isError: true,
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
});
|
|
588
|
+
}, wrapHighRiskToolHandler('delete_location', async ({ id }) => {
|
|
589
|
+
await deleteLocation(id);
|
|
590
|
+
return textResponse(`Location ${id} deleted successfully.`);
|
|
591
|
+
}));
|
|
647
592
|
// ============================================================================
|
|
648
593
|
// Contract Tools
|
|
649
594
|
// ============================================================================
|
|
@@ -951,34 +896,15 @@ server.registerTool('update_leave', {
|
|
|
951
896
|
});
|
|
952
897
|
server.registerTool('cancel_leave', {
|
|
953
898
|
title: 'Cancel Leave Request',
|
|
954
|
-
description: 'Cancel a leave request.',
|
|
899
|
+
description: 'Cancel a leave request. This operation requires confirmation.',
|
|
955
900
|
inputSchema: {
|
|
956
901
|
id: z.number().describe('The leave ID to cancel'),
|
|
902
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this operation'),
|
|
957
903
|
},
|
|
958
|
-
}, async ({ id }) => {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
content: [
|
|
963
|
-
{
|
|
964
|
-
type: 'text',
|
|
965
|
-
text: `Leave request ${id} cancelled successfully.`,
|
|
966
|
-
},
|
|
967
|
-
],
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
catch (error) {
|
|
971
|
-
return {
|
|
972
|
-
content: [
|
|
973
|
-
{
|
|
974
|
-
type: 'text',
|
|
975
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
976
|
-
},
|
|
977
|
-
],
|
|
978
|
-
isError: true,
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
|
-
});
|
|
904
|
+
}, wrapHighRiskToolHandler('cancel_leave', async ({ id }) => {
|
|
905
|
+
await cancelLeave(id);
|
|
906
|
+
return textResponse(`Leave request ${id} cancelled successfully.`);
|
|
907
|
+
}));
|
|
982
908
|
server.registerTool('approve_leave', {
|
|
983
909
|
title: 'Approve Leave Request',
|
|
984
910
|
description: 'Approve a pending leave request.',
|
|
@@ -1012,35 +938,16 @@ server.registerTool('approve_leave', {
|
|
|
1012
938
|
});
|
|
1013
939
|
server.registerTool('reject_leave', {
|
|
1014
940
|
title: 'Reject Leave Request',
|
|
1015
|
-
description: 'Reject a pending leave request.',
|
|
941
|
+
description: 'Reject a pending leave request. This operation requires confirmation.',
|
|
1016
942
|
inputSchema: {
|
|
1017
943
|
id: z.number().describe('The leave ID to reject'),
|
|
1018
944
|
reason: z.string().max(500).optional().describe('Rejection reason'),
|
|
945
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this operation'),
|
|
1019
946
|
},
|
|
1020
|
-
}, async ({ id, reason }) => {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
content: [
|
|
1025
|
-
{
|
|
1026
|
-
type: 'text',
|
|
1027
|
-
text: `Leave request rejected:\n\n${JSON.stringify(leave, null, 2)}`,
|
|
1028
|
-
},
|
|
1029
|
-
],
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
catch (error) {
|
|
1033
|
-
return {
|
|
1034
|
-
content: [
|
|
1035
|
-
{
|
|
1036
|
-
type: 'text',
|
|
1037
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1038
|
-
},
|
|
1039
|
-
],
|
|
1040
|
-
isError: true,
|
|
1041
|
-
};
|
|
1042
|
-
}
|
|
1043
|
-
});
|
|
947
|
+
}, wrapHighRiskToolHandler('reject_leave', async ({ id, reason }) => {
|
|
948
|
+
const leave = await rejectLeave(id, reason ? { reason } : undefined);
|
|
949
|
+
return textResponse(`Leave request rejected:\n\n${JSON.stringify(leave, null, 2)}`);
|
|
950
|
+
}));
|
|
1044
951
|
// ============================================================================
|
|
1045
952
|
// Attendance / Shift Tools
|
|
1046
953
|
// ============================================================================
|
|
@@ -1194,34 +1101,15 @@ server.registerTool('update_shift', {
|
|
|
1194
1101
|
});
|
|
1195
1102
|
server.registerTool('delete_shift', {
|
|
1196
1103
|
title: 'Delete Shift',
|
|
1197
|
-
description: 'Delete a shift record.',
|
|
1104
|
+
description: 'Delete a shift record. This operation requires confirmation.',
|
|
1198
1105
|
inputSchema: {
|
|
1199
1106
|
id: z.number().describe('The shift ID to delete'),
|
|
1107
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this operation'),
|
|
1200
1108
|
},
|
|
1201
|
-
}, async ({ id }) => {
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
content: [
|
|
1206
|
-
{
|
|
1207
|
-
type: 'text',
|
|
1208
|
-
text: `Shift ${id} deleted successfully.`,
|
|
1209
|
-
},
|
|
1210
|
-
],
|
|
1211
|
-
};
|
|
1212
|
-
}
|
|
1213
|
-
catch (error) {
|
|
1214
|
-
return {
|
|
1215
|
-
content: [
|
|
1216
|
-
{
|
|
1217
|
-
type: 'text',
|
|
1218
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1219
|
-
},
|
|
1220
|
-
],
|
|
1221
|
-
isError: true,
|
|
1222
|
-
};
|
|
1223
|
-
}
|
|
1224
|
-
});
|
|
1109
|
+
}, wrapHighRiskToolHandler('delete_shift', async ({ id }) => {
|
|
1110
|
+
await deleteShift(id);
|
|
1111
|
+
return textResponse(`Shift ${id} deleted successfully.`);
|
|
1112
|
+
}));
|
|
1225
1113
|
// ============================================================================
|
|
1226
1114
|
// Document Tools (Read-Only)
|
|
1227
1115
|
// ============================================================================
|
|
@@ -1334,6 +1222,18 @@ server.registerTool('get_document', {
|
|
|
1334
1222
|
}, async ({ id }) => {
|
|
1335
1223
|
try {
|
|
1336
1224
|
const document = await getDocument(id);
|
|
1225
|
+
// Defensive check for undefined/null document
|
|
1226
|
+
if (!document) {
|
|
1227
|
+
return {
|
|
1228
|
+
content: [
|
|
1229
|
+
{
|
|
1230
|
+
type: 'text',
|
|
1231
|
+
text: `Error: Document with ID ${id} exists but returned no data. This may be a Factorial API issue.`,
|
|
1232
|
+
},
|
|
1233
|
+
],
|
|
1234
|
+
isError: true,
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1337
1237
|
return {
|
|
1338
1238
|
content: [
|
|
1339
1239
|
{
|
|
@@ -1369,12 +1269,12 @@ server.registerTool('get_employee_documents', {
|
|
|
1369
1269
|
// Create summary format aligned with list_documents tool
|
|
1370
1270
|
const summary = result.data.map(d => ({
|
|
1371
1271
|
id: d.id,
|
|
1372
|
-
name: d.name,
|
|
1272
|
+
name: d.name ?? '[No name]',
|
|
1373
1273
|
folder_id: d.folder_id,
|
|
1374
1274
|
employee_id: d.employee_id,
|
|
1375
1275
|
author_id: d.author_id,
|
|
1376
|
-
mime_type: d.mime_type,
|
|
1377
|
-
size_bytes: d.size_bytes,
|
|
1276
|
+
mime_type: d.mime_type ?? 'unknown',
|
|
1277
|
+
size_bytes: d.size_bytes ?? 0,
|
|
1378
1278
|
}));
|
|
1379
1279
|
return {
|
|
1380
1280
|
content: [
|
|
@@ -1608,29 +1508,15 @@ server.registerTool('update_project', {
|
|
|
1608
1508
|
});
|
|
1609
1509
|
server.registerTool('delete_project', {
|
|
1610
1510
|
title: 'Delete Project',
|
|
1611
|
-
description: 'Delete a project. This is a
|
|
1511
|
+
description: 'Delete a project. This is a HIGH-RISK operation that requires confirmation.',
|
|
1612
1512
|
inputSchema: {
|
|
1613
1513
|
id: z.number().describe('The project ID to delete'),
|
|
1514
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
1614
1515
|
},
|
|
1615
|
-
}, async ({ id }) => {
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
content: [{ type: 'text', text: `Project ${id} deleted successfully.` }],
|
|
1620
|
-
};
|
|
1621
|
-
}
|
|
1622
|
-
catch (error) {
|
|
1623
|
-
return {
|
|
1624
|
-
content: [
|
|
1625
|
-
{
|
|
1626
|
-
type: 'text',
|
|
1627
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1628
|
-
},
|
|
1629
|
-
],
|
|
1630
|
-
isError: true,
|
|
1631
|
-
};
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1516
|
+
}, wrapHighRiskToolHandler('delete_project', async ({ id }) => {
|
|
1517
|
+
await deleteProject(id);
|
|
1518
|
+
return textResponse(`Project ${id} deleted successfully.`);
|
|
1519
|
+
}));
|
|
1634
1520
|
server.registerTool('list_project_tasks', {
|
|
1635
1521
|
title: 'List Project Tasks',
|
|
1636
1522
|
description: 'Get tasks for a project.',
|
|
@@ -2067,29 +1953,15 @@ server.registerTool('update_training', {
|
|
|
2067
1953
|
});
|
|
2068
1954
|
server.registerTool('delete_training', {
|
|
2069
1955
|
title: 'Delete Training',
|
|
2070
|
-
description: 'Delete a training program.',
|
|
1956
|
+
description: 'Delete a training program. This is a HIGH-RISK operation that requires confirmation.',
|
|
2071
1957
|
inputSchema: {
|
|
2072
1958
|
id: z.number().describe('The training ID to delete'),
|
|
1959
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
2073
1960
|
},
|
|
2074
|
-
}, async ({ id }) => {
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
content: [{ type: 'text', text: `Training ${id} deleted successfully.` }],
|
|
2079
|
-
};
|
|
2080
|
-
}
|
|
2081
|
-
catch (error) {
|
|
2082
|
-
return {
|
|
2083
|
-
content: [
|
|
2084
|
-
{
|
|
2085
|
-
type: 'text',
|
|
2086
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
2087
|
-
},
|
|
2088
|
-
],
|
|
2089
|
-
isError: true,
|
|
2090
|
-
};
|
|
2091
|
-
}
|
|
2092
|
-
});
|
|
1961
|
+
}, wrapHighRiskToolHandler('delete_training', async ({ id }) => {
|
|
1962
|
+
await deleteTraining(id);
|
|
1963
|
+
return textResponse(`Training ${id} deleted successfully.`);
|
|
1964
|
+
}));
|
|
2093
1965
|
server.registerTool('list_training_sessions', {
|
|
2094
1966
|
title: 'List Training Sessions',
|
|
2095
1967
|
description: 'Get sessions for a training program.',
|
|
@@ -2594,29 +2466,15 @@ server.registerTool('update_job_posting', {
|
|
|
2594
2466
|
});
|
|
2595
2467
|
server.registerTool('delete_job_posting', {
|
|
2596
2468
|
title: 'Delete Job Posting',
|
|
2597
|
-
description: 'Delete a job posting.',
|
|
2469
|
+
description: 'Delete a job posting. This is a HIGH-RISK operation that requires confirmation.',
|
|
2598
2470
|
inputSchema: {
|
|
2599
2471
|
id: z.number().describe('Job posting ID to delete'),
|
|
2472
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
2600
2473
|
},
|
|
2601
|
-
}, async ({ id }) => {
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
content: [{ type: 'text', text: `Job posting ${id} deleted successfully.` }],
|
|
2606
|
-
};
|
|
2607
|
-
}
|
|
2608
|
-
catch (error) {
|
|
2609
|
-
return {
|
|
2610
|
-
content: [
|
|
2611
|
-
{
|
|
2612
|
-
type: 'text',
|
|
2613
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
2614
|
-
},
|
|
2615
|
-
],
|
|
2616
|
-
isError: true,
|
|
2617
|
-
};
|
|
2618
|
-
}
|
|
2619
|
-
});
|
|
2474
|
+
}, wrapHighRiskToolHandler('delete_job_posting', async ({ id }) => {
|
|
2475
|
+
await deleteJobPosting(id);
|
|
2476
|
+
return textResponse(`Job posting ${id} deleted successfully.`);
|
|
2477
|
+
}));
|
|
2620
2478
|
server.registerTool('list_candidates', {
|
|
2621
2479
|
title: 'List Candidates',
|
|
2622
2480
|
description: 'Get all candidates.',
|
|
@@ -2740,29 +2598,15 @@ server.registerTool('update_candidate', {
|
|
|
2740
2598
|
});
|
|
2741
2599
|
server.registerTool('delete_candidate', {
|
|
2742
2600
|
title: 'Delete Candidate',
|
|
2743
|
-
description: 'Delete a candidate.',
|
|
2601
|
+
description: 'Delete a candidate. This is a HIGH-RISK operation that requires confirmation.',
|
|
2744
2602
|
inputSchema: {
|
|
2745
2603
|
id: z.number().describe('Candidate ID to delete'),
|
|
2604
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
2746
2605
|
},
|
|
2747
|
-
}, async ({ id }) => {
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
content: [{ type: 'text', text: `Candidate ${id} deleted successfully.` }],
|
|
2752
|
-
};
|
|
2753
|
-
}
|
|
2754
|
-
catch (error) {
|
|
2755
|
-
return {
|
|
2756
|
-
content: [
|
|
2757
|
-
{
|
|
2758
|
-
type: 'text',
|
|
2759
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
2760
|
-
},
|
|
2761
|
-
],
|
|
2762
|
-
isError: true,
|
|
2763
|
-
};
|
|
2764
|
-
}
|
|
2765
|
-
});
|
|
2606
|
+
}, wrapHighRiskToolHandler('delete_candidate', async ({ id }) => {
|
|
2607
|
+
await deleteCandidate(id);
|
|
2608
|
+
return textResponse(`Candidate ${id} deleted successfully.`);
|
|
2609
|
+
}));
|
|
2766
2610
|
server.registerTool('list_applications', {
|
|
2767
2611
|
title: 'List Applications',
|
|
2768
2612
|
description: 'Get job applications.',
|
|
@@ -2881,29 +2725,15 @@ server.registerTool('update_application', {
|
|
|
2881
2725
|
});
|
|
2882
2726
|
server.registerTool('delete_application', {
|
|
2883
2727
|
title: 'Delete Application',
|
|
2884
|
-
description: 'Delete a job application.',
|
|
2728
|
+
description: 'Delete a job application. This is a HIGH-RISK operation that requires confirmation.',
|
|
2885
2729
|
inputSchema: {
|
|
2886
2730
|
id: z.number().describe('Application ID to delete'),
|
|
2731
|
+
confirm: z.boolean().optional().describe('Set to true to confirm this high-risk operation'),
|
|
2887
2732
|
},
|
|
2888
|
-
}, async ({ id }) => {
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
content: [{ type: 'text', text: `Application ${id} deleted successfully.` }],
|
|
2893
|
-
};
|
|
2894
|
-
}
|
|
2895
|
-
catch (error) {
|
|
2896
|
-
return {
|
|
2897
|
-
content: [
|
|
2898
|
-
{
|
|
2899
|
-
type: 'text',
|
|
2900
|
-
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
2901
|
-
},
|
|
2902
|
-
],
|
|
2903
|
-
isError: true,
|
|
2904
|
-
};
|
|
2905
|
-
}
|
|
2906
|
-
});
|
|
2733
|
+
}, wrapHighRiskToolHandler('delete_application', async ({ id }) => {
|
|
2734
|
+
await deleteApplication(id);
|
|
2735
|
+
return textResponse(`Application ${id} deleted successfully.`);
|
|
2736
|
+
}));
|
|
2907
2737
|
server.registerTool('advance_application', {
|
|
2908
2738
|
title: 'Advance Application',
|
|
2909
2739
|
description: 'Move an application to the next hiring stage.',
|
|
@@ -3551,6 +3381,18 @@ Please provide:
|
|
|
3551
3381
|
};
|
|
3552
3382
|
});
|
|
3553
3383
|
// ============================================================================
|
|
3384
|
+
// Graceful Shutdown
|
|
3385
|
+
// ============================================================================
|
|
3386
|
+
/**
|
|
3387
|
+
* Clean up resources on process termination
|
|
3388
|
+
*/
|
|
3389
|
+
function shutdown() {
|
|
3390
|
+
cache.destroy();
|
|
3391
|
+
process.exit(0);
|
|
3392
|
+
}
|
|
3393
|
+
process.on('SIGINT', shutdown);
|
|
3394
|
+
process.on('SIGTERM', shutdown);
|
|
3395
|
+
// ============================================================================
|
|
3554
3396
|
// Start Server
|
|
3555
3397
|
// ============================================================================
|
|
3556
3398
|
async function main() {
|