formbro-mcp-server 1.0.1 → 1.0.2
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 +42 -24
- package/dist/index.js +58 -14
- package/dist/index.js.map +1 -1
- package/dist/services/api-client.d.ts +7 -0
- package/dist/services/api-client.d.ts.map +1 -1
- package/dist/services/api-client.js +113 -2
- package/dist/services/api-client.js.map +1 -1
- package/dist/services/idempotency.d.ts +6 -0
- package/dist/services/idempotency.d.ts.map +1 -0
- package/dist/services/idempotency.js +9 -0
- package/dist/services/idempotency.js.map +1 -0
- package/dist/tools/applications-extra.d.ts +3 -0
- package/dist/tools/applications-extra.d.ts.map +1 -0
- package/dist/tools/applications-extra.js +62 -0
- package/dist/tools/applications-extra.js.map +1 -0
- package/dist/tools/audit.d.ts +3 -0
- package/dist/tools/audit.d.ts.map +1 -0
- package/dist/tools/audit.js +34 -0
- package/dist/tools/audit.js.map +1 -0
- package/dist/tools/employers.d.ts.map +1 -1
- package/dist/tools/employers.js +17 -29
- package/dist/tools/employers.js.map +1 -1
- package/dist/tools/export.d.ts +3 -0
- package/dist/tools/export.d.ts.map +1 -0
- package/dist/tools/export.js +247 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/extract.d.ts +3 -0
- package/dist/tools/extract.d.ts.map +1 -0
- package/dist/tools/extract.js +208 -0
- package/dist/tools/extract.js.map +1 -0
- package/dist/tools/patch.d.ts +10 -0
- package/dist/tools/patch.d.ts.map +1 -0
- package/dist/tools/patch.js +276 -0
- package/dist/tools/patch.js.map +1 -0
- package/dist/tools/program-keys.d.ts +3 -0
- package/dist/tools/program-keys.d.ts.map +1 -0
- package/dist/tools/program-keys.js +13 -0
- package/dist/tools/program-keys.js.map +1 -0
- package/dist/tools/system.d.ts +3 -0
- package/dist/tools/system.d.ts.map +1 -0
- package/dist/tools/system.js +84 -0
- package/dist/tools/system.js.map +1 -0
- package/dist/tools/validate.d.ts +3 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +68 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/tools/write.d.ts +4 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +786 -0
- package/dist/tools/write.js.map +1 -0
- package/package.json +7 -3
- package/server.json +67 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { makeApiRequest, handleApiError } from "../services/api-client.js";
|
|
3
|
+
import { buildApplicationPatchUrl, expandDotNotation, getProgramInfo } from "./patch.js";
|
|
4
|
+
import { normalizeProgramKey } from "./program-keys.js";
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Input Schemas
|
|
7
|
+
// ============================================================================
|
|
8
|
+
const ExtractFromTextSchema = z.object({
|
|
9
|
+
text: z.string().describe("Raw text content to extract structured immigration data from. " +
|
|
10
|
+
"If you have a file (PDF, DOCX, image, etc.), read its content first and pass the extracted text here."),
|
|
11
|
+
program_key: z.string().describe("Program key context for extraction (e.g. sp-out, pgp, hws)."),
|
|
12
|
+
entity_type: z.string().describe("Entity type to extract into: applicant, application, employer."),
|
|
13
|
+
entity_id: z.string().optional().describe("Optional entity ID to use as extraction context."),
|
|
14
|
+
sub_object_type: z.string().optional().describe("Optional sub-object type within the entity (e.g. passport)."),
|
|
15
|
+
model: z.string().optional().describe("AI model override for extraction (defaults to server config)."),
|
|
16
|
+
}).strict();
|
|
17
|
+
const GetImportJsonContractSchema = z.object({
|
|
18
|
+
program_key: z.string().describe("Program key context (e.g. sp-out, sps, hws)."),
|
|
19
|
+
entity_type: z.string().describe("Entity type: applicant, application, sponsor, co_signer, employer, or position."),
|
|
20
|
+
sub_object_type: z.string().optional().describe("Optional top-level model field to extract. Use 'personid' for passport data, not 'passport'."),
|
|
21
|
+
}).strict();
|
|
22
|
+
const ApplyExtractedJsonSchema = z.object({
|
|
23
|
+
target_entity_id: z.string().describe("MongoDB ObjectId of the entity to update."),
|
|
24
|
+
target_entity_type: z.enum(["applicant", "application", "employer"]).describe("Stored entity type to update. Sponsors/co-signers/dependents are stored as applicant records."),
|
|
25
|
+
program_key: z.string().optional().describe("Required when target_entity_type=application."),
|
|
26
|
+
extracted_json: z.record(z.unknown()).or(z.array(z.unknown())).describe("JSON already extracted by the MCP consumer using get_import_json_contract."),
|
|
27
|
+
sub_object_type: z.string().optional().describe("If provided, wraps extracted_json under this top-level field before saving."),
|
|
28
|
+
expected_version: z.number().optional().describe("Optimistic locking version for application/applicant patches."),
|
|
29
|
+
}).strict();
|
|
30
|
+
const GetExtractTaskStatusSchema = z.object({
|
|
31
|
+
task_id: z.string().describe("Task ID returned by a previous async extraction call."),
|
|
32
|
+
}).strict();
|
|
33
|
+
function wrapExtractedJson(extracted_json, sub_object_type) {
|
|
34
|
+
if (!sub_object_type)
|
|
35
|
+
return extracted_json;
|
|
36
|
+
return { [sub_object_type]: extracted_json };
|
|
37
|
+
}
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Tool Registration
|
|
40
|
+
// ============================================================================
|
|
41
|
+
export function registerExtractTools(server) {
|
|
42
|
+
// 0. get_import_json_contract
|
|
43
|
+
server.registerTool("get_import_json_contract", {
|
|
44
|
+
title: "Get Import JSON Contract",
|
|
45
|
+
description: "Preferred MCP import flow. Returns the JSON Schema and extraction prompt that the MCP consumer should use locally. " +
|
|
46
|
+
"The consumer reads files/text, extracts JSON itself, then calls apply_extracted_json. " +
|
|
47
|
+
"Use sub_object_type='personid' for passport data.",
|
|
48
|
+
inputSchema: GetImportJsonContractSchema.shape,
|
|
49
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
50
|
+
}, async ({ program_key, entity_type, sub_object_type }) => {
|
|
51
|
+
try {
|
|
52
|
+
const params = {
|
|
53
|
+
program_key: normalizeProgramKey(program_key),
|
|
54
|
+
entity_type,
|
|
55
|
+
};
|
|
56
|
+
if (sub_object_type)
|
|
57
|
+
params.sub_object_type = sub_object_type;
|
|
58
|
+
const data = await makeApiRequest("/api/import/schema", "GET", undefined, params);
|
|
59
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// 0b. apply_extracted_json
|
|
66
|
+
server.registerTool("apply_extracted_json", {
|
|
67
|
+
title: "Apply Extracted JSON",
|
|
68
|
+
description: "Save JSON that the MCP consumer already extracted using get_import_json_contract. " +
|
|
69
|
+
"This does not run FormBro backend AI extraction. It patches the target applicant, application, or employer.",
|
|
70
|
+
inputSchema: ApplyExtractedJsonSchema.shape,
|
|
71
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
72
|
+
}, async ({ target_entity_id, target_entity_type, program_key, extracted_json, sub_object_type, expected_version }) => {
|
|
73
|
+
try {
|
|
74
|
+
const payload = wrapExtractedJson(extracted_json, sub_object_type);
|
|
75
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
76
|
+
return {
|
|
77
|
+
isError: true,
|
|
78
|
+
content: [{ type: "text", text: "Error: extracted_json must be a JSON object unless sub_object_type is provided." }],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (target_entity_type === "applicant") {
|
|
82
|
+
const params = { skip_validation: true };
|
|
83
|
+
if (expected_version !== undefined)
|
|
84
|
+
params.if_match = expected_version;
|
|
85
|
+
const data = await makeApiRequest(`/api/applicants/${encodeURIComponent(target_entity_id)}`, "PATCH", expandDotNotation(payload), params);
|
|
86
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
87
|
+
}
|
|
88
|
+
if (target_entity_type === "employer") {
|
|
89
|
+
const data = await makeApiRequest(`/api/lmia/employers/${encodeURIComponent(target_entity_id)}`, "PATCH", payload);
|
|
90
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
91
|
+
}
|
|
92
|
+
if (!program_key) {
|
|
93
|
+
return {
|
|
94
|
+
isError: true,
|
|
95
|
+
content: [{ type: "text", text: "Error: program_key is required when target_entity_type='application'." }],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const progInfo = await getProgramInfo(program_key);
|
|
99
|
+
if (!progInfo) {
|
|
100
|
+
return {
|
|
101
|
+
isError: true,
|
|
102
|
+
content: [{ type: "text", text: `Error: Unknown program_key '${program_key}'. Use list_programs to find valid keys.` }],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const params = { skip_validation: true };
|
|
106
|
+
if (expected_version !== undefined)
|
|
107
|
+
params.if_match = expected_version;
|
|
108
|
+
const url = buildApplicationPatchUrl(progInfo.api_endpoint, progInfo.category, target_entity_id);
|
|
109
|
+
const data = await makeApiRequest(url, "PATCH", payload, params);
|
|
110
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// 1. extract_from_text
|
|
117
|
+
server.registerTool("extract_from_text", {
|
|
118
|
+
title: "Extract Data from Text",
|
|
119
|
+
description: "Returns parsed dict only; does NOT create or update records. " +
|
|
120
|
+
"Legacy flow: this asks FormBro backend AI to extract from text. " +
|
|
121
|
+
"Prefer get_import_json_contract + local client extraction + apply_extracted_json for MCP clients. " +
|
|
122
|
+
"Extracts structured immigration data from raw text. " +
|
|
123
|
+
"sub_object_type must be a top-level model field; use 'personid' for passport data.",
|
|
124
|
+
inputSchema: ExtractFromTextSchema.shape,
|
|
125
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
126
|
+
}, async ({ text, program_key, entity_type, entity_id, sub_object_type, model }) => {
|
|
127
|
+
try {
|
|
128
|
+
const body = { text, program_key, entity_type };
|
|
129
|
+
if (entity_id)
|
|
130
|
+
body.entity_id = entity_id;
|
|
131
|
+
if (sub_object_type)
|
|
132
|
+
body.sub_object_type = sub_object_type;
|
|
133
|
+
if (model)
|
|
134
|
+
body.model = model;
|
|
135
|
+
const data = await makeApiRequest("/api/import/text", "POST", body);
|
|
136
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// 2. get_extract_task_status
|
|
143
|
+
server.registerTool("get_extract_task_status", {
|
|
144
|
+
title: "Get Extract Task Status",
|
|
145
|
+
description: "Returns parsed dict only; does NOT create or update records. " +
|
|
146
|
+
"Poll the status of an async extraction task. " +
|
|
147
|
+
"Returns status (pending|running|completed|failed) and extracted data when completed.",
|
|
148
|
+
inputSchema: GetExtractTaskStatusSchema.shape,
|
|
149
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
150
|
+
}, async ({ task_id }) => {
|
|
151
|
+
try {
|
|
152
|
+
const data = await makeApiRequest(`/api/import/task/${encodeURIComponent(task_id)}`, "GET");
|
|
153
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
// 3. list_extract_models
|
|
160
|
+
server.registerTool("list_extract_models", {
|
|
161
|
+
title: "List Available Extract AI Models",
|
|
162
|
+
description: "Returns parsed dict only; does NOT create or update records. " +
|
|
163
|
+
"List all AI models available for extraction.",
|
|
164
|
+
inputSchema: z.object({}).strict().shape,
|
|
165
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
166
|
+
}, async () => {
|
|
167
|
+
try {
|
|
168
|
+
const data = await makeApiRequest("/api/import/models", "GET");
|
|
169
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
// 4. list_extract_formats
|
|
176
|
+
server.registerTool("list_extract_formats", {
|
|
177
|
+
title: "List Supported Extract File Formats",
|
|
178
|
+
description: "Returns parsed dict only; does NOT create or update records. " +
|
|
179
|
+
"List all file formats the extraction engine can read (pdf, docx, jpg, png, etc.).",
|
|
180
|
+
inputSchema: z.object({}).strict().shape,
|
|
181
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
182
|
+
}, async () => {
|
|
183
|
+
try {
|
|
184
|
+
const data = await makeApiRequest("/api/import/formats", "GET");
|
|
185
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
// 5. clear_extract_cache
|
|
192
|
+
server.registerTool("clear_extract_cache", {
|
|
193
|
+
title: "Clear Extract Cache",
|
|
194
|
+
description: "Returns parsed dict only; does NOT create or update records. " +
|
|
195
|
+
"Clear the server-side extraction cache when previously extracted data is stale.",
|
|
196
|
+
inputSchema: z.object({}).strict().shape,
|
|
197
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
198
|
+
}, async () => {
|
|
199
|
+
try {
|
|
200
|
+
const data = await makeApiRequest("/api/import/cache/clear", "POST", {});
|
|
201
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/tools/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare function getProgramInfo(program_key: string): Promise<{
|
|
3
|
+
api_endpoint: string;
|
|
4
|
+
category: string;
|
|
5
|
+
form_ids?: Record<string, string>;
|
|
6
|
+
} | null>;
|
|
7
|
+
export declare function buildApplicationPatchUrl(api_endpoint: string, category: string, application_id: string): string;
|
|
8
|
+
export declare function expandDotNotation(updates: Record<string, unknown>): Record<string, unknown>;
|
|
9
|
+
export declare function registerPatchTools(server: McpServer): void;
|
|
10
|
+
//# sourceMappingURL=patch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/tools/patch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0EpE,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,GAAG,IAAI,CAAC,CAsBR;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAO/G;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsB3F;AA4BD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoL1D"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { makeApiRequest, handleApiError } from "../services/api-client.js";
|
|
3
|
+
import { getProgramLookupKeys } from "./program-keys.js";
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Input Schemas
|
|
6
|
+
// ============================================================================
|
|
7
|
+
const PatchPersonSchema = z.object({
|
|
8
|
+
person_id: z.string().describe("Person (applicant) MongoDB ObjectId."),
|
|
9
|
+
updates: z.record(z.unknown()).describe("Partial update dict matching the applicant model fields. " +
|
|
10
|
+
"Use dot-notation keys for nested fields (e.g. personal.first_name)."),
|
|
11
|
+
expected_version: z.number().optional().describe("Optimistic locking version. Include to prevent overwriting concurrent changes."),
|
|
12
|
+
}).strict();
|
|
13
|
+
const PatchApplicationCaseSchema = z.object({
|
|
14
|
+
application_id: z.string().describe("Application MongoDB ObjectId."),
|
|
15
|
+
program_key: z.string().describe("Program key — used to route to the correct PATCH endpoint."),
|
|
16
|
+
updates: z.record(z.unknown()).describe("Partial update dict. Keys must match the application model fields."),
|
|
17
|
+
expected_version: z.number().optional().describe("Optimistic locking version."),
|
|
18
|
+
}).strict();
|
|
19
|
+
const PatchEmployerSchema = z.object({
|
|
20
|
+
employer_id: z.string().describe("LMIA employer MongoDB ObjectId."),
|
|
21
|
+
updates: z.record(z.unknown()).describe("Partial update dict matching the LMIAEmployer model fields."),
|
|
22
|
+
}).strict();
|
|
23
|
+
const AddNoteSchema = z.object({
|
|
24
|
+
entity_id: z.string().describe("Entity MongoDB ObjectId."),
|
|
25
|
+
entity_type: z.enum(["applicant", "application", "employer"]).describe("Entity type to add a note to."),
|
|
26
|
+
note: z.string().describe("Note text to append."),
|
|
27
|
+
}).strict();
|
|
28
|
+
const ValidatePersonForProgramSchema = z.object({
|
|
29
|
+
person_id: z.string().describe("Applicant MongoDB ObjectId."),
|
|
30
|
+
program_key: z.string().describe("Program key to validate against."),
|
|
31
|
+
role: z.string().describe("Role within the program (applicant|spouse|sponsor|employer etc)."),
|
|
32
|
+
}).strict();
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Helpers
|
|
35
|
+
// ============================================================================
|
|
36
|
+
async function getFormIdForRole(program_key, role) {
|
|
37
|
+
try {
|
|
38
|
+
for (const lookupKey of getProgramLookupKeys(program_key)) {
|
|
39
|
+
try {
|
|
40
|
+
const prog = await makeApiRequest(`/api/programs/${encodeURIComponent(lookupKey)}`, "GET");
|
|
41
|
+
const formId = prog.form_ids?.[role] ?? prog.form_ids?.applicant ?? null;
|
|
42
|
+
if (formId)
|
|
43
|
+
return formId;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function getProgramInfo(program_key) {
|
|
56
|
+
for (const lookupKey of getProgramLookupKeys(program_key)) {
|
|
57
|
+
try {
|
|
58
|
+
const prog = await makeApiRequest(`/api/programs/${encodeURIComponent(lookupKey)}`, "GET");
|
|
59
|
+
if (prog.api_endpoint && prog.category) {
|
|
60
|
+
return {
|
|
61
|
+
api_endpoint: prog.api_endpoint,
|
|
62
|
+
category: prog.category,
|
|
63
|
+
form_ids: prog.form_ids,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
export function buildApplicationPatchUrl(api_endpoint, category, application_id) {
|
|
74
|
+
// LMIA: /api/lmia/{stream}/applications/{id}
|
|
75
|
+
// TR/PR: /api/tr|pr/{endpoint}/{id}
|
|
76
|
+
if (category === "LMIA") {
|
|
77
|
+
return `${api_endpoint}/applications/${encodeURIComponent(application_id)}`;
|
|
78
|
+
}
|
|
79
|
+
return `${api_endpoint}/${encodeURIComponent(application_id)}`;
|
|
80
|
+
}
|
|
81
|
+
export function expandDotNotation(updates) {
|
|
82
|
+
const expanded = {};
|
|
83
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
84
|
+
if (!key.includes(".")) {
|
|
85
|
+
expanded[key] = value;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const parts = key.split(".").filter(Boolean);
|
|
89
|
+
if (parts.length === 0)
|
|
90
|
+
continue;
|
|
91
|
+
let cursor = expanded;
|
|
92
|
+
for (const part of parts.slice(0, -1)) {
|
|
93
|
+
const existing = cursor[part];
|
|
94
|
+
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
95
|
+
cursor[part] = {};
|
|
96
|
+
}
|
|
97
|
+
cursor = cursor[part];
|
|
98
|
+
}
|
|
99
|
+
cursor[parts[parts.length - 1]] = value;
|
|
100
|
+
}
|
|
101
|
+
return expanded;
|
|
102
|
+
}
|
|
103
|
+
/** Look up the PATCH URL for an application by matching its program_name against /api/programs. */
|
|
104
|
+
async function getApplicationPatchUrl(application_id) {
|
|
105
|
+
try {
|
|
106
|
+
const app = await makeApiRequest(`/api/applications/${encodeURIComponent(application_id)}`, "GET");
|
|
107
|
+
if (!app.program_name)
|
|
108
|
+
return null;
|
|
109
|
+
const programs = await makeApiRequest("/api/programs", "GET");
|
|
110
|
+
for (const prog of Object.values(programs)) {
|
|
111
|
+
if (prog.db_name === app.program_name && prog.api_endpoint && prog.category) {
|
|
112
|
+
return buildApplicationPatchUrl(prog.api_endpoint, prog.category, application_id);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// Tool Registration
|
|
123
|
+
// ============================================================================
|
|
124
|
+
export function registerPatchTools(server) {
|
|
125
|
+
// 1. patch_person
|
|
126
|
+
server.registerTool("patch_person", {
|
|
127
|
+
title: "Patch Person (Applicant)",
|
|
128
|
+
description: "Partially update an applicant's data. Sends only the provided fields — other fields are unchanged. " +
|
|
129
|
+
"Provide expected_version to use optimistic locking (recommended when multiple agents may edit). " +
|
|
130
|
+
"Returns the updated applicant object.",
|
|
131
|
+
inputSchema: PatchPersonSchema.shape,
|
|
132
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
133
|
+
}, async ({ person_id, updates, expected_version }) => {
|
|
134
|
+
try {
|
|
135
|
+
const params = { skip_validation: false };
|
|
136
|
+
if (expected_version !== undefined) {
|
|
137
|
+
params.if_match = expected_version;
|
|
138
|
+
}
|
|
139
|
+
const url = `/api/applicants/${encodeURIComponent(person_id)}`;
|
|
140
|
+
const data = await makeApiRequest(url, "PATCH", expandDotNotation(updates), {
|
|
141
|
+
...params,
|
|
142
|
+
skip_validation: true,
|
|
143
|
+
});
|
|
144
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
// 2. patch_application_case
|
|
151
|
+
server.registerTool("patch_application_case", {
|
|
152
|
+
title: "Patch Application / Case",
|
|
153
|
+
description: "Partially update an application or LMIA case. " +
|
|
154
|
+
"Dispatches to the unified applications PATCH endpoint. " +
|
|
155
|
+
"Optionally include expected_version for optimistic locking. " +
|
|
156
|
+
"Returns the updated application object.",
|
|
157
|
+
inputSchema: PatchApplicationCaseSchema.shape,
|
|
158
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
159
|
+
}, async ({ application_id, program_key, updates, expected_version }) => {
|
|
160
|
+
try {
|
|
161
|
+
const progInfo = await getProgramInfo(program_key);
|
|
162
|
+
if (!progInfo) {
|
|
163
|
+
return {
|
|
164
|
+
isError: true,
|
|
165
|
+
content: [{ type: "text", text: `Error: Unknown program_key '${program_key}'. Use list_programs to find valid keys.` }],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const params = { skip_validation: true };
|
|
169
|
+
if (expected_version !== undefined) {
|
|
170
|
+
params.if_match = expected_version;
|
|
171
|
+
}
|
|
172
|
+
const url = buildApplicationPatchUrl(progInfo.api_endpoint, progInfo.category, application_id);
|
|
173
|
+
const data = await makeApiRequest(url, "PATCH", updates, params);
|
|
174
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
// 3. patch_employer
|
|
181
|
+
server.registerTool("patch_employer", {
|
|
182
|
+
title: "Patch LMIA Employer",
|
|
183
|
+
description: "Partially update an LMIA employer record. " +
|
|
184
|
+
"Only the provided fields are updated. " +
|
|
185
|
+
"Returns the updated employer object.",
|
|
186
|
+
inputSchema: PatchEmployerSchema.shape,
|
|
187
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
188
|
+
}, async ({ employer_id, updates }) => {
|
|
189
|
+
try {
|
|
190
|
+
const url = `/api/lmia/employers/${encodeURIComponent(employer_id)}`;
|
|
191
|
+
const data = await makeApiRequest(url, "PATCH", updates);
|
|
192
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
// 4. add_note
|
|
199
|
+
server.registerTool("add_note", {
|
|
200
|
+
title: "Add Note to Entity",
|
|
201
|
+
description: "Append a text note to an applicant, application, or employer. " +
|
|
202
|
+
"Uses PATCH to add the note to the entity's notes array. " +
|
|
203
|
+
"Returns the updated entity.",
|
|
204
|
+
inputSchema: AddNoteSchema.shape,
|
|
205
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
206
|
+
}, async ({ entity_id, entity_type, note }) => {
|
|
207
|
+
try {
|
|
208
|
+
// Backend's `notes` field is a string (not array). Read current value
|
|
209
|
+
// and append the new note with a timestamp separator.
|
|
210
|
+
let getUrl;
|
|
211
|
+
let patchUrl;
|
|
212
|
+
let patchParams;
|
|
213
|
+
if (entity_type === "applicant") {
|
|
214
|
+
getUrl = `/api/applicants/${encodeURIComponent(entity_id)}`;
|
|
215
|
+
patchUrl = getUrl;
|
|
216
|
+
patchParams = { skip_validation: true };
|
|
217
|
+
}
|
|
218
|
+
else if (entity_type === "application") {
|
|
219
|
+
getUrl = `/api/applications/${encodeURIComponent(entity_id)}`;
|
|
220
|
+
const appPatchUrl = await getApplicationPatchUrl(entity_id);
|
|
221
|
+
if (!appPatchUrl) {
|
|
222
|
+
return {
|
|
223
|
+
isError: true,
|
|
224
|
+
content: [{ type: "text", text: `Error: Could not resolve PATCH URL for application '${entity_id}'. Ensure the application exists.` }],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
patchUrl = appPatchUrl;
|
|
228
|
+
patchParams = { skip_validation: true };
|
|
229
|
+
}
|
|
230
|
+
else if (entity_type === "employer") {
|
|
231
|
+
getUrl = `/api/lmia/employers/${encodeURIComponent(entity_id)}`;
|
|
232
|
+
patchUrl = getUrl;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
return {
|
|
236
|
+
isError: true,
|
|
237
|
+
content: [{ type: "text", text: `Error: Unknown entity_type '${entity_type}'.` }],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
const current = await makeApiRequest(getUrl, "GET");
|
|
241
|
+
const timestamp = new Date().toISOString();
|
|
242
|
+
const newNote = `[${timestamp}] ${note}`;
|
|
243
|
+
const combinedNotes = current.notes ? `${current.notes}\n${newNote}` : newNote;
|
|
244
|
+
const data = await makeApiRequest(patchUrl, "PATCH", { notes: combinedNotes }, patchParams);
|
|
245
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
// 5. validate_person_for_program
|
|
252
|
+
server.registerTool("validate_person_for_program", {
|
|
253
|
+
title: "Validate Person for Program",
|
|
254
|
+
description: "Run validation on a saved applicant for a specific program and role. " +
|
|
255
|
+
"Returns validation errors with field paths, error types, and fix suggestions. " +
|
|
256
|
+
"Use after editing a person to confirm they are ready for form filling.",
|
|
257
|
+
inputSchema: ValidatePersonForProgramSchema.shape,
|
|
258
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
259
|
+
}, async ({ person_id, program_key, role }) => {
|
|
260
|
+
try {
|
|
261
|
+
const form_id = await getFormIdForRole(program_key, role);
|
|
262
|
+
if (!form_id) {
|
|
263
|
+
return {
|
|
264
|
+
isError: true,
|
|
265
|
+
content: [{ type: "text", text: `Unknown program_key '${program_key}' or role '${role}'. Use list_programs to find valid program keys and roles.` }],
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
const data = await makeApiRequest(`/api/validate/${encodeURIComponent(form_id)}/${encodeURIComponent(person_id)}`, "POST", {});
|
|
269
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
return { isError: true, content: [{ type: "text", text: handleApiError(error) }] };
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/tools/patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-keys.d.ts","sourceRoot":"","sources":["../../src/tools/program-keys.ts"],"names":[],"mappings":"AAKA,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const PROGRAM_KEY_ALIASES = {
|
|
2
|
+
pgp: "parent-sponsorship",
|
|
3
|
+
sps: "spouse-sponsorship",
|
|
4
|
+
};
|
|
5
|
+
export function normalizeProgramKey(programKey) {
|
|
6
|
+
const key = programKey.trim().toLowerCase();
|
|
7
|
+
return PROGRAM_KEY_ALIASES[key] ?? programKey;
|
|
8
|
+
}
|
|
9
|
+
export function getProgramLookupKeys(programKey) {
|
|
10
|
+
const normalized = normalizeProgramKey(programKey);
|
|
11
|
+
return normalized === programKey ? [programKey] : [programKey, normalized];
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=program-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-keys.js","sourceRoot":"","sources":["../../src/tools/program-keys.ts"],"names":[],"mappings":"AAAA,MAAM,mBAAmB,GAA2B;IAClD,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,oBAAoB;CAC1B,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,MAAM,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACnD,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/tools/system.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+F3D"}
|