@withpica/mcp-server 2.11.0 → 2.22.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 (82) hide show
  1. package/CHANGELOG.md +617 -1
  2. package/dist/config.d.ts +9 -9
  3. package/dist/index.d.ts +1 -1
  4. package/dist/prompts/index.d.ts +66 -34
  5. package/dist/prompts/index.d.ts.map +1 -1
  6. package/dist/prompts/index.js +320 -607
  7. package/dist/prompts/index.js.map +1 -1
  8. package/dist/resources/index.d.ts +53 -53
  9. package/dist/server.d.ts +49 -49
  10. package/dist/tools/agreement-types.d.ts.map +1 -1
  11. package/dist/tools/agreement-types.js +14 -129
  12. package/dist/tools/agreement-types.js.map +1 -1
  13. package/dist/tools/agreements.d.ts.map +1 -1
  14. package/dist/tools/agreements.js +11 -109
  15. package/dist/tools/agreements.js.map +1 -1
  16. package/dist/tools/assets.d.ts.map +1 -1
  17. package/dist/tools/assets.js +17 -257
  18. package/dist/tools/assets.js.map +1 -1
  19. package/dist/tools/bulk.d.ts +7 -1
  20. package/dist/tools/bulk.d.ts.map +1 -1
  21. package/dist/tools/bulk.js +24 -2
  22. package/dist/tools/bulk.js.map +1 -1
  23. package/dist/tools/credits.d.ts.map +1 -1
  24. package/dist/tools/credits.js +27 -13
  25. package/dist/tools/credits.js.map +1 -1
  26. package/dist/tools/discovery.d.ts.map +1 -1
  27. package/dist/tools/discovery.js +8 -0
  28. package/dist/tools/discovery.js.map +1 -1
  29. package/dist/tools/enrichment.d.ts +47 -0
  30. package/dist/tools/enrichment.d.ts.map +1 -1
  31. package/dist/tools/enrichment.js +416 -19
  32. package/dist/tools/enrichment.js.map +1 -1
  33. package/dist/tools/index.d.ts +88 -72
  34. package/dist/tools/labels.d.ts +20 -0
  35. package/dist/tools/labels.d.ts.map +1 -0
  36. package/dist/tools/labels.js +47 -0
  37. package/dist/tools/labels.js.map +1 -0
  38. package/dist/tools/metadata.d.ts.map +1 -1
  39. package/dist/tools/metadata.js +37 -0
  40. package/dist/tools/metadata.js.map +1 -1
  41. package/dist/tools/multimedia.d.ts.map +1 -1
  42. package/dist/tools/multimedia.js +86 -11
  43. package/dist/tools/multimedia.js.map +1 -1
  44. package/dist/tools/notes.d.ts.map +1 -1
  45. package/dist/tools/notes.js +4 -1
  46. package/dist/tools/notes.js.map +1 -1
  47. package/dist/tools/people.d.ts +38 -38
  48. package/dist/tools/projects.d.ts +1 -0
  49. package/dist/tools/projects.d.ts.map +1 -1
  50. package/dist/tools/projects.js +188 -17
  51. package/dist/tools/projects.js.map +1 -1
  52. package/dist/tools/publishers.d.ts +15 -1
  53. package/dist/tools/publishers.d.ts.map +1 -1
  54. package/dist/tools/publishers.js +43 -9
  55. package/dist/tools/publishers.js.map +1 -1
  56. package/dist/tools/recordings.d.ts +30 -30
  57. package/dist/tools/recovery-hints.d.ts.map +1 -1
  58. package/dist/tools/recovery-hints.js +49 -0
  59. package/dist/tools/recovery-hints.js.map +1 -1
  60. package/dist/tools/releases.d.ts +14 -1
  61. package/dist/tools/releases.d.ts.map +1 -1
  62. package/dist/tools/releases.js +247 -36
  63. package/dist/tools/releases.js.map +1 -1
  64. package/dist/tools/search.d.ts +20 -20
  65. package/dist/tools/sessions.d.ts.map +1 -1
  66. package/dist/tools/sessions.js +42 -8
  67. package/dist/tools/sessions.js.map +1 -1
  68. package/dist/tools/settings.d.ts +1 -0
  69. package/dist/tools/settings.d.ts.map +1 -1
  70. package/dist/tools/settings.js +51 -1
  71. package/dist/tools/settings.js.map +1 -1
  72. package/dist/tools/share-links.d.ts.map +1 -1
  73. package/dist/tools/share-links.js +19 -53
  74. package/dist/tools/share-links.js.map +1 -1
  75. package/dist/tools/split-sheets.d.ts.map +1 -1
  76. package/dist/tools/split-sheets.js +3 -42
  77. package/dist/tools/split-sheets.js.map +1 -1
  78. package/dist/tools/team.d.ts.map +1 -1
  79. package/dist/tools/team.js +9 -4
  80. package/dist/tools/team.js.map +1 -1
  81. package/dist/tools/works.d.ts +38 -38
  82. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -11,6 +11,623 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [2.22.0] - 2026-04-18
