@ttctl/mcp 0.0.0 → 0.1.0-rc.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.
Files changed (195) 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 +133 -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 +129 -0
  63. package/dist/tools/output-schemas.d.ts.map +1 -0
  64. package/dist/tools/output-schemas.js +138 -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 +219 -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 +222 -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 +254 -0
  81. package/dist/tools/profile/employment.js.map +1 -0
  82. package/dist/tools/profile/industries.d.ts +30 -0
  83. package/dist/tools/profile/industries.d.ts.map +1 -0
  84. package/dist/tools/profile/industries.js +196 -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 +64 -0
  111. package/dist/tools/profile_basic_show.d.ts.map +1 -0
  112. package/dist/tools/profile_basic_show.js +108 -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_show.d.ts +15 -0
  139. package/dist/tools/profile_external_show.d.ts.map +1 -0
  140. package/dist/tools/profile_external_show.js +59 -0
  141. package/dist/tools/profile_external_show.js.map +1 -0
  142. package/dist/tools/profile_external_update.d.ts +14 -0
  143. package/dist/tools/profile_external_update.d.ts.map +1 -0
  144. package/dist/tools/profile_external_update.js +79 -0
  145. package/dist/tools/profile_external_update.js.map +1 -0
  146. package/dist/tools/profile_reviews_approve_item.d.ts +17 -0
  147. package/dist/tools/profile_reviews_approve_item.d.ts.map +1 -0
  148. package/dist/tools/profile_reviews_approve_item.js +77 -0
  149. package/dist/tools/profile_reviews_approve_item.js.map +1 -0
  150. package/dist/tools/profile_reviews_approve_section.d.ts +15 -0
  151. package/dist/tools/profile_reviews_approve_section.d.ts.map +1 -0
  152. package/dist/tools/profile_reviews_approve_section.js +70 -0
  153. package/dist/tools/profile_reviews_approve_section.js.map +1 -0
  154. package/dist/tools/profile_reviews_list.d.ts +16 -0
  155. package/dist/tools/profile_reviews_list.d.ts.map +1 -0
  156. package/dist/tools/profile_reviews_list.js +58 -0
  157. package/dist/tools/profile_reviews_list.js.map +1 -0
  158. package/dist/tools/profile_reviews_submit_for_review.d.ts +14 -0
  159. package/dist/tools/profile_reviews_submit_for_review.d.ts.map +1 -0
  160. package/dist/tools/profile_reviews_submit_for_review.js +56 -0
  161. package/dist/tools/profile_reviews_submit_for_review.js.map +1 -0
  162. package/dist/tools/profile_skills_add.d.ts +4 -0
  163. package/dist/tools/profile_skills_add.d.ts.map +1 -0
  164. package/dist/tools/profile_skills_add.js +52 -0
  165. package/dist/tools/profile_skills_add.js.map +1 -0
  166. package/dist/tools/profile_skills_autocomplete.d.ts +4 -0
  167. package/dist/tools/profile_skills_autocomplete.d.ts.map +1 -0
  168. package/dist/tools/profile_skills_autocomplete.js +78 -0
  169. package/dist/tools/profile_skills_autocomplete.js.map +1 -0
  170. package/dist/tools/profile_skills_list.d.ts +16 -0
  171. package/dist/tools/profile_skills_list.d.ts.map +1 -0
  172. package/dist/tools/profile_skills_list.js +65 -0
  173. package/dist/tools/profile_skills_list.js.map +1 -0
  174. package/dist/tools/profile_skills_readiness.d.ts +4 -0
  175. package/dist/tools/profile_skills_readiness.d.ts.map +1 -0
  176. package/dist/tools/profile_skills_readiness.js +53 -0
  177. package/dist/tools/profile_skills_readiness.js.map +1 -0
  178. package/dist/tools/profile_skills_remove.d.ts +4 -0
  179. package/dist/tools/profile_skills_remove.d.ts.map +1 -0
  180. package/dist/tools/profile_skills_remove.js +53 -0
  181. package/dist/tools/profile_skills_remove.js.map +1 -0
  182. package/dist/tools/profile_skills_show.d.ts +4 -0
  183. package/dist/tools/profile_skills_show.d.ts.map +1 -0
  184. package/dist/tools/profile_skills_show.js +51 -0
  185. package/dist/tools/profile_skills_show.js.map +1 -0
  186. package/dist/tools/profile_skills_update.d.ts +11 -0
  187. package/dist/tools/profile_skills_update.d.ts.map +1 -0
  188. package/dist/tools/profile_skills_update.js +97 -0
  189. package/dist/tools/profile_skills_update.js.map +1 -0
  190. package/dist/tools/timesheet.d.ts +29 -0
  191. package/dist/tools/timesheet.d.ts.map +1 -0
  192. package/dist/tools/timesheet.js +257 -0
  193. package/dist/tools/timesheet.js.map +1 -0
  194. package/package.json +33 -13
  195. package/index.js +0 -7
