@withpica/mcp-server 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/.claude/settings.local.json +5 -0
  2. package/CHANGELOG.md +1850 -0
  3. package/README.md +304 -0
  4. package/assets/fonts/GeistSans-Light.woff2 +0 -0
  5. package/assets/fonts/InstrumentSerif-Italic.woff2 +0 -0
  6. package/assets/fonts/InstrumentSerif-Regular.woff2 +0 -0
  7. package/dist/apps/download.d.ts +2 -0
  8. package/dist/apps/download.d.ts.map +1 -0
  9. package/dist/apps/download.js +125 -0
  10. package/dist/apps/download.js.map +1 -0
  11. package/dist/apps/generated/shared-bundle.d.ts +5 -0
  12. package/dist/apps/generated/shared-bundle.d.ts.map +1 -0
  13. package/dist/apps/generated/shared-bundle.js +7 -0
  14. package/dist/apps/generated/shared-bundle.js.map +1 -0
  15. package/dist/apps/release.d.ts +2 -0
  16. package/dist/apps/release.d.ts.map +1 -0
  17. package/dist/apps/release.js +69 -0
  18. package/dist/apps/release.js.map +1 -0
  19. package/dist/apps/shared.d.ts +15 -0
  20. package/dist/apps/shared.d.ts.map +1 -0
  21. package/dist/apps/shared.js +480 -0
  22. package/dist/apps/shared.js.map +1 -0
  23. package/dist/apps/upload.d.ts +2 -0
  24. package/dist/apps/upload.d.ts.map +1 -0
  25. package/dist/apps/upload.js +280 -0
  26. package/dist/apps/upload.js.map +1 -0
  27. package/dist/config.d.ts +14 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +73 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +35 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/prompts/index.d.ts +86 -0
  36. package/dist/prompts/index.d.ts.map +1 -0
  37. package/dist/prompts/index.js +645 -0
  38. package/dist/prompts/index.js.map +1 -0
  39. package/dist/resources/agent-guide.d.ts +15 -0
  40. package/dist/resources/agent-guide.d.ts.map +1 -0
  41. package/dist/resources/agent-guide.js +284 -0
  42. package/dist/resources/agent-guide.js.map +1 -0
  43. package/dist/resources/index.d.ts +66 -0
  44. package/dist/resources/index.d.ts.map +1 -0
  45. package/dist/resources/index.js +510 -0
  46. package/dist/resources/index.js.map +1 -0
  47. package/dist/resources/llms-primer.d.ts +2 -0
  48. package/dist/resources/llms-primer.d.ts.map +1 -0
  49. package/dist/resources/llms-primer.js +68 -0
  50. package/dist/resources/llms-primer.js.map +1 -0
  51. package/dist/resources/required-schemas.generated.d.ts +455 -0
  52. package/dist/resources/required-schemas.generated.d.ts.map +1 -0
  53. package/dist/resources/required-schemas.generated.js +1041 -0
  54. package/dist/resources/required-schemas.generated.js.map +1 -0
  55. package/dist/resources/required-schemas.source.d.ts +53 -0
  56. package/dist/resources/required-schemas.source.d.ts.map +1 -0
  57. package/dist/resources/required-schemas.source.js +493 -0
  58. package/dist/resources/required-schemas.source.js.map +1 -0
  59. package/dist/resources/welcome.d.ts +14 -0
  60. package/dist/resources/welcome.d.ts.map +1 -0
  61. package/dist/resources/welcome.js +26 -0
  62. package/dist/resources/welcome.js.map +1 -0
  63. package/dist/server-instructions.d.ts +60 -0
  64. package/dist/server-instructions.d.ts.map +1 -0
  65. package/dist/server-instructions.js +93 -0
  66. package/dist/server-instructions.js.map +1 -0
  67. package/dist/server.d.ts +52 -0
  68. package/dist/server.d.ts.map +1 -0
  69. package/dist/server.js +334 -0
  70. package/dist/server.js.map +1 -0
  71. package/dist/tools/access-simulate.d.ts +23 -0
  72. package/dist/tools/access-simulate.d.ts.map +1 -0
  73. package/dist/tools/access-simulate.js +162 -0
  74. package/dist/tools/access-simulate.js.map +1 -0
  75. package/dist/tools/agent-identity.d.ts +36 -0
  76. package/dist/tools/agent-identity.d.ts.map +1 -0
  77. package/dist/tools/agent-identity.js +274 -0
  78. package/dist/tools/agent-identity.js.map +1 -0
  79. package/dist/tools/agreement-types.d.ts +27 -0
  80. package/dist/tools/agreement-types.d.ts.map +1 -0
  81. package/dist/tools/agreement-types.js +281 -0
  82. package/dist/tools/agreement-types.js.map +1 -0
  83. package/dist/tools/agreements.d.ts +20 -0
  84. package/dist/tools/agreements.d.ts.map +1 -0
  85. package/dist/tools/agreements.js +282 -0
  86. package/dist/tools/agreements.js.map +1 -0
  87. package/dist/tools/analytics.d.ts +20 -0
  88. package/dist/tools/analytics.d.ts.map +1 -0
  89. package/dist/tools/analytics.js +130 -0
  90. package/dist/tools/analytics.js.map +1 -0
  91. package/dist/tools/app-tools.d.ts +15 -0
  92. package/dist/tools/app-tools.d.ts.map +1 -0
  93. package/dist/tools/app-tools.js +388 -0
  94. package/dist/tools/app-tools.js.map +1 -0
  95. package/dist/tools/assets.d.ts +25 -0
  96. package/dist/tools/assets.d.ts.map +1 -0
  97. package/dist/tools/assets.js +454 -0
  98. package/dist/tools/assets.js.map +1 -0
  99. package/dist/tools/audio-files.d.ts +20 -0
  100. package/dist/tools/audio-files.d.ts.map +1 -0
  101. package/dist/tools/audio-files.js +409 -0
  102. package/dist/tools/audio-files.js.map +1 -0
  103. package/dist/tools/audit.d.ts +19 -0
  104. package/dist/tools/audit.d.ts.map +1 -0
  105. package/dist/tools/audit.js +58 -0
  106. package/dist/tools/audit.js.map +1 -0
  107. package/dist/tools/auth.d.ts +22 -0
  108. package/dist/tools/auth.d.ts.map +1 -0
  109. package/dist/tools/auth.js +212 -0
  110. package/dist/tools/auth.js.map +1 -0
  111. package/dist/tools/bulk.d.ts +22 -0
  112. package/dist/tools/bulk.d.ts.map +1 -0
  113. package/dist/tools/bulk.js +164 -0
  114. package/dist/tools/bulk.js.map +1 -0
  115. package/dist/tools/calendar.d.ts +15 -0
  116. package/dist/tools/calendar.d.ts.map +1 -0
  117. package/dist/tools/calendar.js +68 -0
  118. package/dist/tools/calendar.js.map +1 -0
  119. package/dist/tools/collaborators.d.ts +21 -0
  120. package/dist/tools/collaborators.d.ts.map +1 -0
  121. package/dist/tools/collaborators.js +381 -0
  122. package/dist/tools/collaborators.js.map +1 -0
  123. package/dist/tools/comparisons.d.ts +22 -0
  124. package/dist/tools/comparisons.d.ts.map +1 -0
  125. package/dist/tools/comparisons.js +80 -0
  126. package/dist/tools/comparisons.js.map +1 -0
  127. package/dist/tools/credits.d.ts +39 -0
  128. package/dist/tools/credits.d.ts.map +1 -0
  129. package/dist/tools/credits.js +541 -0
  130. package/dist/tools/credits.js.map +1 -0
  131. package/dist/tools/custody-hints.d.ts +16 -0
  132. package/dist/tools/custody-hints.d.ts.map +1 -0
  133. package/dist/tools/custody-hints.js +27 -0
  134. package/dist/tools/custody-hints.js.map +1 -0
  135. package/dist/tools/custody.d.ts +38 -0
  136. package/dist/tools/custody.d.ts.map +1 -0
  137. package/dist/tools/custody.js +281 -0
  138. package/dist/tools/custody.js.map +1 -0
  139. package/dist/tools/dashboard.d.ts +22 -0
  140. package/dist/tools/dashboard.d.ts.map +1 -0
  141. package/dist/tools/dashboard.js +258 -0
  142. package/dist/tools/dashboard.js.map +1 -0
  143. package/dist/tools/directory.d.ts +15 -0
  144. package/dist/tools/directory.d.ts.map +1 -0
  145. package/dist/tools/directory.js +107 -0
  146. package/dist/tools/directory.js.map +1 -0
  147. package/dist/tools/discovery.d.ts +49 -0
  148. package/dist/tools/discovery.d.ts.map +1 -0
  149. package/dist/tools/discovery.js +851 -0
  150. package/dist/tools/discovery.js.map +1 -0
  151. package/dist/tools/disputes.d.ts +18 -0
  152. package/dist/tools/disputes.d.ts.map +1 -0
  153. package/dist/tools/disputes.js +62 -0
  154. package/dist/tools/disputes.js.map +1 -0
  155. package/dist/tools/documents.d.ts +15 -0
  156. package/dist/tools/documents.d.ts.map +1 -0
  157. package/dist/tools/documents.js +37 -0
  158. package/dist/tools/documents.js.map +1 -0
  159. package/dist/tools/duplicates.d.ts +25 -0
  160. package/dist/tools/duplicates.d.ts.map +1 -0
  161. package/dist/tools/duplicates.js +108 -0
  162. package/dist/tools/duplicates.js.map +1 -0
  163. package/dist/tools/enrichment.d.ts +56 -0
  164. package/dist/tools/enrichment.d.ts.map +1 -0
  165. package/dist/tools/enrichment.js +616 -0
  166. package/dist/tools/enrichment.js.map +1 -0
  167. package/dist/tools/exports.d.ts +19 -0
  168. package/dist/tools/exports.d.ts.map +1 -0
  169. package/dist/tools/exports.js +184 -0
  170. package/dist/tools/exports.js.map +1 -0
  171. package/dist/tools/feedback.d.ts +22 -0
  172. package/dist/tools/feedback.d.ts.map +1 -0
  173. package/dist/tools/feedback.js +100 -0
  174. package/dist/tools/feedback.js.map +1 -0
  175. package/dist/tools/forbidden-keywords.d.ts +62 -0
  176. package/dist/tools/forbidden-keywords.d.ts.map +1 -0
  177. package/dist/tools/forbidden-keywords.js +99 -0
  178. package/dist/tools/forbidden-keywords.js.map +1 -0
  179. package/dist/tools/gap-hints.d.ts +53 -0
  180. package/dist/tools/gap-hints.d.ts.map +1 -0
  181. package/dist/tools/gap-hints.js +245 -0
  182. package/dist/tools/gap-hints.js.map +1 -0
  183. package/dist/tools/groups.d.ts +29 -0
  184. package/dist/tools/groups.d.ts.map +1 -0
  185. package/dist/tools/groups.js +186 -0
  186. package/dist/tools/groups.js.map +1 -0
  187. package/dist/tools/import-documents.d.ts +21 -0
  188. package/dist/tools/import-documents.d.ts.map +1 -0
  189. package/dist/tools/import-documents.js +206 -0
  190. package/dist/tools/import-documents.js.map +1 -0
  191. package/dist/tools/import.d.ts +31 -0
  192. package/dist/tools/import.d.ts.map +1 -0
  193. package/dist/tools/import.js +610 -0
  194. package/dist/tools/import.js.map +1 -0
  195. package/dist/tools/index.d.ts +293 -0
  196. package/dist/tools/index.d.ts.map +1 -0
  197. package/dist/tools/index.js +1182 -0
  198. package/dist/tools/index.js.map +1 -0
  199. package/dist/tools/integrations.d.ts +19 -0
  200. package/dist/tools/integrations.d.ts.map +1 -0
  201. package/dist/tools/integrations.js +120 -0
  202. package/dist/tools/integrations.js.map +1 -0
  203. package/dist/tools/labels.d.ts +20 -0
  204. package/dist/tools/labels.d.ts.map +1 -0
  205. package/dist/tools/labels.js +48 -0
  206. package/dist/tools/labels.js.map +1 -0
  207. package/dist/tools/licensing.d.ts +40 -0
  208. package/dist/tools/licensing.d.ts.map +1 -0
  209. package/dist/tools/licensing.js +436 -0
  210. package/dist/tools/licensing.js.map +1 -0
  211. package/dist/tools/memory.d.ts +21 -0
  212. package/dist/tools/memory.d.ts.map +1 -0
  213. package/dist/tools/memory.js +120 -0
  214. package/dist/tools/memory.js.map +1 -0
  215. package/dist/tools/metadata.d.ts +15 -0
  216. package/dist/tools/metadata.d.ts.map +1 -0
  217. package/dist/tools/metadata.js +1532 -0
  218. package/dist/tools/metadata.js.map +1 -0
  219. package/dist/tools/multimedia.d.ts +19 -0
  220. package/dist/tools/multimedia.d.ts.map +1 -0
  221. package/dist/tools/multimedia.js +371 -0
  222. package/dist/tools/multimedia.js.map +1 -0
  223. package/dist/tools/my-reported-issues.d.ts +32 -0
  224. package/dist/tools/my-reported-issues.d.ts.map +1 -0
  225. package/dist/tools/my-reported-issues.js +123 -0
  226. package/dist/tools/my-reported-issues.js.map +1 -0
  227. package/dist/tools/notes.d.ts +21 -0
  228. package/dist/tools/notes.d.ts.map +1 -0
  229. package/dist/tools/notes.js +115 -0
  230. package/dist/tools/notes.js.map +1 -0
  231. package/dist/tools/notifications.d.ts +28 -0
  232. package/dist/tools/notifications.d.ts.map +1 -0
  233. package/dist/tools/notifications.js +417 -0
  234. package/dist/tools/notifications.js.map +1 -0
  235. package/dist/tools/onboarding.d.ts +24 -0
  236. package/dist/tools/onboarding.d.ts.map +1 -0
  237. package/dist/tools/onboarding.js +81 -0
  238. package/dist/tools/onboarding.js.map +1 -0
  239. package/dist/tools/people.d.ts +254 -0
  240. package/dist/tools/people.d.ts.map +1 -0
  241. package/dist/tools/people.js +481 -0
  242. package/dist/tools/people.js.map +1 -0
  243. package/dist/tools/projects.d.ts +20 -0
  244. package/dist/tools/projects.d.ts.map +1 -0
  245. package/dist/tools/projects.js +316 -0
  246. package/dist/tools/projects.js.map +1 -0
  247. package/dist/tools/public-filter.d.ts +43 -0
  248. package/dist/tools/public-filter.d.ts.map +1 -0
  249. package/dist/tools/public-filter.js +356 -0
  250. package/dist/tools/public-filter.js.map +1 -0
  251. package/dist/tools/publishers.d.ts +30 -0
  252. package/dist/tools/publishers.d.ts.map +1 -0
  253. package/dist/tools/publishers.js +105 -0
  254. package/dist/tools/publishers.js.map +1 -0
  255. package/dist/tools/purchases.d.ts +27 -0
  256. package/dist/tools/purchases.d.ts.map +1 -0
  257. package/dist/tools/purchases.js +9 -0
  258. package/dist/tools/purchases.js.map +1 -0
  259. package/dist/tools/recording-attribution-hints.d.ts +24 -0
  260. package/dist/tools/recording-attribution-hints.d.ts.map +1 -0
  261. package/dist/tools/recording-attribution-hints.js +27 -0
  262. package/dist/tools/recording-attribution-hints.js.map +1 -0
  263. package/dist/tools/recordings.d.ts +96 -0
  264. package/dist/tools/recordings.d.ts.map +1 -0
  265. package/dist/tools/recordings.js +564 -0
  266. package/dist/tools/recordings.js.map +1 -0
  267. package/dist/tools/recovery-hints.d.ts +40 -0
  268. package/dist/tools/recovery-hints.d.ts.map +1 -0
  269. package/dist/tools/recovery-hints.js +827 -0
  270. package/dist/tools/recovery-hints.js.map +1 -0
  271. package/dist/tools/release-rich.d.ts +31 -0
  272. package/dist/tools/release-rich.d.ts.map +1 -0
  273. package/dist/tools/release-rich.js +245 -0
  274. package/dist/tools/release-rich.js.map +1 -0
  275. package/dist/tools/releases.d.ts +36 -0
  276. package/dist/tools/releases.d.ts.map +1 -0
  277. package/dist/tools/releases.js +649 -0
  278. package/dist/tools/releases.js.map +1 -0
  279. package/dist/tools/report-issue.d.ts +21 -0
  280. package/dist/tools/report-issue.d.ts.map +1 -0
  281. package/dist/tools/report-issue.js +101 -0
  282. package/dist/tools/report-issue.js.map +1 -0
  283. package/dist/tools/royalties.d.ts +23 -0
  284. package/dist/tools/royalties.d.ts.map +1 -0
  285. package/dist/tools/royalties.js +262 -0
  286. package/dist/tools/royalties.js.map +1 -0
  287. package/dist/tools/search.d.ts +30 -0
  288. package/dist/tools/search.d.ts.map +1 -0
  289. package/dist/tools/search.js +115 -0
  290. package/dist/tools/search.js.map +1 -0
  291. package/dist/tools/send.d.ts +17 -0
  292. package/dist/tools/send.d.ts.map +1 -0
  293. package/dist/tools/send.js +188 -0
  294. package/dist/tools/send.js.map +1 -0
  295. package/dist/tools/sessions.d.ts +18 -0
  296. package/dist/tools/sessions.d.ts.map +1 -0
  297. package/dist/tools/sessions.js +153 -0
  298. package/dist/tools/sessions.js.map +1 -0
  299. package/dist/tools/settings.d.ts +23 -0
  300. package/dist/tools/settings.d.ts.map +1 -0
  301. package/dist/tools/settings.js +365 -0
  302. package/dist/tools/settings.js.map +1 -0
  303. package/dist/tools/share-links.d.ts +22 -0
  304. package/dist/tools/share-links.d.ts.map +1 -0
  305. package/dist/tools/share-links.js +188 -0
  306. package/dist/tools/share-links.js.map +1 -0
  307. package/dist/tools/signup.d.ts +26 -0
  308. package/dist/tools/signup.d.ts.map +1 -0
  309. package/dist/tools/signup.js +266 -0
  310. package/dist/tools/signup.js.map +1 -0
  311. package/dist/tools/split-sheets.d.ts +25 -0
  312. package/dist/tools/split-sheets.d.ts.map +1 -0
  313. package/dist/tools/split-sheets.js +309 -0
  314. package/dist/tools/split-sheets.js.map +1 -0
  315. package/dist/tools/storage-config.d.ts +13 -0
  316. package/dist/tools/storage-config.d.ts.map +1 -0
  317. package/dist/tools/storage-config.js +245 -0
  318. package/dist/tools/storage-config.js.map +1 -0
  319. package/dist/tools/subscription.d.ts +60 -0
  320. package/dist/tools/subscription.d.ts.map +1 -0
  321. package/dist/tools/subscription.js +440 -0
  322. package/dist/tools/subscription.js.map +1 -0
  323. package/dist/tools/sync-placements.d.ts +31 -0
  324. package/dist/tools/sync-placements.d.ts.map +1 -0
  325. package/dist/tools/sync-placements.js +431 -0
  326. package/dist/tools/sync-placements.js.map +1 -0
  327. package/dist/tools/team.d.ts +22 -0
  328. package/dist/tools/team.d.ts.map +1 -0
  329. package/dist/tools/team.js +144 -0
  330. package/dist/tools/team.js.map +1 -0
  331. package/dist/tools/telegram.d.ts +21 -0
  332. package/dist/tools/telegram.d.ts.map +1 -0
  333. package/dist/tools/telegram.js +144 -0
  334. package/dist/tools/telegram.js.map +1 -0
  335. package/dist/tools/uploads.d.ts +17 -0
  336. package/dist/tools/uploads.d.ts.map +1 -0
  337. package/dist/tools/uploads.js +165 -0
  338. package/dist/tools/uploads.js.map +1 -0
  339. package/dist/tools/works.d.ts +71 -0
  340. package/dist/tools/works.d.ts.map +1 -0
  341. package/dist/tools/works.js +694 -0
  342. package/dist/tools/works.js.map +1 -0
  343. package/package.json +54 -0
  344. package/scripts/build-required-schemas.ts +233 -0
  345. package/scripts/bundle-apps.ts +61 -0
  346. package/scripts/refresh-schema-mirror.ts +182 -0
  347. package/server.json +20 -0