15
+
16
+ ### Added
17
+
18
+ - **ADR-174 Phase 2 item 7 follow-up: `pica_projects_attach_works` (stdio).**
19
+ Closes the `work_ids` FIELD_NOT_WIRED gap on `pica_projects_create` /
20
+ `_update`. Pre-slice the MCP tools advertised `work_ids` but the admin
21
+ route silently dropped it — the route redirect message already pointed
22
+ agents at `POST /api/admin/projects/[id]/works`, but no MCP tool
23
+ exposed that path. The new tool accepts
24
+ `{ project_id, works: [{ work_id, project_day?, notes? }...] }` and
25
+ attaches each item via `ProjectsResource.attachWork` with per-item
26
+ result reporting (`attached[]`, `skipped[]` for already-linked,
27
+ `failed[]` for other errors). Registered in `lib/services/mcp-scopes.ts`
28
+ under `write:catalog`.
29
+
30
+ ### Changed
31
+
32
+ - **ADR-174 Phase 2 item 22: `pica_publishers_create` reshaped.** Pre-slice
33
+ the schema exposed only `{ name, ipi }` (2 fields) and the SDK's
34
+ `PublishersResource.create` hit a 404 — the admin route did not exist.
35
+ The companion slice 1 commit added `POST /api/admin/publishers`;
36
+ this slice reshapes the tool to match. All 8 audit-row-22
37
+ Add-candidates surfaced (`legal_name`, `country`, `isni`,
38
+ `publisher_type`, `wikidata_id`, `parent_publisher_id`,
39
+ `founded_date`, `headquarters`) plus the explicit `ipi → ipi_number`
40
+ rename. `parent_publisher_id` description steers agents at
41
+ `pica_publishers_query` to resolve the parent UUID. Required fields:
42
+ `name`, `ipi_number`. The route is idempotent on `ipi_number` — a
43
+ duplicate IPI returns the existing row with `already_existed: true`
44
+ instead of failing.
45
+
46
+ - **ADR-174 Phase 2 items 14+15: `pica_agreements_create` / `_update`
47
+ reshaped to consume `AGREEMENTS_WRITE_PROPERTIES` from
48
+ `@withpica/mcp-utils`.** Tool schemas now advertise all 13
49
+ Add-candidate columns from audit rows 14+15. Tool descriptions steer
50
+ agents toward `counterparty_org_id` (ADR-176 first-class-party) over
51
+ free-text `other_party_name` — use `pica_search_all` to resolve an
52
+ org name to an ID. `_update` description calls out that
53
+ counterparty_org_id changes require the linked-org check at the
54
+ route layer (orgLinkingService.areLinked). No tool signature change
55
+ otherwise; existing fields preserved.
56
+
57
+ ### Route-side companion (non-package, same slice)
58
+
59
+ - `app/api/admin/agreements/route.ts` POST and
60
+ `app/api/admin/agreements/[id]/route.ts` PATCH — phantom/unknown key
61
+ rejection via `AGREEMENT_POST_ALLOWED_FIELDS` /
62
+ `AGREEMENT_PATCH_ALLOWED_FIELDS` /
63
+ `AGREEMENT_WRITE_PHANTOM_REDIRECTS` in
64
+ `lib/services/agreements-write-constants.ts`. Pre-slice both routes
65
+ spread `body` straight into the Supabase insert/update — effectively
66
+ a wide-open write surface. Also surfaces and fixes pre-existing dark
67
+ code in the PATCH test file (3 tests were sending `name` and `type`
68
+ — phantom field names that silently dropped against `title` and
69
+ `agreement_type`).
70
+
71
+ - `app/api/admin/publishers/route.ts` POST (NEW) — publishers had no
72
+ admin route at all pre-slice, so `pica_publishers_create` and the
73
+ SDK's `PublishersResource.create` 404'd at runtime. Slice 1
74
+ (0ba4d400d) adds the route with phantom/unknown-field rejection via
75
+ `PUBLISHERS_POST_ALLOWED_FIELDS` / `PUBLISHERS_WRITE_PHANTOM_REDIRECTS`
76
+ in `lib/services/publishers-write-constants.ts`, idempotent
77
+ deduplication by `ipi_number`, FK pre-validation on
78
+ `parent_publisher_id`, and server-stamped provenance.
79
+
80
+ - **ADR-174 Phase 2 item 21: `pica_multimedia_create` reshaped.** Added
81
+ 15 real-column fields that were invisible to agents pre-ADR-174:
82
+ `credits`, `duration_seconds`, `collection_id`, `display_order`,
83
+ `is_featured`, `is_published`, `venue`, `event_name`,
84
+ `performance_date`, `setlist_position`, `sync_side`, and the external
85
+ identifier set (`spotify_url`, `spotify_track_uri`, `spotify_track_id`,
86
+ `youtube_url`, `youtube_video_id`, `soundcloud_url`, `thumbnail_url`).
87
+ Description now points agents at `POST /api/admin/multimedia/upload`
88
+ for file uploads and `pica_multimedia_link_youtube` for the YouTube
89
+ enrichment flow — the generic create surface is for external-URL
90
+ linking and performance-context metadata.
91
+
92
+ ### Route-side companion (non-package, same slice)
93
+
94
+ - `app/api/admin/multimedia/route.ts` POST — phantom/unknown key guard
95
+ via `MULTIMEDIA_POST_ALLOWED_FIELDS` /
96
+ `MULTIMEDIA_POST_PHANTOM_REDIRECTS` in
97
+ `lib/services/multimedia-write-constants.ts`. Redirects upload-flow
98
+ columns (s3*key, file_name, …) to `/api/admin/multimedia/upload`,
99
+ enrichment columns (youtube_view_count, spotify_popularity) to their
100
+ respective cascades, and scanner columns (virus_scan*\*) to the
101
+ scanner flow. Also closes a latent privilege-escalation path: pre-slice
102
+ the route overwrote `body.user_id` with the authenticated session's
103
+ id, but a caller could still _attempt_ to pass `user_id` (silently
104
+ overwritten). The guard now 400s on `user_id` / `organisation_id`
105
+ injection attempts with a clear PHANTOM_FIELD message.
106
+
107
+ - **ADR-174 Phase 2 item 13: `pica_sessions_create` reshaped.** Dropped
108
+ `additionalProperties: true` per Decision 2. Added 6 previously-missing
109
+ real columns from audit row 13 as explicit Zod properties:
110
+ `description`, `timezone`, `is_all_day`, `location_url`, `recording_id`,
111
+ `status` (enum: scheduled / in_progress / completed / cancelled), plus
112
+ the `metadata` jsonb bag and the `participants` relational array
113
+ (already handled by the service but undocumented in the tool surface).
114
+ `recurrence_rule` deferred — the service's `CreateSessionParams` type
115
+ needs to accept it first (tracked in the route-guard PHANTOM_REDIRECT
116
+ entry).
117
+
118
+ ### Route-side companion (non-package, same slice)
119
+
120
+ - `app/api/admin/sessions/route.ts` POST now reads `body.status` and
121
+ `body.metadata` (pre-slice silently dropped) and 400s on phantom /
122
+ unknown keys via `SESSION_POST_ALLOWED_FIELDS` /
123
+ `SESSION_POST_PHANTOM_REDIRECTS` in
124
+ `lib/services/sessions-write-constants.ts`.
125
+
126
+ - **ADR-174 Phase 2 item 20: `pica_share_links_create` reshaped to
127
+ consume `SHARE_LINKS_WRITE_PROPERTIES` from `@withpica/mcp-utils`.**
128
+ Tool schema now advertises all 13 add-candidate columns from audit
129
+ row 20 that were previously invisible to agents (access_type,
130
+ allowed_person_ids, allow_comments, allow_view_collaborators,
131
+ allow_view_financials, notify_on_access, watermark_audio,
132
+ sent_to_emails, playlist_name, allow_streaming, include_all_files,
133
+ included_file_ids, description). Executor widened to pass every
134
+ caller-provided property through to the SDK / admin route — the
135
+ route-layer allow-list (slice 1) rejects anything outside the
136
+ contract. `password` remains the canonical plain-text input; the
137
+ route hashes to `password_hash`.
138
+
139
+ - **ADR-174 Phase 2 items 16+17: `pica_agreement_types_create` / `_update`
140
+ reshaped to consume `AGREEMENT_TYPES_WRITE_PROPERTIES` from
141
+ `@withpica/mcp-utils`.** Dropped the inlined property map in favour of
142
+ the shared module that documents per-branch applicability. Phantom
143
+ fields `title`, `description`, `points_percentage`, `recoupment_terms`,
144
+ `rights_assigned` removed from the schema (agents sending them now fail
145
+ fast at the admin route guard with a `PHANTOM_FIELD` redirect pointing
146
+ at the canonical column or resolution path). Tool descriptions updated
147
+ to truthfully list the required fields per branch (template needs
148
+ `name` + `category` + `templateText`; producer needs `producer_id` +
149
+ `royalty_points` + `deliverables` + `work_id`|`recording_id`;
150
+ work_for_hire needs `contractor_id` + `contractor_role` + `fee_amount`
151
+ - `services_description` + `work_id`|`recording_id`). Tool description
152
+ for `_update` now calls out that PATCH on producer_agreements and
153
+ work_for_hire_agreements is action-only — the generic update path has
154
+ no live field-update surface on those two branches until a follow-up
155
+ slice promotes the action-based PATCH handlers to accept field
156
+ updates.
157
+
158
+ ### Added
159
+
160
+ - **ADR-179 Phase 1: `pica_resolve_work` (stdio).** Outcome-shaped
161
+ resolver that fans a work out across every eligible enrichment source
162
+ in one call. Replaces the five `pica_enrich_work_*` tools' role at
163
+ the agent layer. Returns `applied[]` / `proposals[]` / `errors[]` /
164
+ `recovery_hints[]`. `isError` is set only when every source that ran
165
+ errored — partial failure is a non-error receipt. Credit + billing
166
+ gates wire through the `external_resolver_call` action key.
167
+ - **ADR-179 Phase 2: `pica_resolve_person` (stdio).** Person-side
168
+ resolver mirroring `pica_resolve_work`. Sources are narrower —
169
+ `isni` | `musicbrainz` — covering the identity-graph cascade rules
170
+ (ISNI→Wikidata and MBID→Wikidata crosswalks plus their downstream
171
+ awards / biography enrichment). Same output shape, same isError
172
+ semantics, same credit-gate action key as the work resolver.
173
+ Registered in `lib/services/mcp-scopes.ts` under `write:people` and
174
+ listed in the layered-discovery `enrichment` category so
175
+ `pica_discover` surfaces it above the deprecated
176
+ `pica_people_enrich_*` pair.
177
+
178
+ ### Deprecated
179
+
180
+ - **`pica_enrich_work_mlc`, `pica_enrich_work_musicbrainz`,
181
+ `pica_enrich_work_discogs`, `pica_enrich_work_spotify`,
182
+ `pica_enrich_work_youtube`.** All five now return
183
+ `TOOL_DEPRECATED` (jsonrpc code -32070) with a suggested-call
184
+ payload pointing at `pica_resolve_work` with the correct `sources`
185
+ narrowing. Tool definitions stay registered so `tools/list` and
186
+ `pica_tool_details` can still surface them with a migration hint for
187
+ one minor version — removal scheduled for the next minor after
188
+ ADR-179 Phase 4's publish.
189
+ - **`pica_people_enrich_isni`, `pica_people_enrich_musicbrainz`.**
190
+ Both now return `TOOL_DEPRECATED` (jsonrpc code -32070) with a
191
+ suggested-call payload pointing at
192
+ `pica_resolve_person(sources: ['isni' | 'musicbrainz'])`. Tool
193
+ definitions stay registered until the next minor; same one-minor-
194
+ version deprecation window as the work-side five.
195
+
196
+ ### Changed
197
+
198
+ - `pica_tool_details` responses for the five deprecated work tools
199
+ now carry a `TOOL_DEPRECATED` entry in `recovery_hints` as the first
200
+ item. Existing `NO_MATCH` / `MISSING_INPUT` hints are kept behind
201
+ it — they are dead code today but stay in the registry until tool
202
+ removal so downstream consumers don't see a mid-version
203
+ disappearance.
204
+ - Same treatment applied to the two deprecated person tools:
205
+ `pica_people_enrich_isni` and `pica_people_enrich_musicbrainz` each
206
+ get a `TOOL_DEPRECATED` recovery hint prepended to their existing
207
+ `NO_MATCH` entry.
208
+
209
+ ## [2.22.0] — 2026-04-16
210
+
211
+ ### Changed
212
+
213
+ - **ADR-174 Phase 2 item 10 (recording_splits): reshape
214
+ `pica_recording_splits_create`.** Adopts the shared
215
+ `RECORDING_SPLITS_WRITE_PROPERTIES` from `@withpica/mcp-utils@1.4.0`,
216
+ dropping `additionalProperties: true` per Decision 2. All 9 audit-
217
+ Keep fields now enumerated as explicit Zod properties — no phantom
218
+ additions, no renames. Description-level hint on `role` replaced
219
+ with a proper `enum` array matching the route's validRoles allow-
220
+ list. Schema is now byte-identical to `@withpica/mcp-server-business`
221
+ (both consume the shared module) — pre-slice they were independent
222
+ byte-divergent-risk copies.
223
+
224
+ ### Route-side companion (non-package, same slice)
225
+
226
+ - `app/api/admin/recordings/[id]/splits/route.ts` POST — UNKNOWN_FIELD
227
+ guard runs before the required-field check so misspelled keys fail
228
+ fast with the field name. See the slice commit.
229
+
230
+ ## [2.21.0] — 2026-04-16
231
+
232
+ ### Fixed
233
+
234
+ - **ADR-174 Phase 2 item 24 (team): `pica_team_update_role` now actually
235
+ updates role.** Pre-ADR-174 the tool was named `_update_role` but its
236
+ Zod schema only accepted `permissions` — the `role` field was missing
237
+ entirely. The admin PATCH route at `/api/admin/team/[id]` hard-
238
+ destructured `{ permissions }` and silently dropped every other
239
+ field, so even if an agent hand-crafted a call with `role` the DB
240
+ write would not happen. Audit row 24 flagged this as "Add `role`, or
241
+ rename the tool." Fixed by adding `role: string` to the MCP Zod
242
+ schema, widening the route to build the update object from whichever
243
+ of `role` / `permissions` are provided, and making the old
244
+ "permissions required" check accept "at least one of role or
245
+ permissions." `id` stays required; `role` and `permissions` are now
246
+ both optional but at least one must be set.
247
+
248
+ ### Route-side companion (non-package, same slice)
249
+
250
+ - `app/api/admin/team/[id]/route.ts` PATCH — phantom/unknown key
251
+ rejection via `TEAM_MEMBERSHIP_PATCH_ALLOWED_FIELDS` (allow-list of
252
+ `permissions` + `role`), error message updated from "permissions
253
+ required" to "at least one of permissions or role is required", and
254
+ "failed to update permissions" to "failed to update team membership"
255
+ (now-generic — it updates role too).
256
+
257
+ ## [2.20.0] — 2026-04-16
258
+
259
+ ### Changed
260
+
261
+ - **ADR-174 Phase 2 item 7 (projects): reshape `pica_projects_create` /
262
+ `pica_projects_update` Zod schemas.** Exposed 9 Add-candidate fields
263
+ from audit row 18 that were already plumbed end-to-end through the
264
+ route and service but invisible to agents via tool discovery:
265
+ `start_date`, `end_date`, `location_name`, `location_address`,
266
+ `location_url`, `virtual_url`, `is_open`, `max_participants`, `status`
267
+ (enum: draft / scheduled / active / completed / cancelled). Also
268
+ surfaced the route-level `generate_invite_code` flag and the
269
+ freeform `metadata` jsonb object. Dropped `work_ids` from both
270
+ schemas — the pre-ADR-174 tool advertised `work_ids` but the admin
271
+ POST / PATCH routes never routed it to the `project_works` junction
272
+ (see commit `edf890a24` for the route-side FIELD_NOT_WIRED rejection
273
+ and redirect message pointing at
274
+ `POST /api/admin/projects/[id]/works`). The `project_type`
275
+ description replaces the pre-ADR-174 "album, ep, compilation, single,
276
+ mixtape" hint (none of which are valid backend values) with the
277
+ actual convention: writing_camp, recording_session, production,
278
+ mixing, mastering, retreat, other.
279
+
280
+ ### Route-side companion (non-package, same slice)
281
+
282
+ - `app/api/admin/projects/route.ts` POST and
283
+ `app/api/admin/projects/[id]/route.ts` PATCH — phantom/unknown key
284
+ rejection with `FIELD_NOT_WIRED` redirect for `work_ids`. See commit
285
+ `edf890a24`.
286
+
287
+ ## [2.19.0] — 2026-04-16
288
+
289
+ ### Added
290
+
291
+ - **ADR-178: `pica_enrichment_propose` stdio tool.** New agentic write
292
+ tool that files enrichment proposals sourced from open-web research
293
+ (Audiomack, Songdata, MusicBrainz page, label portals, artist bios,
294
+ etc.) rather than from PICA's structured cascade. Every proposed
295
+ field must cite at least one source URL — `sources[].fields` arrays
296
+ form the trust moat, and the server rejects uncited claims with
297
+ `code: MISSING_SOURCE`. Source type routes the proposal as
298
+ `source = 'agent_research'`, `rule_id = 'agent_research'` on the
299
+ existing `enrichment_proposals` table (no new queue, no new review
300
+ tools — reuses `pica_enrichment_proposals_list` / `_apply` /
301
+ `_reject` from `2.10.0`).
302
+
303
+ Tool description carries ADR-178 Decision 3 language verbatim: when
304
+ the user is in-session, the agent asks for approval directly and
305
+ calls `pica_enrichment_proposal_apply` after confirmation — the
306
+ dashboard card is the receipt, not the workflow. This shapes agent
307
+ behaviour in-context without needing a new code path for "in-
308
+ session approval".
309
+
310
+ Wrapped in `withBillingGate` and (via
311
+ `@withpica/mcp-utils@1.3.0`) `withCreditGate` under the new
312
+ `enrichment_propose` action key. Credit gating is telemetric only
313
+ while ADR-162 keeps the subscription gate on; the wrap is already
314
+ in place so re-enabling billing doesn't need a tool-surface change.
315
+
316
+ ### Fixed
317
+
318
+ - **ADR-178 slice 1b regression caught in smoke test:** agent-research
319
+ proposals whose `proposed_fields` cite columns that don't exist on
320
+ the target table (tempo_bpm, musical_key, producers — the Heinzmann
321
+ transcript's fields, not columns on `works`) used to 500 with a
322
+ Postgres "column does not exist" error because the service built a
323
+ column-scoped `SELECT` from the proposed keys. Fix snapshots the
324
+ full live row and builds `current_fields` from the intersection of
325
+ proposed keys and actual columns. Unknown keys now land as pending
326
+ proposals with an empty baseline instead of crashing the request.
327
+ Apply path for unknown-column fields is a separate open question on
328
+ the ADR (see Open Question 5).
329
+
330
+ ## [2.18.0] — 2026-04-16
331
+
332
+ ### Changed
333
+
334
+ - **ADR-174 Phase 2 item 6: reshape `pica_credits_update` Zod schema.**
335
+ Dropped phantom `publisher_name` and `publisher_ipi` properties —
336
+ `work_credits` has no columns for either. Agents now resolve a
337
+ publisher name or IPI to a UUID via `pica_publishers_query` (or
338
+ create one via `pica_publishers_create`) and pass the result as
339
+ `publisher_id`. Added three audit "Add candidate" columns to the
340
+ per-credit-object shape: `is_primary` (boolean), `notes` (string),
341
+ `attestation_status` (enum: pending / attested / disputed /
342
+ declined). `attested_at` / `attested_by` remain service-managed.
343
+ Description refresh calls out `credit_type` as the canonical column
344
+ name stored behind the `role` alias and `writer_split_percentage`
345
+ behind `splits`. No required-field change — `person_id`, `role`,
346
+ `splits` stay required.
347
+
348
+ ### Route-side companion (non-package, same slice)
349
+
350
+ - `app/api/admin/works/[id]/credits/route.ts` POST — phantom/unknown
351
+ key rejection on each `credits[i]` element with field name + index
352
+ in the error payload, plus a mirror-fill step that normalises
353
+ `role` ↔ `credit_type` and `splits` ↔ `writer_split_percentage` so
354
+ callers sending either spelling flow through. See commit
355
+ `dbfb098ae` for the server-side guard.
356
+
357
+ ### Not covered by this slice
358
+
359
+ - `work_collaborators` (publishing-side POST at
360
+ `app/api/admin/works/[id]/collaborators/route.ts`) was not in the
361
+ ADR-174 audit — the MCP tool's `updateCollaborators` SDK hop hits
362
+ that route for writer/composer/lyricist/arranger roles today and
363
+ inherits a separate column set. Tracked as a follow-up slice.
364
+
365
+ ## [2.17.0] — 2026-04-16
366
+
367
+ ### Changed
368
+
369
+ - **ADR-174 Phase 2 item 5: reshape `pica_physical_assets_create` and
370
+ `pica_physical_assets_update` Zod schemas.** Adopted the shared
371
+ `PHYSICAL_ASSETS_WRITE_PROPERTIES` from `@withpica/mcp-utils@1.2.0`,
372
+ dropped `additionalProperties: true` on both tools, and moved 11
373
+ phantom top-level fields (`current_valuation`, `valuation_currency`,
374
+ `valuation_source`, `valuation_date`, `valuation_notes`,
375
+ `reverb_listing_url`, `ebay_item_url`, `insured`,
376
+ `insurance_provider`, `insurance_policy_number`, `insurance_coverage`)
377
+ off the top-level surface. Agents set these via
378
+ `external_references: { current_valuation: 1500, insurer: "ACME", ... }`
379
+ per the ADR-174 Open Decision 1 (2026-04-14) resolution. Two fields
380
+ were renamed at the jsonb layer: `insurance_provider → insurer`,
381
+ `insurance_coverage → insured_value`. `asset_type`, `condition`,
382
+ `acquisition_method`, `license_type`, and `status` gained proper
383
+ `enum` arrays matching the underlying `physical_assets_*_check` CHECK
384
+ constraints — pre-reshape they were loose strings with the enum
385
+ hinted in the description (so callers could pass `studio_equipment`
386
+ at the MCP layer and get a 500 from the CHECK constraint at the DB
387
+ layer).
388
+ - **No description lie.** Both tool descriptions now explicitly name
389
+ `external_references` as the home for valuation/insurance/DSP URL
390
+ details rather than the pre-ADR-174 "tracks … valuation, photos,
391
+ insurance, and status" claim that the schema couldn't honour.
392
+
393
+ ### Route-side companion (non-package, same slice)
394
+
395
+ - `app/api/admin/assets/route.ts` POST and
396
+ `app/api/admin/assets/[id]/route.ts` PATCH — phantom/unknown key
397
+ rejection with redirect messages (400 + `PHANTOM_FIELD` /
398
+ `UNKNOWN_FIELD` error codes). See commit `ced46b889` for the
399
+ server-side guard.
400
+
401
+ ## [2.16.0] — 2026-04-15
402
+
403
+ ### Added
404
+
405
+ - **ADR-173: five release-track tools.** Closes the gap flagged by two
406
+ independent external MCP reviewers on 2026-04-14 ("release layer looks
407
+ shallow"). New tools on the stdio transport:
408
+ - `pica_releases_attach_track` — attach a recording and/or work at a
409
+ specific `(disc_number, track_number)`. Idempotent on position.
410
+ At least one of `recording_id` / `work_id` is required.
411
+ - `pica_releases_list_tracks` — list tracks in `(disc, track)` order
412
+ with inlined title/artist/ISRC/duration from the linked recording
413
+ and work.
414
+ - `pica_releases_detach_track` — soft-confirmation detach by position
415
+ (preview without `confirm:true`, delete with).
416
+ - `pica_releases_reorder_tracks` — transactional positional reorder
417
+ via the `reorder_release_tracks_atomic` Postgres RPC. Rejects
418
+ duplicate positions in the payload before any DB write.
419
+ - `pica_releases_attach_recording_with_work` — compound workflow that
420
+ auto-pulls the recording's linked work onto the new track row.
421
+
422
+ ### Changed
423
+
424
+ - **`pica_works_inspect` and `pica_recordings_inspect` gain a `releases`
425
+ section.** Lazy (only fetched when requested). Returns every release
426
+ the entity appears on with its track position. Answers "which albums
427
+ is this master on?" in one call — previously unanswerable via MCP.
428
+
429
+ ### Fixed
430
+
431
+ - **`pica_releases_list_tracks` 500 on every call.** Pre-merge E2E
432
+ caught two latent bugs in the `listTracks` service query: a missing
433
+ FK `release_tracks.recording_id → recordings(id)` (PostgREST could
434
+ not resolve the `recording:recordings(...)` embed) and a
435
+ `duration_seconds` column reference where the live column is
436
+ `duration_ms`. Fixed in migration
437
+ `20260415_01_adr173_fix_release_tracks_recording_fk.sql` +
438
+ a rename in `lib/services/releases.ts`. The migration also NULLs 85
439
+ orphan `recording_id` values on production left behind by the
440
+ 2026-04-04 soundslikefez duplicate-works cleanup.
441
+
442
+ ### Note on version number
443
+
444
+ This release would have been `2.15.0` per the original ADR-173
445
+ implementation record, but `2.15.0` was taken on `develop` by the
446
+ ADR-174 Phase 2 item 4 slice while the ADR-173 fix commits were in
447
+ flight. Bumped to `2.16.0` to keep the published package timeline
448
+ linear.
449
+
450
+ ## [2.15.0] — 2026-04-15
451
+
452
+ ### Changed
453
+
454
+ - **ADR-174 Phase 2 item 4: `pica_people_create` / `pica_people_update`
455
+ schema reconciliation.** Introduced `PEOPLE_WRITE_PROPERTIES` as the
456
+ canonical source of truth for the people write surface — every
457
+ property maps to a real column on either `public.people` or
458
+ `public.person_enrichment`. `additionalProperties: true` is off;
459
+ unknown keys 400 at the HTTP layer (see develop commit
460
+ `fbea9e2a3`).
461
+ - **Satellite-routing made explicit.** Eleven fields remain in the
462
+ schema but their descriptions now name `person_enrichment` as the
463
+ write target: external identifiers (`isni`, `musicbrainz_id`,
464
+ `wikidata_id`, `discogs_artist_id`, `deezer_artist_id`) and
465
+ biographical data (`date_of_birth`, `gender`, `nationality`,
466
+ `birth_place`, `instruments`, `career_start_year`). The service
467
+ fans these out through `syncPersonEnrichmentSatellite`. Correction
468
+ to the original audit (row 7) landed in ADR-174's Corrections
469
+ block: six of these fields were classified as "Remove — no column
470
+ on people", which missed the satellite hop. They are not phantom
471
+ writes, and subsequent slices must audit satellite write paths
472
+ before classifying any field as phantom.
473
+ - **Twelve add-candidates surfaced** (audit row 7 "Missing writable
474
+ columns"): `middle_name`, `person_type`, `company`, `position`,
475
+ `territory`, `social_media`, `emails`, `pro_name`,
476
+ `pro_member_number`, `mcps_member_number`, `relationship_strength`,
477
+ `email_preferences`. All verified against `public.people` columns
478
+ 2026-04-15 (project `fwgcmjhlwevdnxgqmkmh`).
479
+ - **Deprecated duplicates rejected.** `type` (deprecated dup of
480
+ `person_type`) and `role` (deprecated singular of `roles`) are
481
+ now 400 PHANTOM_FIELD with a redirect message naming the canonical
482
+ column. Both DB columns still exist as unused dead space —
483
+ removing them is out of scope and scheduled for ADR-165-style
484
+ cleanup.
485
+ - **Description lies removed.** The audit (row 8) flagged
486
+ `pica_people_update` description as "Additional fields are also
487
+ accepted" with no enumeration. That sentence is gone from both
488
+ `create` and `update` descriptions.
489
+
490
+ ### Breaking
491
+
492
+ - Callers that were passing the deprecated `type` / `role`
493
+ duplicates now get a 400 with a redirect hint — previously the
494
+ keys were silently dropped by the ORM. Same failure-mode calculus
495
+ as the works / recordings slices — the writes were already
496
+ failing, now they fail visibly.
497
+ - Callers that were passing arbitrary unlisted keys now get a 400 —
498
+ previously `additionalProperties: true` let them through and the
499
+ ORM dropped them silently. Zero rows observed in `people.metadata`
500
+ jsonb for any of the pre-existing phantom keys (verified during
501
+ ADR-174 Phase 1 2026-04-14).
502
+
503
+ ## [2.14.0] — 2026-04-14
504
+
505
+ ### Changed
506
+
507
+ - **ADR-174 Phase 2: `pica_recordings_create` / `pica_recordings_update`
508
+ schema reconciliation.** Introduced `RECORDING_WRITE_PROPERTIES` as
509
+ the canonical source of truth for the recordings write surface —
510
+ every property maps to a real column on `public.recordings`. Added
511
+ thirteen fields the DB exposes that the tool was hiding:
512
+ `duration_ms`, `preview_url`, `album_art_url`, `spotify_url`,
513
+ `spotify_track_uri`, `spotify_track_id`, `youtube_video_id`,
514
+ `youtube_url`, `apple_music_url`, `deezer_track_id`,
515
+ `mlc_recording_id`, `mlc_song_code`, `isrc_prefix`. The
516
+ `version_type` field is now enum-restricted to the ADR-166 values
517
+ (`master`, `alternate_master`, `music_video`, `lyric_video`,
518
+ `live_performance`, `acoustic`, `remix`, `cover`, `alternate`),
519
+ matching the `recordings_version_type_check` DB constraint.
520
+ - **`pica_recordings_create` default `version_type` changed from
521
+ `"original"` to `"master"`.** Pre-fix the executor defaulted to
522
+ `"original"`, which is not a valid version_type — every call without
523
+ an explicit type tripped the recording-type CHECK constraint and
524
+ surfaced as a 500 from the service. `"master"` is the DB-level
525
+ default and the canonical ADR-166 value.
526
+ - **Title rename made explicit.** `recording_title` is the canonical
527
+ column on `public.recordings`. The tool keeps `title` as an input
528
+ alias for ergonomics; the schema now declares both fields with the
529
+ rename called out in their descriptions, instead of relying on
530
+ `additionalProperties: true` to hide the translation.
531
+ - Tool descriptions now steer album metadata (`album_name`,
532
+ `album_release_date`, `upc`, `track_number`) to
533
+ `pica_releases_create/update`, ISWCs to `pica_works_create/update`,
534
+ and label metadata to `pica_releases_*.label_organization_id` via
535
+ `pica_labels_query`. `duration_seconds` is explicitly named as the
536
+ works convention; `recordings` carries `duration_ms`.
537
+
538
+ ### Removed
539
+
540
+ - **ADR-174 Phase 2: seven phantom fields rejected on
541
+ `pica_recordings_create` / `pica_recordings_update`.** The Zod schema
542
+ no longer accepts them and `additionalProperties: true` is gone:
543
+ `album_name`, `album_release_date`, `upc`, `track_number`, `label`,
544
+ `duration_seconds`, `iswc` — none of these corresponded to columns on
545
+ `recordings`. The HTTP route at `POST/PATCH /api/admin/recordings[/id]`
546
+ now 400s on any of these keys with a redirect message naming the
547
+ correct tool (commit `cffa6f947`).
548
+
549
+ ## [2.13.1] — 2026-04-14
550
+
551
+ ### Changed
552
+
553
+ - **ADR-174 Phase 2: `pica_works_bulk_update.updates` schema gated on
554
+ `WORK_WRITE_PROPERTIES`.** The bulk tool was the last write-path
555
+ surface that still accepted any key — `updates: { type: "object" }`
556
+ with no property list (audit row 25). Now validates against the same
557
+ canonical schema as `pica_works_update`: phantom keys (label, upc,
558
+ album_name, …) and arbitrary unlisted keys fail fast with a
559
+ descriptive `VALIDATION_ERROR` before the SDK is called. One bad key
560
+ invalidates the whole batch — no partial writes.
561
+
562
+ ## [2.13.0] — 2026-04-14
563
+
564
+ ### Changed
565
+
566
+ - **ADR-174 Phase 2: `pica_works_create` / `pica_works_update` schema
567
+ reconciliation.** Introduced `WORK_WRITE_PROPERTIES` as the canonical
568
+ source of truth for the works write surface — every property maps to
569
+ a real column on `public.works`. Added five fields the DB exposes
570
+ that the tool was hiding: `tempo`, `key`, `display_artist`,
571
+ `published`, `tunecode`. Tool descriptions now steer album/release
572
+ metadata (`album_name`, `album_art_url`, `track_number`, `upc`,
573
+ `spotify_url`) to `pica_releases_create/update` and label metadata to
574
+ `pica_releases_*.label_organization_id` via `pica_labels_query`.
575
+
576
+ ### Removed
577
+
578
+ - **ADR-174 Phase 2: seven phantom fields removed from
579
+ `pica_works_create` / `pica_works_update`.** `label`, `spotify_url`,
580
+ `album_name`, `album_release_date`, `album_art_url`, `track_number`,
581
+ `upc` — none of these corresponded to columns on `works`. The HTTP
582
+ route at `POST/PATCH /api/admin/works[/id]` now 400s on any of these
583
+ keys with a redirect message naming the correct tool (commit
584
+ `9d68b16b1`). Previously they routed silently into the
585
+ `work_album_metadata` / `work_spotify_data` satellites that ADR-165
586
+ marked as dead — a write succeeded but no reader could find the
587
+ value.
588
+ - **ADR-174 Phase 2: `additionalProperties: true` removed from both
589
+ works write schemas.** The tool no longer silently accepts arbitrary
590
+ keys; unknown keys surface as validation errors. Description lies
591
+ about `available_for_licensing`, `vocal_type`, `energy`,
592
+ `danceability` also removed — those fields live on satellite tables
593
+ and are not exposed through MCP.
594
+
595
+ ## [2.12.0] — 2026-04-14
596
+
597
+ ### Added
598
+
599
+ - **ADR-174 Phase 2: `pica_labels_query` tool** — read-only resolution of
600
+ label names to `organisations.id`. Returns label organisations
601
+ (`org_type='label'`) whose name or display_name matches the substring
602
+ query, for use as `releases.label_organization_id` via
603
+ `pica_releases_create` / `pica_releases_update`. `query` and `limit`
604
+ both optional; limit defaults to 50, max 100. Category: catalog.
605
+ Annotations: `readOnlyHint: true`.
606
+
607
+ ### Changed
608
+
609
+ - **ADR-174 Phase 2: `pica_releases_create` / `pica_releases_update`
610
+ schema reconciliation.** Input schemas now expose the nine ADR-174
611
+ Decision 3 fields that `releases` actually stores:
612
+ `label_organization_id`, `distributor_organization_id`,
613
+ `pre_release_date`, `artwork_url`, `spotify_album_uri`, `spotify_url`,
614
+ `apple_music_url`, `other_urls`, `notes`. Tool descriptions now
615
+ direct agents to call `pica_labels_query` (new) or `pica_search_all`
616
+ to resolve a label/distributor name to an organisation ID before
617
+ writing.
618
+
619
+ ### Removed
620
+
621
+ - **ADR-174 Phase 2: freetext `label` removed from
622
+ `pica_releases_create` / `pica_releases_update`.** The field never
623
+ corresponded to a real column on `releases` — the DB models labels
624
+ via `label_organization_id` FK. Agents must now resolve a label name
625
+ to an organisation ID (via `pica_labels_query`) instead of passing a
626
+ string. Pre-fix behaviour: tool schema accepted `label`, service
627
+ propagated it to the DB, the DB rejected it as `42703 column does not
628
+ exist`, every call 500'd. No working integrations could have relied
629
+ on this — the change is strictly a fix, not a break.
630
+
14
631
  ## [2.11.0] — 2026-04-13
15
632
 
16
633
  ### Changed
@@ -31,7 +648,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
31
648
  `audit-credits`, `new-catalog-setup`, `register-my-works`,
32
649
  `prepare-for-sync`. Functionality folded into new skills —
33
650
  see design spec for mapping.
34
-
35
651
  - `workspace-autopilot` now routes through the full journey sequence
36
652
  (identity → catalog → audio → gaps → collaborators → ownership →
37
653
  notifications → exports) instead of the old 5-condition router.
package/dist/config.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  export interface ServerConfig {
2
- picaApiKey: string | null;
3
- picaApiUrl: string;
4
- serverName: string;
5
- version: string;
6
- debug: boolean;
7
- lobbyMode: boolean;
8
- credentialsPath: string;
9
- discoveryMode: boolean;
2
+ picaApiKey: string | null;
3
+ picaApiUrl: string;
4
+ serverName: string;
5
+ version: string;
6
+ debug: boolean;
7
+ lobbyMode: boolean;
8
+ credentialsPath: string;
9
+ discoveryMode: boolean;
10
10
  }
11
11
  export declare function loadConfig(): ServerConfig;
12
12
  export declare function validateConfig(config: ServerConfig): void;
13
- //# sourceMappingURL=config.d.ts.map
13
+ //# sourceMappingURL=config.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
- //# sourceMappingURL=index.d.ts.map
3
+ //# sourceMappingURL=index.d.ts.map