@ttctl/mcp 0.0.0 → 0.1.0-rc.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.
Files changed (191) hide show
  1. package/README.md +72 -9
  2. package/dist/auth.d.ts +40 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +69 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/data-handling.d.ts +91 -0
  7. package/dist/data-handling.d.ts.map +1 -0
  8. package/dist/data-handling.js +129 -0
  9. package/dist/data-handling.js.map +1 -0
  10. package/dist/diagnostic.d.ts +262 -0
  11. package/dist/diagnostic.d.ts.map +1 -0
  12. package/dist/diagnostic.js +362 -0
  13. package/dist/diagnostic.js.map +1 -0
  14. package/dist/errors.d.ts +54 -0
  15. package/dist/errors.d.ts.map +1 -0
  16. package/dist/errors.js +48 -0
  17. package/dist/errors.js.map +1 -0
  18. package/dist/index.d.ts +8 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +7 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/kill-switch-hook.d.ts +67 -0
  23. package/dist/kill-switch-hook.d.ts.map +1 -0
  24. package/dist/kill-switch-hook.js +61 -0
  25. package/dist/kill-switch-hook.js.map +1 -0
  26. package/dist/server.d.ts +100 -0
  27. package/dist/server.d.ts.map +1 -0
  28. package/dist/server.js +157 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/tools/_shared.d.ts +227 -0
  31. package/dist/tools/_shared.d.ts.map +1 -0
  32. package/dist/tools/_shared.js +238 -0
  33. package/dist/tools/_shared.js.map +1 -0
  34. package/dist/tools/applications.d.ts +27 -0
  35. package/dist/tools/applications.d.ts.map +1 -0
  36. package/dist/tools/applications.js +192 -0
  37. package/dist/tools/applications.js.map +1 -0
  38. package/dist/tools/availability.d.ts +33 -0
  39. package/dist/tools/availability.d.ts.map +1 -0
  40. package/dist/tools/availability.js +272 -0
  41. package/dist/tools/availability.js.map +1 -0
  42. package/dist/tools/contracts.d.ts +29 -0
  43. package/dist/tools/contracts.d.ts.map +1 -0
  44. package/dist/tools/contracts.js +157 -0
  45. package/dist/tools/contracts.js.map +1 -0
  46. package/dist/tools/engagements.d.ts +36 -0
  47. package/dist/tools/engagements.d.ts.map +1 -0
  48. package/dist/tools/engagements.js +408 -0
  49. package/dist/tools/engagements.js.map +1 -0
  50. package/dist/tools/file-upload.d.ts +133 -0
  51. package/dist/tools/file-upload.d.ts.map +1 -0
  52. package/dist/tools/file-upload.js +247 -0
  53. package/dist/tools/file-upload.js.map +1 -0
  54. package/dist/tools/index.d.ts +28 -0
  55. package/dist/tools/index.d.ts.map +1 -0
  56. package/dist/tools/index.js +131 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/jobs.d.ts +37 -0
  59. package/dist/tools/jobs.d.ts.map +1 -0
  60. package/dist/tools/jobs.js +505 -0
  61. package/dist/tools/jobs.js.map +1 -0
  62. package/dist/tools/output-schemas.d.ts +115 -0
  63. package/dist/tools/output-schemas.d.ts.map +1 -0
  64. package/dist/tools/output-schemas.js +130 -0
  65. package/dist/tools/output-schemas.js.map +1 -0
  66. package/dist/tools/payments.d.ts +36 -0
  67. package/dist/tools/payments.d.ts.map +1 -0
  68. package/dist/tools/payments.js +373 -0
  69. package/dist/tools/payments.js.map +1 -0
  70. package/dist/tools/profile/certifications.d.ts +18 -0
  71. package/dist/tools/profile/certifications.d.ts.map +1 -0
  72. package/dist/tools/profile/certifications.js +193 -0
  73. package/dist/tools/profile/certifications.js.map +1 -0
  74. package/dist/tools/profile/education.d.ts +23 -0
  75. package/dist/tools/profile/education.d.ts.map +1 -0
  76. package/dist/tools/profile/education.js +196 -0
  77. package/dist/tools/profile/education.js.map +1 -0
  78. package/dist/tools/profile/employment.d.ts +23 -0
  79. package/dist/tools/profile/employment.d.ts.map +1 -0
  80. package/dist/tools/profile/employment.js +228 -0
  81. package/dist/tools/profile/employment.js.map +1 -0
  82. package/dist/tools/profile/industries.d.ts +22 -0
  83. package/dist/tools/profile/industries.d.ts.map +1 -0
  84. package/dist/tools/profile/industries.js +168 -0
  85. package/dist/tools/profile/industries.js.map +1 -0
  86. package/dist/tools/profile/portfolio.d.ts +22 -0
  87. package/dist/tools/profile/portfolio.d.ts.map +1 -0
  88. package/dist/tools/profile/portfolio.js +341 -0
  89. package/dist/tools/profile/portfolio.js.map +1 -0
  90. package/dist/tools/profile/resume.d.ts +16 -0
  91. package/dist/tools/profile/resume.d.ts.map +1 -0
  92. package/dist/tools/profile/resume.js +107 -0
  93. package/dist/tools/profile/resume.js.map +1 -0
  94. package/dist/tools/profile/shared.d.ts +85 -0
  95. package/dist/tools/profile/shared.d.ts.map +1 -0
  96. package/dist/tools/profile/shared.js +128 -0
  97. package/dist/tools/profile/shared.js.map +1 -0
  98. package/dist/tools/profile/visas.d.ts +15 -0
  99. package/dist/tools/profile/visas.d.ts.map +1 -0
  100. package/dist/tools/profile/visas.js +170 -0
  101. package/dist/tools/profile/visas.js.map +1 -0
  102. package/dist/tools/profile_basic_photo_show.d.ts +14 -0
  103. package/dist/tools/profile_basic_photo_show.d.ts.map +1 -0
  104. package/dist/tools/profile_basic_photo_show.js +59 -0
  105. package/dist/tools/profile_basic_photo_show.js.map +1 -0
  106. package/dist/tools/profile_basic_photo_upload.d.ts +24 -0
  107. package/dist/tools/profile_basic_photo_upload.d.ts.map +1 -0
  108. package/dist/tools/profile_basic_photo_upload.js +90 -0
  109. package/dist/tools/profile_basic_photo_upload.js.map +1 -0
  110. package/dist/tools/profile_basic_show.d.ts +19 -0
  111. package/dist/tools/profile_basic_show.d.ts.map +1 -0
  112. package/dist/tools/profile_basic_show.js +64 -0
  113. package/dist/tools/profile_basic_show.js.map +1 -0
  114. package/dist/tools/profile_basic_update.d.ts +37 -0
  115. package/dist/tools/profile_basic_update.d.ts.map +1 -0
  116. package/dist/tools/profile_basic_update.js +97 -0
  117. package/dist/tools/profile_basic_update.js.map +1 -0
  118. package/dist/tools/profile_external_advanced_wizard_show.d.ts +14 -0
  119. package/dist/tools/profile_external_advanced_wizard_show.d.ts.map +1 -0
  120. package/dist/tools/profile_external_advanced_wizard_show.js +56 -0
  121. package/dist/tools/profile_external_advanced_wizard_show.js.map +1 -0
  122. package/dist/tools/profile_external_custom_requirements_set.d.ts +13 -0
  123. package/dist/tools/profile_external_custom_requirements_set.d.ts.map +1 -0
  124. package/dist/tools/profile_external_custom_requirements_set.js +75 -0
  125. package/dist/tools/profile_external_custom_requirements_set.js.map +1 -0
  126. package/dist/tools/profile_external_custom_requirements_show.d.ts +14 -0
  127. package/dist/tools/profile_external_custom_requirements_show.d.ts.map +1 -0
  128. package/dist/tools/profile_external_custom_requirements_show.js +56 -0
  129. package/dist/tools/profile_external_custom_requirements_show.js.map +1 -0
  130. package/dist/tools/profile_external_readiness.d.ts +12 -0
  131. package/dist/tools/profile_external_readiness.d.ts.map +1 -0
  132. package/dist/tools/profile_external_readiness.js +54 -0
  133. package/dist/tools/profile_external_readiness.js.map +1 -0
  134. package/dist/tools/profile_external_recommendations.d.ts +15 -0
  135. package/dist/tools/profile_external_recommendations.d.ts.map +1 -0
  136. package/dist/tools/profile_external_recommendations.js +57 -0
  137. package/dist/tools/profile_external_recommendations.js.map +1 -0
  138. package/dist/tools/profile_external_update.d.ts +14 -0
  139. package/dist/tools/profile_external_update.d.ts.map +1 -0
  140. package/dist/tools/profile_external_update.js +79 -0
  141. package/dist/tools/profile_external_update.js.map +1 -0
  142. package/dist/tools/profile_reviews_approve_item.d.ts +17 -0
  143. package/dist/tools/profile_reviews_approve_item.d.ts.map +1 -0
  144. package/dist/tools/profile_reviews_approve_item.js +77 -0
  145. package/dist/tools/profile_reviews_approve_item.js.map +1 -0
  146. package/dist/tools/profile_reviews_approve_section.d.ts +15 -0
  147. package/dist/tools/profile_reviews_approve_section.d.ts.map +1 -0
  148. package/dist/tools/profile_reviews_approve_section.js +70 -0
  149. package/dist/tools/profile_reviews_approve_section.js.map +1 -0
  150. package/dist/tools/profile_reviews_list.d.ts +16 -0
  151. package/dist/tools/profile_reviews_list.d.ts.map +1 -0
  152. package/dist/tools/profile_reviews_list.js +58 -0
  153. package/dist/tools/profile_reviews_list.js.map +1 -0
  154. package/dist/tools/profile_reviews_submit_for_review.d.ts +14 -0
  155. package/dist/tools/profile_reviews_submit_for_review.d.ts.map +1 -0
  156. package/dist/tools/profile_reviews_submit_for_review.js +56 -0
  157. package/dist/tools/profile_reviews_submit_for_review.js.map +1 -0
  158. package/dist/tools/profile_skills_add.d.ts +4 -0
  159. package/dist/tools/profile_skills_add.d.ts.map +1 -0
  160. package/dist/tools/profile_skills_add.js +52 -0
  161. package/dist/tools/profile_skills_add.js.map +1 -0
  162. package/dist/tools/profile_skills_autocomplete.d.ts +4 -0
  163. package/dist/tools/profile_skills_autocomplete.d.ts.map +1 -0
  164. package/dist/tools/profile_skills_autocomplete.js +78 -0
  165. package/dist/tools/profile_skills_autocomplete.js.map +1 -0
  166. package/dist/tools/profile_skills_list.d.ts +16 -0
  167. package/dist/tools/profile_skills_list.d.ts.map +1 -0
  168. package/dist/tools/profile_skills_list.js +65 -0
  169. package/dist/tools/profile_skills_list.js.map +1 -0
  170. package/dist/tools/profile_skills_readiness.d.ts +4 -0
  171. package/dist/tools/profile_skills_readiness.d.ts.map +1 -0
  172. package/dist/tools/profile_skills_readiness.js +53 -0
  173. package/dist/tools/profile_skills_readiness.js.map +1 -0
  174. package/dist/tools/profile_skills_remove.d.ts +4 -0
  175. package/dist/tools/profile_skills_remove.d.ts.map +1 -0
  176. package/dist/tools/profile_skills_remove.js +53 -0
  177. package/dist/tools/profile_skills_remove.js.map +1 -0
  178. package/dist/tools/profile_skills_show.d.ts +4 -0
  179. package/dist/tools/profile_skills_show.d.ts.map +1 -0
  180. package/dist/tools/profile_skills_show.js +51 -0
  181. package/dist/tools/profile_skills_show.js.map +1 -0
  182. package/dist/tools/profile_skills_update.d.ts +11 -0
  183. package/dist/tools/profile_skills_update.d.ts.map +1 -0
  184. package/dist/tools/profile_skills_update.js +97 -0
  185. package/dist/tools/profile_skills_update.js.map +1 -0
  186. package/dist/tools/timesheet.d.ts +29 -0
  187. package/dist/tools/timesheet.d.ts.map +1 -0
  188. package/dist/tools/timesheet.js +257 -0
  189. package/dist/tools/timesheet.js.map +1 -0
  190. package/package.json +33 -13
  191. package/index.js +0 -7
