UNPKG

@withpica/mcp-server

Version:

MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog

164 lines • 9.43 kB
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved. import { formatSuccess } from "@withpica/mcp-utils"; export class RecordingCustodyTools { pica; constructor(pica) { this.pica = pica; } getTools() { return [ { definition: { name: "pica_recording_custody_assign", scope: "admin", audiences: ["stdio", "http", "public"], tier: "write", description: "Transfer custody of a recording to another party — e.g. when a demo is " + "delivered to a label, a recording is licensed, or master ownership is assigned. " + "Control types (delivery, license, admin_grant) leave ownership " + "unchanged. Ownership types: " + "'assignment' (title transfers), 'full_transfer' (ownership AND control) — these " + "also move the master ownership splits append-only (the transferor's active era " + "closes, the transferee's opens; partial transfers are refused if ambiguous or " + "exceeding the transferor's share). Credits never move. " + "To RECORD who owns a master (e.g. the artist owns 100%): full_transfer, percentage 100, " + "their new_custodian_global_creator_id — if they already hold the master split, the split " + "history is left untouched and only the custody leg is written; when that global creator " + "is exactly one person in your catalogue, the new split row carries that person. " + "Supply exactly one custodian target. reason is required. " + "Admin/owner access required; you must own the recording. " + "Use pica_recording_provenance first to read the current chain; " + "this one writes a new leg.", workflows: "infrastructure", vernacular_kind: "specialist", vernacular_reason: "Specialist context; not yet covered by the Creator Question Atlas — pending telemetry-driven addition per ADR-226 Phase 4 substrate writes.", inputSchema: { type: "object", properties: { recording_id: { type: "string", description: "UUID of the recording whose custody to transfer.", }, transfer_type: { type: "string", enum: [ "delivery", "license", "admin_grant", "assignment", "full_transfer", ], description: "'delivery' = handed over; 'license' = rights to use; 'admin_grant' = administration; " + "'assignment' = ownership (title) transfers; 'full_transfer' = ownership AND control. " + "Ownership types also move the master ownership splits append-only.", }, percentage: { type: "number", description: "Share being transferred, > 0 and <= 100. For ownership types this is the " + "share of master ownership that moves from the transferor to the transferee.", }, territory: { type: "string", description: "Territory code the transfer applies to — 'WW' for worldwide (the convention the work-level custody chain reads).", }, reason: { type: "string", description: "Required freetext explaining the handoff.", }, new_custodian_org_id: { type: "string", description: "UUID of the receiving org. Supply exactly one custodian target.", }, new_custodian_global_publisher_id: { type: "string", description: "Global publisher identity of the receiver. Supply exactly one custodian target.", }, new_custodian_global_creator_id: { type: "string", description: "Global creator identity of the receiver. Supply exactly one custodian target.", }, evidence: { type: "string", description: "Optional reference/URL to the agreement or document backing this transfer.", }, }, required: [ "recording_id", "transfer_type", "percentage", "territory", "reason", ], }, annotations: { title: "assign recording custody", destructiveHint: false, idempotentHint: false, }, }, executor: this.assign.bind(this), }, { definition: { name: "pica_recording_provenance", scope: "read:catalog", audiences: ["stdio", "http", "public"], tier: "read", description: "Use when the user asks: 'who controls this recording?', 'show the recording's " + "chain of custody', 'where did this master come from?'. Returns the ordered custody " + "legs (each transfer: custodian, type, territory, percentage, effective dates, reason) " + "plus the immutable origin credits (who made it). Available to any authenticated org member. " + "To record a new transfer rather than read the chain, use " + "pica_recording_custody_assign.", workflows: "infrastructure", vernacular_kind: "creator-entry", inputSchema: { type: "object", properties: { recording_id: { type: "string", description: "UUID of the recording whose provenance trail to fetch.", }, }, required: ["recording_id"], }, annotations: { title: "recording provenance trail", readOnlyHint: true, idempotentHint: true, }, }, executor: this.provenance.bind(this), }, ]; } async assign(args) { const data = await this.pica.recordingCustody.assign({ recording_id: args.recording_id, transfer_type: args.transfer_type, percentage: args.percentage, territory: args.territory, reason: args.reason, new_custodian_org_id: args.new_custodian_org_id, new_custodian_global_publisher_id: args.new_custodian_global_publisher_id, new_custodian_global_creator_id: args.new_custodian_global_creator_id, evidence: args.evidence, }); const isOwnership = args.transfer_type === "assignment" || args.transfer_type === "full_transfer"; return formatSuccess(isOwnership ? `Custody recorded (${args.transfer_type}). A new custody leg was written. Master ownership splits moved append-only (transferor era closed, transferee era opened) — unless the transferee already held that share, in which case the split history is unchanged. Read pica_recording_splits_list to confirm.` : `Custody transferred (${args.transfer_type}). A new custody leg was recorded on the recording's control chain.`, data); } async provenance(args) { const data = await this.pica.recordingCustody.trail({ recording_id: args.recording_id, }); const legs = data?.legs ?? []; const originCredits = data?.originCredits ?? []; return formatSuccess(legs.length > 0 || originCredits.length > 0 ? `Provenance trail: ${legs.length} custody leg(s) + ${originCredits.length} origin credit(s).` : "No custody legs or origin credits recorded for this recording yet.", data); } } //# sourceMappingURL=recording-custody.js.map