@withpica/mcp-server 2.1.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 (226) hide show
  1. package/README.md +305 -0
  2. package/dist/config.d.ts +34 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +33 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/index.d.ts +7 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +34 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/pica-sdk.d.ts +1162 -0
  11. package/dist/pica-sdk.d.ts.map +1 -0
  12. package/dist/pica-sdk.js +1371 -0
  13. package/dist/pica-sdk.js.map +1 -0
  14. package/dist/prompts/index.d.ts +78 -0
  15. package/dist/prompts/index.d.ts.map +1 -0
  16. package/dist/prompts/index.js +513 -0
  17. package/dist/prompts/index.js.map +1 -0
  18. package/dist/resources/index.d.ts +64 -0
  19. package/dist/resources/index.d.ts.map +1 -0
  20. package/dist/resources/index.js +310 -0
  21. package/dist/resources/index.js.map +1 -0
  22. package/dist/resources/llms-primer.d.ts +2 -0
  23. package/dist/resources/llms-primer.d.ts.map +1 -0
  24. package/dist/resources/llms-primer.js +67 -0
  25. package/dist/resources/llms-primer.js.map +1 -0
  26. package/dist/server.d.ts +27 -0
  27. package/dist/server.d.ts.map +1 -0
  28. package/dist/server.js +140 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/tools/agreement-types.d.ts +37 -0
  31. package/dist/tools/agreement-types.d.ts.map +1 -0
  32. package/dist/tools/agreement-types.js +579 -0
  33. package/dist/tools/agreement-types.js.map +1 -0
  34. package/dist/tools/agreements.d.ts +21 -0
  35. package/dist/tools/agreements.d.ts.map +1 -0
  36. package/dist/tools/agreements.js +328 -0
  37. package/dist/tools/agreements.js.map +1 -0
  38. package/dist/tools/analytics.d.ts +20 -0
  39. package/dist/tools/analytics.d.ts.map +1 -0
  40. package/dist/tools/analytics.js +126 -0
  41. package/dist/tools/analytics.js.map +1 -0
  42. package/dist/tools/assets.d.ts +23 -0
  43. package/dist/tools/assets.d.ts.map +1 -0
  44. package/dist/tools/assets.js +220 -0
  45. package/dist/tools/assets.js.map +1 -0
  46. package/dist/tools/audio-files.d.ts +21 -0
  47. package/dist/tools/audio-files.d.ts.map +1 -0
  48. package/dist/tools/audio-files.js +358 -0
  49. package/dist/tools/audio-files.js.map +1 -0
  50. package/dist/tools/bulk.d.ts +16 -0
  51. package/dist/tools/bulk.d.ts.map +1 -0
  52. package/dist/tools/bulk.js +82 -0
  53. package/dist/tools/bulk.js.map +1 -0
  54. package/dist/tools/calendar.d.ts +15 -0
  55. package/dist/tools/calendar.d.ts.map +1 -0
  56. package/dist/tools/calendar.js +69 -0
  57. package/dist/tools/calendar.js.map +1 -0
  58. package/dist/tools/collaborators.d.ts +17 -0
  59. package/dist/tools/collaborators.d.ts.map +1 -0
  60. package/dist/tools/collaborators.js +133 -0
  61. package/dist/tools/collaborators.js.map +1 -0
  62. package/dist/tools/comparisons.d.ts +22 -0
  63. package/dist/tools/comparisons.d.ts.map +1 -0
  64. package/dist/tools/comparisons.js +86 -0
  65. package/dist/tools/comparisons.js.map +1 -0
  66. package/dist/tools/credits.d.ts +17 -0
  67. package/dist/tools/credits.d.ts.map +1 -0
  68. package/dist/tools/credits.js +136 -0
  69. package/dist/tools/credits.js.map +1 -0
  70. package/dist/tools/dashboard.d.ts +20 -0
  71. package/dist/tools/dashboard.d.ts.map +1 -0
  72. package/dist/tools/dashboard.js +156 -0
  73. package/dist/tools/dashboard.js.map +1 -0
  74. package/dist/tools/directory.d.ts +15 -0
  75. package/dist/tools/directory.d.ts.map +1 -0
  76. package/dist/tools/directory.js +108 -0
  77. package/dist/tools/directory.js.map +1 -0
  78. package/dist/tools/disputes.d.ts +18 -0
  79. package/dist/tools/disputes.d.ts.map +1 -0
  80. package/dist/tools/disputes.js +66 -0
  81. package/dist/tools/disputes.js.map +1 -0
  82. package/dist/tools/documents.d.ts +15 -0
  83. package/dist/tools/documents.d.ts.map +1 -0
  84. package/dist/tools/documents.js +38 -0
  85. package/dist/tools/documents.js.map +1 -0
  86. package/dist/tools/duplicates.d.ts +16 -0
  87. package/dist/tools/duplicates.d.ts.map +1 -0
  88. package/dist/tools/duplicates.js +72 -0
  89. package/dist/tools/duplicates.js.map +1 -0
  90. package/dist/tools/enrichment.d.ts +23 -0
  91. package/dist/tools/enrichment.d.ts.map +1 -0
  92. package/dist/tools/enrichment.js +207 -0
  93. package/dist/tools/enrichment.js.map +1 -0
  94. package/dist/tools/exports.d.ts +19 -0
  95. package/dist/tools/exports.d.ts.map +1 -0
  96. package/dist/tools/exports.js +155 -0
  97. package/dist/tools/exports.js.map +1 -0
  98. package/dist/tools/health.d.ts +17 -0
  99. package/dist/tools/health.d.ts.map +1 -0
  100. package/dist/tools/health.js +69 -0
  101. package/dist/tools/health.js.map +1 -0
  102. package/dist/tools/import-documents.d.ts +21 -0
  103. package/dist/tools/import-documents.d.ts.map +1 -0
  104. package/dist/tools/import-documents.js +191 -0
  105. package/dist/tools/import-documents.js.map +1 -0
  106. package/dist/tools/import.d.ts +29 -0
  107. package/dist/tools/import.d.ts.map +1 -0
  108. package/dist/tools/import.js +404 -0
  109. package/dist/tools/import.js.map +1 -0
  110. package/dist/tools/index.d.ts +48 -0
  111. package/dist/tools/index.d.ts.map +1 -0
  112. package/dist/tools/index.js +394 -0
  113. package/dist/tools/index.js.map +1 -0
  114. package/dist/tools/integrations.d.ts +15 -0
  115. package/dist/tools/integrations.d.ts.map +1 -0
  116. package/dist/tools/integrations.js +102 -0
  117. package/dist/tools/integrations.js.map +1 -0
  118. package/dist/tools/licensing.d.ts +40 -0
  119. package/dist/tools/licensing.d.ts.map +1 -0
  120. package/dist/tools/licensing.js +436 -0
  121. package/dist/tools/licensing.js.map +1 -0
  122. package/dist/tools/memory.d.ts +21 -0
  123. package/dist/tools/memory.d.ts.map +1 -0
  124. package/dist/tools/memory.js +121 -0
  125. package/dist/tools/memory.js.map +1 -0
  126. package/dist/tools/multimedia.d.ts +19 -0
  127. package/dist/tools/multimedia.d.ts.map +1 -0
  128. package/dist/tools/multimedia.js +293 -0
  129. package/dist/tools/multimedia.js.map +1 -0
  130. package/dist/tools/notes.d.ts +21 -0
  131. package/dist/tools/notes.d.ts.map +1 -0
  132. package/dist/tools/notes.js +126 -0
  133. package/dist/tools/notes.js.map +1 -0
  134. package/dist/tools/notifications.d.ts +17 -0
  135. package/dist/tools/notifications.d.ts.map +1 -0
  136. package/dist/tools/notifications.js +117 -0
  137. package/dist/tools/notifications.js.map +1 -0
  138. package/dist/tools/people.d.ts +53 -0
  139. package/dist/tools/people.d.ts.map +1 -0
  140. package/dist/tools/people.js +534 -0
  141. package/dist/tools/people.js.map +1 -0
  142. package/dist/tools/pica-score.d.ts +15 -0
  143. package/dist/tools/pica-score.d.ts.map +1 -0
  144. package/dist/tools/pica-score.js +30 -0
  145. package/dist/tools/pica-score.js.map +1 -0
  146. package/dist/tools/projects.d.ts +19 -0
  147. package/dist/tools/projects.d.ts.map +1 -0
  148. package/dist/tools/projects.js +142 -0
  149. package/dist/tools/projects.js.map +1 -0
  150. package/dist/tools/purchases.d.ts +15 -0
  151. package/dist/tools/purchases.d.ts.map +1 -0
  152. package/dist/tools/purchases.js +65 -0
  153. package/dist/tools/purchases.js.map +1 -0
  154. package/dist/tools/recordings.d.ts +41 -0
  155. package/dist/tools/recordings.d.ts.map +1 -0
  156. package/dist/tools/recordings.js +293 -0
  157. package/dist/tools/recordings.js.map +1 -0
  158. package/dist/tools/registration.d.ts +16 -0
  159. package/dist/tools/registration.d.ts.map +1 -0
  160. package/dist/tools/registration.js +52 -0
  161. package/dist/tools/registration.js.map +1 -0
  162. package/dist/tools/releases.d.ts +18 -0
  163. package/dist/tools/releases.d.ts.map +1 -0
  164. package/dist/tools/releases.js +138 -0
  165. package/dist/tools/releases.js.map +1 -0
  166. package/dist/tools/royalties.d.ts +23 -0
  167. package/dist/tools/royalties.d.ts.map +1 -0
  168. package/dist/tools/royalties.js +263 -0
  169. package/dist/tools/royalties.js.map +1 -0
  170. package/dist/tools/search.d.ts +30 -0
  171. package/dist/tools/search.d.ts.map +1 -0
  172. package/dist/tools/search.js +117 -0
  173. package/dist/tools/search.js.map +1 -0
  174. package/dist/tools/send.d.ts +18 -0
  175. package/dist/tools/send.d.ts.map +1 -0
  176. package/dist/tools/send.js +189 -0
  177. package/dist/tools/send.js.map +1 -0
  178. package/dist/tools/sessions.d.ts +18 -0
  179. package/dist/tools/sessions.d.ts.map +1 -0
  180. package/dist/tools/sessions.js +107 -0
  181. package/dist/tools/sessions.js.map +1 -0
  182. package/dist/tools/settings.d.ts +18 -0
  183. package/dist/tools/settings.d.ts.map +1 -0
  184. package/dist/tools/settings.js +98 -0
  185. package/dist/tools/settings.js.map +1 -0
  186. package/dist/tools/share-links.d.ts +19 -0
  187. package/dist/tools/share-links.d.ts.map +1 -0
  188. package/dist/tools/share-links.js +126 -0
  189. package/dist/tools/share-links.js.map +1 -0
  190. package/dist/tools/split-sheets.d.ts +24 -0
  191. package/dist/tools/split-sheets.d.ts.map +1 -0
  192. package/dist/tools/split-sheets.js +189 -0
  193. package/dist/tools/split-sheets.js.map +1 -0
  194. package/dist/tools/team.d.ts +22 -0
  195. package/dist/tools/team.d.ts.map +1 -0
  196. package/dist/tools/team.js +139 -0
  197. package/dist/tools/team.js.map +1 -0
  198. package/dist/tools/telegram.d.ts +20 -0
  199. package/dist/tools/telegram.d.ts.map +1 -0
  200. package/dist/tools/telegram.js +94 -0
  201. package/dist/tools/telegram.js.map +1 -0
  202. package/dist/tools/uploads.d.ts +17 -0
  203. package/dist/tools/uploads.d.ts.map +1 -0
  204. package/dist/tools/uploads.js +159 -0
  205. package/dist/tools/uploads.js.map +1 -0
  206. package/dist/tools/works.d.ts +53 -0
  207. package/dist/tools/works.d.ts.map +1 -0
  208. package/dist/tools/works.js +517 -0
  209. package/dist/tools/works.js.map +1 -0
  210. package/dist/utils/credit-gate.d.ts +17 -0
  211. package/dist/utils/credit-gate.d.ts.map +1 -0
  212. package/dist/utils/credit-gate.js +111 -0
  213. package/dist/utils/credit-gate.js.map +1 -0
  214. package/dist/utils/errors.d.ts +29 -0
  215. package/dist/utils/errors.d.ts.map +1 -0
  216. package/dist/utils/errors.js +114 -0
  217. package/dist/utils/errors.js.map +1 -0
  218. package/dist/utils/formatting.d.ts +63 -0
  219. package/dist/utils/formatting.d.ts.map +1 -0
  220. package/dist/utils/formatting.js +130 -0
  221. package/dist/utils/formatting.js.map +1 -0
  222. package/dist/utils/mpp.d.ts +78 -0
  223. package/dist/utils/mpp.d.ts.map +1 -0
  224. package/dist/utils/mpp.js +136 -0
  225. package/dist/utils/mpp.js.map +1 -0
  226. package/package.json +44 -0