@@ -0,0 +1,212 @@
1
+ // Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
2
+ import { writeCredentials, clearCredentials, } from "@withpica/mcp-utils";
3
+ const POLL_INTERVAL_MS = 3000;
4
+ const POLL_TIMEOUT_MS = 5 * 60 * 1000;
5
+ export class AuthTools {
6
+ config;
7
+ reinitialize;
8
+ signOutCallback;
9
+ constructor(config, reinitialize, signOutCallback = () => { }) {
10
+ this.config = config;
11
+ this.reinitialize = reinitialize;
12
+ this.signOutCallback = signOutCallback;
13
+ }
14
+ getTools() {
15
+ return [
16
+ {
17
+ definition: {
18
+ name: "pica_sign_in",
19
+ description: "sign in to PICA with your email — sends a magic link to your inbox. " +
20
+ "use this to connect your music catalog. no API key needed.",
21
+ workflows: "infrastructure",
22
+ inputSchema: {
23
+ type: "object",
24
+ properties: {
25
+ email: {
26
+ type: "string",
27
+ description: "your email address",
28
+ },
29
+ },
30
+ required: ["email"],
31
+ },
32
+ },
33
+ executor: this.signIn.bind(this),
34
+ },
35
+ {
36
+ definition: {
37
+ name: "pica_sign_out",
38
+ description: "sign out of PICA — clears your saved credentials",
39
+ workflows: "infrastructure",
40
+ inputSchema: {
41
+ type: "object",
42
+ properties: {},
43
+ },
44
+ },
45
+ executor: this.signOut.bind(this),
46
+ },
47
+ ];
48
+ }
49
+ async signIn(args) {
50
+ const email = args.email?.trim()?.toLowerCase();
51
+ if (!email || !email.includes("@") || !email.includes(".")) {
52
+ return {
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: "that doesn't look like an email address — please try again",
57
+ },
58
+ ],
59
+ isError: true,
60
+ };
61
+ }
62
+ const apiUrl = this.config.picaApiUrl.replace(/\/api$/, "");
63
+ const authorizeUrl = `${apiUrl}/api/public/mcp-auth/authorize`;
64
+ const tokenUrl = `${apiUrl}/api/public/mcp-auth/token`;
65
+ // Step 1: Request magic link
66
+ let deviceCode;
67
+ let interval;
68
+ try {
69
+ const res = await fetch(authorizeUrl, {
70
+ method: "POST",
71
+ headers: { "Content-Type": "application/json" },
72
+ body: JSON.stringify({ email }),
73
+ });
74
+ if (res.status === 429) {
75
+ return {
76
+ content: [
77
+ {
78
+ type: "text",
79
+ text: "too many sign-in attempts — try again in an hour",
80
+ },
81
+ ],
82
+ isError: true,
83
+ };
84
+ }
85
+ if (!res.ok) {
86
+ return {
87
+ content: [
88
+ {
89
+ type: "text",
90
+ text: "failed to send magic link — please try again",
91
+ },
92
+ ],
93
+ isError: true,
94
+ };
95
+ }
96
+ const data = (await res.json());
97
+ deviceCode = data.device_code;
98
+ interval = (data.interval || 3) * 1000;
99
+ console.error(`[MCP Auth] Magic link sent to ${email}`);
100
+ }
101
+ catch {
102
+ return {
103
+ content: [
104
+ {
105
+ type: "text",
106
+ text: "couldn't reach PICA — check your internet connection and try again",
107
+ },
108
+ ],
109
+ isError: true,
110
+ };
111
+ }
112
+ // Step 2: Poll for token
113
+ const startTime = Date.now();
114
+ while (Date.now() - startTime < POLL_TIMEOUT_MS) {
115
+ await new Promise((resolve) => setTimeout(resolve, interval));
116
+ try {
117
+ const res = await fetch(tokenUrl, {
118
+ method: "POST",
119
+ headers: { "Content-Type": "application/json" },
120
+ body: JSON.stringify({
121
+ device_code: deviceCode,
122
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
123
+ }),
124
+ });
125
+ const data = (await res.json());
126
+ if (data.error === "authorization_pending") {
127
+ continue;
128
+ }
129
+ if (data.error === "expired_token") {
130
+ return {
131
+ content: [
132
+ {
133
+ type: "text",
134
+ text: "magic link expired — say 'sign me in' to try again",
135
+ },
136
+ ],
137
+ isError: true,
138
+ };
139
+ }
140
+ if (data.access_token) {
141
+ const credentials = {
142
+ api_key: data.access_token,
143
+ email,
144
+ org_name: data.org_name || "my catalog",
145
+ authenticated_at: new Date().toISOString(),
146
+ };
147
+ writeCredentials(this.config.credentialsPath, credentials);
148
+ this.reinitialize(data.access_token);
149
+ console.error(`[MCP Auth] Signed in as ${email}`);
150
+ if (data.is_new_user) {
151
+ return {
152
+ content: [
153
+ {
154
+ type: "text",
155
+ text: `welcome to PICA, ${email}. you're all signed in.\n\n` +
156
+ `quick first thing — your workspace is currently named "My Organization" (the boring default). want to give it a real name? it'll appear on exports, share links, and anywhere else your catalog shows up. just tell me what to call it, or say "skip" to set it later.\n\n` +
157
+ `after that, we can:\n` +
158
+ `- add your first song manually\n` +
159
+ `- import an existing catalog from a CSV\n` +
160
+ `- connect Spotify and pull your discography automatically\n\n` +
161
+ `what works for you?`,
162
+ },
163
+ ],
164
+ };
165
+ }
166
+ return {
167
+ content: [
168
+ {
169
+ type: "text",
170
+ text: `signed in as ${email} (${data.org_name || "my catalog"}).\n\n` +
171
+ `all tools are now available. try "what needs attention?" to see your catalog status.`,
172
+ },
173
+ ],
174
+ };
175
+ }
176
+ }
177
+ catch {
178
+ continue;
179
+ }
180
+ }
181
+ return {
182
+ content: [
183
+ {
184
+ type: "text",
185
+ text: "magic link expired — say 'sign me in' to try again",
186
+ },
187
+ ],
188
+ isError: true,
189
+ };
190
+ }
191
+ async signOut(_args) {
192
+ clearCredentials(this.config.credentialsPath);
193
+ // Reset the server back to lobby mode: clear PicaClient, rebuild
194
+ // toolRegistry/resourceRegistry so the next tools/list call returns
195
+ // only [pica_sign_in, pica_sign_out]. Without this the client keeps
196
+ // seeing the full authenticated tool surface until the process is
197
+ // restarted, which would let an "ex-signed-out" client still call
198
+ // privileged tools (the calls would fail at the API layer, but the
199
+ // surface area itself shouldn't lie about what's available).
200
+ this.signOutCallback();
201
+ console.error("[MCP Auth] Signed out — credentials cleared, lobby restored");
202
+ return {
203
+ content: [
204
+ {
205
+ type: "text",
206
+ text: "signed out of PICA. say 'sign me in' to reconnect.",
207
+ },
208
+ ],
209
+ };
210
+ }
211
+ }
212
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Bulk Operations Tools — MCP tools for batch updates.
3
+ *
4
+ * ADR-174 Phase 2 item 2 follow-up: `pica_works_bulk_update.updates`
5
+ * validates against `WORK_WRITE_PROPERTIES` — the same canonical source
6
+ * of truth that gates `pica_works_update`. Without this, bulk update is
7
+ * the last surface that still accepts any key (the silent-data-loss
8
+ * vector the audit flagged at row 25).
9
+ */
10
+ import { PicaClient } from "@withpica/mcp-sdk";
11
+ import { ToolDefinition, ToolExecutor } from "./index.js";
12
+ export declare class BulkTools {
13
+ private pica;
14
+ constructor(pica: PicaClient);
15
+ getTools(): Array<{
16
+ definition: ToolDefinition;
17
+ executor: ToolExecutor;
18
+ }>;
19
+ private bulkUpdateWorks;
20
+ private bulkUpdatePeopleRoles;
21
+ }
22
+ //# sourceMappingURL=bulk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk.d.ts","sourceRoot":"","sources":["../../src/tools/bulk.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EACL,cAAc,EACd,YAAY,EAGb,MAAM,YAAY,CAAC;AAepB,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YA6E3D,eAAe;YAyDf,qBAAqB;CA4CpC"}
@@ -0,0 +1,164 @@
1
+ // Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
2
+ import { elicitBulkConfirmation, formatSuccess, formatValidationError, } from "@withpica/mcp-utils";
3
+ import { WORK_WRITE_PROPERTIES } from "./works.js";
4
+ /**
5
+ * Set of legal keys for the bulk `updates` object. Mirrors the
6
+ * `pica_works_update` schema exactly — if it's not writable singly,
7
+ * it's not writable in bulk either.
8
+ */
9
+ const BULK_UPDATE_ALLOWED_KEYS = new Set(Object.keys(WORK_WRITE_PROPERTIES));
10
+ export class BulkTools {
11
+ pica;
12
+ constructor(pica) {
13
+ this.pica = pica;
14
+ }
15
+ getTools() {
16
+ return [
17
+ {
18
+ definition: {
19
+ name: "pica_works_bulk_update",
20
+ description: "Batch update multiple works at once. The `updates` object validates against the same " +
21
+ "schema as `pica_works_update` — only real `works` columns are accepted. " +
22
+ "Phantom keys (label, upc, album_name, album_art_url, album_release_date, track_number, " +
23
+ "spotify_url) are rejected with the same redirect hints as the single-update tool.",
24
+ workflows: "infrastructure",
25
+ inputSchema: {
26
+ type: "object",
27
+ properties: {
28
+ work_ids: {
29
+ type: "array",
30
+ items: { type: "string" },
31
+ description: "Array of work IDs to update",
32
+ },
33
+ updates: {
34
+ type: "object",
35
+ description: "Fields to apply to every work in `work_ids`. Same schema as `pica_works_update` " +
36
+ "minus the `id` field. Every key must be a real `works` column.",
37
+ properties: WORK_WRITE_PROPERTIES,
38
+ },
39
+ dry_run: {
40
+ type: "boolean",
41
+ description: "When true, returns { dry_run: true, would_affect, sample_changes } without persisting any update. Use to preview the bulk before committing.",
42
+ },
43
+ },
44
+ required: ["work_ids", "updates"],
45
+ },
46
+ previewMode: "dry_run",
47
+ },
48
+ executor: this.bulkUpdateWorks.bind(this),
49
+ },
50
+ {
51
+ definition: {
52
+ name: "pica_people_bulk_update_roles",
53
+ description: "Batch update roles for multiple people at once",
54
+ workflows: "infrastructure",
55
+ inputSchema: {
56
+ type: "object",
57
+ properties: {
58
+ person_ids: {
59
+ type: "array",
60
+ items: { type: "string" },
61
+ description: "Array of person IDs to update",
62
+ },
63
+ action: {
64
+ type: "string",
65
+ enum: ["add", "remove"],
66
+ description: "Whether to add or remove the specified roles",
67
+ },
68
+ roles: {
69
+ type: "array",
70
+ items: { type: "string" },
71
+ description: "Roles to add/remove (e.g. ['writer', 'composer', 'performer'])",
72
+ },
73
+ dry_run: {
74
+ type: "boolean",
75
+ description: "When true, returns { dry_run: true, would_affect, sample_changes } without modifying any person. Preview before committing.",
76
+ },
77
+ },
78
+ required: ["person_ids", "action", "roles"],
79
+ },
80
+ previewMode: "dry_run",
81
+ },
82
+ executor: this.bulkUpdatePeopleRoles.bind(this),
83
+ },
84
+ ];
85
+ }
86
+ async bulkUpdateWorks(args, ctx) {
87
+ if (!args.work_ids?.length) {
88
+ return formatValidationError({ work_ids: "must be a non-empty array" });
89
+ }
90
+ if (!args.updates || Object.keys(args.updates).length === 0) {
91
+ return formatValidationError({
92
+ updates: "must contain at least one field",
93
+ });
94
+ }
95
+ // ADR-174 Phase 2 — every key must be a real `works` column. Without
96
+ // this runtime check, an agent could still call the tool with a
97
+ // phantom key (e.g. upc) and the HTTP backstop would 400 per row —
98
+ // wasteful and opaque. Fail fast at the tool boundary instead.
99
+ const invalidKeys = Object.keys(args.updates).filter((k) => !BULK_UPDATE_ALLOWED_KEYS.has(k));
100
+ if (invalidKeys.length > 0) {
101
+ return formatValidationError({
102
+ updates: `unknown field(s): ${invalidKeys.join(", ")}. Allowed fields match pica_works_update: ${[...BULK_UPDATE_ALLOWED_KEYS].sort().join(", ")}`,
103
+ });
104
+ }
105
+ // ADR-199 Stream 5a — dry_run preview. Validation already passed,
106
+ // so the preview reflects exactly what would be sent.
107
+ if (args.dry_run === true) {
108
+ return formatSuccess(`Dry run — would update ${args.work_ids.length} work(s) with ${Object.keys(args.updates).length} field(s)`, {
109
+ dry_run: true,
110
+ would_affect: args.work_ids,
111
+ sample_changes: args.updates,
112
+ field_count: Object.keys(args.updates).length,
113
+ target_count: args.work_ids.length,
114
+ });
115
+ }
116
+ // ADR-200 Phase 1 — Class D form-confirmation gate. Returns
117
+ // `no_gate` for clients without elicitation support (universal
118
+ // floor), or after the user accepts with confirm=true.
119
+ const gate = await elicitBulkConfirmation({
120
+ server: ctx?.server,
121
+ args,
122
+ action: "Bulk-update works",
123
+ impactSummary: `${args.work_ids.length} work(s), ${Object.keys(args.updates).length} field(s)`,
124
+ warning: "This update is applied to every selected work and cannot be undone in bulk.",
125
+ });
126
+ if (gate.kind === "abort")
127
+ return gate.result;
128
+ const result = await this.pica.bulk.updateWorks(args.work_ids, args.updates);
129
+ return formatSuccess(`Bulk updated ${args.work_ids.length} works`, result);
130
+ }
131
+ async bulkUpdatePeopleRoles(args, ctx) {
132
+ if (!args.person_ids?.length) {
133
+ return formatValidationError({ person_ids: "must be a non-empty array" });
134
+ }
135
+ if (!args.roles?.length) {
136
+ return formatValidationError({ roles: "must be a non-empty array" });
137
+ }
138
+ // ADR-199 Stream 5a — dry_run preview before role mutation.
139
+ if (args.dry_run === true) {
140
+ const action = args.action || "add";
141
+ return formatSuccess(`Dry run — would ${action} ${args.roles.length} role(s) on ${args.person_ids.length} person(s)`, {
142
+ dry_run: true,
143
+ would_affect: args.person_ids,
144
+ action,
145
+ roles: args.roles,
146
+ target_count: args.person_ids.length,
147
+ });
148
+ }
149
+ // ADR-200 Phase 1 — Class D form-confirmation gate.
150
+ const action = args.action || "add";
151
+ const gate = await elicitBulkConfirmation({
152
+ server: ctx?.server,
153
+ args,
154
+ action: `Bulk ${action} roles`,
155
+ impactSummary: `${args.roles.length} role(s) across ${args.person_ids.length} person(s)`,
156
+ warning: `Roles to ${action}: ${args.roles.join(", ")}.`,
157
+ });
158
+ if (gate.kind === "abort")
159
+ return gate.result;
160
+ const result = await this.pica.bulk.updatePeopleRoles(args.person_ids, args.roles, action);
161
+ return formatSuccess(`Bulk updated roles for ${args.person_ids.length} people`, result);
162
+ }
163
+ }
164
+ //# sourceMappingURL=bulk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk.js","sourceRoot":"","sources":["../../src/tools/bulk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Calendar Tools — view upcoming events, deadlines, and scheduled sessions
3
+ */
4
+ import { PicaClient } from "@withpica/mcp-sdk";
5
+ import { ToolDefinition, ToolExecutor } from "./index.js";
6
+ export declare class CalendarTools {
7
+ private pica;
8
+ constructor(pica: PicaClient);
9
+ getTools(): Array<{
10
+ definition: ToolDefinition;
11
+ executor: ToolExecutor;
12
+ }>;
13
+ private getEvents;
14
+ }
15
+ //# sourceMappingURL=calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../src/tools/calendar.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAGtE,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YA6C3D,SAAS;CAqBxB"}
@@ -0,0 +1,68 @@
1
+ // Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
2
+ import { formatStructuredList } from "@withpica/mcp-utils";
3
+ export class CalendarTools {
4
+ pica;
5
+ constructor(pica) {
6
+ this.pica = pica;
7
+ }
8
+ getTools() {
9
+ return [
10
+ {
11
+ definition: {
12
+ name: "pica_calendar_events",
13
+ description: "Get upcoming calendar events — sessions, agreement deadlines, release dates, " +
14
+ "invoice due dates, and Google Calendar events. Defaults to the next 30 days.",
15
+ workflows: "infrastructure",
16
+ inputSchema: {
17
+ type: "object",
18
+ properties: {
19
+ start_date: {
20
+ type: "string",
21
+ description: "Start date (YYYY-MM-DD). Defaults to today.",
22
+ },
23
+ end_date: {
24
+ type: "string",
25
+ description: "End date (YYYY-MM-DD). Defaults to 30 days from start.",
26
+ },
27
+ types: {
28
+ type: "array",
29
+ items: { type: "string" },
30
+ description: "Filter by event type: session, invoice_due, invoice_sent, " +
31
+ "payment_received, agreement_expiry, agreement_signing, " +
32
+ "work_release, google_calendar",
33
+ },
34
+ work_id: {
35
+ type: "string",
36
+ description: "Filter events linked to a specific work",
37
+ },
38
+ search: {
39
+ type: "string",
40
+ description: "Search events by title",
41
+ },
42
+ },
43
+ },
44
+ },
45
+ executor: this.getEvents.bind(this),
46
+ },
47
+ ];
48
+ }
49
+ async getEvents(args) {
50
+ const today = new Date().toISOString().split("T")[0];
51
+ const thirtyDays = new Date(Date.now() + 30 * 86400000)
52
+ .toISOString()
53
+ .split("T")[0];
54
+ const result = await this.pica.calendar.getEvents({
55
+ startDate: args.start_date || today,
56
+ endDate: args.end_date || thirtyDays,
57
+ types: args.types,
58
+ workId: args.work_id,
59
+ search: args.search,
60
+ });
61
+ const events = Array.isArray(result) ? result : result?.events || [];
62
+ return formatStructuredList(events, "event", {
63
+ startDate: args.start_date || today,
64
+ endDate: args.end_date || thirtyDays,
65
+ });
66
+ }
67
+ }
68
+ //# sourceMappingURL=calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../src/tools/calendar.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAQ7D,OAAO,EAAiB,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,MAAM,OAAO,aAAa;IAChB,IAAI,CAAa;IAEzB,YAAY,IAAgB;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,QAAQ;QACN,OAAO;YACL;gBACE,UAAU,EAAE;oBACV,IAAI,EAAE,sBAAsB;oBAC5B,WAAW,EACT,+EAA+E;wBAC/E,8EAA8E;oBAChF,SAAS,EAAE,gBAAgB;oBAC3B,WAAW,EAAE;wBACX,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,UAAU,EAAE;gCACV,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,6CAA6C;6BAC3D;4BACD,QAAQ,EAAE;gCACR,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,wDAAwD;6BAC3D;4BACD,KAAK,EAAE;gCACL,IAAI,EAAE,OAAO;gCACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gCACzB,WAAW,EACT,4DAA4D;oCAC5D,yDAAyD;oCACzD,+BAA+B;6BAClC;4BACD,OAAO,EAAE;gCACP,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,yCAAyC;6BACvD;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,wBAAwB;6BACtC;yBACF;qBACF;iBACF;gBACD,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;aACpC;SACF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,IAAyB;QAC/C,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC;aACpD,WAAW,EAAE;aACb,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAChD,SAAS,EAAE,IAAI,CAAC,UAAU,IAAI,KAAK;YACnC,OAAO,EAAE,IAAI,CAAC,QAAQ,IAAI,UAAU;YACpC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;QAErE,OAAO,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE;YAC3C,SAAS,EAAE,IAAI,CAAC,UAAU,IAAI,KAAK;YACnC,OAAO,EAAE,IAAI,CAAC,QAAQ,IAAI,UAAU;SACrC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Collaborator Tools - MCP tools for inviting and managing collaborators
3
+ */
4
+ import { PicaClient } from "@withpica/mcp-sdk";
5
+ import { ToolDefinition, ToolExecutor } from "./index.js";
6
+ export declare class CollaboratorsTools {
7
+ private pica;
8
+ constructor(pica: PicaClient);
9
+ getTools(): Array<{
10
+ definition: ToolDefinition;
11
+ executor: ToolExecutor;
12
+ }>;
13
+ private inviteCollaborator;
14
+ private listInvites;
15
+ private resendInvite;
16
+ private listIncoming;
17
+ private acceptInvite;
18
+ private disputeInvite;
19
+ private inviteBulk;
20
+ }
21
+ //# sourceMappingURL=collaborators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaborators.d.ts","sourceRoot":"","sources":["../../src/tools/collaborators.ts"],"names":[],"mappings":"AAeA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EACL,cAAc,EACd,YAAY,EAGb,MAAM,YAAY,CAAC;AAQpB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YAqP3D,kBAAkB;YAgClB,WAAW;YAmCX,YAAY;YAQZ,YAAY;YAoBZ,YAAY;YAiBZ,aAAa;YAWb,UAAU;CA+DzB"}