@withpica/mcp-server 2.6.2 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pica-sdk.d.ts +1231 -0
- package/dist/pica-sdk.d.ts.map +1 -0
- package/dist/pica-sdk.js +1403 -0
- package/dist/pica-sdk.js.map +1 -0
- package/dist/tools/assets.d.ts +4 -0
- package/dist/tools/assets.d.ts.map +1 -1
- package/dist/tools/assets.js +190 -0
- package/dist/tools/assets.js.map +1 -1
- package/dist/tools/audio-files.d.ts.map +1 -1
- package/dist/tools/audio-files.js +5 -5
- package/dist/tools/audio-files.js.map +1 -1
- package/dist/tools/collaborators.d.ts +4 -0
- package/dist/tools/collaborators.d.ts.map +1 -1
- package/dist/tools/collaborators.js +188 -8
- package/dist/tools/collaborators.js.map +1 -1
- package/dist/tools/custody-hints.d.ts +16 -0
- package/dist/tools/custody-hints.d.ts.map +1 -0
- package/dist/tools/custody-hints.js +27 -0
- package/dist/tools/custody-hints.js.map +1 -0
- package/dist/tools/custody.d.ts +38 -0
- package/dist/tools/custody.d.ts.map +1 -0
- package/dist/tools/custody.js +274 -0
- package/dist/tools/custody.js.map +1 -0
- package/dist/tools/enrichment.d.ts.map +1 -1
- package/dist/tools/enrichment.js +6 -6
- package/dist/tools/enrichment.js.map +1 -1
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/exports.js +4 -4
- package/dist/tools/exports.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/metadata.d.ts.map +1 -1
- package/dist/tools/metadata.js +37 -0
- package/dist/tools/metadata.js.map +1 -1
- package/dist/tools/notifications.d.ts +3 -0
- package/dist/tools/notifications.d.ts.map +1 -1
- package/dist/tools/notifications.js +176 -27
- package/dist/tools/notifications.js.map +1 -1
- package/dist/tools/recordings.d.ts.map +1 -1
- package/dist/tools/recordings.js +16 -1
- package/dist/tools/recordings.js.map +1 -1
- package/dist/tools/telegram.d.ts +1 -0
- package/dist/tools/telegram.d.ts.map +1 -1
- package/dist/tools/telegram.js +53 -0
- package/dist/tools/telegram.js.map +1 -1
- package/dist/tools/works.d.ts.map +1 -1
- package/dist/tools/works.js +15 -0
- package/dist/tools/works.js.map +1 -1
- package/dist/utils/errors.d.ts +29 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +115 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/formatting.d.ts +82 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +125 -0
- package/dist/utils/formatting.js.map +1 -0
- package/package.json +1 -1
- package/server.json +1 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
|
|
2
|
+
/**
|
|
3
|
+
* Error handling utilities for MCP server
|
|
4
|
+
*/
|
|
5
|
+
export class McpServerError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
details;
|
|
8
|
+
constructor(message, code, details) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.details = details;
|
|
12
|
+
this.name = "McpServerError";
|
|
13
|
+
Object.setPrototypeOf(this, McpServerError.prototype);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class AuthenticationError extends McpServerError {
|
|
17
|
+
constructor(message = "Authentication failed", details) {
|
|
18
|
+
super(message, "AUTHENTICATION_ERROR", details);
|
|
19
|
+
this.name = "AuthenticationError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class ToolExecutionError extends McpServerError {
|
|
23
|
+
constructor(message, details) {
|
|
24
|
+
super(message, "TOOL_EXECUTION_ERROR", details);
|
|
25
|
+
this.name = "ToolExecutionError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class ResourceError extends McpServerError {
|
|
29
|
+
constructor(message, details) {
|
|
30
|
+
super(message, "RESOURCE_ERROR", details);
|
|
31
|
+
this.name = "ResourceError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format error for MCP response
|
|
36
|
+
*/
|
|
37
|
+
export function formatError(error) {
|
|
38
|
+
if (error instanceof McpServerError) {
|
|
39
|
+
return {
|
|
40
|
+
type: "text",
|
|
41
|
+
text: JSON.stringify({
|
|
42
|
+
error: error.code,
|
|
43
|
+
message: error.message,
|
|
44
|
+
details: error.details,
|
|
45
|
+
}, null, 2),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Classify ApiError from SDK layer
|
|
49
|
+
const status = error?.status;
|
|
50
|
+
if (status === 0 ||
|
|
51
|
+
(error instanceof Error && error.message?.includes("timed out"))) {
|
|
52
|
+
return {
|
|
53
|
+
type: "text",
|
|
54
|
+
text: JSON.stringify({
|
|
55
|
+
error: "REQUEST_TIMEOUT",
|
|
56
|
+
message: "API request timed out after retries. The server may be slow or unreachable.",
|
|
57
|
+
}, null, 2),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (status === 401 || status === 403) {
|
|
61
|
+
return {
|
|
62
|
+
type: "text",
|
|
63
|
+
text: JSON.stringify({
|
|
64
|
+
error: "AUTHENTICATION_ERROR",
|
|
65
|
+
message: "API authentication failed. Check your PICA_API_KEY is valid.",
|
|
66
|
+
status,
|
|
67
|
+
}, null, 2),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (status === 429) {
|
|
71
|
+
return {
|
|
72
|
+
type: "text",
|
|
73
|
+
text: JSON.stringify({
|
|
74
|
+
error: "RATE_LIMITED",
|
|
75
|
+
message: "API rate limit exceeded after retries. Try again in a moment.",
|
|
76
|
+
status,
|
|
77
|
+
}, null, 2),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (error instanceof Error) {
|
|
81
|
+
return {
|
|
82
|
+
type: "text",
|
|
83
|
+
text: JSON.stringify({
|
|
84
|
+
error: "UNKNOWN_ERROR",
|
|
85
|
+
message: error.message,
|
|
86
|
+
}, null, 2),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
type: "text",
|
|
91
|
+
text: JSON.stringify({
|
|
92
|
+
error: "UNKNOWN_ERROR",
|
|
93
|
+
message: String(error),
|
|
94
|
+
}, null, 2),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Log error with structured context (JSON to stderr for machine parsing)
|
|
99
|
+
*/
|
|
100
|
+
export function logError(context, error) {
|
|
101
|
+
const entry = {
|
|
102
|
+
level: "error",
|
|
103
|
+
context,
|
|
104
|
+
message: error instanceof Error ? error.message : String(error),
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
};
|
|
107
|
+
if (error?.status)
|
|
108
|
+
entry.status = error.status;
|
|
109
|
+
if (error?.retryable !== undefined)
|
|
110
|
+
entry.retryable = error.retryable;
|
|
111
|
+
if (error instanceof Error && error.stack)
|
|
112
|
+
entry.stack = error.stack;
|
|
113
|
+
console.error(JSON.stringify(entry));
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response formatting utilities
|
|
3
|
+
*
|
|
4
|
+
* All formatters return FormattedResult — both human-readable text content
|
|
5
|
+
* AND a structuredContent object for machine parsing (ADR-104 §1.2).
|
|
6
|
+
*/
|
|
7
|
+
export interface FormattedResult {
|
|
8
|
+
content: Array<{
|
|
9
|
+
type: string;
|
|
10
|
+
text: string;
|
|
11
|
+
}>;
|
|
12
|
+
structuredContent?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Format data as JSON text for MCP response
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatAsText(data: any): FormattedResult;
|
|
18
|
+
/**
|
|
19
|
+
* Completion hint — tells the LLM what's missing on entities just touched.
|
|
20
|
+
* The LLM decides whether and how to surface these to the user.
|
|
21
|
+
*/
|
|
22
|
+
export interface CompletionHint {
|
|
23
|
+
gap: string;
|
|
24
|
+
suggestion: string;
|
|
25
|
+
count?: number;
|
|
26
|
+
severity?: "critical" | "important" | "nice_to_have";
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Format success message, with optional completion hints for the guided loop.
|
|
30
|
+
*
|
|
31
|
+
* Completion hints are structured data appended to the response so the LLM
|
|
32
|
+
* can naturally suggest the next step without PICA dictating the conversation.
|
|
33
|
+
* If no hints are provided, the response is identical to the old format.
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatSuccess(
|
|
36
|
+
message: string,
|
|
37
|
+
data?: any,
|
|
38
|
+
completionHints?: CompletionHint[],
|
|
39
|
+
): FormattedResult;
|
|
40
|
+
/**
|
|
41
|
+
* Map raw gap objects from the completeness API into CompletionHints.
|
|
42
|
+
* The API response shape varies — this handles the known field names.
|
|
43
|
+
*/
|
|
44
|
+
export declare function mapGapsToHints(
|
|
45
|
+
gaps: any[],
|
|
46
|
+
limit?: number,
|
|
47
|
+
): CompletionHint[];
|
|
48
|
+
/**
|
|
49
|
+
* Format array of items with count
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatList<T>(
|
|
52
|
+
items: T[],
|
|
53
|
+
metadata?: Record<string, any>,
|
|
54
|
+
): FormattedResult;
|
|
55
|
+
/**
|
|
56
|
+
* Truncate text to max length
|
|
57
|
+
*/
|
|
58
|
+
export declare function truncate(text: string, maxLength?: number): string;
|
|
59
|
+
/**
|
|
60
|
+
* Format validation error
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatValidationError(
|
|
63
|
+
fields: Record<string, string>,
|
|
64
|
+
): FormattedResult;
|
|
65
|
+
/**
|
|
66
|
+
* Format structured response with dual content blocks:
|
|
67
|
+
* - Human-readable text (includes full JSON so all MCP clients can read it)
|
|
68
|
+
* - Machine-parseable structuredContent object
|
|
69
|
+
*/
|
|
70
|
+
export declare function formatStructured(
|
|
71
|
+
data: any,
|
|
72
|
+
summary?: string,
|
|
73
|
+
): FormattedResult;
|
|
74
|
+
/**
|
|
75
|
+
* Format a list with both human summary and structured JSON
|
|
76
|
+
*/
|
|
77
|
+
export declare function formatStructuredList<T>(
|
|
78
|
+
items: T[],
|
|
79
|
+
entityName: string,
|
|
80
|
+
metadata?: Record<string, any>,
|
|
81
|
+
): FormattedResult;
|
|
82
|
+
//# sourceMappingURL=formatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,eAAe,CAKvD;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,cAAc,CAAC;CACtD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,GAAG,EACV,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,eAAe,CA0BjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,GAAG,EAAE,EACX,KAAK,GAAE,MAAU,GAChB,cAAc,EAAE,CAOlB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,EAAE,EACV,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,eAAe,CAsBjB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAa,GAAG,MAAM,CAKvE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,eAAe,CAWjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe,CAW7E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,KAAK,EAAE,CAAC,EAAE,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,eAAe,CAOjB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
|
|
2
|
+
/**
|
|
3
|
+
* Format data as JSON text for MCP response
|
|
4
|
+
*/
|
|
5
|
+
export function formatAsText(data) {
|
|
6
|
+
return {
|
|
7
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
8
|
+
structuredContent: data,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Format success message, with optional completion hints for the guided loop.
|
|
13
|
+
*
|
|
14
|
+
* Completion hints are structured data appended to the response so the LLM
|
|
15
|
+
* can naturally suggest the next step without PICA dictating the conversation.
|
|
16
|
+
* If no hints are provided, the response is identical to the old format.
|
|
17
|
+
*/
|
|
18
|
+
export function formatSuccess(message, data, completionHints) {
|
|
19
|
+
const response = {
|
|
20
|
+
success: true,
|
|
21
|
+
message,
|
|
22
|
+
};
|
|
23
|
+
if (data !== undefined) {
|
|
24
|
+
response.data = data;
|
|
25
|
+
}
|
|
26
|
+
if (completionHints && completionHints.length > 0) {
|
|
27
|
+
response.completion_hints = completionHints;
|
|
28
|
+
// Append a human-readable summary so all LLMs can see the hints
|
|
29
|
+
const hintLines = completionHints
|
|
30
|
+
.map((h) => `- ${h.suggestion}${h.count ? ` (${h.count} works)` : ""}`)
|
|
31
|
+
.join("\n");
|
|
32
|
+
message += `\n\nNext steps you could take:\n${hintLines}`;
|
|
33
|
+
response.message = message; // Keep structuredContent in sync with text
|
|
34
|
+
}
|
|
35
|
+
const jsonText = JSON.stringify(response, null, 2);
|
|
36
|
+
return {
|
|
37
|
+
content: [{ type: "text", text: `${message}\n\n${jsonText}` }],
|
|
38
|
+
structuredContent: response,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Map raw gap objects from the completeness API into CompletionHints.
|
|
43
|
+
* The API response shape varies — this handles the known field names.
|
|
44
|
+
*/
|
|
45
|
+
export function mapGapsToHints(gaps, limit = 5) {
|
|
46
|
+
if (!Array.isArray(gaps))
|
|
47
|
+
return [];
|
|
48
|
+
return gaps.slice(0, limit).map((g) => ({
|
|
49
|
+
gap: g.key || g.field || g.type || "unknown",
|
|
50
|
+
suggestion: g.suggestion || g.label || g.description || "",
|
|
51
|
+
severity: g.severity || "important",
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Format array of items with count
|
|
56
|
+
*/
|
|
57
|
+
export function formatList(items, metadata) {
|
|
58
|
+
const response = {
|
|
59
|
+
count: items.length,
|
|
60
|
+
items,
|
|
61
|
+
};
|
|
62
|
+
if (metadata) {
|
|
63
|
+
response.metadata = metadata;
|
|
64
|
+
}
|
|
65
|
+
const summary = `Found ${items.length} item${items.length !== 1 ? "s" : ""}.`;
|
|
66
|
+
const jsonText = JSON.stringify(response, null, 2);
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: "text",
|
|
71
|
+
text: `${summary}\n\n${jsonText}`,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
structuredContent: response,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Truncate text to max length
|
|
79
|
+
*/
|
|
80
|
+
export function truncate(text, maxLength = 1000) {
|
|
81
|
+
if (text.length <= maxLength) {
|
|
82
|
+
return text;
|
|
83
|
+
}
|
|
84
|
+
return text.substring(0, maxLength) + "... (truncated)";
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Format validation error
|
|
88
|
+
*/
|
|
89
|
+
export function formatValidationError(fields) {
|
|
90
|
+
const structured = {
|
|
91
|
+
error: "VALIDATION_ERROR",
|
|
92
|
+
message: "Validation failed",
|
|
93
|
+
fields,
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
content: [{ type: "text", text: JSON.stringify(structured, null, 2) }],
|
|
97
|
+
structuredContent: structured,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Format structured response with dual content blocks:
|
|
102
|
+
* - Human-readable text (includes full JSON so all MCP clients can read it)
|
|
103
|
+
* - Machine-parseable structuredContent object
|
|
104
|
+
*/
|
|
105
|
+
export function formatStructured(data, summary) {
|
|
106
|
+
const jsonText = JSON.stringify(data, null, 2);
|
|
107
|
+
return {
|
|
108
|
+
content: [
|
|
109
|
+
{
|
|
110
|
+
type: "text",
|
|
111
|
+
text: summary ? `${summary}\n\n${jsonText}` : jsonText,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
structuredContent: data,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Format a list with both human summary and structured JSON
|
|
119
|
+
*/
|
|
120
|
+
export function formatStructuredList(items, entityName, metadata) {
|
|
121
|
+
const count = items.length;
|
|
122
|
+
const summary = `Found ${count} ${entityName}${count !== 1 ? "s" : ""}${metadata?.query ? ` matching "${metadata.query}"` : ""}.`;
|
|
123
|
+
return formatStructured({ count, items, ...metadata }, summary);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=formatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.withpica/pica",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "manage your music catalog through conversation — works, recordings, credits, agreements, royalties",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/withpica/pica",
|
|
7
7
|
"source": "github"
|