@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
115 lines • 5.82 kB
JavaScript
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
import { formatStructuredList, formatSuccess } from "@withpica/mcp-utils";
export class PublishersTools {
pica;
constructor(pica) {
this.pica = pica;
}
getTools() {
return [
{
definition: {
name: "pica_publishers_query",
scope: "read:catalog",
audiences: ["stdio", "http", "public"],
tier: "read",
description: "Find publishers by name or IPI. Use before setting publisher on credits. " +
"→ then: pica_credits_update (link publisher to a credit)",
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: {
query: {
type: "string",
description: "Search by publisher name or IPI",
},
limit: {
type: "number",
description: "Max results (default: 50)",
},
},
},
},
executor: this.queryPublishers.bind(this),
},
{
definition: {
name: "pica_publishers_create",
scope: "write:catalog",
audiences: ["stdio", "http", "public"],
tier: "write",
description: "Create (or fetch existing) publisher in the catalog-wide " +
"`global_publishers` table. Idempotent by ipi_number — if a " +
"publisher with the same IPI already exists, returns the existing " +
"row. Check `pica_publishers_query` first to avoid duplicates and " +
"to resolve parent_publisher_id.",
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: {
name: { type: "string", description: "Publisher name." },
ipi_number: {
type: "string",
description: "Publisher IPI number (9-11 digits; normalised to 11 with " +
"leading zero-padding). Required.",
},
legal_name: {
type: "string",
description: "Legal entity name (e.g. 'Example Publishing Ltd.') — optional.",
},
country: {
type: "string",
description: "ISO country code (e.g. 'GB', 'US').",
},
isni: {
type: "string",
description: "ISNI identifier (16-character alphanumeric) if the publisher has one.",
},
publisher_type: {
type: "string",
description: "Category label (e.g. 'major', 'indie', 'admin', 'self_published'). Freeform — no backend CHECK.",
},
wikidata_id: {
type: "string",
description: "Wikidata Q-number (e.g. 'Q123456').",
},
parent_publisher_id: {
type: "string",
description: "UUID of parent publisher for subsidiary/admin relationships. FK → global_publishers.id. Use `pica_publishers_query` to find the parent's ID before passing it here; the route returns FK_NOT_FOUND if the UUID does not exist.",
},
founded_date: {
type: "string",
description: "Founding date (YYYY-MM-DD).",
},
headquarters: {
type: "string",
description: "Freeform location (e.g. 'London, UK').",
},
},
required: ["name", "ipi_number"],
},
},
executor: this.createPublisher.bind(this),
},
];
}
async queryPublishers(args) {
const result = await this.pica.publishers.list({
query: args.query,
limit: args.limit || 50,
});
const publishers = Array.isArray(result) ? result : result?.data || [];
return formatStructuredList(publishers, "publisher", {
total: publishers.length,
});
}
async createPublisher(args) {
const result = await this.pica.publishers.create(args);
return formatSuccess("Publisher created", result);
}
}
//# sourceMappingURL=publishers.js.map