@@ -0,0 +1,193 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { parseDateInput, profile } from "@ttctl/core";
4
+ import { z } from "zod";
5
+ import { buildMcpDryRunPreview, dryRunResponse } from "../_shared.js";
6
+ import { dateInput, jsonSuccess, presentToolError, textSuccess } from "./shared.js";
7
+ const DRY_RUN_FIELD = z
8
+ .boolean()
9
+ .optional()
10
+ .describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
11
+ /**
12
+ * Register the five `profile.certifications.*` MCP tools on `server`.
13
+ *
14
+ * MCP tool names use ONLY the canonical `certifications` form — the CLI
15
+ * alias `certs` (per #72) is CLI-only and never appears in the MCP
16
+ * catalog.
17
+ *
18
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. When
19
+ * `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
20
+ * MCP-layer preview building. `show` previews `GET_CERTIFICATION` (the
21
+ * apply path lists then filters client-side; no per-id selector exists).
22
+ * `profileId` carries `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply
23
+ * path resolves it via a sibling profile read.
24
+ */
25
+ export function registerCertificationsTools(server, ctx) {
26
+ server.registerTool("ttctl_profile_certifications_add", {
27
+ title: "Add certification entry",
28
+ description: "Add a new certification entry (name + issuer, with optional issue / expiration dates, credential URL, and credential ID). Dates accept ISO-8601 (YYYY-MM-DD) or year-only (YYYY); month is preserved when given.",
29
+ inputSchema: {
30
+ name: z.string().min(1).describe("certification name (mapped to certificate)"),
31
+ issuer: z.string().min(1).describe("issuing organization (mapped to institution)"),
32
+ issued: dateInput.optional().describe("issue date — ISO-8601 or year"),
33
+ expires: dateInput.optional().describe("expiration date — ISO-8601 or year"),
34
+ link: z.url().optional().describe("credential URL"),
35
+ number: z.string().optional().describe("credential ID / certificate number"),
36
+ dryRun: DRY_RUN_FIELD,
37
+ },
38
+ }, async (input) => {
39
+ const auth = await ctx.resolveTokenForTool("profile.certifications.add");
40
+ if ("error" in auth)
41
+ return auth.error;
42
+ const fields = {
43
+ certificate: input.name,
44
+ institution: input.issuer,
45
+ };
46
+ try {
47
+ if (input.issued !== undefined) {
48
+ const parsed = parseDateInput(input.issued, "issued");
49
+ fields.validFromMonth = parsed.month;
50
+ fields.validFromYear = parsed.year;
51
+ }
52
+ if (input.expires !== undefined) {
53
+ const parsed = parseDateInput(input.expires, "expires");
54
+ fields.validToMonth = parsed.month;
55
+ fields.validToYear = parsed.year;
56
+ }
57
+ }
58
+ catch (err) {
59
+ return presentToolError("profile.certifications.add", err);
60
+ }
61
+ if (input.link !== undefined)
62
+ fields.link = input.link;
63
+ if (input.number !== undefined)
64
+ fields.number = input.number;
65
+ if (input.dryRun === true) {
66
+ return dryRunResponse(buildMcpDryRunPreview("CREATE_CERTIFICATION", "talent-profile", { input: { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER, certification: fields } }, auth.token));
67
+ }
68
+ try {
69
+ const created = await profile.certifications.add(auth.token, fields);
70
+ return jsonSuccess(created);
71
+ }
72
+ catch (err) {
73
+ return presentToolError("profile.certifications.add", err);
74
+ }
75
+ });
76
+ server.registerTool("ttctl_profile_certifications_update", {
77
+ title: "Update certification entry",
78
+ description: "Update an existing certification entry by id. At least one field must be supplied.",
79
+ inputSchema: {
80
+ id: z.string().min(1).describe("certification id (V1-Certification-NNN)"),
81
+ name: z.string().optional(),
82
+ issuer: z.string().optional(),
83
+ issued: dateInput.optional(),
84
+ expires: dateInput.optional(),
85
+ link: z.url().optional(),
86
+ number: z.string().optional(),
87
+ highlight: z.boolean().optional(),
88
+ dryRun: DRY_RUN_FIELD,
89
+ },
90
+ }, async (input) => {
91
+ const auth = await ctx.resolveTokenForTool("profile.certifications.update");
92
+ if ("error" in auth)
93
+ return auth.error;
94
+ const fields = {};
95
+ try {
96
+ if (input.issued !== undefined) {
97
+ const parsed = parseDateInput(input.issued, "issued");
98
+ fields.validFromMonth = parsed.month;
99
+ fields.validFromYear = parsed.year;
100
+ }
101
+ if (input.expires !== undefined) {
102
+ const parsed = parseDateInput(input.expires, "expires");
103
+ fields.validToMonth = parsed.month;
104
+ fields.validToYear = parsed.year;
105
+ }
106
+ }
107
+ catch (err) {
108
+ return presentToolError("profile.certifications.update", err);
109
+ }
110
+ if (input.name !== undefined)
111
+ fields.certificate = input.name;
112
+ if (input.issuer !== undefined)
113
+ fields.institution = input.issuer;
114
+ if (input.link !== undefined)
115
+ fields.link = input.link;
116
+ if (input.number !== undefined)
117
+ fields.number = input.number;
118
+ if (input.highlight !== undefined)
119
+ fields.highlight = input.highlight;
120
+ if (input.dryRun === true) {
121
+ return dryRunResponse(buildMcpDryRunPreview("UPDATE_CERTIFICATION", "talent-profile", { input: { certificationId: input.id, certification: fields } }, auth.token));
122
+ }
123
+ try {
124
+ const updated = await profile.certifications.update(auth.token, input.id, fields);
125
+ return jsonSuccess(updated);
126
+ }
127
+ catch (err) {
128
+ return presentToolError("profile.certifications.update", err);
129
+ }
130
+ });
131
+ server.registerTool("ttctl_profile_certifications_remove", {
132
+ title: "Remove certification entry",
133
+ description: "Remove a certification entry by id.",
134
+ inputSchema: { id: z.string().min(1).describe("certification id"), dryRun: DRY_RUN_FIELD },
135
+ }, async (input) => {
136
+ const auth = await ctx.resolveTokenForTool("profile.certifications.remove");
137
+ if ("error" in auth)
138
+ return auth.error;
139
+ if (input.dryRun === true) {
140
+ return dryRunResponse(buildMcpDryRunPreview("REMOVE_CERTIFICATION", "talent-profile", { input: { certificationId: input.id } }, auth.token));
141
+ }
142
+ try {
143
+ const id = await profile.certifications.remove(auth.token, input.id);
144
+ return textSuccess(`Certification ${id} removed.`);
145
+ }
146
+ catch (err) {
147
+ return presentToolError("profile.certifications.remove", err);
148
+ }
149
+ });
150
+ server.registerTool("ttctl_profile_certifications_show", {
151
+ title: "Show certification entry",
152
+ description: "Show a single certification entry by id (returns the row as JSON). Note: the underlying wire call lists all rows and filters client-side; the dry-run preview emits `GET_CERTIFICATION` (the list query) accordingly.",
153
+ inputSchema: { id: z.string().min(1).describe("certification id"), dryRun: DRY_RUN_FIELD },
154
+ }, async (input) => {
155
+ const auth = await ctx.resolveTokenForTool("profile.certifications.show");
156
+ if ("error" in auth)
157
+ return auth.error;
158
+ if (input.dryRun === true) {
159
+ return dryRunResponse(buildMcpDryRunPreview("GET_CERTIFICATION", "talent-profile", { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER }, auth.token));
160
+ }
161
+ try {
162
+ const row = await profile.certifications.show(auth.token, input.id);
163
+ return jsonSuccess(row);
164
+ }
165
+ catch (err) {
166
+ return presentToolError("profile.certifications.show", err);
167
+ }
168
+ });
169
+ server.registerTool("ttctl_profile_certifications_highlight", {
170
+ title: "Toggle certification highlight",
171
+ description: "Toggle the highlight flag on a certification entry.",
172
+ inputSchema: {
173
+ id: z.string().min(1).describe("certification id"),
174
+ highlight: z.boolean().default(true),
175
+ dryRun: DRY_RUN_FIELD,
176
+ },
177
+ }, async (input) => {
178
+ const auth = await ctx.resolveTokenForTool("profile.certifications.highlight");
179
+ if ("error" in auth)
180
+ return auth.error;
181
+ if (input.dryRun === true) {
182
+ return dryRunResponse(buildMcpDryRunPreview("highlightCertification", "talent-profile", { id: input.id, highlight: input.highlight }, auth.token));
183
+ }
184
+ try {
185
+ const result = await profile.certifications.highlight(auth.token, input.id, input.highlight);
186
+ return jsonSuccess(result);
187
+ }
188
+ catch (err) {
189
+ return presentToolError("profile.certifications.highlight", err);
190
+ }
191
+ });
192
+ }
193
+ //# sourceMappingURL=certifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certifications.js","sourceRoot":"","sources":["../../../src/tools/profile/certifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolRegistrationContext } from "../_shared.js";
3
+ /**
4
+ * Register the five `profile.education.*` MCP tools on `server`. Mirrors
5
+ * the CLI surface 1:1 (canonical names — no CLI-only aliases per project
6
+ * policy in #72).
7
+ *
8
+ * Tools:
9
+ * - ttctl_profile_education_add
10
+ * - ttctl_profile_education_update
11
+ * - ttctl_profile_education_remove
12
+ * - ttctl_profile_education_show
13
+ * - ttctl_profile_education_highlight
14
+ *
15
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. When
16
+ * `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
17
+ * MCP-layer preview building. `show` previews `GET_EDUCATION` (the
18
+ * apply path lists then filters client-side; no per-id selector exists).
19
+ * `profileId` carries `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply
20
+ * path resolves it via a sibling profile read.
21
+ */
22
+ export declare function registerEducationTools(server: McpServer, ctx: ToolRegistrationContext): void;
23
+ //# sourceMappingURL=education.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"education.d.ts","sourceRoot":"","sources":["../../../src/tools/profile/education.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAyC,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAWpG;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAyM5F"}
@@ -0,0 +1,196 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { parseDateInput, profile } from "@ttctl/core";
4
+ import { z } from "zod";
5
+ import { buildMcpDryRunPreview, dryRunResponse } from "../_shared.js";
6
+ import { profileEducationRowOutputSchema, profileRowRemoveOutputSchema } from "../output-schemas.js";
7
+ import { dateInput, jsonSuccess, presentToolError, textWithStructuredSuccess } from "./shared.js";
8
+ const DRY_RUN_FIELD = z
9
+ .boolean()
10
+ .optional()
11
+ .describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
12
+ /**
13
+ * Register the five `profile.education.*` MCP tools on `server`. Mirrors
14
+ * the CLI surface 1:1 (canonical names — no CLI-only aliases per project
15
+ * policy in #72).
16
+ *
17
+ * Tools:
18
+ * - ttctl_profile_education_add
19
+ * - ttctl_profile_education_update
20
+ * - ttctl_profile_education_remove
21
+ * - ttctl_profile_education_show
22
+ * - ttctl_profile_education_highlight
23
+ *
24
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. When
25
+ * `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
26
+ * MCP-layer preview building. `show` previews `GET_EDUCATION` (the
27
+ * apply path lists then filters client-side; no per-id selector exists).
28
+ * `profileId` carries `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply
29
+ * path resolves it via a sibling profile read.
30
+ */
31
+ export function registerEducationTools(server, ctx) {
32
+ server.registerTool("ttctl_profile_education_add", {
33
+ title: "Add education entry",
34
+ description: "Add a new education entry (institution + degree, with optional field of study, location, title, and start/end years). Dates accept ISO-8601 (YYYY-MM-DD) or year-only (YYYY).",
35
+ inputSchema: {
36
+ institution: z.string().min(1).describe("school / university name"),
37
+ degree: z.string().min(1).describe("degree (e.g. BSc, MSc, PhD)"),
38
+ from: dateInput.optional().describe("start date — ISO-8601 or year"),
39
+ to: dateInput.optional().describe("end date — ISO-8601 or year"),
40
+ fieldOfStudy: z.string().optional(),
41
+ location: z.string().optional(),
42
+ title: z.string().optional(),
43
+ dryRun: DRY_RUN_FIELD,
44
+ },
45
+ outputSchema: profileEducationRowOutputSchema.shape,
46
+ }, async (input) => {
47
+ const auth = await ctx.resolveTokenForTool("profile.education.add");
48
+ if ("error" in auth)
49
+ return auth.error;
50
+ const fields = {
51
+ institution: input.institution,
52
+ degree: input.degree,
53
+ };
54
+ try {
55
+ if (input.from !== undefined)
56
+ fields.yearFrom = parseDateInput(input.from, "from").year;
57
+ if (input.to !== undefined)
58
+ fields.yearTo = parseDateInput(input.to, "to").year;
59
+ }
60
+ catch (err) {
61
+ return presentToolError("profile.education.add", err);
62
+ }
63
+ if (input.fieldOfStudy !== undefined)
64
+ fields.fieldOfStudy = input.fieldOfStudy;
65
+ if (input.location !== undefined)
66
+ fields.location = input.location;
67
+ if (input.title !== undefined)
68
+ fields.title = input.title;
69
+ if (input.dryRun === true) {
70
+ return dryRunResponse(buildMcpDryRunPreview("CREATE_EDUCATION", "talent-profile", { input: { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER, education: fields } }, auth.token));
71
+ }
72
+ try {
73
+ const created = await profile.education.add(auth.token, fields);
74
+ return jsonSuccess(created);
75
+ }
76
+ catch (err) {
77
+ return presentToolError("profile.education.add", err);
78
+ }
79
+ });
80
+ server.registerTool("ttctl_profile_education_update", {
81
+ title: "Update education entry",
82
+ description: "Update an existing education entry by id. At least one field must be supplied.",
83
+ inputSchema: {
84
+ id: z.string().min(1).describe("education id (V1-Education-NNN)"),
85
+ institution: z.string().optional(),
86
+ degree: z.string().optional(),
87
+ from: dateInput.optional(),
88
+ to: dateInput.optional(),
89
+ fieldOfStudy: z.string().optional(),
90
+ location: z.string().optional(),
91
+ title: z.string().optional(),
92
+ highlight: z.boolean().optional(),
93
+ dryRun: DRY_RUN_FIELD,
94
+ },
95
+ outputSchema: profileEducationRowOutputSchema.shape,
96
+ }, async (input) => {
97
+ const auth = await ctx.resolveTokenForTool("profile.education.update");
98
+ if ("error" in auth)
99
+ return auth.error;
100
+ const fields = {};
101
+ try {
102
+ if (input.from !== undefined)
103
+ fields.yearFrom = parseDateInput(input.from, "from").year;
104
+ if (input.to !== undefined)
105
+ fields.yearTo = parseDateInput(input.to, "to").year;
106
+ }
107
+ catch (err) {
108
+ return presentToolError("profile.education.update", err);
109
+ }
110
+ if (input.institution !== undefined)
111
+ fields.institution = input.institution;
112
+ if (input.degree !== undefined)
113
+ fields.degree = input.degree;
114
+ if (input.fieldOfStudy !== undefined)
115
+ fields.fieldOfStudy = input.fieldOfStudy;
116
+ if (input.location !== undefined)
117
+ fields.location = input.location;
118
+ if (input.title !== undefined)
119
+ fields.title = input.title;
120
+ if (input.highlight !== undefined)
121
+ fields.highlight = input.highlight;
122
+ if (input.dryRun === true) {
123
+ return dryRunResponse(buildMcpDryRunPreview("UPDATE_EDUCATION", "talent-profile", { input: { educationId: input.id, education: fields } }, auth.token));
124
+ }
125
+ try {
126
+ const updated = await profile.education.update(auth.token, input.id, fields);
127
+ return jsonSuccess(updated);
128
+ }
129
+ catch (err) {
130
+ return presentToolError("profile.education.update", err);
131
+ }
132
+ });
133
+ server.registerTool("ttctl_profile_education_remove", {
134
+ title: "Remove education entry",
135
+ description: "Remove an education entry by id.",
136
+ inputSchema: { id: z.string().min(1).describe("education id"), dryRun: DRY_RUN_FIELD },
137
+ outputSchema: profileRowRemoveOutputSchema.shape,
138
+ }, async (input) => {
139
+ const auth = await ctx.resolveTokenForTool("profile.education.remove");
140
+ if ("error" in auth)
141
+ return auth.error;
142
+ if (input.dryRun === true) {
143
+ return dryRunResponse(buildMcpDryRunPreview("REMOVE_EDUCATION", "talent-profile", { input: { educationId: input.id } }, auth.token));
144
+ }
145
+ try {
146
+ const id = await profile.education.remove(auth.token, input.id);
147
+ return textWithStructuredSuccess(`Education ${id} removed.`, { id, removed: true });
148
+ }
149
+ catch (err) {
150
+ return presentToolError("profile.education.remove", err);
151
+ }
152
+ });
153
+ server.registerTool("ttctl_profile_education_show", {
154
+ title: "Show education entry",
155
+ description: "Show a single education entry by id (returns the row as JSON). Note: the underlying wire call lists all rows and filters client-side; the dry-run preview emits `GET_EDUCATION` (the list query) accordingly.",
156
+ inputSchema: { id: z.string().min(1).describe("education id"), dryRun: DRY_RUN_FIELD },
157
+ }, async (input) => {
158
+ const auth = await ctx.resolveTokenForTool("profile.education.show");
159
+ if ("error" in auth)
160
+ return auth.error;
161
+ if (input.dryRun === true) {
162
+ return dryRunResponse(buildMcpDryRunPreview("GET_EDUCATION", "talent-profile", { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER }, auth.token));
163
+ }
164
+ try {
165
+ const row = await profile.education.show(auth.token, input.id);
166
+ return jsonSuccess(row);
167
+ }
168
+ catch (err) {
169
+ return presentToolError("profile.education.show", err);
170
+ }
171
+ });
172
+ server.registerTool("ttctl_profile_education_highlight", {
173
+ title: "Toggle education highlight",
174
+ description: "Toggle the highlight flag on an education entry.",
175
+ inputSchema: {
176
+ id: z.string().min(1).describe("education id"),
177
+ highlight: z.boolean().default(true).describe("true to highlight, false to un-highlight"),
178
+ dryRun: DRY_RUN_FIELD,
179
+ },
180
+ }, async (input) => {
181
+ const auth = await ctx.resolveTokenForTool("profile.education.highlight");
182
+ if ("error" in auth)
183
+ return auth.error;
184
+ if (input.dryRun === true) {
185
+ return dryRunResponse(buildMcpDryRunPreview("highlightEducation", "talent-profile", { id: input.id, highlight: input.highlight }, auth.token));
186
+ }
187
+ try {
188
+ const result = await profile.education.highlight(auth.token, input.id, input.highlight);
189
+ return jsonSuccess(result);
190
+ }
191
+ catch (err) {
192
+ return presentToolError("profile.education.highlight", err);
193
+ }
194
+ });
195
+ }
196
+ //# sourceMappingURL=education.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"education.js","sourceRoot":"","sources":["../../../src/tools/profile/education.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAgC,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,+BAA+B,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAElG,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+JAA+J,CAChK,CAAC;AAEJ;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,GAA4B;IACpF,MAAM,CAAC,YAAY,CACjB,6BAA6B,EAC7B;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,+KAA+K;QACjL,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YACnE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACjE,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YACpE,EAAE,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAChE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC5B,MAAM,EAAE,aAAa;SACtB;QACD,YAAY,EAAE,+BAA+B,CAAC,KAAK;KACpD,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;QACpE,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAsC;YAChD,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC;QACF,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC;YACxF,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS;gBAAE,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;QAClF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;YAAE,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QAC/E,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QACnE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAE1D,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,kBAAkB,EAClB,gBAAgB,EAChB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EACzF,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAChE,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gCAAgC,EAChC;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,gFAAgF;QAC7F,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YACjE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC7B,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE;YAC1B,EAAE,EAAE,SAAS,CAAC,QAAQ,EAAE;YACxB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC5B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YACjC,MAAM,EAAE,aAAa;SACtB;QACD,YAAY,EAAE,+BAA+B,CAAC,KAAK;KACpD,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,CAAC;QACvE,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAsC,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC;YACxF,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS;gBAAE,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;QAClF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;YAAE,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC7D,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;YAAE,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QAC/E,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QACnE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1D,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAEtE,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,kBAAkB,EAClB,gBAAgB,EAChB,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EACvD,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC7E,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gCAAgC,EAChC;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,kCAAkC;QAC/C,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;QACtF,YAAY,EAAE,4BAA4B,CAAC,KAAK;KACjD,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,CAAC;QACvE,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAC9G,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YAChE,OAAO,yBAAyB,CAAC,aAAa,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACtF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,8BAA8B,EAC9B;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,+MAA+M;QACjN,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;KACvF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;QACrE,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,eAAe,EACf,gBAAgB,EAChB,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAC3D,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YAC/D,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,mCAAmC,EACnC;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,kDAAkD;QAC/D,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC9C,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACzF,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,6BAA6B,CAAC,CAAC;QAC1E,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,oBAAoB,EACpB,gBAAgB,EAChB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,EAC5C,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACxF,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,gBAAgB,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolRegistrationContext } from "../_shared.js";
3
+ /**
4
+ * Register the six `profile.employment.*` MCP tools on `server`.
5
+ *
6
+ * MCP tool names use ONLY the canonical `employment` form — the CLI
7
+ * alias `experience` (per #72) is CLI-only and never appears in the MCP
8
+ * catalog.
9
+ *
10
+ * The sixth tool (`employer_autocomplete`) is the catalog lookup leaf
11
+ * — it returns suggestions from the known-employer database, useful
12
+ * for resolving free-text employer names to canonical Toptal IDs
13
+ * before adding a new employment row.
14
+ *
15
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. When
16
+ * `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
17
+ * MCP-layer preview building. `show` previews `GET_WORK_EXPERIENCE` (the
18
+ * apply path lists then filters client-side; no per-id selector exists).
19
+ * `profileId` carries `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply
20
+ * path resolves it via a sibling profile read.
21
+ */
22
+ export declare function registerEmploymentTools(server: McpServer, ctx: ToolRegistrationContext): void;
23
+ //# sourceMappingURL=employment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employment.d.ts","sourceRoot":"","sources":["../../../src/tools/profile/employment.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAyC,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAWpG;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA8P7F"}