@@ -0,0 +1,517 @@
1
+ /**
2
+ * Works Tools - MCP tools for managing musical works
3
+ */
4
+ import { formatAsText, formatSuccess, formatStructuredList, mapGapsToHints, } from "../utils/formatting.js";
5
+ export class WorksTools {
6
+ pica;
7
+ constructor(pica) {
8
+ this.pica = pica;
9
+ }
10
+ /**
11
+ * Get all works tools
12
+ */
13
+ getTools() {
14
+ return [
15
+ {
16
+ definition: {
17
+ name: "pica_works_list",
18
+ description: "List musical works from PICA catalog with optional filters. " +
19
+ "→ then: pica_works_get_full (full details), pica_work_completeness (gap check), pica_credits_list (see credits)",
20
+ inputSchema: {
21
+ type: "object",
22
+ properties: {
23
+ limit: {
24
+ type: "number",
25
+ description: "Maximum number of results to return (default: 50)",
26
+ },
27
+ search: {
28
+ type: "string",
29
+ description: "Search query to filter works by title or ISWC",
30
+ },
31
+ verified: {
32
+ type: "boolean",
33
+ description: "Filter by verification status (true = verified only, false = unverified only)",
34
+ },
35
+ },
36
+ },
37
+ },
38
+ executor: this.listWorks.bind(this),
39
+ },
40
+ {
41
+ definition: {
42
+ name: "pica_works_get",
43
+ description: "Get details of a specific musical work by ID. " +
44
+ "→ then: pica_works_get_full (all context in one call), pica_credits_list (see credits), pica_work_completeness (gap check)",
45
+ inputSchema: {
46
+ type: "object",
47
+ properties: {
48
+ id: {
49
+ type: "string",
50
+ description: "Work ID",
51
+ },
52
+ },
53
+ required: ["id"],
54
+ },
55
+ },
56
+ executor: this.getWork.bind(this),
57
+ },
58
+ {
59
+ definition: {
60
+ name: "pica_works_create",
61
+ description: "Create a new musical work. Any field from the Work schema can be passed — " +
62
+ "the most commonly used fields are listed below, but additional fields " +
63
+ "are also accepted via additionalProperties. " +
64
+ "→ then: pica_credits_update (add writers), pica_work_completeness (check gaps), pica_enrich_work (fill identifiers)",
65
+ inputSchema: {
66
+ type: "object",
67
+ properties: {
68
+ title: {
69
+ type: "string",
70
+ description: "Work title (required)",
71
+ },
72
+ work_type: {
73
+ type: "string",
74
+ description: "Type of work (required)",
75
+ enum: ["song", "library", "demo", "sample"],
76
+ },
77
+ work_status: {
78
+ type: "string",
79
+ enum: [
80
+ "demo",
81
+ "unreleased",
82
+ "released",
83
+ "pitched",
84
+ "placed",
85
+ "archived",
86
+ ],
87
+ description: "Work status (default: unreleased)",
88
+ },
89
+ iswc: {
90
+ type: "string",
91
+ description: "International Standard Musical Work Code",
92
+ },
93
+ isrc: {
94
+ type: "string",
95
+ description: "International Standard Recording Code",
96
+ },
97
+ duration_seconds: {
98
+ type: "number",
99
+ description: "Duration in seconds",
100
+ },
101
+ genre: {
102
+ type: "array",
103
+ items: { type: "string" },
104
+ description: "Genre tags",
105
+ },
106
+ mood: {
107
+ type: "array",
108
+ items: { type: "string" },
109
+ description: "Mood tags",
110
+ },
111
+ primary_artist: {
112
+ type: "string",
113
+ description: "Primary artist name",
114
+ },
115
+ primary_artist_id: {
116
+ type: "string",
117
+ description: "Primary artist person ID",
118
+ },
119
+ label: {
120
+ type: "string",
121
+ description: "Record label name",
122
+ },
123
+ spotify_track_uri: {
124
+ type: "string",
125
+ description: "Spotify track URI",
126
+ },
127
+ spotify_url: {
128
+ type: "string",
129
+ description: "Spotify URL",
130
+ },
131
+ album_name: {
132
+ type: "string",
133
+ description: "Album name",
134
+ },
135
+ album_release_date: {
136
+ type: "string",
137
+ description: "Album release date (ISO 8601)",
138
+ },
139
+ album_art_url: {
140
+ type: "string",
141
+ description: "URL to album artwork",
142
+ },
143
+ track_number: {
144
+ type: "number",
145
+ description: "Track number on album",
146
+ },
147
+ upc: {
148
+ type: "string",
149
+ description: "Universal Product Code",
150
+ },
151
+ publisher_name: {
152
+ type: "string",
153
+ description: "Publisher name",
154
+ },
155
+ lyrics: {
156
+ type: "string",
157
+ description: "Lyrics text",
158
+ },
159
+ lyrics_language: {
160
+ type: "string",
161
+ description: "Language of lyrics (ISO 639-1)",
162
+ },
163
+ notes: {
164
+ type: "string",
165
+ description: "Internal notes",
166
+ },
167
+ },
168
+ required: ["title", "work_type"],
169
+ additionalProperties: true,
170
+ },
171
+ },
172
+ executor: this.createWork.bind(this),
173
+ },
174
+ {
175
+ definition: {
176
+ name: "pica_works_update",
177
+ description: "Update an existing musical work. Any field from the Work schema can be passed — " +
178
+ "the most commonly used fields are listed below, but additional fields " +
179
+ "(e.g. album_name, album_art_url, track_number, upc, notes, published, " +
180
+ "available_for_licensing, vocal_type, energy, danceability, tempo, key) " +
181
+ "are also accepted.",
182
+ inputSchema: {
183
+ type: "object",
184
+ properties: {
185
+ id: {
186
+ type: "string",
187
+ description: "Work ID (required)",
188
+ },
189
+ title: {
190
+ type: "string",
191
+ description: "Work title",
192
+ },
193
+ iswc: {
194
+ type: "string",
195
+ description: "International Standard Musical Work Code",
196
+ },
197
+ isrc: {
198
+ type: "string",
199
+ description: "International Standard Recording Code (prefer setting on recordings table instead)",
200
+ },
201
+ duration_seconds: {
202
+ type: "number",
203
+ description: "Duration in seconds",
204
+ },
205
+ lyrics: {
206
+ type: "string",
207
+ description: "Lyrics text",
208
+ },
209
+ work_status: {
210
+ type: "string",
211
+ enum: [
212
+ "demo",
213
+ "unreleased",
214
+ "released",
215
+ "pitched",
216
+ "placed",
217
+ "archived",
218
+ ],
219
+ description: "Work status (state machine validates transitions)",
220
+ },
221
+ work_type: {
222
+ type: "string",
223
+ enum: ["song", "library", "demo", "sample"],
224
+ description: "Type of work",
225
+ },
226
+ genre: {
227
+ type: "array",
228
+ items: { type: "string" },
229
+ description: "Genre tags (e.g. ['R&B', 'Soul'])",
230
+ },
231
+ mood: {
232
+ type: "array",
233
+ items: { type: "string" },
234
+ description: "Mood tags (e.g. ['Uplifting', 'Reflective'])",
235
+ },
236
+ primary_artist: {
237
+ type: "string",
238
+ description: "Primary artist name",
239
+ },
240
+ primary_artist_id: {
241
+ type: "string",
242
+ description: "Primary artist person ID",
243
+ },
244
+ label: {
245
+ type: "string",
246
+ description: "Record label name",
247
+ },
248
+ spotify_track_uri: {
249
+ type: "string",
250
+ description: "Spotify track URI (e.g. spotify:track:0b8ZtRm9u3xSzRazABeHFF)",
251
+ },
252
+ spotify_url: {
253
+ type: "string",
254
+ description: "Spotify URL (e.g. https://open.spotify.com/track/...)",
255
+ },
256
+ album_name: {
257
+ type: "string",
258
+ description: "Album name",
259
+ },
260
+ album_release_date: {
261
+ type: "string",
262
+ description: "Album release date (ISO 8601, e.g. 2020-03-06)",
263
+ },
264
+ album_art_url: {
265
+ type: "string",
266
+ description: "URL to album artwork image",
267
+ },
268
+ track_number: {
269
+ type: "number",
270
+ description: "Track number on album",
271
+ },
272
+ upc: {
273
+ type: "string",
274
+ description: "Universal Product Code (album-level barcode)",
275
+ },
276
+ publisher_name: {
277
+ type: "string",
278
+ description: "Publisher name",
279
+ },
280
+ lyrics_language: {
281
+ type: "string",
282
+ description: "Language of lyrics (ISO 639-1, e.g. 'en')",
283
+ },
284
+ notes: {
285
+ type: "string",
286
+ description: "Internal notes",
287
+ },
288
+ },
289
+ required: ["id"],
290
+ additionalProperties: true,
291
+ },
292
+ },
293
+ executor: this.updateWork.bind(this),
294
+ },
295
+ {
296
+ definition: {
297
+ name: "pica_works_delete",
298
+ description: "Delete a musical work",
299
+ inputSchema: {
300
+ type: "object",
301
+ properties: {
302
+ id: {
303
+ type: "string",
304
+ description: "Work ID",
305
+ },
306
+ },
307
+ required: ["id"],
308
+ },
309
+ },
310
+ executor: this.deleteWork.bind(this),
311
+ },
312
+ {
313
+ definition: {
314
+ name: "pica_works_verify",
315
+ description: "Mark a work as verified",
316
+ inputSchema: {
317
+ type: "object",
318
+ properties: {
319
+ id: {
320
+ type: "string",
321
+ description: "Work ID",
322
+ },
323
+ },
324
+ required: ["id"],
325
+ },
326
+ },
327
+ executor: this.verifyWork.bind(this),
328
+ },
329
+ {
330
+ definition: {
331
+ name: "pica_works_search",
332
+ description: "Search works by title, ISWC, or other criteria. " +
333
+ "→ then: pica_works_get_full (full details), pica_work_completeness (gap check), pica_enrich_work (fill gaps)",
334
+ inputSchema: {
335
+ type: "object",
336
+ properties: {
337
+ query: {
338
+ type: "string",
339
+ description: "Search query",
340
+ },
341
+ limit: {
342
+ type: "number",
343
+ description: "Maximum number of results (default: 50)",
344
+ },
345
+ },
346
+ required: ["query"],
347
+ },
348
+ },
349
+ executor: this.searchWorks.bind(this),
350
+ },
351
+ {
352
+ definition: {
353
+ name: "pica_works_bulk_delete",
354
+ description: "Delete multiple works at once",
355
+ inputSchema: {
356
+ type: "object",
357
+ properties: {
358
+ ids: {
359
+ type: "array",
360
+ description: "Array of work IDs to delete",
361
+ items: {
362
+ type: "string",
363
+ },
364
+ },
365
+ },
366
+ required: ["ids"],
367
+ },
368
+ },
369
+ executor: this.bulkDeleteWorks.bind(this),
370
+ },
371
+ {
372
+ definition: {
373
+ name: "pica_works_get_full",
374
+ description: "Get FULL context for a work in a single call — the work record plus all its " +
375
+ "credits, recordings, audio files, agreements, completeness score, and registration " +
376
+ "status across PROs. Use this instead of making 6+ separate tool calls when you need " +
377
+ "to understand or reason about a work's complete state. " +
378
+ "→ then: pica_enrich_work (fill gaps), pica_credits_update (fix credits), pica_export_song_registration (register)",
379
+ inputSchema: {
380
+ type: "object",
381
+ properties: {
382
+ id: {
383
+ type: "string",
384
+ description: "Work ID",
385
+ },
386
+ },
387
+ required: ["id"],
388
+ },
389
+ },
390
+ executor: this.getWorkFull.bind(this),
391
+ },
392
+ ];
393
+ }
394
+ /**
395
+ * List works (server-side search and pagination)
396
+ */
397
+ async listWorks(args) {
398
+ const limit = args.limit || 50;
399
+ const result = await this.pica.works.search({
400
+ query: args.search,
401
+ limit,
402
+ });
403
+ let items = result.data;
404
+ // Client-side verified filter (not supported by API query params)
405
+ if (args.verified !== undefined) {
406
+ items = items.filter((work) => work.is_verified === args.verified);
407
+ }
408
+ return formatStructuredList(items, "work", {
409
+ total: result.total,
410
+ limit,
411
+ hasMore: result.hasMore,
412
+ });
413
+ }
414
+ /**
415
+ * Get work by ID
416
+ */
417
+ async getWork(args) {
418
+ const work = await this.pica.works.get(args.id);
419
+ // Enrich with ISRC prefix intelligence if work has ISRC
420
+ let prefix_intel = null;
421
+ if (work.isrc) {
422
+ prefix_intel = await this.pica.recordings.prefixLookup(work.isrc);
423
+ }
424
+ return formatAsText({ ...work, prefix_intel });
425
+ }
426
+ /**
427
+ * Create work
428
+ */
429
+ async createWork(args) {
430
+ const work = await this.pica.works.create(args);
431
+ // Generate completion hints for the newly created work
432
+ const hints = [];
433
+ if (work?.id) {
434
+ try {
435
+ const completeness = await this.pica.health.getWorkCompleteness(work.id);
436
+ hints.push(...mapGapsToHints(completeness?.gaps || completeness?.missing || []));
437
+ }
438
+ catch {
439
+ // Best-effort — don't fail the create
440
+ }
441
+ // Hint about AI disclosure if not set
442
+ if (!args.ai_disclosure) {
443
+ hints.push({
444
+ gap: "no_ai_disclosure",
445
+ suggestion: "Set AI disclosure — is this work human-made, AI-assisted, or AI-generated? (pica_works_update with ai_disclosure: none/assisted/generated)",
446
+ severity: "important",
447
+ });
448
+ }
449
+ }
450
+ return formatSuccess("Work created successfully", work, hints);
451
+ }
452
+ /**
453
+ * Update work
454
+ */
455
+ async updateWork(args) {
456
+ const { id, ...updates } = args;
457
+ const work = await this.pica.works.update(id, updates);
458
+ return formatSuccess("Work updated successfully", work);
459
+ }
460
+ /**
461
+ * Delete work
462
+ */
463
+ async deleteWork(args) {
464
+ await this.pica.works.delete(args.id);
465
+ return formatSuccess(`Work ${args.id} deleted successfully`);
466
+ }
467
+ /**
468
+ * Verify work
469
+ */
470
+ async verifyWork(args) {
471
+ const work = await this.pica.works.verify(args.id);
472
+ return formatSuccess("Work verified successfully", work);
473
+ }
474
+ /**
475
+ * Search works (server-side)
476
+ */
477
+ async searchWorks(args) {
478
+ const limit = args.limit || 50;
479
+ const result = await this.pica.works.search({
480
+ query: args.query,
481
+ limit,
482
+ });
483
+ return formatStructuredList(result.data, "work", {
484
+ query: args.query,
485
+ total: result.total,
486
+ limit,
487
+ hasMore: result.hasMore,
488
+ });
489
+ }
490
+ /**
491
+ * Bulk delete works
492
+ */
493
+ async bulkDeleteWorks(args) {
494
+ await this.pica.works.bulkDelete(args.ids);
495
+ return formatSuccess(`${args.ids.length} works deleted successfully`);
496
+ }
497
+ /**
498
+ * Get full work context bundle
499
+ */
500
+ async getWorkFull(args) {
501
+ const result = await this.pica.entityContext.getWorkFull(args.id);
502
+ const data = result;
503
+ const creditCount = data.credits?.length || 0;
504
+ const recordingCount = data.recordings?.length || 0;
505
+ const agreementCount = data.agreements?.length || 0;
506
+ const title = data.work?.title || args.id;
507
+ const score = data.work?.completeness_score;
508
+ const registeredPros = (data.registration || [])
509
+ .filter((r) => r.registered === true)
510
+ .map((r) => r.pro);
511
+ return formatSuccess(`"${title}" — ${creditCount} credits, ${recordingCount} recordings, ` +
512
+ `${agreementCount} agreements. ` +
513
+ `Completeness: ${score != null ? `${score}/100` : "not scored"}. ` +
514
+ `PROs registered: ${registeredPros.length > 0 ? registeredPros.join(", ") : "none"}.`, result);
515
+ }
516
+ }
517
+ //# sourceMappingURL=works.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"works.js","sourceRoot":"","sources":["../../src/tools/works.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * MCP-level pre-flight credit check with MPP inline payment fallback.
3
+ *
4
+ * Resolution order:
5
+ * 1. Check credit balance → sufficient → deduct at API layer → execute tool
6
+ * 2. Insufficient + MPP configured + credential → charge via MPP → execute + receipt
7
+ * 3. Insufficient + MPP configured + no credential → return -32042 payment challenge
8
+ * 4. Insufficient + MPP not configured → return insufficient_credits error with purchase hint
9
+ *
10
+ * Credit spending still happens at the API layer for path 1.
11
+ * MPP charges bypass credits entirely — the agent pays per-operation.
12
+ */
13
+ import type { PicaClient } from "../pica-sdk.js";
14
+ import type { ToolExecutor } from "../tools/index.js";
15
+ export declare const COST_MAP: Record<string, number>;
16
+ export declare function withCreditGate(pica: PicaClient, actionKey: string, operationName: string, executor: ToolExecutor): ToolExecutor;
17
+ //# sourceMappingURL=credit-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-gate.d.ts","sourceRoot":"","sources":["../../src/utils/credit-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,mBAAmB,CAAC;AASlE,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQ3C,CAAC;AAeF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,YAAY,GACrB,YAAY,CAgGd"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * MCP-level pre-flight credit check with MPP inline payment fallback.
3
+ *
4
+ * Resolution order:
5
+ * 1. Check credit balance → sufficient → deduct at API layer → execute tool
6
+ * 2. Insufficient + MPP configured + credential → charge via MPP → execute + receipt
7
+ * 3. Insufficient + MPP configured + no credential → return -32042 payment challenge
8
+ * 4. Insufficient + MPP not configured → return insufficient_credits error with purchase hint
9
+ *
10
+ * Credit spending still happens at the API layer for path 1.
11
+ * MPP charges bypass credits entirely — the agent pays per-operation.
12
+ */
13
+ import { chargeMpp, formatMppPrice, isMppConfigured, MPP_DEFAULT_CURRENCY, } from "./mpp.js";
14
+ export const COST_MAP = {
15
+ analysis_audio: 1,
16
+ analysis_lyrics: 1,
17
+ analysis_audio_identify: 3,
18
+ external_mlc_lookup: 1,
19
+ export_song_registration: 1,
20
+ export_industry_csv: 1,
21
+ export_catalog_asset_report: 5,
22
+ };
23
+ const GRACE_DEBT_LIMIT = -5;
24
+ /** Operation names for MPP charge descriptions */
25
+ const OPERATION_NAMES = {
26
+ analysis_audio: "Audio analysis",
27
+ analysis_lyrics: "Lyrics transcription",
28
+ analysis_audio_identify: "Audio identification",
29
+ external_mlc_lookup: "MLC enrichment",
30
+ export_song_registration: "Song registration export",
31
+ export_industry_csv: "Industry-ready export",
32
+ export_catalog_asset_report: "Catalog asset report",
33
+ };
34
+ export function withCreditGate(pica, actionKey, operationName, executor) {
35
+ const cost = COST_MAP[actionKey];
36
+ if (!cost)
37
+ return executor; // free or unknown — pass through
38
+ return async (args) => {
39
+ // --- Path 1: Check credit balance ---
40
+ let balanceInsufficient = false;
41
+ let available = 0;
42
+ try {
43
+ const balanceData = await pica.creditsBalance.getBalance();
44
+ available =
45
+ balanceData?.balance ??
46
+ balanceData?.data?.balance ??
47
+ 0;
48
+ if (available - cost >= GRACE_DEBT_LIMIT) {
49
+ // Sufficient credits — execute normally (API layer deducts)
50
+ return executor(args);
51
+ }
52
+ balanceInsufficient = true;
53
+ }
54
+ catch {
55
+ // Fail open on credit check errors — let the tool execute
56
+ return executor(args);
57
+ }
58
+ // --- Balance insufficient from here ---
59
+ // --- Path 2 & 3: Try MPP if configured ---
60
+ if (balanceInsufficient && isMppConfigured()) {
61
+ try {
62
+ // Extract _meta from args if present (threaded from MCP request)
63
+ const extra = args._meta ? { _meta: args._meta } : {};
64
+ const currency = args._mpp_currency || MPP_DEFAULT_CURRENCY;
65
+ const mppResult = await chargeMpp(cost, OPERATION_NAMES[actionKey] || operationName, currency, extra);
66
+ if (mppResult) {
67
+ if (mppResult.status === 402) {
68
+ // Path 3: No credential — return payment challenge
69
+ // The McpError will be thrown and handled by the MCP SDK
70
+ throw mppResult.challenge;
71
+ }
72
+ // Path 2: Payment succeeded — execute and attach receipt
73
+ const toolResult = await executor(args);
74
+ return mppResult.withReceipt(toolResult);
75
+ }
76
+ }
77
+ catch (error) {
78
+ // Re-throw MCP payment errors (they're the 402 challenge)
79
+ if (error &&
80
+ typeof error === "object" &&
81
+ "code" in error &&
82
+ error.code === -32042) {
83
+ throw error;
84
+ }
85
+ // MPP failed for other reason — fall through to insufficient_credits
86
+ }
87
+ }
88
+ // --- Path 4: No MPP or MPP failed — return insufficient_credits ---
89
+ const priceHint = isMppConfigured()
90
+ ? ` (${formatMppPrice(cost)} via inline payment)`
91
+ : "";
92
+ return {
93
+ content: [
94
+ {
95
+ type: "text",
96
+ text: JSON.stringify({
97
+ error: "insufficient_credits",
98
+ message: `${operationName} costs ${cost} pica credit${cost !== 1 ? "s" : ""}, but you only have ${available}. Purchase more credits to continue.${priceHint}`,
99
+ balance: available,
100
+ cost,
101
+ action: actionKey,
102
+ purchase_hint: "Use pica_credits_purchase to get a checkout link, or visit /settings (credits tab).",
103
+ fallback_url: "https://withpica.com/settings?tab=credits",
104
+ }, null, 2),
105
+ },
106
+ ],
107
+ isError: true,
108
+ };
109
+ };
110
+ }
111
+ //# sourceMappingURL=credit-gate.js.map