itfin-mcp 0.1.3 → 0.1.4
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/server.js +20 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ In CLI mode each tool is a command without the `itfin_` prefix: `itfin_get_entri
|
|
|
78
78
|
| `itfin_get_entries` | Your time entries, and which days are open, closed or in the future |
|
|
79
79
|
| `itfin_create_entry` / `itfin_update_entry` / `itfin_delete_entry` | Change time entries |
|
|
80
80
|
| `itfin_get_workspace_settings` | Minimum comment length; whether reopen requests are on |
|
|
81
|
-
| `itfin_request_reopen` / `itfin_list_reopen_requests` | Ask a manager to reopen closed days; see your requests |
|
|
81
|
+
| `itfin_request_reopen` / `itfin_list_reopen_requests` / `itfin_cancel_reopen_request` | Ask a manager to reopen closed days; see or cancel your requests |
|
|
82
82
|
| `itfin_list_leave_types` | Leave types and reasons you can use |
|
|
83
83
|
| `itfin_request_leave` | Request full days, or some hours of one day |
|
|
84
84
|
| `itfin_list_leave_requests` / `itfin_cancel_leave_request` | See or cancel your leave requests |
|
package/dist/server.js
CHANGED
|
@@ -146,7 +146,9 @@ export function createItfinServer(deps) {
|
|
|
146
146
|
return me.Id;
|
|
147
147
|
}
|
|
148
148
|
async function reopenRequests() {
|
|
149
|
-
|
|
149
|
+
const requests = await itfin.get("/v1/requests/my", { "filter[requestType]": "OpenReporting", page: 1, size: 50 });
|
|
150
|
+
// Also filtered here, so itfin_cancel_reopen_request can't reach a leave request if ITFin ignores the filter.
|
|
151
|
+
return requests.filter((r) => (r.RequestType ?? "OpenReporting") === "OpenReporting");
|
|
150
152
|
}
|
|
151
153
|
async function reopenRequestsCovering(date) {
|
|
152
154
|
return (await reopenRequests()).map(toReopenRequest).filter((r) => r.from <= date && date <= r.to);
|
|
@@ -348,6 +350,23 @@ export function createItfinServer(deps) {
|
|
|
348
350
|
}
|
|
349
351
|
return fileReopenRequest({ from: args.from, to: args.to, reason: args.reason });
|
|
350
352
|
}));
|
|
353
|
+
server.registerTool("itfin_cancel_reopen_request", {
|
|
354
|
+
title: "Cancel a reopen request",
|
|
355
|
+
description: "Cancels (deletes) one of the user's reopen requests by id (from itfin_list_reopen_requests). Only call this when the user asked to cancel that request. " +
|
|
356
|
+
"Works for pending requests; whether an approved one can still be cancelled is up to ITFin.",
|
|
357
|
+
inputSchema: { id: z.number().int() },
|
|
358
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
359
|
+
}, ({ id }) => handle(async () => {
|
|
360
|
+
// Look the id up among the user's reopen requests, so this tool can't cancel other kinds of requests.
|
|
361
|
+
const request = (await reopenRequests()).find((r) => r.Id === id);
|
|
362
|
+
if (!request)
|
|
363
|
+
throw new ToolError("NOT_FOUND", `No reopen request ${id} among the user's recent reopen requests.`);
|
|
364
|
+
if ([...CLOSED_REQUEST_STATUSES, "Declined"].includes(request.Status)) {
|
|
365
|
+
throw new ToolError("VALIDATION", `Reopen request ${id} is already ${request.Status}.`, { request: toReopenRequest(request) });
|
|
366
|
+
}
|
|
367
|
+
await itfin.request("DELETE", `/v1/requests/${id}`);
|
|
368
|
+
return { cancelled: id, request: toReopenRequest(request) };
|
|
369
|
+
}));
|
|
351
370
|
/** Leave types the user can request, as the web app's "Request time off" form offers them. */
|
|
352
371
|
async function leaveTypes() {
|
|
353
372
|
const [types, settings] = await Promise.all([
|