@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
80 lines • 4.34 kB
JavaScript
// Copyright (c) 2025-2026 Withpica Ltd. All rights reserved.
import { formatSuccess } from "@withpica/mcp-utils";
export class ConsentTools {
pica;
constructor(pica) {
this.pica = pica;
}
getTools() {
return [
{
definition: {
name: "pica_consent_readiness",
scope: "read:catalog",
audiences: ["stdio", "http", "public"],
tier: "read",
description: "Use when the user asks: 'how much of my catalogue is clearable for AI training?', " +
"'who hasn't given consent?', 'can I license this catalogue for AI training?', " +
"'what's blocking an AI deal?', 'am I ready for an AI licensing conversation?'. " +
"Returns an org-scoped consent readiness verdict. " +
"`rungs` gives cleared / partial / blocked / unset asset counts at each consent " +
"level (tracking_only < sync < voice_model < full_training) — an asset is cleared " +
"at a level ONLY when every credited contributor has granted at least that level, " +
"and a single explicit revocation blocks it at every level. " +
"`blockers` names credited people with no consent recorded (state 'unset') or an " +
"explicit refusal (state 'revoked'), ranked with refusals first then by how much " +
"of the catalogue they touch. " +
"`blockedAssets` names what is blocked and by whom. " +
"`truncated` reports honestly when a list was capped; pass `limit` to widen it. " +
"→ then: pica_people_inspect (open a named blocker), " +
"pica_export_ai_consent (produce the full file for a counterparty).",
workflows: "infrastructure",
vernacular_kind: "creator-entry",
inputSchema: {
type: "object",
properties: {
limit: {
type: "number",
description: "How many blockers and blocked assets to return (default 25). Raise it to see the full chase-list.",
},
},
},
annotations: {
title: "consent readiness",
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
},
nextSteps: [
{
tool: "pica_people_inspect",
reason: "Open a named blocker's record to chase or record their consent decision.",
when: "on_success",
},
{
tool: "pica_export_ai_consent",
reason: "Produce the full consent file when a counterparty needs the document rather than the answer.",
when: "on_success",
},
],
},
executor: this.readiness.bind(this),
},
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async readiness(args) {
const limit = typeof args?.limit === "number" && Number.isInteger(args.limit) && args.limit > 0
? args.limit
: undefined;
const data = await this.pica.consent.readiness(limit ? { limit } : undefined);
const cleared = data?.rungs?.full_training?.cleared ?? 0;
const total = (data?.totals?.works ?? 0) + (data?.totals?.recordings ?? 0);
const blockers = data?.blockers?.length ?? 0;
const blockerClause = blockers === 0
? "every credited person has recorded a decision"
: `${blockers} credited ${blockers === 1 ? "person has" : "people have"} not`;
return formatSuccess(`${cleared} of ${total} assets cleared for AI training; ${blockerClause}`, data);
}
}
//# sourceMappingURL=consent.js.map