@@ -0,0 +1,254 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { parseDateInput, profile, splitParagraphs } from "@ttctl/core";
4
+ import { z } from "zod";
5
+ import { buildMcpDryRunPreview, dryRunResponse } from "../_shared.js";
6
+ import { profileEmploymentRowOutputSchema, 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 six `profile.employment.*` MCP tools on `server`.
14
+ *
15
+ * MCP tool names use ONLY the canonical `employment` form — the CLI
16
+ * alias `experience` (per #72) is CLI-only and never appears in the MCP
17
+ * catalog.
18
+ *
19
+ * The sixth tool (`employer_autocomplete`) is the catalog lookup leaf
20
+ * — it returns suggestions from the known-employer database, useful
21
+ * for resolving free-text employer names to canonical Toptal IDs
22
+ * before adding a new employment row.
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_WORK_EXPERIENCE` (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 registerEmploymentTools(server, ctx) {
32
+ server.registerTool("ttctl_profile_employment_add", {
33
+ title: "Add employment entry",
34
+ description: "Add a new employment entry (company + role, with optional start/end years and `current` flag). Dates accept ISO-8601 (YYYY-MM-DD) or year-only (YYYY); year only is stored.",
35
+ inputSchema: {
36
+ company: z.string().min(1).describe("company / employer name"),
37
+ role: z.string().min(1).describe("job title (mapped to position)"),
38
+ from: dateInput.optional().describe("start date — ISO-8601 or year"),
39
+ to: dateInput.optional().describe("end date — ISO-8601 or year"),
40
+ current: z.boolean().optional().describe("mark as current position (no end date)"),
41
+ website: z.url().optional().describe("company website"),
42
+ description: z
43
+ .string()
44
+ .optional()
45
+ .describe("multi-paragraph description; split on blank lines into experienceItems"),
46
+ dryRun: DRY_RUN_FIELD,
47
+ },
48
+ outputSchema: profileEmploymentRowOutputSchema.shape,
49
+ }, async (input) => {
50
+ const auth = await ctx.resolveTokenForTool("profile.employment.add");
51
+ if ("error" in auth)
52
+ return auth.error;
53
+ const fields = {
54
+ company: input.company,
55
+ position: input.role,
56
+ };
57
+ try {
58
+ if (input.from !== undefined)
59
+ fields.startDate = parseDateInput(input.from, "from").year;
60
+ if (input.to !== undefined)
61
+ fields.endDate = parseDateInput(input.to, "to").year;
62
+ }
63
+ catch (err) {
64
+ return presentToolError("profile.employment.add", err);
65
+ }
66
+ if (input.current === true)
67
+ fields.endDate = null;
68
+ if (input.website !== undefined) {
69
+ fields.companyWebsite = input.website;
70
+ fields.noWebsite = false;
71
+ }
72
+ if (input.description !== undefined) {
73
+ fields.experienceItems = splitParagraphs(input.description);
74
+ }
75
+ if (input.dryRun === true) {
76
+ return dryRunResponse(buildMcpDryRunPreview("CreateEmployment", "talent-profile", { input: { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER, employment: fields } }, auth.token));
77
+ }
78
+ try {
79
+ const created = await profile.employment.add(auth.token, fields);
80
+ return jsonSuccess(created);
81
+ }
82
+ catch (err) {
83
+ return presentToolError("profile.employment.add", err);
84
+ }
85
+ });
86
+ server.registerTool("ttctl_profile_employment_update", {
87
+ title: "Update employment entry",
88
+ description: "Update an existing employment entry by id. At least one field must be supplied. `description` is multi-paragraph free-text and splits on blank lines.",
89
+ inputSchema: {
90
+ id: z.string().min(1).describe("employment id (V1-Employment-NNN)"),
91
+ company: z.string().optional(),
92
+ role: z.string().optional(),
93
+ from: dateInput.optional(),
94
+ to: dateInput.optional(),
95
+ current: z.boolean().optional(),
96
+ website: z.url().optional(),
97
+ description: z.string().optional(),
98
+ highlight: z.boolean().optional(),
99
+ dryRun: DRY_RUN_FIELD,
100
+ },
101
+ outputSchema: profileEmploymentRowOutputSchema.shape,
102
+ }, async (input) => {
103
+ const auth = await ctx.resolveTokenForTool("profile.employment.update");
104
+ if ("error" in auth)
105
+ return auth.error;
106
+ const fields = {};
107
+ try {
108
+ if (input.from !== undefined)
109
+ fields.startDate = parseDateInput(input.from, "from").year;
110
+ if (input.to !== undefined)
111
+ fields.endDate = parseDateInput(input.to, "to").year;
112
+ }
113
+ catch (err) {
114
+ return presentToolError("profile.employment.update", err);
115
+ }
116
+ if (input.current === true)
117
+ fields.endDate = null;
118
+ if (input.company !== undefined)
119
+ fields.company = input.company;
120
+ if (input.role !== undefined)
121
+ fields.position = input.role;
122
+ if (input.website !== undefined) {
123
+ fields.companyWebsite = input.website;
124
+ fields.noWebsite = false;
125
+ }
126
+ if (input.description !== undefined) {
127
+ fields.experienceItems = splitParagraphs(input.description);
128
+ }
129
+ if (input.highlight !== undefined)
130
+ fields.highlight = input.highlight;
131
+ if (input.dryRun === true) {
132
+ return dryRunResponse(buildMcpDryRunPreview("UpdateEmployment", "talent-profile", { input: { employmentId: input.id, employment: fields } }, auth.token));
133
+ }
134
+ try {
135
+ const updated = await profile.employment.update(auth.token, input.id, fields);
136
+ return jsonSuccess(updated);
137
+ }
138
+ catch (err) {
139
+ return presentToolError("profile.employment.update", err);
140
+ }
141
+ });
142
+ server.registerTool("ttctl_profile_employment_remove", {
143
+ title: "Remove employment entry",
144
+ description: "Remove an employment entry by id.",
145
+ inputSchema: { id: z.string().min(1).describe("employment id"), dryRun: DRY_RUN_FIELD },
146
+ outputSchema: profileRowRemoveOutputSchema.shape,
147
+ }, async (input) => {
148
+ const auth = await ctx.resolveTokenForTool("profile.employment.remove");
149
+ if ("error" in auth)
150
+ return auth.error;
151
+ if (input.dryRun === true) {
152
+ return dryRunResponse(buildMcpDryRunPreview("RemoveEmployment", "talent-profile", { input: { employmentId: input.id } }, auth.token));
153
+ }
154
+ try {
155
+ const id = await profile.employment.remove(auth.token, input.id);
156
+ return textWithStructuredSuccess(`Employment ${id} removed.`, { id, removed: true });
157
+ }
158
+ catch (err) {
159
+ return presentToolError("profile.employment.remove", err);
160
+ }
161
+ });
162
+ server.registerTool("ttctl_profile_employment_show", {
163
+ title: "Show employment entry",
164
+ description: "Show a single employment 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_WORK_EXPERIENCE` (the list query) accordingly.",
165
+ inputSchema: { id: z.string().min(1).describe("employment id"), dryRun: DRY_RUN_FIELD },
166
+ }, async (input) => {
167
+ const auth = await ctx.resolveTokenForTool("profile.employment.show");
168
+ if ("error" in auth)
169
+ return auth.error;
170
+ if (input.dryRun === true) {
171
+ return dryRunResponse(buildMcpDryRunPreview("GET_WORK_EXPERIENCE", "talent-profile", { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER }, auth.token));
172
+ }
173
+ try {
174
+ const row = await profile.employment.show(auth.token, input.id);
175
+ return jsonSuccess(row);
176
+ }
177
+ catch (err) {
178
+ return presentToolError("profile.employment.show", err);
179
+ }
180
+ });
181
+ server.registerTool("ttctl_profile_employment_list", {
182
+ title: "List employment entries",
183
+ description: [
184
+ "List every employment entry on the signed-in user's Toptal profile, with each row's full per-item shape (mirrors `ttctl_profile_employment_show`).",
185
+ "",
186
+ "Example user prompts that should map to this tool:",
187
+ ' - "What employment entries do I have on my Toptal profile?"',
188
+ ' - "Show me all my Toptal work experience."',
189
+ ' - "List my Toptal employment IDs so I can edit one."',
190
+ ].join("\n"),
191
+ inputSchema: { dryRun: DRY_RUN_FIELD },
192
+ }, async (input) => {
193
+ const auth = await ctx.resolveTokenForTool("profile.employment.list");
194
+ if ("error" in auth)
195
+ return auth.error;
196
+ if (input.dryRun === true) {
197
+ return dryRunResponse(buildMcpDryRunPreview("GET_WORK_EXPERIENCE", "talent-profile", { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER }, auth.token));
198
+ }
199
+ try {
200
+ const rows = await profile.employment.list(auth.token);
201
+ return jsonSuccess(rows);
202
+ }
203
+ catch (err) {
204
+ return presentToolError("profile.employment.list", err);
205
+ }
206
+ });
207
+ server.registerTool("ttctl_profile_employment_highlight", {
208
+ title: "Toggle employment highlight",
209
+ description: "Toggle the highlight flag on an employment entry.",
210
+ inputSchema: {
211
+ id: z.string().min(1).describe("employment id"),
212
+ highlight: z.boolean().default(true),
213
+ dryRun: DRY_RUN_FIELD,
214
+ },
215
+ }, async (input) => {
216
+ const auth = await ctx.resolveTokenForTool("profile.employment.highlight");
217
+ if ("error" in auth)
218
+ return auth.error;
219
+ if (input.dryRun === true) {
220
+ return dryRunResponse(buildMcpDryRunPreview("highlightEmployment", "talent-profile", { id: input.id, highlight: input.highlight }, auth.token));
221
+ }
222
+ try {
223
+ const result = await profile.employment.highlight(auth.token, input.id, input.highlight);
224
+ return jsonSuccess(result);
225
+ }
226
+ catch (err) {
227
+ return presentToolError("profile.employment.highlight", err);
228
+ }
229
+ });
230
+ server.registerTool("ttctl_profile_employment_employer_autocomplete", {
231
+ title: "Search employer catalog",
232
+ description: 'Search the known-employer catalog by name (e.g. "Google"). Returns up to `limit` suggestions with their canonical IDs.',
233
+ inputSchema: {
234
+ query: z.string().min(1).describe("search term"),
235
+ limit: z.number().int().min(1).max(50).default(10).describe("max results"),
236
+ dryRun: DRY_RUN_FIELD,
237
+ },
238
+ }, async (input) => {
239
+ const auth = await ctx.resolveTokenForTool("profile.employment.employer_autocomplete");
240
+ if ("error" in auth)
241
+ return auth.error;
242
+ if (input.dryRun === true) {
243
+ return dryRunResponse(buildMcpDryRunPreview("GET_EMPLOYERS_AUTOCOMPLETE", "talent-profile", { search: input.query, limit: input.limit }, auth.token));
244
+ }
245
+ try {
246
+ const suggestions = await profile.employment.employerAutocomplete(auth.token, input.query, input.limit);
247
+ return jsonSuccess(suggestions);
248
+ }
249
+ catch (err) {
250
+ return presentToolError("profile.employment.employer_autocomplete", err);
251
+ }
252
+ });
253
+ }
254
+ //# sourceMappingURL=employment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employment.js","sourceRoot":"","sources":["../../../src/tools/profile/employment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolRegistrationContext } from "../_shared.js";
3
+ /**
4
+ * Register the six `profile.industries.*` MCP tools on `server`.
5
+ *
6
+ * Tools:
7
+ * - ttctl_profile_industries_add
8
+ * - ttctl_profile_industries_update
9
+ * - ttctl_profile_industries_remove
10
+ * - ttctl_profile_industries_show
11
+ * - ttctl_profile_industries_list
12
+ * - ttctl_profile_industries_autocomplete (catalog lookup, distinct
13
+ * from add — the autocomplete leaf returns suggestions from the
14
+ * known-industry database; add does NOT consult the catalog)
15
+ *
16
+ * `show` is the per-id read companion of `list`, added in #342 to close
17
+ * the Class A surface-shape gap (the service exported a `show()` but
18
+ * neither CLI nor MCP exposed it). The underlying wire call is a true
19
+ * per-id `node()` lookup (`GetIndustryProfile`), distinct from the
20
+ * list-and-filter pattern used by `certifications.show` / `education.show` /
21
+ * `employment.show`.
22
+ *
23
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`.
24
+ * When `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
25
+ * MCP-layer preview building. `profileId` carries
26
+ * `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply path resolves it via
27
+ * a sibling profile read (`extractProfileId`).
28
+ */
29
+ export declare function registerIndustriesTools(server: McpServer, ctx: ToolRegistrationContext): void;
30
+ //# sourceMappingURL=industries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"industries.d.ts","sourceRoot":"","sources":["../../../src/tools/profile/industries.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAyC,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAWpG;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAgN7F"}
@@ -0,0 +1,196 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { profile } from "@ttctl/core";
4
+ import { z } from "zod";
5
+ import { buildMcpDryRunPreview, dryRunResponse } from "../_shared.js";
6
+ import { profileIndustriesRowOutputSchema } from "../output-schemas.js";
7
+ import { jsonSuccess, presentToolError, textSuccess } 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 six `profile.industries.*` MCP tools on `server`.
14
+ *
15
+ * Tools:
16
+ * - ttctl_profile_industries_add
17
+ * - ttctl_profile_industries_update
18
+ * - ttctl_profile_industries_remove
19
+ * - ttctl_profile_industries_show
20
+ * - ttctl_profile_industries_list
21
+ * - ttctl_profile_industries_autocomplete (catalog lookup, distinct
22
+ * from add — the autocomplete leaf returns suggestions from the
23
+ * known-industry database; add does NOT consult the catalog)
24
+ *
25
+ * `show` is the per-id read companion of `list`, added in #342 to close
26
+ * the Class A surface-shape gap (the service exported a `show()` but
27
+ * neither CLI nor MCP exposed it). The underlying wire call is a true
28
+ * per-id `node()` lookup (`GetIndustryProfile`), distinct from the
29
+ * list-and-filter pattern used by `certifications.show` / `education.show` /
30
+ * `employment.show`.
31
+ *
32
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`.
33
+ * When `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
34
+ * MCP-layer preview building. `profileId` carries
35
+ * `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply path resolves it via
36
+ * a sibling profile read (`extractProfileId`).
37
+ */
38
+ export function registerIndustriesTools(server, ctx) {
39
+ server.registerTool("ttctl_profile_industries_add", {
40
+ title: "Add industry-profile entry",
41
+ description: "Add a new industry-profile entry to the user's profile (the user's authored domain-expertise entry). `name` becomes the title; `connection` becomes domainArea (the user's role within the industry, e.g. 'Backend' for the 'Healthcare' industry).",
42
+ inputSchema: {
43
+ name: z.string().min(1).describe("industry name (mapped to title)"),
44
+ connection: z.string().optional().describe("connection / role within the industry"),
45
+ about: z.string().optional().describe("longer-form description"),
46
+ dryRun: DRY_RUN_FIELD,
47
+ },
48
+ }, async (input) => {
49
+ const auth = await ctx.resolveTokenForTool("profile.industries.add");
50
+ if ("error" in auth)
51
+ return auth.error;
52
+ const fields = { title: input.name };
53
+ if (input.connection !== undefined)
54
+ fields.domainArea = input.connection;
55
+ if (input.about !== undefined)
56
+ fields.about = input.about;
57
+ if (input.dryRun === true) {
58
+ return dryRunResponse(buildMcpDryRunPreview("CreateIndustryProfile", "talent-profile", { input: { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER, industryProfile: fields } }, auth.token));
59
+ }
60
+ try {
61
+ const created = await profile.industries.add(auth.token, fields);
62
+ return jsonSuccess(created);
63
+ }
64
+ catch (err) {
65
+ return presentToolError("profile.industries.add", err);
66
+ }
67
+ });
68
+ server.registerTool("ttctl_profile_industries_update", {
69
+ title: "Update industry-profile entry",
70
+ description: "Update an existing industry-profile entry by id. At least one field must be supplied.",
71
+ inputSchema: {
72
+ id: z.string().min(1).describe("industry profile id"),
73
+ name: z.string().optional(),
74
+ connection: z.string().optional(),
75
+ about: z.string().optional(),
76
+ dryRun: DRY_RUN_FIELD,
77
+ },
78
+ outputSchema: profileIndustriesRowOutputSchema.shape,
79
+ }, async (input) => {
80
+ const auth = await ctx.resolveTokenForTool("profile.industries.update");
81
+ if ("error" in auth)
82
+ return auth.error;
83
+ const fields = {};
84
+ if (input.name !== undefined)
85
+ fields.title = input.name;
86
+ if (input.connection !== undefined)
87
+ fields.domainArea = input.connection;
88
+ if (input.about !== undefined)
89
+ fields.about = input.about;
90
+ if (input.dryRun === true) {
91
+ return dryRunResponse(buildMcpDryRunPreview("UpdateIndustryProfile", "talent-profile", { input: { industryProfileId: input.id, industryProfile: fields } }, auth.token));
92
+ }
93
+ try {
94
+ const updated = await profile.industries.update(auth.token, input.id, fields);
95
+ return jsonSuccess(updated);
96
+ }
97
+ catch (err) {
98
+ return presentToolError("profile.industries.update", err);
99
+ }
100
+ });
101
+ server.registerTool("ttctl_profile_industries_remove", {
102
+ title: "Remove industry-profile entry",
103
+ description: "Remove an industry-profile entry by id.",
104
+ inputSchema: {
105
+ id: z.string().min(1).describe("industry profile id"),
106
+ dryRun: DRY_RUN_FIELD,
107
+ },
108
+ }, async (input) => {
109
+ const auth = await ctx.resolveTokenForTool("profile.industries.remove");
110
+ if ("error" in auth)
111
+ return auth.error;
112
+ if (input.dryRun === true) {
113
+ return dryRunResponse(buildMcpDryRunPreview("RemoveIndustryProfile", "talent-profile", { input: { industryProfileId: input.id } }, auth.token));
114
+ }
115
+ try {
116
+ const id = await profile.industries.remove(auth.token, input.id);
117
+ return textSuccess(`Industry ${id} removed.`);
118
+ }
119
+ catch (err) {
120
+ return presentToolError("profile.industries.remove", err);
121
+ }
122
+ });
123
+ server.registerTool("ttctl_profile_industries_show", {
124
+ title: "Show industry-profile entry",
125
+ description: "Show a single industry-profile entry by id (returns the row as JSON). Resolved via the `node()` GraphQL resolver — a true per-id lookup, distinct from certifications/education/employment `show` which list-and-filter client-side.",
126
+ inputSchema: { id: z.string().min(1).describe("industry profile id"), dryRun: DRY_RUN_FIELD },
127
+ outputSchema: profileIndustriesRowOutputSchema.shape,
128
+ }, async (input) => {
129
+ const auth = await ctx.resolveTokenForTool("profile.industries.show");
130
+ if ("error" in auth)
131
+ return auth.error;
132
+ if (input.dryRun === true) {
133
+ return dryRunResponse(buildMcpDryRunPreview("GetIndustryProfile", "talent-profile", { id: input.id }, auth.token));
134
+ }
135
+ try {
136
+ const row = await profile.industries.show(auth.token, input.id);
137
+ return jsonSuccess(row);
138
+ }
139
+ catch (err) {
140
+ return presentToolError("profile.industries.show", err);
141
+ }
142
+ });
143
+ server.registerTool("ttctl_profile_industries_list", {
144
+ title: "List industry-profile entries",
145
+ description: "List the user's industry-profile entries (returns an array of rows as JSON).",
146
+ inputSchema: { dryRun: DRY_RUN_FIELD },
147
+ }, async (input) => {
148
+ const auth = await ctx.resolveTokenForTool("profile.industries.list");
149
+ if ("error" in auth)
150
+ return auth.error;
151
+ if (input.dryRun === true) {
152
+ return dryRunResponse(buildMcpDryRunPreview("ListIndustryProfiles", "talent-profile", { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER }, auth.token));
153
+ }
154
+ try {
155
+ const rows = await profile.industries.list(auth.token);
156
+ return jsonSuccess(rows);
157
+ }
158
+ catch (err) {
159
+ return presentToolError("profile.industries.list", err);
160
+ }
161
+ });
162
+ server.registerTool("ttctl_profile_industries_autocomplete", {
163
+ title: "Search industries catalog",
164
+ description: 'Search the known-industries catalog by name (e.g. "Healthcare"). Returns up to `limit` suggestions with their canonical IDs. Distinct from `industries_add` — this is a lookup leaf, not a write.',
165
+ inputSchema: {
166
+ query: z.string().min(1).describe("search term"),
167
+ limit: z.number().int().min(1).max(50).default(10),
168
+ withoutIds: z
169
+ .array(z.string())
170
+ .optional()
171
+ .describe("exclude these industry IDs from the result (e.g. industries already on the profile)"),
172
+ dryRun: DRY_RUN_FIELD,
173
+ },
174
+ }, async (input) => {
175
+ const auth = await ctx.resolveTokenForTool("profile.industries.autocomplete");
176
+ if ("error" in auth)
177
+ return auth.error;
178
+ if (input.dryRun === true) {
179
+ const variables = { search: input.query, limit: input.limit };
180
+ if (input.withoutIds !== undefined)
181
+ variables["withoutIds"] = input.withoutIds;
182
+ return dryRunResponse(buildMcpDryRunPreview("GET_INDUSTRIES_FOR_AUTOCOMPLETE", "talent-profile", variables, auth.token));
183
+ }
184
+ try {
185
+ const opts = { limit: input.limit };
186
+ if (input.withoutIds !== undefined)
187
+ opts.withoutIds = input.withoutIds;
188
+ const suggestions = await profile.industries.autocomplete(auth.token, input.query, opts);
189
+ return jsonSuccess(suggestions);
190
+ }
191
+ catch (err) {
192
+ return presentToolError("profile.industries.autocomplete", err);
193
+ }
194
+ });
195
+ }
196
+ //# sourceMappingURL=industries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"industries.js","sourceRoot":"","sources":["../../../src/tools/profile/industries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolRegistrationContext } from "../_shared.js";
3
+ /**
4
+ * Register the eight `ttctl_profile_portfolio_*` MCP tools per the #75
5
+ * spec. Tool names use the canonical sub-domain `portfolio` (NOT the CLI
6
+ * alias `projects`) per project policy.
7
+ *
8
+ * Each tool maps 1:1 to a CLI leaf — the schemas describe the same set
9
+ * of fields, with file-upload tools accepting the dual `filePath` /
10
+ * `content` (base64) input per the spec.
11
+ *
12
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. When
13
+ * `dryRun: true`, returns the uniform `{ ok: true, dryRun: true, preview }`
14
+ * envelope via MCP-layer preview building. For `upload_cover` /
15
+ * `upload_file`, the dry-run path emits the GraphQL operations envelope
16
+ * only (`file: null` placeholder) — the multipart binary body is NOT
17
+ * enumerated, mirroring the `profile.resume.upload` convention.
18
+ * `profileId` carries `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply
19
+ * path resolves it via a sibling profile read.
20
+ */
21
+ export declare function registerPortfolioTools(server: McpServer, ctx: ToolRegistrationContext): void;
22
+ //# sourceMappingURL=portfolio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../../../src/tools/profile/portfolio.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,OAAO,EAAyC,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAC;AASpG;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA4T5F"}