@withpica/mcp-sdk 3.13.0 → 3.15.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.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [3.15.0] - 2026-09-08
15
+
16
+ ### Added
17
+
18
+ - `selections` resource (ADR-319 saved catalog selections) — `list`,
19
+ `create`, `inspect` (id + optional `resolve`/`limit`/`offset`), `update`,
20
+ `delete` over `/admin/selections`. Backs the new `pica_selections_*` MCP
21
+ tools (Task 8).
22
+ - `health.catalogHealthFix` accepts an optional `selections` array
23
+ (`{ actionId, chosenPersonId }`) — the human choice a `resolve_person`
24
+ action needs. Type-only on this side (the body is forwarded as-is); the
25
+ route validates it.
26
+
27
+ PR #2118 (`fix/avatar-import-path-2026-09-03`) is merged into the release branch, so its changes ship in the version below; publish in the order mcp-utils → mcp-sdk → mcp-server.
28
+
29
+ ## [3.14.0] - 2026-09-04
30
+
31
+ ### Added
32
+
33
+ - `MultimediaResource.importFromUrl` returns `MultimediaImportResult` (item + `via`, `source_url`, `profile_image`, `work_link` receipts) via `requestWithEnvelope` and accepts `person_id` (PR #2118, merged into this release).
34
+ - `requestWithEnvelope<T, TRest>` keeps top-level envelope fields (PR #2118).
35
+
36
+ - **`offset` on `AudioFilesResource.list()`, `NotesResource.list()`,
37
+ `SessionsResource.list()`** — companions to the mcp-server `offset`
38
+ additions on `pica_audio_query`/`pica_notes_query`/`pica_sessions_query`
39
+ (Task 10, 2026-09-03). Each forwards `offset` as a query-string param
40
+ exactly like the existing `limit`, omitted when not passed.
41
+
14
42
  ## [3.13.0] - 2026-08-26
15
43
 
16
44
  The MPP pay rail (spec 2026-08-24 WS-B): a new resource to mint a pay link,
package/dist/index.d.ts CHANGED
@@ -493,6 +493,37 @@ interface MultimediaItem {
493
493
  created_at: string;
494
494
  updated_at: string;
495
495
  }
496
+ /**
497
+ * The full response of `POST /admin/multimedia/import-from-url`.
498
+ *
499
+ * The route returns the created row in `data` and its receipts as SIBLINGS
500
+ * of `data`: `via` (was the given URL a direct image, or a page whose
501
+ * declared og:image was followed?), the `source_url` actually downloaded,
502
+ * and the outcome of the two optional follow-on writes — `profile_image`
503
+ * (the person's avatar) and `work_link`. Those receipts are the only way a
504
+ * caller learns whether the artist photo was really set, so
505
+ * `MultimediaResource.importFromUrl` reads the whole envelope rather than
506
+ * `request()`'s `.data`. `item` is the created row (`data` on the wire).
507
+ */
508
+ interface MultimediaImportResult {
509
+ item: MultimediaItem;
510
+ multimedia_id: string;
511
+ s3_url: string;
512
+ via: "direct" | "og:image";
513
+ source_url: string;
514
+ message: string;
515
+ profile_image?: {
516
+ person_id: string;
517
+ set: boolean;
518
+ code?: string;
519
+ reason?: string;
520
+ };
521
+ work_link?: {
522
+ work_id: string;
523
+ linked: boolean;
524
+ reason?: string;
525
+ };
526
+ }
496
527
  interface Agreement {
497
528
  id: string;
498
529
  organisation_id: string;
@@ -861,12 +892,18 @@ declare class BaseResource {
861
892
  * carries `twin`/`twin_error` as siblings of `data` — `request()`'s
862
893
  * `return data.data || data` would otherwise silently drop them before
863
894
  * the MCP tool ever sees a twin was created.
895
+ *
896
+ * `TRest` types any FURTHER siblings a specific route puts next to
897
+ * `data` (e.g. `POST /admin/multimedia/import-from-url` returns `via`,
898
+ * `source_url`, `profile_image`, `work_link`). It defaults to `unknown`,
899
+ * which is the identity for intersection, so the existing
900
+ * `requestWithEnvelope<Work>` call sites keep exactly the type they had.
864
901
  */
865
- protected requestWithEnvelope<T>(method: string, path: string, body?: any): Promise<{
902
+ protected requestWithEnvelope<T, TRest = unknown>(method: string, path: string, body?: any): Promise<{
866
903
  data: T;
867
904
  twin?: unknown;
868
905
  twin_error?: string;
869
- }>;
906
+ } & TRest>;
870
907
  /**
871
908
  * Make a request whose SUCCESS body is raw text, not a JSON envelope —
872
909
  * for routes that stream a generated file (e.g. `text/csv`) rather than
@@ -1479,6 +1516,7 @@ declare class AudioFilesResource extends BaseResource {
1479
1516
  unassigned?: boolean;
1480
1517
  query?: string;
1481
1518
  limit?: number;
1519
+ offset?: number;
1482
1520
  }): Promise<AudioFile[]>;
1483
1521
  get(id: string): Promise<AudioFile>;
1484
1522
  /**
@@ -1577,7 +1615,8 @@ declare class MultimediaResource extends BaseResource {
1577
1615
  title?: string;
1578
1616
  source?: string;
1579
1617
  work_id?: string;
1580
- }): Promise<MultimediaItem>;
1618
+ person_id?: string;
1619
+ }): Promise<MultimediaImportResult>;
1581
1620
  linkYoutube(params: {
1582
1621
  youtube_video_id: string;
1583
1622
  title: string;
@@ -1795,6 +1834,7 @@ declare class NotesResource extends BaseResource {
1795
1834
  work?: string;
1796
1835
  person?: string;
1797
1836
  limit?: number;
1837
+ offset?: number;
1798
1838
  }): Promise<any[]>;
1799
1839
  get(id: string): Promise<any>;
1800
1840
  create(content: string, metadata?: {
@@ -2290,11 +2330,17 @@ declare class HealthResource extends BaseResource {
2290
2330
  /**
2291
2331
  * ADR-273 — apply accepted fix actions from a prior plan. Requires planToken
2292
2332
  * from catalogHealthPlan; accept is a list of actionIds (or "all_safe_auto").
2333
+ * `selections` carries the human choice a resolve_person action needs
2334
+ * ({ actionId, chosenPersonId }); a selection also accepts its action.
2293
2335
  * Returns honest per-action met/unmet plus a fresh verdict.
2294
2336
  */
2295
2337
  catalogHealthFix(body: {
2296
2338
  planToken: string;
2297
2339
  accept: string[];
2340
+ selections?: Array<{
2341
+ actionId: string;
2342
+ chosenPersonId: string;
2343
+ }>;
2298
2344
  }): Promise<CatalogHealthFixResult>;
2299
2345
  }
2300
2346
  declare class DashboardResource extends BaseResource {
@@ -3292,11 +3338,16 @@ interface ImportAnalysis {
3292
3338
  };
3293
3339
  }
3294
3340
  interface ImportValidation {
3341
+ /** True when no row carries a severity "error" entry — warnings do not
3342
+ * invalidate a row, so `valid` can be true with `errors` non-empty. */
3295
3343
  valid: boolean;
3296
3344
  errors: Array<{
3297
3345
  row: number;
3298
3346
  field: string;
3299
- message: string;
3347
+ /** The server's ValidationError carries the text in `error`; `message`
3348
+ * is kept for callers that normalised it. Read `error ?? message`. */
3349
+ error?: string;
3350
+ message?: string;
3300
3351
  severity: "error" | "warning";
3301
3352
  }>;
3302
3353
  validRowCount: number;
@@ -4405,6 +4456,7 @@ declare class ReleasesResource extends BaseResource {
4405
4456
  declare class SessionsResource extends BaseResource {
4406
4457
  list(params?: {
4407
4458
  limit?: number;
4459
+ offset?: number;
4408
4460
  }): Promise<any>;
4409
4461
  get(id: string): Promise<any>;
4410
4462
  create(data: Record<string, any>): Promise<any>;
@@ -4490,6 +4542,104 @@ declare class StatementsResource extends BaseResource {
4490
4542
  rows: unknown[];
4491
4543
  }): Promise<Record<string, unknown>>;
4492
4544
  }
4545
+ /**
4546
+ * ADR-319 — saved catalog selections. `mcp-sdk` is a standalone published
4547
+ * package with no access to the app's path aliases, so this is a hand-kept
4548
+ * mirror of `lib/services/catalog-selection/types.ts` rather than an
4549
+ * import. Keep the two in sync by hand when the shape changes.
4550
+ *
4551
+ * `evaluable`/`substrate_rows`/`org_rows` on {@link CoverageEntry} are the
4552
+ * whole point of the feature (ADR-319 Decision 3): a zero-member resolution
4553
+ * with `substrate_rows === 0` on a clause means "PICA does not know", not
4554
+ * "there are none" — the never-invent rule applied to a selection.
4555
+ */
4556
+ export type SubstrateUnit = "works" | "credit_rows" | "audio_analysis_rows";
4557
+ export interface CoverageEntry {
4558
+ clause: string;
4559
+ /**
4560
+ * False when the resolver had nothing to run the clause against — today,
4561
+ * a role class the vocabulary no longer carries, which a stored predicate
4562
+ * can still name. The clause is narrowed to nothing rather than dropped,
4563
+ * and this flag is what says the empty answer is PICA's ignorance rather
4564
+ * than the catalogue's.
4565
+ */
4566
+ evaluable: boolean;
4567
+ substrate_rows: number;
4568
+ /**
4569
+ * What `substrate_rows` counted. NOT the same unit as `org_rows`, which is
4570
+ * always works: a role clause counts credits and a trait clause counts
4571
+ * audio analyses, so the two numbers are not two halves of one fraction.
4572
+ */
4573
+ substrate_unit: SubstrateUnit;
4574
+ org_rows: number;
4575
+ }
4576
+ export interface PlayableRef {
4577
+ source: "spotify" | "youtube" | "apple" | "audio_file";
4578
+ ref: string;
4579
+ }
4580
+ export interface SelectionMember {
4581
+ work_id: string;
4582
+ title: string;
4583
+ primary_artist: string | null;
4584
+ playable: PlayableRef | null;
4585
+ has_lyrics: boolean;
4586
+ }
4587
+ export interface ResolveResult {
4588
+ members: SelectionMember[];
4589
+ total: number;
4590
+ coverage: CoverageEntry[];
4591
+ /** True when `total` exceeded the page size and members is a first page. */
4592
+ truncated: boolean;
4593
+ }
4594
+ export interface CatalogSelection {
4595
+ id: string;
4596
+ organisation_id: string;
4597
+ name: string;
4598
+ description: string | null;
4599
+ predicate: Record<string, unknown>;
4600
+ renderer: "listen" | "worklist";
4601
+ visibility: "private" | "shared" | "public";
4602
+ created_by: string | null;
4603
+ created_at: string;
4604
+ updated_at: string;
4605
+ last_resolved_at: string | null;
4606
+ last_resolved_count: number | null;
4607
+ is_deleted: boolean;
4608
+ }
4609
+ export interface CreateSelectionInput {
4610
+ name: string;
4611
+ description?: string;
4612
+ /** `{ version: 1, all: [...clauses] }` — validated server-side. */
4613
+ predicate: Record<string, unknown>;
4614
+ renderer?: "listen" | "worklist";
4615
+ }
4616
+ export interface UpdateSelectionInput {
4617
+ name?: string;
4618
+ description?: string;
4619
+ predicate?: Record<string, unknown>;
4620
+ }
4621
+ declare class SelectionsResource extends BaseResource {
4622
+ list(params?: {
4623
+ limit?: number;
4624
+ offset?: number;
4625
+ }): Promise<CatalogSelection[]>;
4626
+ create(data: CreateSelectionInput): Promise<CatalogSelection>;
4627
+ /**
4628
+ * Per-id read. `resolve: true` also resolves the predicate — the route
4629
+ * returns `{ selection, resolution }` instead of `{ selection }`, and
4630
+ * `resolution` is omitted below when the caller didn't ask for it.
4631
+ */
4632
+ inspect(id: string, opts?: {
4633
+ resolve?: boolean;
4634
+ limit?: number;
4635
+ offset?: number;
4636
+ }): Promise<{
4637
+ selection: CatalogSelection;
4638
+ resolution?: ResolveResult;
4639
+ }>;
4640
+ update(id: string, data: UpdateSelectionInput): Promise<CatalogSelection>;
4641
+ delete(id: string): Promise<void>;
4642
+ }
4493
4643
  declare class ShareLinksResource extends BaseResource {
4494
4644
  list(params?: {
4495
4645
  work_id?: string;
@@ -4813,6 +4963,8 @@ export declare class PicaClient {
4813
4963
  workForHire: WorkForHireResource;
4814
4964
  royalties: RoyaltiesResource;
4815
4965
  statements: StatementsResource;
4966
+ /** ADR-319 — saved catalog selections. */
4967
+ selections: SelectionsResource;
4816
4968
  shareLinks: ShareLinksResource;
4817
4969
  consent: ConsentResource;
4818
4970
  custody: CustodyResource;
@@ -4850,5 +5002,5 @@ export declare class PicaClient {
4850
5002
  }): Promise<CatalogStats | Record<string, unknown>>;
4851
5003
  constructor(config: PicaClientConfig);
4852
5004
  }
4853
- export type { Work, Person, Recording, PaginatedResult, PicaClientConfig, SyncSearchParams, SyncTrack, SyncSearchResult, LicenseEnquiryInput, LicenseEnquiry, BookingEnquiry, WorkCredit, WorkCreditsInput, PicaScore, PicaScorePillar, AudioFile, AudioAnalysisStatus, PresignedUploadResult, CompleteUploadResult, IdentifyResult, MultimediaItem, Agreement, AgreementWorkLink, CreateAgreementFromTemplateParams, AgreementSendForSignatureResult, AgreementSendForSignatureSentEntry, AgreementSendForSignatureSkippedEntry, AgreementSendForSignatureSkipReason, SyncPlacement, SyncPlacementSource, SyncPlacementRecording, SyncPlacementWithRelations, SyncPlacementContactInput, SyncPlacementRecordingInput, SyncPlacementSourceInput, CreateSyncPlacementInput, UpdateSyncPlacementInput, SyncPlacementQueryParams, SyncPlacementStatus, SyncPlacementVerificationStatus, SyncPlacementConfidentialityLevel, SyncPlacementSourceKind, CatalogStats, NotificationsSummary, CreateUploadSessionInput, CreateUploadSessionResult, };
5005
+ export type { Work, Person, Recording, PaginatedResult, PicaClientConfig, SyncSearchParams, SyncTrack, SyncSearchResult, LicenseEnquiryInput, LicenseEnquiry, BookingEnquiry, WorkCredit, WorkCreditsInput, PicaScore, PicaScorePillar, AudioFile, AudioAnalysisStatus, PresignedUploadResult, CompleteUploadResult, IdentifyResult, MultimediaItem, MultimediaImportResult, Agreement, AgreementWorkLink, CreateAgreementFromTemplateParams, AgreementSendForSignatureResult, AgreementSendForSignatureSentEntry, AgreementSendForSignatureSkippedEntry, AgreementSendForSignatureSkipReason, SyncPlacement, SyncPlacementSource, SyncPlacementRecording, SyncPlacementWithRelations, SyncPlacementContactInput, SyncPlacementRecordingInput, SyncPlacementSourceInput, CreateSyncPlacementInput, UpdateSyncPlacementInput, SyncPlacementQueryParams, SyncPlacementStatus, SyncPlacementVerificationStatus, SyncPlacementConfidentialityLevel, SyncPlacementSourceKind, CatalogStats, NotificationsSummary, CreateUploadSessionInput, CreateUploadSessionResult, };
4854
5006
  //# sourceMappingURL=index.d.ts.map