formbro-mcp-server 1.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/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +299 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/common.d.ts +77 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +42 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/services/api-client.d.ts +38 -0
- package/dist/services/api-client.d.ts.map +1 -0
- package/dist/services/api-client.js +125 -0
- package/dist/services/api-client.js.map +1 -0
- package/dist/tools/applicants.d.ts +6 -0
- package/dist/tools/applicants.d.ts.map +1 -0
- package/dist/tools/applicants.js +261 -0
- package/dist/tools/applicants.js.map +1 -0
- package/dist/tools/applications.d.ts +6 -0
- package/dist/tools/applications.d.ts.map +1 -0
- package/dist/tools/applications.js +225 -0
- package/dist/tools/applications.js.map +1 -0
- package/dist/tools/employers.d.ts +6 -0
- package/dist/tools/employers.d.ts.map +1 -0
- package/dist/tools/employers.js +243 -0
- package/dist/tools/employers.js.map +1 -0
- package/dist/tools/find.d.ts +6 -0
- package/dist/tools/find.d.ts.map +1 -0
- package/dist/tools/find.js +122 -0
- package/dist/tools/find.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// Application Tools for FormBro MCP Server
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { makeApiRequest, handleApiError } from "../services/api-client.js";
|
|
4
|
+
import { ListWithSearchSchema, IdWithFormatSchema } from "../schemas/common.js";
|
|
5
|
+
import { ResponseFormat, CHARACTER_LIMIT } from "../constants.js";
|
|
6
|
+
// Extended schema for listing applications
|
|
7
|
+
const ListApplicationsSchema = ListWithSearchSchema.extend({
|
|
8
|
+
program: z.enum(["tr", "pr", "lmia"])
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Filter by program type: 'tr' (Temporary Residence), 'pr' (Permanent Residence), 'lmia' (Labour Market Impact Assessment)"),
|
|
11
|
+
status: z.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Filter by application status (e.g., 'draft', 'in_progress', 'submitted', 'approved', 'refused')")
|
|
14
|
+
}).strict();
|
|
15
|
+
/**
|
|
16
|
+
* Format application data as Markdown
|
|
17
|
+
*/
|
|
18
|
+
function formatApplicationMarkdown(app) {
|
|
19
|
+
const lines = [];
|
|
20
|
+
lines.push(`## ${app.case_name || "Unnamed Application"} (${app.id})`);
|
|
21
|
+
lines.push("");
|
|
22
|
+
if (app.program_type)
|
|
23
|
+
lines.push(`- **Program**: ${app.program_type.toUpperCase()}`);
|
|
24
|
+
if (app.status)
|
|
25
|
+
lines.push(`- **Status**: ${app.status}`);
|
|
26
|
+
if (app.applicant_id)
|
|
27
|
+
lines.push(`- **Applicant ID**: ${app.applicant_id}`);
|
|
28
|
+
if (app.employer_id)
|
|
29
|
+
lines.push(`- **Employer ID**: ${app.employer_id}`);
|
|
30
|
+
lines.push(`- **Created**: ${app.created_date}`);
|
|
31
|
+
if (app.last_modified_date) {
|
|
32
|
+
lines.push(`- **Last Modified**: ${app.last_modified_date}`);
|
|
33
|
+
}
|
|
34
|
+
return lines.join("\n");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Format applications list as Markdown
|
|
38
|
+
*/
|
|
39
|
+
function formatApplicationsListMarkdown(applications, total, offset) {
|
|
40
|
+
const lines = [
|
|
41
|
+
"# Applications List",
|
|
42
|
+
"",
|
|
43
|
+
`Found ${total} applications (showing ${applications.length} from offset ${offset})`,
|
|
44
|
+
""
|
|
45
|
+
];
|
|
46
|
+
for (const app of applications) {
|
|
47
|
+
lines.push(formatApplicationMarkdown(app));
|
|
48
|
+
lines.push("---");
|
|
49
|
+
lines.push("");
|
|
50
|
+
}
|
|
51
|
+
return lines.join("\n");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Register application tools with the MCP server
|
|
55
|
+
*/
|
|
56
|
+
export function registerApplicationTools(server) {
|
|
57
|
+
// List Applications Tool
|
|
58
|
+
server.registerTool("formbro_list_applications", {
|
|
59
|
+
title: "List FormBro Applications",
|
|
60
|
+
description: `List immigration applications in the FormBro system.
|
|
61
|
+
|
|
62
|
+
This tool retrieves a paginated list of applications across different immigration programs:
|
|
63
|
+
- TR (Temporary Residence): Work permits, study permits, visitor visas
|
|
64
|
+
- PR (Permanent Residence): Family sponsorship, Express Entry, PNP
|
|
65
|
+
- LMIA (Labour Market Impact Assessment): Employer applications for foreign workers
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
- limit (number): Maximum results to return, 1-100 (default: 20)
|
|
69
|
+
- offset (number): Number of results to skip for pagination (default: 0)
|
|
70
|
+
- search (string, optional): Search query to filter by case name
|
|
71
|
+
- program (string, optional): Filter by program type ('tr', 'pr', 'lmia')
|
|
72
|
+
- status (string, optional): Filter by status ('draft', 'in_progress', 'submitted', 'approved', 'refused')
|
|
73
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Paginated list of applications with case names, programs, statuses, and related IDs.
|
|
77
|
+
|
|
78
|
+
Examples:
|
|
79
|
+
- "List all applications" -> params: {}
|
|
80
|
+
- "Show LMIA applications" -> params: { program: "lmia" }
|
|
81
|
+
- "Find approved PR cases" -> params: { program: "pr", status: "approved" }`,
|
|
82
|
+
inputSchema: ListApplicationsSchema,
|
|
83
|
+
annotations: {
|
|
84
|
+
readOnlyHint: true,
|
|
85
|
+
destructiveHint: false,
|
|
86
|
+
idempotentHint: true,
|
|
87
|
+
openWorldHint: true
|
|
88
|
+
}
|
|
89
|
+
}, async (params) => {
|
|
90
|
+
try {
|
|
91
|
+
let applications;
|
|
92
|
+
// Use search endpoint when search query is provided
|
|
93
|
+
if (params.search) {
|
|
94
|
+
const searchParams = {
|
|
95
|
+
q: params.search,
|
|
96
|
+
limit: params.limit
|
|
97
|
+
};
|
|
98
|
+
applications = await makeApiRequest("/api/dashboard/search", "GET", undefined, searchParams);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Use regular applications endpoint for listing
|
|
102
|
+
const queryParams = {
|
|
103
|
+
skip: params.offset,
|
|
104
|
+
limit: params.limit
|
|
105
|
+
};
|
|
106
|
+
if (params.status)
|
|
107
|
+
queryParams.status = params.status;
|
|
108
|
+
if (params.program)
|
|
109
|
+
queryParams.program_type = params.program.toUpperCase();
|
|
110
|
+
applications = await makeApiRequest("/api/dashboard/applications", "GET", undefined, queryParams);
|
|
111
|
+
}
|
|
112
|
+
const total = applications.length;
|
|
113
|
+
if (!applications.length) {
|
|
114
|
+
return {
|
|
115
|
+
content: [{
|
|
116
|
+
type: "text",
|
|
117
|
+
text: params.program
|
|
118
|
+
? `No ${params.program.toUpperCase()} applications found`
|
|
119
|
+
: "No applications found"
|
|
120
|
+
}]
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const output = {
|
|
124
|
+
total,
|
|
125
|
+
count: applications.length,
|
|
126
|
+
offset: params.offset,
|
|
127
|
+
items: applications.map(a => ({
|
|
128
|
+
id: a.id,
|
|
129
|
+
case_name: a.case_name,
|
|
130
|
+
program_type: a.program_type,
|
|
131
|
+
status: a.status,
|
|
132
|
+
applicant_id: a.applicant_id,
|
|
133
|
+
employer_id: a.employer_id,
|
|
134
|
+
created_date: a.created_date,
|
|
135
|
+
last_modified_date: a.last_modified_date
|
|
136
|
+
})),
|
|
137
|
+
has_more: total > params.offset + applications.length,
|
|
138
|
+
...(total > params.offset + applications.length ? {
|
|
139
|
+
next_offset: params.offset + applications.length
|
|
140
|
+
} : {})
|
|
141
|
+
};
|
|
142
|
+
let textContent;
|
|
143
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
144
|
+
textContent = formatApplicationsListMarkdown(applications, total, params.offset);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
textContent = JSON.stringify(output, null, 2);
|
|
148
|
+
}
|
|
149
|
+
if (textContent.length > CHARACTER_LIMIT) {
|
|
150
|
+
textContent = textContent.substring(0, CHARACTER_LIMIT) +
|
|
151
|
+
"\n\n[Response truncated. Use smaller limit or offset to see more results.]";
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
content: [{ type: "text", text: textContent }],
|
|
155
|
+
structuredContent: output
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return {
|
|
160
|
+
isError: true,
|
|
161
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// Get Single Application Tool
|
|
166
|
+
server.registerTool("formbro_get_application", {
|
|
167
|
+
title: "Get FormBro Application Details",
|
|
168
|
+
description: `Get detailed information about a specific immigration application.
|
|
169
|
+
|
|
170
|
+
This tool retrieves comprehensive information about an application including:
|
|
171
|
+
- Case identification and status
|
|
172
|
+
- Program-specific details (TR forms, PR sponsorship info, LMIA job details)
|
|
173
|
+
- Associated applicant and employer information
|
|
174
|
+
- Timeline and modification history
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
- id (string): The application's unique identifier (MongoDB ObjectId)
|
|
178
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Complete application details with all available information.
|
|
182
|
+
|
|
183
|
+
Examples:
|
|
184
|
+
- "Get application 507f1f77bcf86cd799439011" -> params: { id: "507f1f77bcf86cd799439011" }`,
|
|
185
|
+
inputSchema: IdWithFormatSchema,
|
|
186
|
+
annotations: {
|
|
187
|
+
readOnlyHint: true,
|
|
188
|
+
destructiveHint: false,
|
|
189
|
+
idempotentHint: true,
|
|
190
|
+
openWorldHint: true
|
|
191
|
+
}
|
|
192
|
+
}, async (params) => {
|
|
193
|
+
try {
|
|
194
|
+
// Use unified endpoint that works for all program types (TR/PR/LMIA)
|
|
195
|
+
const application = await makeApiRequest(`/api/applications/${params.id}`, "GET");
|
|
196
|
+
let textContent;
|
|
197
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
198
|
+
const lines = [
|
|
199
|
+
"# Application Details",
|
|
200
|
+
"",
|
|
201
|
+
formatApplicationMarkdown(application)
|
|
202
|
+
];
|
|
203
|
+
textContent = lines.join("\n");
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
textContent = JSON.stringify(application, null, 2);
|
|
207
|
+
}
|
|
208
|
+
if (textContent.length > CHARACTER_LIMIT) {
|
|
209
|
+
textContent = textContent.substring(0, CHARACTER_LIMIT) +
|
|
210
|
+
"\n\n[Response truncated due to size. Use JSON format for complete data.]";
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
content: [{ type: "text", text: textContent }],
|
|
214
|
+
structuredContent: application
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
return {
|
|
219
|
+
isError: true,
|
|
220
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=applications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applications.js","sourceRoot":"","sources":["../../src/tools/applications.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"employers.d.ts","sourceRoot":"","sources":["../../src/tools/employers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8DpE;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkN7D"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// Employer Tools for FormBro MCP Server
|
|
2
|
+
import { makeApiRequest, handleApiError } from "../services/api-client.js";
|
|
3
|
+
import { ListWithSearchSchema, IdWithFormatSchema } from "../schemas/common.js";
|
|
4
|
+
import { ResponseFormat, CHARACTER_LIMIT } from "../constants.js";
|
|
5
|
+
/**
|
|
6
|
+
* Format employer data as Markdown
|
|
7
|
+
*/
|
|
8
|
+
function formatEmployerMarkdown(employer) {
|
|
9
|
+
const lines = [];
|
|
10
|
+
const general = employer.general || {};
|
|
11
|
+
lines.push(`## ${general.legal_name || general.operating_name || "Unknown Employer"} (${employer.id})`);
|
|
12
|
+
lines.push("");
|
|
13
|
+
if (general.legal_name)
|
|
14
|
+
lines.push(`- **Legal Name**: ${general.legal_name}`);
|
|
15
|
+
if (general.operating_name && general.operating_name !== general.legal_name) {
|
|
16
|
+
lines.push(`- **Operating Name**: ${general.operating_name}`);
|
|
17
|
+
}
|
|
18
|
+
if (general.business_number)
|
|
19
|
+
lines.push(`- **Business Number**: ${general.business_number}`);
|
|
20
|
+
if (general.industry)
|
|
21
|
+
lines.push(`- **Industry**: ${general.industry}`);
|
|
22
|
+
if (general.website)
|
|
23
|
+
lines.push(`- **Website**: ${general.website}`);
|
|
24
|
+
if (employer.created_date) {
|
|
25
|
+
lines.push(`- **Created**: ${employer.created_date}`);
|
|
26
|
+
}
|
|
27
|
+
if (employer.last_modified_date) {
|
|
28
|
+
lines.push(`- **Last Modified**: ${employer.last_modified_date}`);
|
|
29
|
+
}
|
|
30
|
+
return lines.join("\n");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Format employers list as Markdown
|
|
34
|
+
*/
|
|
35
|
+
function formatEmployersListMarkdown(employers, total, offset) {
|
|
36
|
+
const lines = [
|
|
37
|
+
"# Employers List",
|
|
38
|
+
"",
|
|
39
|
+
`Found ${total} employers (showing ${employers.length} from offset ${offset})`,
|
|
40
|
+
""
|
|
41
|
+
];
|
|
42
|
+
for (const employer of employers) {
|
|
43
|
+
lines.push(formatEmployerMarkdown(employer));
|
|
44
|
+
lines.push("---");
|
|
45
|
+
lines.push("");
|
|
46
|
+
}
|
|
47
|
+
return lines.join("\n");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Register employer tools with the MCP server
|
|
51
|
+
*/
|
|
52
|
+
export function registerEmployerTools(server) {
|
|
53
|
+
// List Employers Tool
|
|
54
|
+
server.registerTool("formbro_list_employers", {
|
|
55
|
+
title: "List FormBro Employers",
|
|
56
|
+
description: `List employers in the FormBro LMIA management system.
|
|
57
|
+
|
|
58
|
+
This tool retrieves a paginated list of employers who have LMIA applications.
|
|
59
|
+
Each employer record includes company information, contact details, and business addresses.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
- limit (number): Maximum results to return, 1-100 (default: 20)
|
|
63
|
+
- offset (number): Number of results to skip for pagination (default: 0)
|
|
64
|
+
- search (string, optional): Search query to filter by company name, business number, etc.
|
|
65
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Paginated list of employers with company information and contact details.
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
- "List all employers" -> params: {}
|
|
72
|
+
- "Find employer Tech Corp" -> params: { search: "Tech Corp" }
|
|
73
|
+
- "Get employers page 2" -> params: { offset: 20, limit: 20 }`,
|
|
74
|
+
inputSchema: ListWithSearchSchema,
|
|
75
|
+
annotations: {
|
|
76
|
+
readOnlyHint: true,
|
|
77
|
+
destructiveHint: false,
|
|
78
|
+
idempotentHint: true,
|
|
79
|
+
openWorldHint: true
|
|
80
|
+
}
|
|
81
|
+
}, async (params) => {
|
|
82
|
+
try {
|
|
83
|
+
const queryParams = {
|
|
84
|
+
skip: params.offset,
|
|
85
|
+
limit: params.limit
|
|
86
|
+
};
|
|
87
|
+
if (params.search)
|
|
88
|
+
queryParams.search = params.search;
|
|
89
|
+
const response = await makeApiRequest("/api/lmia/employers", "GET", undefined, queryParams);
|
|
90
|
+
const employers = response.items || [];
|
|
91
|
+
const total = response.total || 0;
|
|
92
|
+
if (!employers.length) {
|
|
93
|
+
return {
|
|
94
|
+
content: [{
|
|
95
|
+
type: "text",
|
|
96
|
+
text: params.search
|
|
97
|
+
? `No employers found matching '${params.search}'`
|
|
98
|
+
: "No employers found"
|
|
99
|
+
}]
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const output = {
|
|
103
|
+
total,
|
|
104
|
+
count: employers.length,
|
|
105
|
+
offset: params.offset,
|
|
106
|
+
items: employers.map(e => ({
|
|
107
|
+
id: e.id,
|
|
108
|
+
legal_name: e.general?.legal_name,
|
|
109
|
+
operating_name: e.general?.operating_name,
|
|
110
|
+
business_number: e.general?.business_number,
|
|
111
|
+
industry: e.general?.industry,
|
|
112
|
+
website: e.general?.website,
|
|
113
|
+
created_date: e.created_date
|
|
114
|
+
})),
|
|
115
|
+
has_more: total > params.offset + employers.length,
|
|
116
|
+
...(total > params.offset + employers.length ? {
|
|
117
|
+
next_offset: params.offset + employers.length
|
|
118
|
+
} : {})
|
|
119
|
+
};
|
|
120
|
+
let textContent;
|
|
121
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
122
|
+
textContent = formatEmployersListMarkdown(employers, total, params.offset);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
textContent = JSON.stringify(output, null, 2);
|
|
126
|
+
}
|
|
127
|
+
if (textContent.length > CHARACTER_LIMIT) {
|
|
128
|
+
textContent = textContent.substring(0, CHARACTER_LIMIT) +
|
|
129
|
+
"\n\n[Response truncated. Use smaller limit or offset to see more results.]";
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
content: [{ type: "text", text: textContent }],
|
|
133
|
+
structuredContent: output
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return {
|
|
138
|
+
isError: true,
|
|
139
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// Get Single Employer Tool
|
|
144
|
+
server.registerTool("formbro_get_employer", {
|
|
145
|
+
title: "Get FormBro Employer Details",
|
|
146
|
+
description: `Get detailed information about a specific employer in FormBro.
|
|
147
|
+
|
|
148
|
+
This tool retrieves comprehensive employer information including:
|
|
149
|
+
- Company identification (legal name, operating name, business number)
|
|
150
|
+
- Industry and website
|
|
151
|
+
- Business, mailing, and work site addresses
|
|
152
|
+
- Primary and secondary contact persons
|
|
153
|
+
- Job offer information
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
- id (string): The employer's unique identifier (MongoDB ObjectId)
|
|
157
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Complete employer profile with all available information.
|
|
161
|
+
|
|
162
|
+
Examples:
|
|
163
|
+
- "Get employer 507f1f77bcf86cd799439011" -> params: { id: "507f1f77bcf86cd799439011" }`,
|
|
164
|
+
inputSchema: IdWithFormatSchema,
|
|
165
|
+
annotations: {
|
|
166
|
+
readOnlyHint: true,
|
|
167
|
+
destructiveHint: false,
|
|
168
|
+
idempotentHint: true,
|
|
169
|
+
openWorldHint: true
|
|
170
|
+
}
|
|
171
|
+
}, async (params) => {
|
|
172
|
+
try {
|
|
173
|
+
const employer = await makeApiRequest(`/api/lmia/employers/${params.id}`, "GET");
|
|
174
|
+
let textContent;
|
|
175
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
176
|
+
const lines = [
|
|
177
|
+
"# Employer Details",
|
|
178
|
+
"",
|
|
179
|
+
formatEmployerMarkdown(employer)
|
|
180
|
+
];
|
|
181
|
+
// Add address information if available
|
|
182
|
+
if (employer.addresses) {
|
|
183
|
+
lines.push("", "### Addresses", "");
|
|
184
|
+
const addresses = employer.addresses;
|
|
185
|
+
for (const [type, addr] of Object.entries(addresses)) {
|
|
186
|
+
if (addr && typeof addr === "object") {
|
|
187
|
+
const parts = [
|
|
188
|
+
addr.street_number,
|
|
189
|
+
addr.street_name,
|
|
190
|
+
addr.unit,
|
|
191
|
+
addr.city,
|
|
192
|
+
addr.province,
|
|
193
|
+
addr.postal_code,
|
|
194
|
+
addr.country
|
|
195
|
+
].filter(Boolean);
|
|
196
|
+
if (parts.length) {
|
|
197
|
+
lines.push(`- **${type}**: ${parts.join(", ")}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Add contact information if available
|
|
203
|
+
if (employer.contacts) {
|
|
204
|
+
lines.push("", "### Contacts", "");
|
|
205
|
+
const contacts = employer.contacts;
|
|
206
|
+
for (const [type, contact] of Object.entries(contacts)) {
|
|
207
|
+
if (contact && typeof contact === "object") {
|
|
208
|
+
const name = [contact.first_name, contact.last_name].filter(Boolean).join(" ");
|
|
209
|
+
if (name) {
|
|
210
|
+
lines.push(`- **${type}**: ${name}`);
|
|
211
|
+
if (contact.email)
|
|
212
|
+
lines.push(` - Email: ${contact.email}`);
|
|
213
|
+
if (contact.phone)
|
|
214
|
+
lines.push(` - Phone: ${contact.phone}`);
|
|
215
|
+
if (contact.job_title)
|
|
216
|
+
lines.push(` - Title: ${contact.job_title}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
textContent = lines.join("\n");
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
textContent = JSON.stringify(employer, null, 2);
|
|
225
|
+
}
|
|
226
|
+
if (textContent.length > CHARACTER_LIMIT) {
|
|
227
|
+
textContent = textContent.substring(0, CHARACTER_LIMIT) +
|
|
228
|
+
"\n\n[Response truncated due to size. Use JSON format for complete data.]";
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
content: [{ type: "text", text: textContent }],
|
|
232
|
+
structuredContent: employer
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
return {
|
|
237
|
+
isError: true,
|
|
238
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=employers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"employers.js","sourceRoot":"","sources":["../../src/tools/employers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../src/tools/find.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA+EpE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4ExD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Smart Find Tool for FormBro MCP Server
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { makeApiRequest, handleApiError } from "../services/api-client.js";
|
|
4
|
+
// Input schema for find tool
|
|
5
|
+
const FindSchema = z.object({
|
|
6
|
+
name: z.string()
|
|
7
|
+
.min(1)
|
|
8
|
+
.describe("Name to search for. Supports full name in any order (e.g., 'John Smith' or 'Zhang Wei')"),
|
|
9
|
+
program: z.enum(["tr", "pr", "lmia"])
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Filter by program type: 'tr' (Temporary Residence), 'pr' (Permanent Residence), 'lmia' (Labour Market Impact Assessment)"),
|
|
12
|
+
include: z.array(z.enum(["applications", "employer"]))
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Related data to include. Use ['applications'] to get applicant's applications, or ['applications', 'employer'] for LMIA cases"),
|
|
15
|
+
limit: z.number()
|
|
16
|
+
.int()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(20)
|
|
19
|
+
.optional()
|
|
20
|
+
.default(5)
|
|
21
|
+
.describe("Maximum number of results to return (1-20, default: 5)")
|
|
22
|
+
}).strict();
|
|
23
|
+
/**
|
|
24
|
+
* Format find results as compact text
|
|
25
|
+
*/
|
|
26
|
+
function formatFindResults(response) {
|
|
27
|
+
if (response.total === 0) {
|
|
28
|
+
return "No matching applicants found.";
|
|
29
|
+
}
|
|
30
|
+
const lines = [];
|
|
31
|
+
lines.push(`Found ${response.total} applicant(s):\n`);
|
|
32
|
+
for (const result of response.results) {
|
|
33
|
+
lines.push(`## ${result.name} (${result.id})`);
|
|
34
|
+
if (result.email)
|
|
35
|
+
lines.push(` Email: ${result.email}`);
|
|
36
|
+
if (result.phone)
|
|
37
|
+
lines.push(` Phone: ${result.phone}`);
|
|
38
|
+
if (result.dob)
|
|
39
|
+
lines.push(` DOB: ${result.dob}`);
|
|
40
|
+
if (result.applications && result.applications.length > 0) {
|
|
41
|
+
lines.push(` Applications (${result.applications.length}):`);
|
|
42
|
+
for (const app of result.applications) {
|
|
43
|
+
lines.push(` - [${app.status}] ${app.program} (${app.id})`);
|
|
44
|
+
lines.push(` Created: ${app.created}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (result.applications !== undefined) {
|
|
48
|
+
lines.push(" Applications: None");
|
|
49
|
+
}
|
|
50
|
+
lines.push("");
|
|
51
|
+
}
|
|
52
|
+
return lines.join("\n");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Register find tool with the MCP server
|
|
56
|
+
*/
|
|
57
|
+
export function registerFindTool(server) {
|
|
58
|
+
server.registerTool("formbro_find", {
|
|
59
|
+
title: "Smart Find in FormBro",
|
|
60
|
+
description: `Smart search for applicants and their applications in FormBro.
|
|
61
|
+
|
|
62
|
+
USE THIS TOOL FIRST for most queries - it combines search and detail fetching in one call.
|
|
63
|
+
|
|
64
|
+
KEY FEATURES:
|
|
65
|
+
- Intelligent name matching: Handles "First Last" and "Last First" order automatically
|
|
66
|
+
(e.g., "Zhang Wei" matches whether stored as given_name="Zhang" or given_name="Wei")
|
|
67
|
+
- Returns applicant details with optional related applications in one call
|
|
68
|
+
- Compact JSON response optimized for AI processing
|
|
69
|
+
|
|
70
|
+
COMMON USE CASES:
|
|
71
|
+
1. Find applicant: { "name": "Zhang Wei" }
|
|
72
|
+
2. Find with applications: { "name": "Wei", "include": ["applications"] }
|
|
73
|
+
3. Find TR applicants: { "name": "John", "program": "tr", "include": ["applications"] }
|
|
74
|
+
|
|
75
|
+
WHEN TO USE OTHER TOOLS:
|
|
76
|
+
- formbro_list_applicants: Browse all applicants without name search
|
|
77
|
+
- formbro_get_applicant: Get full details by known ID
|
|
78
|
+
- formbro_list_applications: Search by case name or browse applications`,
|
|
79
|
+
inputSchema: FindSchema,
|
|
80
|
+
annotations: {
|
|
81
|
+
readOnlyHint: true,
|
|
82
|
+
destructiveHint: false,
|
|
83
|
+
idempotentHint: true,
|
|
84
|
+
openWorldHint: true
|
|
85
|
+
}
|
|
86
|
+
}, async (args) => {
|
|
87
|
+
try {
|
|
88
|
+
// Build query parameters
|
|
89
|
+
const params = {
|
|
90
|
+
name: args.name,
|
|
91
|
+
limit: args.limit || 5
|
|
92
|
+
};
|
|
93
|
+
if (args.program) {
|
|
94
|
+
params.program = args.program;
|
|
95
|
+
}
|
|
96
|
+
if (args.include && args.include.length > 0) {
|
|
97
|
+
params.include = args.include.join(",");
|
|
98
|
+
}
|
|
99
|
+
const response = await makeApiRequest("/mcp/find", "GET", undefined, params);
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: "text",
|
|
104
|
+
text: formatFindResults(response)
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return {
|
|
111
|
+
isError: true,
|
|
112
|
+
content: [
|
|
113
|
+
{
|
|
114
|
+
type: "text",
|
|
115
|
+
text: handleApiError(error)
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=find.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/tools/find.ts"],"names":[],"mappings":"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"}
|