@withpica/mcp-server
Version:
MCP Server for withPICA — enables AI assistants to interact with your withPICA music catalog
84 lines • 4 kB
TypeScript
/**
* Audio Files Tools - MCP tools for managing audio files and analysis
*/
import { PicaClient } from "@withpica/mcp-sdk";
import { ToolDefinition, ToolExecutor } from "./index.js";
/**
* Project one audio row to its list shape. Dropped on purpose:
* `waveform_data` (the weight — on pica_audio_inspect sections:["waveform"]),
* sample-rate / bit-depth / danceability (inspect sections:["analysis"]),
* and `metadata`, `file_path`, `cdn_url`, `extraction_error`, analysis
* version/processor and the `recording` / `work` embeds — storage internals
* not exposed over MCP. See queryAudioFiles for the measurement.
*/
export declare function toAudioListItem(row: unknown): Record<string, unknown>;
/**
* The `identification` section of pica_audio_inspect — what ACRCloud said this
* file is. Built from the single-file GET, which already carries the
* audio_analysis_results satellite flattened onto the row (findById in
* lib/services/audio-files/queries.ts selects `audio_analysis_results(*)`), so
* the section costs no extra call.
*
* Before 2026-09-26 no read tool exposed these columns: the only way an agent
* saw a match was the full row echoed by pica_audio_update, which #2360
* slimmed — leaving them unreachable (ops issue 3cf19a67).
*
* Deliberately lean: each DSP entry keeps only track_id + link (artwork,
* preview URLs and artist genres are dropped), and the ACRCloud AI-detection
* payload is cut to its headline fields (the per-stem and per-generator
* probability arrays are left out). Values are copied as stored, never
* rescaled: `identification_confidence` is ACRCloud's match score as written
* (25-100 across prod rows on 2026-09-26). `ai_detection.confidence` is the
* AI probability on 0-100 (the AiDetectionAcrcloud type). Its prod values
* span 0.2-96.47, which looked like mixed scales, but read against the
* verdict on 2026-09-26 (723 rows, one model_id): every `ai_generated` row is
* ≥ 61.91 and every `human` row ≤ 47.71, and all 363 values ≤ 1 are `human`
* — one 0-100 scale, with human tracks scoring near zero. A file never run
* through ACRCloud reports `identification_status: null`.
*/
export declare function toIdentificationSection(file: unknown): Record<string, unknown>;
/**
* The one-line summary of a matched pica_audio_identify.
*
* The route (app/api/admin/audio-files/[id]/identify) returns the service's
* IdentificationResult FLAT — `title`, `artist`, `confidence`,
* `externalIds.isrc[]` at the top level. Until 2026-09-26 this tool read a
* `result.match` object the route has never sent, so a real match never
* reached this branch; and it multiplied `confidence` by 100, which only a
* 0-1 score would need. ACRCloud's music score is 0-100 — every stored
* `audio_analysis_results.identification_confidence` on prod reads 25-100
* (2026-09-26) — so it is printed as-is.
*/
export declare function describeIdentifyMatch(result: unknown): string;
export declare class AudioFilesTools {
private pica;
constructor(pica: PicaClient);
getTools(): Array<{
definition: ToolDefinition;
executor: ToolExecutor;
}>;
private assignAudio;
/**
* When an assign failed and one of the passed ids exists as the OTHER
* entity type, name the mistake precisely. Returns null when the probe
* finds nothing (the original error is rethrown by the caller).
*/
private wrongIdTypeHint;
private bulkAssignSuggested;
private dismissMatch;
private updateAudio;
private bulkUpdateAudio;
private deleteAudioFile;
private queryAudioFiles;
private inspectAudioFile;
private analyzeAudioFile;
private presignedUpload;
private completeUpload;
private identifyAudioFile;
/**
* ADR-232 § Decision 4 — pica_audio_pipeline_status executor.
* Forwards to the SDK; the service-layer aggregator does the work.
*/
private audioPipelineStatus;
}
//# sourceMappingURL=audio-files.d.ts.map