@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,130 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { z } from "zod";
4
+ /**
5
+ * MCP `outputSchema` definitions for the top-10 write-capable tools
6
+ * (#226). Each schema mirrors the TypeScript return type from
7
+ * `@ttctl/core` so LLM clients reading the tool registry can validate
8
+ * the structured payload they receive.
9
+ *
10
+ * Each schema describes the SUCCESS-path payload only. Dry-run responses
11
+ * use the uniform `{ ok, dryRun, preview }` envelope advertised via the
12
+ * tool description (see `_shared.ts` § `dryRunResponse`) and intentionally
13
+ * carry NO `structuredContent` — the SDK skips `outputSchema` validation
14
+ * when `structuredContent` is absent (per `@modelcontextprotocol/sdk`
15
+ * `_validateOutput`), so dry-run paths bypass success-shape validation
16
+ * cleanly.
17
+ *
18
+ * The MCP SDK's `normalizeObjectSchema` accepts only ZodObject shapes for
19
+ * `outputSchema`; unions and discriminated unions are silently dropped.
20
+ * Therefore each schema below is a single `z.object()` describing the
21
+ * apply-path payload — sufficient for the AC ("LLM clients can validate
22
+ * tool output against the schema").
23
+ */
24
+ /**
25
+ * Shape returned by `profile.basic.set()` on the apply path —
26
+ * mirrors `UpdateProfileResult` from `@ttctl/core`.
27
+ */
28
+ export const profileBasicUpdateOutputSchema = z.object({
29
+ profile: z.object({
30
+ id: z.string(),
31
+ about: z.string().nullable(),
32
+ quote: z.string().nullable(),
33
+ }),
34
+ notice: z.string().nullable(),
35
+ });
36
+ /**
37
+ * Shape returned by `profile.basic.photoUpload()` — mirrors `PhotoUrl`
38
+ * from `@ttctl/core`.
39
+ */
40
+ export const profileBasicPhotoUploadOutputSchema = z.object({
41
+ default: z.string().nullable(),
42
+ original: z.string().nullable(),
43
+ small: z.string().nullable(),
44
+ cropped: z
45
+ .object({
46
+ x: z.number(),
47
+ y: z.number(),
48
+ width: z.number(),
49
+ height: z.number(),
50
+ })
51
+ .nullable(),
52
+ isResolutionSatisfied: z.boolean(),
53
+ });
54
+ /**
55
+ * Shape returned by `profile.resume.upload()` — mirrors
56
+ * `UploadResumeResult` from `@ttctl/core`.
57
+ */
58
+ export const profileResumeUploadOutputSchema = z.object({
59
+ success: z.boolean(),
60
+ });
61
+ /**
62
+ * Shape returned by `profile.education.add()` / `update()` — mirrors
63
+ * `Education` from `@ttctl/core`.
64
+ */
65
+ export const profileEducationRowOutputSchema = z.object({
66
+ id: z.string(),
67
+ institution: z.string(),
68
+ degree: z.string(),
69
+ fieldOfStudy: z.string().nullable(),
70
+ location: z.string().nullable(),
71
+ title: z.string().nullable(),
72
+ yearFrom: z.number().nullable(),
73
+ yearTo: z.number().nullable(),
74
+ highlight: z.boolean(),
75
+ });
76
+ /**
77
+ * Shape returned by the `*_remove` tools' structured-content slot —
78
+ * `{ id, removed: true }`. The `text` content slot retains the
79
+ * human-readable confirmation; `structuredContent` exposes a typed
80
+ * acknowledgment.
81
+ */
82
+ export const profileRowRemoveOutputSchema = z.object({
83
+ id: z.string(),
84
+ removed: z.literal(true),
85
+ });
86
+ /**
87
+ * Shape returned by `profile.employment.add()` / `update()` — mirrors
88
+ * `Employment` from `@ttctl/core`.
89
+ */
90
+ export const profileEmploymentRowOutputSchema = z.object({
91
+ id: z.string(),
92
+ company: z.string(),
93
+ position: z.string(),
94
+ companyWebsite: z.string().nullable(),
95
+ noWebsite: z.boolean(),
96
+ startDate: z.number().nullable(),
97
+ endDate: z.number().nullable(),
98
+ experienceItems: z.array(z.string()).nullable(),
99
+ highlight: z.boolean(),
100
+ showViaToptal: z.boolean(),
101
+ toptalRelated: z.boolean(),
102
+ });
103
+ /**
104
+ * Shape returned by `profile.industries.update()` — mirrors
105
+ * `IndustryProfile` from `@ttctl/core`.
106
+ */
107
+ export const profileIndustriesRowOutputSchema = z.object({
108
+ id: z.string(),
109
+ title: z.string(),
110
+ about: z.string().nullable(),
111
+ domainArea: z.string().nullable(),
112
+ });
113
+ /**
114
+ * Tool names (frozen) that the test suite asserts must carry a populated
115
+ * `outputSchema`. Adding a new write-capable tool: append its name here
116
+ * and define the schema above.
117
+ */
118
+ export const TOOLS_WITH_OUTPUT_SCHEMA = [
119
+ "ttctl_profile_basic_update",
120
+ "ttctl_profile_basic_photo_upload",
121
+ "ttctl_profile_resume_upload",
122
+ "ttctl_profile_education_add",
123
+ "ttctl_profile_education_update",
124
+ "ttctl_profile_education_remove",
125
+ "ttctl_profile_employment_add",
126
+ "ttctl_profile_employment_update",
127
+ "ttctl_profile_employment_remove",
128
+ "ttctl_profile_industries_update",
129
+ ];
130
+ //# sourceMappingURL=output-schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-schemas.js","sourceRoot":"","sources":["../../src/tools/output-schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolRegistrationContext } from "./_shared.js";
3
+ /**
4
+ * Register the `ttctl_payments_*` MCP tools (#149). 7 tools across 3
5
+ * sub-namespaces:
6
+ *
7
+ * - `ttctl_payments_payouts_list`
8
+ * - `ttctl_payments_payouts_show`
9
+ * - `ttctl_payments_methods_list`
10
+ * - `ttctl_payments_methods_show`
11
+ * - `ttctl_payments_rate_show`
12
+ * - `ttctl_payments_rate_questions`
13
+ * - `ttctl_payments_rate_change`
14
+ *
15
+ * Each tool maps 1:1 to a CLI leaf. The `<id>` argument is the
16
+ * `TalentPayment.id` for payouts, `PaymentOption.id` for methods.
17
+ *
18
+ * **Scope refinements** (per #149 comment 4441685270, post-investigation):
19
+ * - Original `rate-change list` (no list endpoint exists) → replaced
20
+ * with `rate_show` (unified projection) + `rate_questions`
21
+ * (form discovery).
22
+ * - Original `rate-change request` (2 of 5 mutation inputs) →
23
+ * replaced with full `rate_change` (kind, rate, optional
24
+ * engagement, comment, answers[]).
25
+ *
26
+ * **Dry-run path** (issue #165): every tool accepts `dryRun?: boolean`.
27
+ * Read-only tools build the preview at the MCP layer via
28
+ * `buildMcpDryRunPreview`; `rate_change` passes through to the
29
+ * core's `dryRun` option (mutation supports it natively).
30
+ *
31
+ * **Per CLAUDE.md schema/contract validation rule**: every payment
32
+ * operation is hand-authored (no codegen types) → mandatory live E2E
33
+ * coverage before merge. See `packages/e2e/src/3*-payments-*.e2e.test.ts`.
34
+ */
35
+ export declare function registerPaymentsTools(server: McpServer, ctx: ToolRegistrationContext): void;
36
+ //# sourceMappingURL=payments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payments.d.ts","sourceRoot":"","sources":["../../src/tools/payments.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,OAAO,EAAyC,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AASnG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA0S3F"}
@@ -0,0 +1,373 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { payments } from "@ttctl/core";
4
+ import { z } from "zod";
5
+ import { ttctlErrorToToolResponseOrNull } from "../errors.js";
6
+ import { buildMcpDryRunPreview, dryRunResponse } 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 `ttctl_payments_*` MCP tools (#149). 7 tools across 3
13
+ * sub-namespaces:
14
+ *
15
+ * - `ttctl_payments_payouts_list`
16
+ * - `ttctl_payments_payouts_show`
17
+ * - `ttctl_payments_methods_list`
18
+ * - `ttctl_payments_methods_show`
19
+ * - `ttctl_payments_rate_show`
20
+ * - `ttctl_payments_rate_questions`
21
+ * - `ttctl_payments_rate_change`
22
+ *
23
+ * Each tool maps 1:1 to a CLI leaf. The `<id>` argument is the
24
+ * `TalentPayment.id` for payouts, `PaymentOption.id` for methods.
25
+ *
26
+ * **Scope refinements** (per #149 comment 4441685270, post-investigation):
27
+ * - Original `rate-change list` (no list endpoint exists) → replaced
28
+ * with `rate_show` (unified projection) + `rate_questions`
29
+ * (form discovery).
30
+ * - Original `rate-change request` (2 of 5 mutation inputs) →
31
+ * replaced with full `rate_change` (kind, rate, optional
32
+ * engagement, comment, answers[]).
33
+ *
34
+ * **Dry-run path** (issue #165): every tool accepts `dryRun?: boolean`.
35
+ * Read-only tools build the preview at the MCP layer via
36
+ * `buildMcpDryRunPreview`; `rate_change` passes through to the
37
+ * core's `dryRun` option (mutation supports it natively).
38
+ *
39
+ * **Per CLAUDE.md schema/contract validation rule**: every payment
40
+ * operation is hand-authored (no codegen types) → mandatory live E2E
41
+ * coverage before merge. See `packages/e2e/src/3*-payments-*.e2e.test.ts`.
42
+ */
43
+ export function registerPaymentsTools(server, ctx) {
44
+ server.registerTool("ttctl_payments_payouts_list", {
45
+ title: "List historical payouts",
46
+ description: [
47
+ "List the signed-in user's historical Toptal payouts.",
48
+ "A payout is a `TalentPayment` record carrying the billing-cycle amount,",
49
+ "status (PAID / DUE / OUTSTANDING / OVERDUE / ON_HOLD / DISPUTED), and",
50
+ "memorandum adjustments.",
51
+ "",
52
+ "Optional `fromDate` / `toDate` (YYYY-MM-DD, inclusive) filter by",
53
+ "`createdOn`. The server returns at most 20 records per call.",
54
+ "",
55
+ "Example user prompts:",
56
+ ' - "Show me my recent Toptal payouts."',
57
+ ' - "List payouts from January 2026."',
58
+ ].join("\n"),
59
+ inputSchema: {
60
+ fromDate: z.string().optional().describe("Filter lower bound (YYYY-MM-DD, inclusive)"),
61
+ toDate: z.string().optional().describe("Filter upper bound (YYYY-MM-DD, inclusive)"),
62
+ dryRun: DRY_RUN_FIELD,
63
+ },
64
+ }, async (args) => {
65
+ const auth = await ctx.resolveToolAuth();
66
+ if (!auth.ok)
67
+ return auth.response;
68
+ const opts = {};
69
+ if (args.fromDate !== undefined)
70
+ opts.fromDate = args.fromDate;
71
+ if (args.toDate !== undefined)
72
+ opts.toDate = args.toDate;
73
+ if (args.dryRun === true) {
74
+ const hasFilter = opts.fromDate !== undefined || opts.toDate !== undefined;
75
+ const variables = {
76
+ filters: hasFilter ? { createdOn: { from: opts.fromDate ?? null, to: opts.toDate ?? null } } : null,
77
+ };
78
+ return dryRunResponse(buildMcpDryRunPreview("Payments", "mobile-gateway", variables, auth.token));
79
+ }
80
+ try {
81
+ const result = await payments.payouts.list(auth.token, opts);
82
+ return successResponse(result);
83
+ }
84
+ catch (err) {
85
+ return mapPaymentsError(err);
86
+ }
87
+ });
88
+ server.registerTool("ttctl_payments_payouts_show", {
89
+ title: "Show one payout",
90
+ description: [
91
+ "Fetch one payout's full detail by `TalentPayment.id` (the row id from",
92
+ "`ttctl_payments_payouts_list`).",
93
+ "",
94
+ "Example user prompts:",
95
+ ' - "Show payout pmt_xyz."',
96
+ ' - "What is the amount of my Toptal payout pmt_abc?"',
97
+ ].join("\n"),
98
+ inputSchema: {
99
+ id: z.string().describe("Payout id (TalentPayment.id from `payments_payouts_list`)"),
100
+ dryRun: DRY_RUN_FIELD,
101
+ },
102
+ }, async (args) => {
103
+ const auth = await ctx.resolveToolAuth();
104
+ if (!auth.ok)
105
+ return auth.response;
106
+ if (args.dryRun === true) {
107
+ return dryRunResponse(buildMcpDryRunPreview("Payment", "mobile-gateway", { id: args.id }, auth.token));
108
+ }
109
+ try {
110
+ const item = await payments.payouts.show(auth.token, args.id);
111
+ return successResponse(item);
112
+ }
113
+ catch (err) {
114
+ return mapPaymentsError(err);
115
+ }
116
+ });
117
+ server.registerTool("ttctl_payments_methods_list", {
118
+ title: "List configured payment methods",
119
+ description: [
120
+ "List the talent's configured Toptal payment methods (Payoneer / wire /",
121
+ "Toptal Payments / etc.). The preferred method is marked",
122
+ "`preferredOption: true`.",
123
+ "",
124
+ "Read-only — adding / removing / changing preferred method is out of scope",
125
+ "for v1 (the Toptal admin flow lives in the web portal).",
126
+ "",
127
+ "Example user prompts:",
128
+ ' - "What payment methods are configured on my Toptal account?"',
129
+ ' - "Which is my preferred Toptal payment method?"',
130
+ ].join("\n"),
131
+ inputSchema: { dryRun: DRY_RUN_FIELD },
132
+ }, async (args) => {
133
+ const auth = await ctx.resolveToolAuth();
134
+ if (!auth.ok)
135
+ return auth.response;
136
+ if (args.dryRun === true) {
137
+ return dryRunResponse(buildMcpDryRunPreview("PaymentOptions", "mobile-gateway", {}, auth.token));
138
+ }
139
+ try {
140
+ const items = await payments.methods.list(auth.token);
141
+ return successResponse(items);
142
+ }
143
+ catch (err) {
144
+ return mapPaymentsError(err);
145
+ }
146
+ });
147
+ server.registerTool("ttctl_payments_methods_show", {
148
+ title: "Show one payment method",
149
+ description: [
150
+ "Fetch one payment method's detail by id. No per-id wire op exists; the",
151
+ "tool fetches the full list and filters locally.",
152
+ "",
153
+ "Dry-run note: the underlying preview is for `PaymentOptions` (the list",
154
+ "query), since the per-method filter is a client-side operation.",
155
+ ].join("\n"),
156
+ inputSchema: {
157
+ id: z.string().describe("Payment method id (PaymentOption.id from `payments_methods_list`)"),
158
+ dryRun: DRY_RUN_FIELD,
159
+ },
160
+ }, async (args) => {
161
+ const auth = await ctx.resolveToolAuth();
162
+ if (!auth.ok)
163
+ return auth.response;
164
+ if (args.dryRun === true) {
165
+ return dryRunResponse(buildMcpDryRunPreview("PaymentOptions", "mobile-gateway", {}, auth.token));
166
+ }
167
+ try {
168
+ const item = await payments.methods.show(auth.token, args.id);
169
+ return successResponse(item);
170
+ }
171
+ catch (err) {
172
+ return mapPaymentsError(err);
173
+ }
174
+ });
175
+ server.registerTool("ttctl_payments_rate_show", {
176
+ title: "Show current rate + rate-change status",
177
+ description: [
178
+ "Show the talent's current default hourly rate, market insight",
179
+ "(competitiveness, recommended rate), validation rules (min rate, rate",
180
+ "step), and the most-recent or in-flight rate-change request.",
181
+ "",
182
+ "Unified projection — issues 2 parallel queries (`LastRateChangeRequest`",
183
+ "+ `RateChangeFormDetails`) and composes the result.",
184
+ "",
185
+ "Example user prompts:",
186
+ ' - "What is my current Toptal rate?"',
187
+ ' - "Show me the status of my rate-change request."',
188
+ ' - "What is the minimum hourly rate I can request?"',
189
+ ].join("\n"),
190
+ inputSchema: { dryRun: DRY_RUN_FIELD },
191
+ }, async (args) => {
192
+ const auth = await ctx.resolveToolAuth();
193
+ if (!auth.ok)
194
+ return auth.response;
195
+ if (args.dryRun === true) {
196
+ // 2 parallel queries — surface both previews.
197
+ const previews = [
198
+ buildMcpDryRunPreview("LastRateChangeRequest", "mobile-gateway", {}, auth.token),
199
+ buildMcpDryRunPreview("RateChangeFormDetails", "mobile-gateway", {}, auth.token),
200
+ ];
201
+ return {
202
+ content: [{ type: "text", text: JSON.stringify({ ok: true, dryRun: true, previews }, null, 2) }],
203
+ };
204
+ }
205
+ try {
206
+ const proj = await payments.rate.show(auth.token);
207
+ return successResponse(proj);
208
+ }
209
+ catch (err) {
210
+ return mapPaymentsError(err);
211
+ }
212
+ });
213
+ server.registerTool("ttctl_payments_rate_questions", {
214
+ title: "List rate-change form questions",
215
+ description: [
216
+ "List the form questions the user must answer when submitting a",
217
+ "rate-change request. Discovery sub-command — call this BEFORE",
218
+ "`ttctl_payments_rate_change` to learn the required `answers[]` shape.",
219
+ "",
220
+ "Each question returns `{id, kind: 'RADIO'|'TEXT', label, options[]}`.",
221
+ "`RADIO` kind: pick `value` from `options[].label`. `TEXT` kind: free-text.",
222
+ "An option may set `commentRequired: true` — when chosen, pass an",
223
+ "accompanying answer comment.",
224
+ "",
225
+ "Example user prompts:",
226
+ ' - "What questions do I need to answer for a Toptal rate change?"',
227
+ ].join("\n"),
228
+ inputSchema: { dryRun: DRY_RUN_FIELD },
229
+ }, async (args) => {
230
+ const auth = await ctx.resolveToolAuth();
231
+ if (!auth.ok)
232
+ return auth.response;
233
+ if (args.dryRun === true) {
234
+ return dryRunResponse(buildMcpDryRunPreview("RateChangeRequestQuestions", "mobile-gateway", {}, auth.token));
235
+ }
236
+ try {
237
+ const items = await payments.rate.questions(auth.token);
238
+ return successResponse(items);
239
+ }
240
+ catch (err) {
241
+ return mapPaymentsError(err);
242
+ }
243
+ });
244
+ server.registerTool("ttctl_payments_rate_change", {
245
+ title: "Submit a rate-change request",
246
+ description: [
247
+ "Submit a rate-change request on the talent's Toptal account.",
248
+ "",
249
+ "Required:",
250
+ " - `kind`: one of `current-engagement`, `future-engagements`,",
251
+ " `consultation`.",
252
+ " - `desiredRate`: target hourly rate as a decimal string (e.g.",
253
+ ' `"95.0"`).',
254
+ " - `answers`: array of `{questionId, value, comment?}` — fetch the",
255
+ " catalog via `ttctl_payments_rate_questions` and answer each.",
256
+ "",
257
+ "Conditional:",
258
+ " - `engagementId`: REQUIRED for `kind: current-engagement`; rejected",
259
+ " for the other two kinds (those are account-wide).",
260
+ "",
261
+ "Optional:",
262
+ " - `talentComment`: free-text comment attached to the request.",
263
+ "",
264
+ "**This is a write operation**: it submits a rate-change request to",
265
+ "Toptal's compliance flow. The request enters a PENDING / CLAIMED",
266
+ "lifecycle; the server reviews and may approve, modify, or reject.",
267
+ "Confirm with the user before invoking.",
268
+ "",
269
+ "Example user prompts:",
270
+ ' - "Submit a rate-change request to $95/hr on engagement act_xyz."',
271
+ ' - "Raise my default Toptal rate to $100/hr."',
272
+ ].join("\n"),
273
+ inputSchema: {
274
+ kind: z
275
+ .enum([...payments.RATE_CHANGE_KINDS])
276
+ .describe("Rate-change kind: current-engagement / future-engagements / consultation"),
277
+ desiredRate: z.string().describe('Target hourly rate as a decimal string (e.g. "95.0")'),
278
+ engagementId: z
279
+ .string()
280
+ .optional()
281
+ .describe("Engagement id (required for kind=current-engagement; rejected otherwise)"),
282
+ talentComment: z.string().optional().describe("Optional free-text comment attached to the request"),
283
+ answers: z
284
+ .array(z.object({
285
+ questionId: z.string(),
286
+ value: z.string(),
287
+ comment: z.string().optional(),
288
+ }))
289
+ .describe("Answers to the form questions returned by `ttctl_payments_rate_questions`. Each entry: {questionId, value, comment?}."),
290
+ dryRun: DRY_RUN_FIELD,
291
+ },
292
+ }, async (args) => {
293
+ const auth = await ctx.resolveToolAuth();
294
+ if (!auth.ok)
295
+ return auth.response;
296
+ try {
297
+ const opts = {
298
+ kind: args.kind,
299
+ desiredRate: args.desiredRate,
300
+ answers: args.answers.map((a) => {
301
+ const entry = { questionId: a.questionId, value: a.value };
302
+ if (a.comment !== undefined)
303
+ entry.comment = a.comment;
304
+ return entry;
305
+ }),
306
+ };
307
+ if (args.engagementId !== undefined)
308
+ opts.engagementId = args.engagementId;
309
+ if (args.talentComment !== undefined)
310
+ opts.talentComment = args.talentComment;
311
+ const outcome = await payments.rate.change(auth.token, opts, { dryRun: args.dryRun ?? false });
312
+ if (outcome.kind === "preview")
313
+ return dryRunResponse(outcome.preview);
314
+ return successResponse({
315
+ result: outcome.result,
316
+ notice: outcome.notice,
317
+ });
318
+ }
319
+ catch (err) {
320
+ return mapPaymentsError(err);
321
+ }
322
+ });
323
+ }
324
+ function successResponse(data) {
325
+ return {
326
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
327
+ };
328
+ }
329
+ function mapPaymentsError(err) {
330
+ const typed = ttctlErrorToToolResponseOrNull(err);
331
+ if (typed !== null)
332
+ return typed;
333
+ if (err instanceof payments.PaymentsError) {
334
+ return {
335
+ isError: true,
336
+ content: [
337
+ {
338
+ type: "text",
339
+ text: [`Error: ${err.message}`, "", recoveryForCode(err.code), "", `(Code: ${err.code})`].join("\n"),
340
+ },
341
+ ],
342
+ };
343
+ }
344
+ const message = err instanceof Error ? err.message : String(err);
345
+ return {
346
+ isError: true,
347
+ content: [
348
+ {
349
+ type: "text",
350
+ text: [
351
+ `Error: payments request failed: ${message}`,
352
+ "",
353
+ "Recovery: Retry; if the failure persists, file an issue.",
354
+ "",
355
+ "(Code: UNKNOWN)",
356
+ ].join("\n"),
357
+ },
358
+ ],
359
+ };
360
+ }
361
+ function recoveryForCode(code) {
362
+ switch (code) {
363
+ case "NOT_FOUND":
364
+ return "Recovery: Verify the id (use `ttctl_payments_payouts_list` or `ttctl_payments_methods_list` to discover ids).";
365
+ case "MISSING_INPUT":
366
+ return "Recovery: Adjust the input per the description and re-run.";
367
+ case "MUTATION_ERROR":
368
+ return "Recovery: The mutation was rejected by the server (often: rate below minRate, missing answers, ineligibility). Check the message above; try `ttctl_payments_rate_questions` for the form catalog.";
369
+ default:
370
+ return "Recovery: Adjust the tool input or retry; see the code below.";
371
+ }
372
+ }
373
+ //# sourceMappingURL=payments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/tools/payments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolRegistrationContext } from "../_shared.js";
3
+ /**
4
+ * Register the five `profile.certifications.*` MCP tools on `server`.
5
+ *
6
+ * MCP tool names use ONLY the canonical `certifications` form — the CLI
7
+ * alias `certs` (per #72) is CLI-only and never appears in the MCP
8
+ * catalog.
9
+ *
10
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. When
11
+ * `dryRun: true`, returns `{ ok: true, dryRun: true, preview }` via
12
+ * MCP-layer preview building. `show` previews `GET_CERTIFICATION` (the
13
+ * apply path lists then filters client-side; no per-id selector exists).
14
+ * `profileId` carries `DRY_RUN_PROFILE_ID_PLACEHOLDER` where the apply
15
+ * path resolves it via a sibling profile read.
16
+ */
17
+ export declare function registerCertificationsTools(server: McpServer, ctx: ToolRegistrationContext): void;
18
+ //# sourceMappingURL=certifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certifications.d.ts","sourceRoot":"","sources":["../../../src/tools/profile/certifications.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAyC,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAUpG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAuNjG"}