UNPKG

@withpica/mcp-server

Version:

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

76 lines • 3.62 kB
/** * ADR-333 D7 — the optional `catalogue` argument. * * An organisation that looks after other people's catalogues names the client * on each call: `catalogue: <id from pica_portfolio_list>`. Per call, never a * session switch, so an agent cannot write to the wrong client after * forgetting which one it switched to. * * Which tools take it is decided by scope: every tool that reads or writes a * catalogue's own records (catalog, people, agreements, files, analytics). * Account, keys, billing, team and feedback tools (`always`, `admin`, * `write:agent_identity`, `write:feedback`) never act for a client. Money * tools (`read:finances`, `write:finances`) don't yet: the MCP route decides * money access from the caller's own catalogue and its finance switch, and * money through a relationship is off by default (ADR-333 D3) until PR 1.3 * decides it for a client catalogue. CATALOGUE_EXCLUDED_TOOLS lists the rest, * each with its reason. * * The registry adds the argument to those tools' schemas at registration, so * every surface lists it (tools/list, pica_tool_details, pica_execute), and * runs each such call inside `withCatalogue` (@withpica/mcp-sdk). The app * decides whether the relationship allows the call; the SDK fails closed if * the app does not confirm it acted for that catalogue. */ import type { ToolScope } from "@withpica/mcp-utils"; import type { CatalogueCallReport } from "@withpica/mcp-sdk"; export declare const CATALOGUE_ARG = "catalogue"; /** Scopes whose tools act on a catalogue's own records. */ export declare const CATALOGUE_SCOPES: ReadonlySet<ToolScope>; /** Tools in those scopes that must not act for a client, and why. */ export declare const CATALOGUE_EXCLUDED_TOOLS: ReadonlySet<string>; export declare const CATALOGUE_PROPERTY: { readonly type: "string"; readonly format: "uuid"; readonly description: string; }; export declare function takesCatalogue(definition: { name: string; scope?: ToolScope; }): boolean; /** * Why a `catalogue` value cannot be used for this tool, in plain words, or * null when it can. A value is never silently ignored: a tool that cannot act * for a client refuses rather than acting for the caller's own catalogue. */ export declare function catalogueRefusal(definition: { name: string; scope?: ToolScope; }, value: unknown): string | null; /** The parts of a tool answer this module reads and extends. */ interface ToolAnswer { content?: Array<{ type: string; text?: string; }>; isError?: boolean; [k: string]: unknown; } /** * A tool's answer for a call made in a client catalogue, checked against what * the app actually served (the SDK's CatalogueCallReport). * * Many tools fail their parts soft — an inspect tool turns each refused * section into a null or an error field and still answers "success". In a * client catalogue most routes are not opened (lib/auth/catalogue-routes.ts), * so such a tool could answer "success" with nothing in it. Here: * - every request refused and none answered → a plain refusal naming them; * - some refused → the answer stands, with a line naming what was not * available, so nothing is left out silently; * - an answer that is already an error, or a call that refused nothing, is * returned unchanged. * Pinned by mcp-server/src/__tests__/tools/catalogue-argument.test.ts. */ export declare function settleCatalogueAnswer<T extends ToolAnswer>(toolName: string, answer: T, report: CatalogueCallReport): T | ToolAnswer; export {}; //# sourceMappingURL=catalogue-argument.d.ts.map