@withpica/mcp-sdk 3.14.0 → 3.16.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 +30 -0
- package/dist/index.d.ts +146 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [3.16.0] - 2026-09-09
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `works.search()` accepts `has_lyrics` (boolean) and writes it to the query
|
|
19
|
+
string. Without it a caller could not count works holding a lyric sheet
|
|
20
|
+
without paging the whole catalogue, which is how a connector session came to
|
|
21
|
+
inspect one work, see `lyrics: null`, and report that lyrics were not being
|
|
22
|
+
stored for an org holding 178 of them (PICA FIX_LOG 2026-09-09).
|
|
23
|
+
|
|
24
|
+
⚠️ **`@withpica/mcp-server` must not be published against 3.15.0 once its
|
|
25
|
+
`pica_works_query` declares `has_lyrics`.** `URLSearchParams` drops unknown
|
|
26
|
+
keys silently, so an older SDK would send no filter, the route would return the
|
|
27
|
+
unfiltered catalogue, and the tool description tells the agent to read `total`
|
|
28
|
+
as the answer — it would report every work as having lyrics. Publish this
|
|
29
|
+
package first.
|
|
30
|
+
|
|
31
|
+
## [3.15.0] - 2026-09-08
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- `selections` resource (ADR-319 saved catalog selections) — `list`,
|
|
36
|
+
`create`, `inspect` (id + optional `resolve`/`limit`/`offset`), `update`,
|
|
37
|
+
`delete` over `/admin/selections`. Backs the new `pica_selections_*` MCP
|
|
38
|
+
tools (Task 8).
|
|
39
|
+
- `health.catalogHealthFix` accepts an optional `selections` array
|
|
40
|
+
(`{ actionId, chosenPersonId }`) — the human choice a `resolve_person`
|
|
41
|
+
action needs. Type-only on this side (the body is forwarded as-is); the
|
|
42
|
+
route validates it.
|
|
43
|
+
|
|
14
44
|
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.
|
|
15
45
|
|
|
16
46
|
## [3.14.0] - 2026-09-04
|
package/dist/index.d.ts
CHANGED
|
@@ -985,6 +985,11 @@ declare class WorksResource extends BaseResource {
|
|
|
985
985
|
has_iswc?: boolean;
|
|
986
986
|
/** Filter to works that have (true) or lack (false) a publisher_name. */
|
|
987
987
|
has_publisher?: boolean;
|
|
988
|
+
/**
|
|
989
|
+
* Filter to works that have (true) or lack (false) a stored lyric sheet
|
|
990
|
+
* (works.lyrics; blank counts as lacking).
|
|
991
|
+
*/
|
|
992
|
+
has_lyrics?: boolean;
|
|
988
993
|
}): Promise<PaginatedResult<Work>>;
|
|
989
994
|
get(id: string): Promise<Work>;
|
|
990
995
|
create(data: Partial<Work> & {
|
|
@@ -1508,6 +1513,31 @@ interface IdentifyResult {
|
|
|
1508
1513
|
confidence: number;
|
|
1509
1514
|
};
|
|
1510
1515
|
}
|
|
1516
|
+
export interface AudioFileTranscriptSegment {
|
|
1517
|
+
start: number;
|
|
1518
|
+
end: number;
|
|
1519
|
+
text: string;
|
|
1520
|
+
confidence?: number;
|
|
1521
|
+
}
|
|
1522
|
+
export interface AudioFileTranscript {
|
|
1523
|
+
audio_file_id: string;
|
|
1524
|
+
has_transcript: boolean;
|
|
1525
|
+
/** absent when has_transcript is false */
|
|
1526
|
+
work_id?: string | null;
|
|
1527
|
+
recording_id?: string | null;
|
|
1528
|
+
/** false when the transcript reaches no work — nothing else can show it */
|
|
1529
|
+
reaches_work?: boolean;
|
|
1530
|
+
transcript: {
|
|
1531
|
+
full_text: string;
|
|
1532
|
+
language: string | null;
|
|
1533
|
+
confidence: number | null;
|
|
1534
|
+
segment_count: number;
|
|
1535
|
+
segments: AudioFileTranscriptSegment[];
|
|
1536
|
+
processor: string | null;
|
|
1537
|
+
model_version: string | null;
|
|
1538
|
+
created_at: string | null;
|
|
1539
|
+
} | null;
|
|
1540
|
+
}
|
|
1511
1541
|
declare class AudioFilesResource extends BaseResource {
|
|
1512
1542
|
list(params?: {
|
|
1513
1543
|
work_id?: string;
|
|
@@ -1519,6 +1549,16 @@ declare class AudioFilesResource extends BaseResource {
|
|
|
1519
1549
|
offset?: number;
|
|
1520
1550
|
}): Promise<AudioFile[]>;
|
|
1521
1551
|
get(id: string): Promise<AudioFile>;
|
|
1552
|
+
/**
|
|
1553
|
+
* The stored Whisper transcript for one audio file, linked to a work or not.
|
|
1554
|
+
*
|
|
1555
|
+
* Until 2026-09-07 a transcript was readable only as `works.lyrics` after
|
|
1556
|
+
* propagation, so a transcript on an unlinked file had no reader at all —
|
|
1557
|
+
* 218 of 558 on prod. `has_transcript: false` is a normal answer, not an
|
|
1558
|
+
* error, and `reaches_work` says whether this transcript can be seen
|
|
1559
|
+
* anywhere else.
|
|
1560
|
+
*/
|
|
1561
|
+
getTranscript(id: string): Promise<AudioFileTranscript>;
|
|
1522
1562
|
/**
|
|
1523
1563
|
* Attach ALL orphan audio files whose suggested match is ISRC-high and
|
|
1524
1564
|
* non-ambiguous, in one call. Pairings are recomputed server-side at
|
|
@@ -2330,11 +2370,17 @@ declare class HealthResource extends BaseResource {
|
|
|
2330
2370
|
/**
|
|
2331
2371
|
* ADR-273 — apply accepted fix actions from a prior plan. Requires planToken
|
|
2332
2372
|
* from catalogHealthPlan; accept is a list of actionIds (or "all_safe_auto").
|
|
2373
|
+
* `selections` carries the human choice a resolve_person action needs
|
|
2374
|
+
* ({ actionId, chosenPersonId }); a selection also accepts its action.
|
|
2333
2375
|
* Returns honest per-action met/unmet plus a fresh verdict.
|
|
2334
2376
|
*/
|
|
2335
2377
|
catalogHealthFix(body: {
|
|
2336
2378
|
planToken: string;
|
|
2337
2379
|
accept: string[];
|
|
2380
|
+
selections?: Array<{
|
|
2381
|
+
actionId: string;
|
|
2382
|
+
chosenPersonId: string;
|
|
2383
|
+
}>;
|
|
2338
2384
|
}): Promise<CatalogHealthFixResult>;
|
|
2339
2385
|
}
|
|
2340
2386
|
declare class DashboardResource extends BaseResource {
|
|
@@ -4536,6 +4582,104 @@ declare class StatementsResource extends BaseResource {
|
|
|
4536
4582
|
rows: unknown[];
|
|
4537
4583
|
}): Promise<Record<string, unknown>>;
|
|
4538
4584
|
}
|
|
4585
|
+
/**
|
|
4586
|
+
* ADR-319 — saved catalog selections. `mcp-sdk` is a standalone published
|
|
4587
|
+
* package with no access to the app's path aliases, so this is a hand-kept
|
|
4588
|
+
* mirror of `lib/services/catalog-selection/types.ts` rather than an
|
|
4589
|
+
* import. Keep the two in sync by hand when the shape changes.
|
|
4590
|
+
*
|
|
4591
|
+
* `evaluable`/`substrate_rows`/`org_rows` on {@link CoverageEntry} are the
|
|
4592
|
+
* whole point of the feature (ADR-319 Decision 3): a zero-member resolution
|
|
4593
|
+
* with `substrate_rows === 0` on a clause means "PICA does not know", not
|
|
4594
|
+
* "there are none" — the never-invent rule applied to a selection.
|
|
4595
|
+
*/
|
|
4596
|
+
export type SubstrateUnit = "works" | "credit_rows" | "audio_analysis_rows";
|
|
4597
|
+
export interface CoverageEntry {
|
|
4598
|
+
clause: string;
|
|
4599
|
+
/**
|
|
4600
|
+
* False when the resolver had nothing to run the clause against — today,
|
|
4601
|
+
* a role class the vocabulary no longer carries, which a stored predicate
|
|
4602
|
+
* can still name. The clause is narrowed to nothing rather than dropped,
|
|
4603
|
+
* and this flag is what says the empty answer is PICA's ignorance rather
|
|
4604
|
+
* than the catalogue's.
|
|
4605
|
+
*/
|
|
4606
|
+
evaluable: boolean;
|
|
4607
|
+
substrate_rows: number;
|
|
4608
|
+
/**
|
|
4609
|
+
* What `substrate_rows` counted. NOT the same unit as `org_rows`, which is
|
|
4610
|
+
* always works: a role clause counts credits and a trait clause counts
|
|
4611
|
+
* audio analyses, so the two numbers are not two halves of one fraction.
|
|
4612
|
+
*/
|
|
4613
|
+
substrate_unit: SubstrateUnit;
|
|
4614
|
+
org_rows: number;
|
|
4615
|
+
}
|
|
4616
|
+
export interface PlayableRef {
|
|
4617
|
+
source: "spotify" | "youtube" | "apple" | "audio_file";
|
|
4618
|
+
ref: string;
|
|
4619
|
+
}
|
|
4620
|
+
export interface SelectionMember {
|
|
4621
|
+
work_id: string;
|
|
4622
|
+
title: string;
|
|
4623
|
+
primary_artist: string | null;
|
|
4624
|
+
playable: PlayableRef | null;
|
|
4625
|
+
has_lyrics: boolean;
|
|
4626
|
+
}
|
|
4627
|
+
export interface ResolveResult {
|
|
4628
|
+
members: SelectionMember[];
|
|
4629
|
+
total: number;
|
|
4630
|
+
coverage: CoverageEntry[];
|
|
4631
|
+
/** True when `total` exceeded the page size and members is a first page. */
|
|
4632
|
+
truncated: boolean;
|
|
4633
|
+
}
|
|
4634
|
+
export interface CatalogSelection {
|
|
4635
|
+
id: string;
|
|
4636
|
+
organisation_id: string;
|
|
4637
|
+
name: string;
|
|
4638
|
+
description: string | null;
|
|
4639
|
+
predicate: Record<string, unknown>;
|
|
4640
|
+
renderer: "listen" | "worklist";
|
|
4641
|
+
visibility: "private" | "shared" | "public";
|
|
4642
|
+
created_by: string | null;
|
|
4643
|
+
created_at: string;
|
|
4644
|
+
updated_at: string;
|
|
4645
|
+
last_resolved_at: string | null;
|
|
4646
|
+
last_resolved_count: number | null;
|
|
4647
|
+
is_deleted: boolean;
|
|
4648
|
+
}
|
|
4649
|
+
export interface CreateSelectionInput {
|
|
4650
|
+
name: string;
|
|
4651
|
+
description?: string;
|
|
4652
|
+
/** `{ version: 1, all: [...clauses] }` — validated server-side. */
|
|
4653
|
+
predicate: Record<string, unknown>;
|
|
4654
|
+
renderer?: "listen" | "worklist";
|
|
4655
|
+
}
|
|
4656
|
+
export interface UpdateSelectionInput {
|
|
4657
|
+
name?: string;
|
|
4658
|
+
description?: string;
|
|
4659
|
+
predicate?: Record<string, unknown>;
|
|
4660
|
+
}
|
|
4661
|
+
declare class SelectionsResource extends BaseResource {
|
|
4662
|
+
list(params?: {
|
|
4663
|
+
limit?: number;
|
|
4664
|
+
offset?: number;
|
|
4665
|
+
}): Promise<CatalogSelection[]>;
|
|
4666
|
+
create(data: CreateSelectionInput): Promise<CatalogSelection>;
|
|
4667
|
+
/**
|
|
4668
|
+
* Per-id read. `resolve: true` also resolves the predicate — the route
|
|
4669
|
+
* returns `{ selection, resolution }` instead of `{ selection }`, and
|
|
4670
|
+
* `resolution` is omitted below when the caller didn't ask for it.
|
|
4671
|
+
*/
|
|
4672
|
+
inspect(id: string, opts?: {
|
|
4673
|
+
resolve?: boolean;
|
|
4674
|
+
limit?: number;
|
|
4675
|
+
offset?: number;
|
|
4676
|
+
}): Promise<{
|
|
4677
|
+
selection: CatalogSelection;
|
|
4678
|
+
resolution?: ResolveResult;
|
|
4679
|
+
}>;
|
|
4680
|
+
update(id: string, data: UpdateSelectionInput): Promise<CatalogSelection>;
|
|
4681
|
+
delete(id: string): Promise<void>;
|
|
4682
|
+
}
|
|
4539
4683
|
declare class ShareLinksResource extends BaseResource {
|
|
4540
4684
|
list(params?: {
|
|
4541
4685
|
work_id?: string;
|
|
@@ -4859,6 +5003,8 @@ export declare class PicaClient {
|
|
|
4859
5003
|
workForHire: WorkForHireResource;
|
|
4860
5004
|
royalties: RoyaltiesResource;
|
|
4861
5005
|
statements: StatementsResource;
|
|
5006
|
+
/** ADR-319 — saved catalog selections. */
|
|
5007
|
+
selections: SelectionsResource;
|
|
4862
5008
|
shareLinks: ShareLinksResource;
|
|
4863
5009
|
consent: ConsentResource;
|
|
4864
5010
|
custody: CustodyResource;
|