@withpica/mcp-server 2.5.4 → 2.6.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.
Files changed (269) hide show
  1. package/dist/apps/download.d.ts +2 -0
  2. package/dist/apps/download.d.ts.map +1 -0
  3. package/dist/apps/download.js +125 -0
  4. package/dist/apps/download.js.map +1 -0
  5. package/dist/apps/shared.d.ts +11 -0
  6. package/dist/apps/shared.d.ts.map +1 -1
  7. package/dist/apps/shared.js +212 -0
  8. package/dist/apps/shared.js.map +1 -1
  9. package/dist/apps/upload.d.ts +2 -0
  10. package/dist/apps/upload.d.ts.map +1 -0
  11. package/dist/apps/upload.js +280 -0
  12. package/dist/apps/upload.js.map +1 -0
  13. package/dist/config.d.ts +1 -0
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +6 -1
  16. package/dist/config.js.map +1 -1
  17. package/dist/resources/index.d.ts +1 -1
  18. package/dist/resources/index.d.ts.map +1 -1
  19. package/dist/resources/index.js +39 -8
  20. package/dist/resources/index.js.map +1 -1
  21. package/dist/server.d.ts.map +1 -1
  22. package/dist/server.js +18 -6
  23. package/dist/server.js.map +1 -1
  24. package/dist/tools/agreement-types.d.ts +1 -1
  25. package/dist/tools/agreement-types.d.ts.map +1 -1
  26. package/dist/tools/agreement-types.js +2 -2
  27. package/dist/tools/agreement-types.js.map +1 -1
  28. package/dist/tools/agreements.d.ts +1 -1
  29. package/dist/tools/agreements.d.ts.map +1 -1
  30. package/dist/tools/agreements.js +2 -2
  31. package/dist/tools/agreements.js.map +1 -1
  32. package/dist/tools/analytics.d.ts +1 -1
  33. package/dist/tools/analytics.d.ts.map +1 -1
  34. package/dist/tools/analytics.js +1 -1
  35. package/dist/tools/analytics.js.map +1 -1
  36. package/dist/tools/app-tools.d.ts +8 -5
  37. package/dist/tools/app-tools.d.ts.map +1 -1
  38. package/dist/tools/app-tools.js +215 -54
  39. package/dist/tools/app-tools.js.map +1 -1
  40. package/dist/tools/assets.d.ts +1 -1
  41. package/dist/tools/assets.d.ts.map +1 -1
  42. package/dist/tools/assets.js +215 -14
  43. package/dist/tools/assets.js.map +1 -1
  44. package/dist/tools/audio-files.d.ts +1 -1
  45. package/dist/tools/audio-files.d.ts.map +1 -1
  46. package/dist/tools/audio-files.js +2 -2
  47. package/dist/tools/audio-files.js.map +1 -1
  48. package/dist/tools/auth.d.ts.map +1 -1
  49. package/dist/tools/auth.js +8 -3
  50. package/dist/tools/auth.js.map +1 -1
  51. package/dist/tools/bulk.d.ts +1 -1
  52. package/dist/tools/bulk.d.ts.map +1 -1
  53. package/dist/tools/bulk.js +1 -1
  54. package/dist/tools/bulk.js.map +1 -1
  55. package/dist/tools/calendar.d.ts +1 -1
  56. package/dist/tools/calendar.d.ts.map +1 -1
  57. package/dist/tools/calendar.js +1 -1
  58. package/dist/tools/calendar.js.map +1 -1
  59. package/dist/tools/collaborators.d.ts +1 -1
  60. package/dist/tools/collaborators.d.ts.map +1 -1
  61. package/dist/tools/collaborators.js +1 -1
  62. package/dist/tools/collaborators.js.map +1 -1
  63. package/dist/tools/comparisons.d.ts +1 -1
  64. package/dist/tools/comparisons.d.ts.map +1 -1
  65. package/dist/tools/comparisons.js +1 -1
  66. package/dist/tools/comparisons.js.map +1 -1
  67. package/dist/tools/credits.d.ts +1 -1
  68. package/dist/tools/credits.d.ts.map +1 -1
  69. package/dist/tools/credits.js +2 -2
  70. package/dist/tools/credits.js.map +1 -1
  71. package/dist/tools/dashboard.d.ts +1 -1
  72. package/dist/tools/dashboard.d.ts.map +1 -1
  73. package/dist/tools/dashboard.js +1 -1
  74. package/dist/tools/dashboard.js.map +1 -1
  75. package/dist/tools/directory.d.ts +1 -1
  76. package/dist/tools/directory.d.ts.map +1 -1
  77. package/dist/tools/directory.js +1 -1
  78. package/dist/tools/directory.js.map +1 -1
  79. package/dist/tools/discovery.d.ts +28 -0
  80. package/dist/tools/discovery.d.ts.map +1 -0
  81. package/dist/tools/discovery.js +560 -0
  82. package/dist/tools/discovery.js.map +1 -0
  83. package/dist/tools/disputes.d.ts +1 -1
  84. package/dist/tools/disputes.d.ts.map +1 -1
  85. package/dist/tools/disputes.js +1 -1
  86. package/dist/tools/disputes.js.map +1 -1
  87. package/dist/tools/documents.d.ts +1 -1
  88. package/dist/tools/documents.d.ts.map +1 -1
  89. package/dist/tools/documents.js +1 -1
  90. package/dist/tools/documents.js.map +1 -1
  91. package/dist/tools/duplicates.d.ts +1 -1
  92. package/dist/tools/duplicates.d.ts.map +1 -1
  93. package/dist/tools/duplicates.js +5 -3
  94. package/dist/tools/duplicates.js.map +1 -1
  95. package/dist/tools/enrichment.d.ts +1 -1
  96. package/dist/tools/enrichment.d.ts.map +1 -1
  97. package/dist/tools/enrichment.js +3 -3
  98. package/dist/tools/enrichment.js.map +1 -1
  99. package/dist/tools/exports.d.ts +1 -1
  100. package/dist/tools/exports.d.ts.map +1 -1
  101. package/dist/tools/exports.js +2 -2
  102. package/dist/tools/exports.js.map +1 -1
  103. package/dist/tools/import-documents.d.ts +1 -1
  104. package/dist/tools/import-documents.d.ts.map +1 -1
  105. package/dist/tools/import-documents.js +1 -1
  106. package/dist/tools/import-documents.js.map +1 -1
  107. package/dist/tools/import.d.ts +1 -1
  108. package/dist/tools/import.d.ts.map +1 -1
  109. package/dist/tools/import.js +1 -1
  110. package/dist/tools/import.js.map +1 -1
  111. package/dist/tools/index.d.ts +8 -4
  112. package/dist/tools/index.d.ts.map +1 -1
  113. package/dist/tools/index.js +43 -16
  114. package/dist/tools/index.js.map +1 -1
  115. package/dist/tools/integrations.d.ts +1 -1
  116. package/dist/tools/integrations.d.ts.map +1 -1
  117. package/dist/tools/integrations.js +1 -1
  118. package/dist/tools/integrations.js.map +1 -1
  119. package/dist/tools/licensing.d.ts +1 -1
  120. package/dist/tools/licensing.d.ts.map +1 -1
  121. package/dist/tools/licensing.js +1 -1
  122. package/dist/tools/licensing.js.map +1 -1
  123. package/dist/tools/memory.d.ts +1 -1
  124. package/dist/tools/memory.d.ts.map +1 -1
  125. package/dist/tools/memory.js +1 -1
  126. package/dist/tools/memory.js.map +1 -1
  127. package/dist/tools/metadata.d.ts.map +1 -1
  128. package/dist/tools/metadata.js +15 -3
  129. package/dist/tools/metadata.js.map +1 -1
  130. package/dist/tools/multimedia.d.ts +1 -1
  131. package/dist/tools/multimedia.d.ts.map +1 -1
  132. package/dist/tools/multimedia.js +1 -1
  133. package/dist/tools/multimedia.js.map +1 -1
  134. package/dist/tools/notes.d.ts +1 -1
  135. package/dist/tools/notes.d.ts.map +1 -1
  136. package/dist/tools/notes.js +1 -1
  137. package/dist/tools/notes.js.map +1 -1
  138. package/dist/tools/notifications.d.ts +1 -1
  139. package/dist/tools/notifications.d.ts.map +1 -1
  140. package/dist/tools/notifications.js +1 -1
  141. package/dist/tools/notifications.js.map +1 -1
  142. package/dist/tools/people.d.ts +1 -1
  143. package/dist/tools/people.d.ts.map +1 -1
  144. package/dist/tools/people.js +2 -2
  145. package/dist/tools/people.js.map +1 -1
  146. package/dist/tools/projects.d.ts +1 -1
  147. package/dist/tools/projects.d.ts.map +1 -1
  148. package/dist/tools/projects.js +1 -1
  149. package/dist/tools/projects.js.map +1 -1
  150. package/dist/tools/publishers.d.ts +1 -1
  151. package/dist/tools/publishers.d.ts.map +1 -1
  152. package/dist/tools/publishers.js +1 -1
  153. package/dist/tools/publishers.js.map +1 -1
  154. package/dist/tools/purchases.d.ts +1 -1
  155. package/dist/tools/purchases.d.ts.map +1 -1
  156. package/dist/tools/purchases.js +1 -1
  157. package/dist/tools/purchases.js.map +1 -1
  158. package/dist/tools/recordings.d.ts +1 -1
  159. package/dist/tools/recordings.d.ts.map +1 -1
  160. package/dist/tools/recordings.js +1 -1
  161. package/dist/tools/recordings.js.map +1 -1
  162. package/dist/tools/releases.d.ts +1 -1
  163. package/dist/tools/releases.d.ts.map +1 -1
  164. package/dist/tools/releases.js +1 -1
  165. package/dist/tools/releases.js.map +1 -1
  166. package/dist/tools/royalties.d.ts +1 -1
  167. package/dist/tools/royalties.d.ts.map +1 -1
  168. package/dist/tools/royalties.js +1 -1
  169. package/dist/tools/royalties.js.map +1 -1
  170. package/dist/tools/search.d.ts +1 -1
  171. package/dist/tools/search.d.ts.map +1 -1
  172. package/dist/tools/search.js +1 -1
  173. package/dist/tools/search.js.map +1 -1
  174. package/dist/tools/send.d.ts +1 -1
  175. package/dist/tools/send.d.ts.map +1 -1
  176. package/dist/tools/send.js +1 -1
  177. package/dist/tools/send.js.map +1 -1
  178. package/dist/tools/sessions.d.ts +1 -1
  179. package/dist/tools/sessions.d.ts.map +1 -1
  180. package/dist/tools/sessions.js +1 -1
  181. package/dist/tools/sessions.js.map +1 -1
  182. package/dist/tools/settings.d.ts +1 -1
  183. package/dist/tools/settings.d.ts.map +1 -1
  184. package/dist/tools/settings.js +1 -1
  185. package/dist/tools/settings.js.map +1 -1
  186. package/dist/tools/share-links.d.ts +1 -1
  187. package/dist/tools/share-links.d.ts.map +1 -1
  188. package/dist/tools/share-links.js +1 -1
  189. package/dist/tools/share-links.js.map +1 -1
  190. package/dist/tools/split-sheets.d.ts +1 -1
  191. package/dist/tools/split-sheets.d.ts.map +1 -1
  192. package/dist/tools/split-sheets.js +1 -1
  193. package/dist/tools/split-sheets.js.map +1 -1
  194. package/dist/tools/team.d.ts +1 -1
  195. package/dist/tools/team.d.ts.map +1 -1
  196. package/dist/tools/team.js +1 -1
  197. package/dist/tools/team.js.map +1 -1
  198. package/dist/tools/telegram.d.ts +1 -1
  199. package/dist/tools/telegram.d.ts.map +1 -1
  200. package/dist/tools/telegram.js +1 -1
  201. package/dist/tools/telegram.js.map +1 -1
  202. package/dist/tools/uploads.d.ts +1 -1
  203. package/dist/tools/uploads.d.ts.map +1 -1
  204. package/dist/tools/uploads.js +1 -1
  205. package/dist/tools/uploads.js.map +1 -1
  206. package/dist/tools/works.d.ts +1 -1
  207. package/dist/tools/works.d.ts.map +1 -1
  208. package/dist/tools/works.js +1 -1
  209. package/dist/tools/works.js.map +1 -1
  210. package/package.json +3 -1
  211. package/.mcpregistry_github_token +0 -1
  212. package/.mcpregistry_registry_token +0 -1
  213. package/dist/apps/briefing.d.ts +0 -2
  214. package/dist/apps/briefing.d.ts.map +0 -1
  215. package/dist/apps/briefing.js +0 -308
  216. package/dist/apps/briefing.js.map +0 -1
  217. package/dist/pica-sdk.d.ts +0 -1181
  218. package/dist/pica-sdk.d.ts.map +0 -1
  219. package/dist/pica-sdk.js +0 -1419
  220. package/dist/pica-sdk.js.map +0 -1
  221. package/dist/tools/health.d.ts +0 -17
  222. package/dist/tools/health.d.ts.map +0 -1
  223. package/dist/tools/health.js +0 -67
  224. package/dist/tools/health.js.map +0 -1
  225. package/dist/tools/pica-score.d.ts +0 -15
  226. package/dist/tools/pica-score.d.ts.map +0 -1
  227. package/dist/tools/pica-score.js +0 -28
  228. package/dist/tools/pica-score.js.map +0 -1
  229. package/dist/tools/registration.d.ts +0 -16
  230. package/dist/tools/registration.d.ts.map +0 -1
  231. package/dist/tools/registration.js +0 -50
  232. package/dist/tools/registration.js.map +0 -1
  233. package/dist/utils/audit.d.ts +0 -28
  234. package/dist/utils/audit.d.ts.map +0 -1
  235. package/dist/utils/audit.js +0 -28
  236. package/dist/utils/audit.js.map +0 -1
  237. package/dist/utils/confirmation.d.ts +0 -12
  238. package/dist/utils/confirmation.d.ts.map +0 -1
  239. package/dist/utils/confirmation.js +0 -78
  240. package/dist/utils/confirmation.js.map +0 -1
  241. package/dist/utils/credentials.d.ts +0 -11
  242. package/dist/utils/credentials.d.ts.map +0 -1
  243. package/dist/utils/credentials.js +0 -47
  244. package/dist/utils/credentials.js.map +0 -1
  245. package/dist/utils/credit-gate.d.ts +0 -17
  246. package/dist/utils/credit-gate.d.ts.map +0 -1
  247. package/dist/utils/credit-gate.js +0 -100
  248. package/dist/utils/credit-gate.js.map +0 -1
  249. package/dist/utils/enrichment-format.d.ts +0 -31
  250. package/dist/utils/enrichment-format.d.ts.map +0 -1
  251. package/dist/utils/enrichment-format.js +0 -69
  252. package/dist/utils/enrichment-format.js.map +0 -1
  253. package/dist/utils/errors.d.ts +0 -29
  254. package/dist/utils/errors.d.ts.map +0 -1
  255. package/dist/utils/errors.js +0 -139
  256. package/dist/utils/errors.js.map +0 -1
  257. package/dist/utils/formatting.d.ts +0 -64
  258. package/dist/utils/formatting.d.ts.map +0 -1
  259. package/dist/utils/formatting.js +0 -153
  260. package/dist/utils/formatting.js.map +0 -1
  261. package/dist/utils/mpp.d.ts +0 -63
  262. package/dist/utils/mpp.d.ts.map +0 -1
  263. package/dist/utils/mpp.js +0 -137
  264. package/dist/utils/mpp.js.map +0 -1
  265. package/dist/utils/notify-parties.d.ts +0 -35
  266. package/dist/utils/notify-parties.d.ts.map +0 -1
  267. package/dist/utils/notify-parties.js +0 -59
  268. package/dist/utils/notify-parties.js.map +0 -1
  269. package/server.json +0 -30
@@ -1,100 +0,0 @@
1
- // Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
2
- import { chargeMpp, formatMppPrice, isMppConfigured, MPP_DEFAULT_CURRENCY, } from "./mpp.js";
3
- export const COST_MAP = {
4
- analysis_audio: 1,
5
- analysis_lyrics: 1,
6
- analysis_audio_identify: 3,
7
- external_mlc_lookup: 1,
8
- export_song_registration: 1,
9
- export_industry_csv: 1,
10
- export_catalog_asset_report: 5,
11
- };
12
- const GRACE_DEBT_LIMIT = -5;
13
- /** Operation names for MPP charge descriptions */
14
- const OPERATION_NAMES = {
15
- analysis_audio: "Audio analysis",
16
- analysis_lyrics: "Lyrics transcription",
17
- analysis_audio_identify: "Audio identification",
18
- external_mlc_lookup: "MLC enrichment",
19
- export_song_registration: "Song registration export",
20
- export_industry_csv: "Industry-ready export",
21
- export_catalog_asset_report: "Catalog asset report",
22
- };
23
- export function withCreditGate(pica, actionKey, operationName, executor) {
24
- const cost = COST_MAP[actionKey];
25
- if (!cost)
26
- return executor; // free or unknown — pass through
27
- return async (args) => {
28
- // --- Path 1: Check credit balance ---
29
- let balanceInsufficient = false;
30
- let available = 0;
31
- try {
32
- const balanceData = await pica.creditsBalance.getBalance();
33
- available =
34
- balanceData?.balance ??
35
- balanceData?.data?.balance ??
36
- 0;
37
- if (available - cost >= GRACE_DEBT_LIMIT) {
38
- // Sufficient credits — execute normally (API layer deducts)
39
- return executor(args);
40
- }
41
- balanceInsufficient = true;
42
- }
43
- catch {
44
- // Fail open on credit check errors — let the tool execute
45
- return executor(args);
46
- }
47
- // --- Balance insufficient from here ---
48
- // --- Path 2 & 3: Try MPP if configured ---
49
- if (balanceInsufficient && isMppConfigured()) {
50
- try {
51
- // Extract _meta from args if present (threaded from MCP request)
52
- const extra = args._meta ? { _meta: args._meta } : {};
53
- const currency = args._mpp_currency || MPP_DEFAULT_CURRENCY;
54
- const mppResult = await chargeMpp(cost, OPERATION_NAMES[actionKey] || operationName, currency, extra);
55
- if (mppResult) {
56
- if (mppResult.status === 402) {
57
- // Path 3: No credential — return payment challenge
58
- // The McpError will be thrown and handled by the MCP SDK
59
- throw mppResult.challenge;
60
- }
61
- // Path 2: Payment succeeded — execute and attach receipt
62
- const toolResult = await executor(args);
63
- return mppResult.withReceipt(toolResult);
64
- }
65
- }
66
- catch (error) {
67
- // Re-throw MCP payment errors (they're the 402 challenge)
68
- if (error &&
69
- typeof error === "object" &&
70
- "code" in error &&
71
- error.code === -32042) {
72
- throw error;
73
- }
74
- // MPP failed for other reason — fall through to insufficient_credits
75
- }
76
- }
77
- // --- Path 4: No MPP or MPP failed — return insufficient_credits ---
78
- const priceHint = isMppConfigured()
79
- ? ` (${formatMppPrice(cost)} via inline payment)`
80
- : "";
81
- return {
82
- content: [
83
- {
84
- type: "text",
85
- text: JSON.stringify({
86
- error: "insufficient_credits",
87
- message: `${operationName} costs ${cost} pica credit${cost !== 1 ? "s" : ""}, but you only have ${available}. Purchase more credits to continue.${priceHint}`,
88
- balance: available,
89
- cost,
90
- action: actionKey,
91
- purchase_hint: "Use pica_credits_purchase to get a checkout link, or visit /settings (credits tab).",
92
- fallback_url: "https://withpica.com/settings?tab=credits",
93
- }, null, 2),
94
- },
95
- ],
96
- isError: true,
97
- };
98
- };
99
- }
100
- //# sourceMappingURL=credit-gate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"credit-gate.js","sourceRoot":"","sources":["../../src/utils/credit-gate.ts"],"names":[],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- /**
2
- * Shared enrichment result formatting utilities
3
- *
4
- * Detects whether an enrichment call actually found data and formats
5
- * the response accordingly — matched / partial / no_match.
6
- * Prevents tools from returning unconditional success messages when
7
- * the API returned nothing. (ADR-149 Phase 2)
8
- */
9
- import { ToolResult } from "../tools/index.js";
10
- export type ResultQuality = "matched" | "partial" | "no_match";
11
- /**
12
- * Inspect the raw enrichment result and determine data quality.
13
- *
14
- * Resolution order:
15
- * 1. If the API already set `result_quality`, trust it.
16
- * 2. If `fieldsUpdated` is present, use count to decide.
17
- * 3. If `writers`/`publishers` arrays are present (MLC shape), check emptiness.
18
- * 4. If a non-empty `data` object is present, treat as matched.
19
- * 5. Default to `partial` — better than falsely claiming "no match".
20
- */
21
- export declare function detectResultQuality(result: unknown): ResultQuality;
22
- /**
23
- * Build a ToolResult for an enrichment call with quality signalling.
24
- *
25
- * @param entityType "work" | "person"
26
- * @param entityId The ID that was enriched
27
- * @param source Display name of the source ("MLC", "MusicBrainz", "general", …)
28
- * @param result Raw API response
29
- */
30
- export declare function formatEnrichmentResult(entityType: string, entityId: string, source: string, result: unknown): ToolResult;
31
- //# sourceMappingURL=enrichment-format.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enrichment-format.d.ts","sourceRoot":"","sources":["../../src/utils/enrichment-format.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/D;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CA+BlE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,GACd,UAAU,CA0BZ"}
@@ -1,69 +0,0 @@
1
- // Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
2
- /**
3
- * Inspect the raw enrichment result and determine data quality.
4
- *
5
- * Resolution order:
6
- * 1. If the API already set `result_quality`, trust it.
7
- * 2. If `fieldsUpdated` is present, use count to decide.
8
- * 3. If `writers`/`publishers` arrays are present (MLC shape), check emptiness.
9
- * 4. If a non-empty `data` object is present, treat as matched.
10
- * 5. Default to `partial` — better than falsely claiming "no match".
11
- */
12
- export function detectResultQuality(result) {
13
- if (!result || typeof result !== "object")
14
- return "no_match";
15
- const r = result;
16
- if (r.result_quality === "matched" || r.result_quality === "partial" || r.result_quality === "no_match") {
17
- return r.result_quality;
18
- }
19
- if (typeof r.fieldsUpdated === "number") {
20
- return r.fieldsUpdated > 0 ? "matched" : "no_match";
21
- }
22
- const hasWriters = Array.isArray(r.writers);
23
- const hasPublishers = Array.isArray(r.publishers);
24
- if (hasWriters || hasPublishers) {
25
- const writersEmpty = hasWriters && r.writers.length === 0;
26
- const publishersEmpty = hasPublishers && r.publishers.length === 0;
27
- if ((hasWriters ? writersEmpty : true) &&
28
- (hasPublishers ? publishersEmpty : true)) {
29
- return "no_match";
30
- }
31
- return "matched";
32
- }
33
- if (r.data && typeof r.data === "object" && Object.keys(r.data).length > 0) {
34
- return "matched";
35
- }
36
- return "partial";
37
- }
38
- /**
39
- * Build a ToolResult for an enrichment call with quality signalling.
40
- *
41
- * @param entityType "work" | "person"
42
- * @param entityId The ID that was enriched
43
- * @param source Display name of the source ("MLC", "MusicBrainz", "general", …)
44
- * @param result Raw API response
45
- */
46
- export function formatEnrichmentResult(entityType, entityId, source, result) {
47
- const quality = detectResultQuality(result);
48
- const messages = {
49
- matched: `${source} enrichment complete for ${entityType} ${entityId} — data found and applied`,
50
- partial: `${source} enrichment complete for ${entityType} ${entityId} — some data found`,
51
- no_match: `no ${source} match found for ${entityType} ${entityId}`,
52
- };
53
- const response = {
54
- success: true,
55
- message: messages[quality],
56
- result_quality: quality,
57
- data: result,
58
- };
59
- if (quality === "no_match") {
60
- response.suggestion =
61
- "try a different enrichment source for additional metadata";
62
- }
63
- const jsonText = JSON.stringify(response, null, 2);
64
- return {
65
- content: [{ type: "text", text: `${response.message}\n\n${jsonText}` }],
66
- structuredContent: response,
67
- };
68
- }
69
- //# sourceMappingURL=enrichment-format.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enrichment-format.js","sourceRoot":"","sources":["../../src/utils/enrichment-format.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAe7D;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC;IAC7D,MAAM,CAAC,GAAG,MAAiC,CAAC;IAE5C,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,IAAI,CAAC,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;QACxG,OAAO,CAAC,CAAC,cAA+B,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;IACtD,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,UAAU,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,UAAU,IAAK,CAAC,CAAC,OAAqB,CAAC,MAAM,KAAK,CAAC,CAAC;QACzE,MAAM,eAAe,GAAG,aAAa,IAAK,CAAC,CAAC,UAAwB,CAAC,MAAM,KAAK,CAAC,CAAC;QAClF,IACE,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;YAClC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,EACxC,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAkB,EAClB,QAAgB,EAChB,MAAc,EACd,MAAe;IAEf,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE5C,MAAM,QAAQ,GAAkC;QAC9C,OAAO,EAAE,GAAG,MAAM,4BAA4B,UAAU,IAAI,QAAQ,2BAA2B;QAC/F,OAAO,EAAE,GAAG,MAAM,4BAA4B,UAAU,IAAI,QAAQ,oBAAoB;QACxF,QAAQ,EAAE,MAAM,MAAM,oBAAoB,UAAU,IAAI,QAAQ,EAAE;KACnE,CAAC;IAEF,MAAM,QAAQ,GAA4B;QACxC,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;QAC1B,cAAc,EAAE,OAAO;QACvB,IAAI,EAAE,MAAM;KACb,CAAC;IAEF,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,QAAQ,CAAC,UAAU;YACjB,2DAA2D,CAAC;IAChE,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACnD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,OAAO,OAAO,QAAQ,EAAE,EAAE,CAAC;QACvE,iBAAiB,EAAE,QAAQ;KAC5B,CAAC;AACJ,CAAC"}
@@ -1,29 +0,0 @@
1
- /**
2
- * Error handling utilities for MCP server
3
- */
4
- export declare class McpServerError extends Error {
5
- code: string;
6
- details?: any | undefined;
7
- constructor(message: string, code: string, details?: any | undefined);
8
- }
9
- export declare class AuthenticationError extends McpServerError {
10
- constructor(message?: string, details?: any);
11
- }
12
- export declare class ToolExecutionError extends McpServerError {
13
- constructor(message: string, details?: any);
14
- }
15
- export declare class ResourceError extends McpServerError {
16
- constructor(message: string, details?: any);
17
- }
18
- /**
19
- * Format error for MCP response
20
- */
21
- export declare function formatError(error: any): {
22
- type: string;
23
- text: string;
24
- };
25
- /**
26
- * Log error with structured context (JSON to stderr for machine parsing)
27
- */
28
- export declare function logError(context: string, error: any): void;
29
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,qBAAa,cAAe,SAAQ,KAAK;IAG9B,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC,EAAE,GAAG;gBAFpB,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,GAAG,YAAA;CAMvB;AAED,qBAAa,mBAAoB,SAAQ,cAAc;gBACzC,OAAO,GAAE,MAAgC,EAAE,OAAO,CAAC,EAAE,GAAG;CAIrE;AAED,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;CAI3C;AAED,qBAAa,aAAc,SAAQ,cAAc;gBACnC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;CAI3C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAwHtE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAc1D"}
@@ -1,139 +0,0 @@
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
- const status = error?.status;
39
- const rawMessage = error instanceof Error ? error.message : error?.message || String(error);
40
- // Attempt to parse structured error body from API responses
41
- let structuredBody = null;
42
- try {
43
- if (typeof rawMessage === "string" && rawMessage.startsWith("{")) {
44
- structuredBody = JSON.parse(rawMessage);
45
- }
46
- }
47
- catch {
48
- // Not JSON — use raw message
49
- }
50
- if (error instanceof McpServerError) {
51
- return {
52
- type: "text",
53
- text: JSON.stringify({
54
- error: error.code,
55
- message: error.message,
56
- details: error.details,
57
- retry_safe: false,
58
- }, null, 2),
59
- };
60
- }
61
- // Classify ApiError from SDK layer
62
- if (status === 0 ||
63
- (error instanceof Error && error.message?.includes("timed out"))) {
64
- return {
65
- type: "text",
66
- text: JSON.stringify({
67
- error: "REQUEST_TIMEOUT",
68
- message: "API request timed out after retries. The server may be slow or unreachable.",
69
- retry_safe: true,
70
- suggestion: "wait a moment and try again",
71
- }, null, 2),
72
- };
73
- }
74
- if (status === 401 || status === 403) {
75
- return {
76
- type: "text",
77
- text: JSON.stringify({
78
- error: "AUTHENTICATION_ERROR",
79
- message: "API authentication failed. Check your PICA_API_KEY is valid.",
80
- status,
81
- retry_safe: false,
82
- suggestion: "your API key may be invalid or expired — check your PICA settings",
83
- }, null, 2),
84
- };
85
- }
86
- if (status === 429) {
87
- return {
88
- type: "text",
89
- text: JSON.stringify({
90
- error: "RATE_LIMITED",
91
- message: "API rate limit exceeded after retries. Try again in a moment.",
92
- status,
93
- retry_safe: true,
94
- suggestion: "wait a moment and try again",
95
- }, null, 2),
96
- };
97
- }
98
- // Structured error body from API — propagate domain-specific codes
99
- if (structuredBody?.error_code) {
100
- return {
101
- type: "text",
102
- text: JSON.stringify({
103
- error: structuredBody.error_code,
104
- message: structuredBody.message || rawMessage,
105
- details: structuredBody.details,
106
- retry_safe: false,
107
- }, null, 2),
108
- };
109
- }
110
- // Generic fallback
111
- const message = error instanceof Error ? error.message : String(error);
112
- return {
113
- type: "text",
114
- text: JSON.stringify({
115
- error: "UNKNOWN_ERROR",
116
- message,
117
- retry_safe: false,
118
- }, null, 2),
119
- };
120
- }
121
- /**
122
- * Log error with structured context (JSON to stderr for machine parsing)
123
- */
124
- export function logError(context, error) {
125
- const entry = {
126
- level: "error",
127
- context,
128
- message: error instanceof Error ? error.message : String(error),
129
- timestamp: new Date().toISOString(),
130
- };
131
- if (error?.status)
132
- entry.status = error.status;
133
- if (error?.retryable !== undefined)
134
- entry.retryable = error.retryable;
135
- if (error instanceof Error && error.stack)
136
- entry.stack = error.stack;
137
- console.error(JSON.stringify(entry));
138
- }
139
- //# sourceMappingURL=errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
@@ -1,64 +0,0 @@
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(message: string, data?: any, completionHints?: CompletionHint[]): FormattedResult;
36
- /**
37
- * Map raw gap objects from the completeness API into CompletionHints.
38
- * The API response shape varies — this handles the known field names.
39
- */
40
- export declare function mapGapsToHints(gaps: any[], limit?: number): CompletionHint[];
41
- /**
42
- * Format array of items with count
43
- */
44
- export declare function formatList<T>(items: T[], metadata?: Record<string, any>): FormattedResult;
45
- /**
46
- * Truncate text to max length
47
- */
48
- export declare function truncate(text: string, maxLength?: number): string;
49
- /**
50
- * Format validation error
51
- */
52
- export declare function formatValidationError(fields: Record<string, string>): FormattedResult;
53
- /**
54
- * Format structured response with dual content blocks:
55
- * - Human-readable text (includes full JSON so all MCP clients can read it)
56
- * - Machine-parseable structuredContent object
57
- */
58
- export declare function formatStructured(data: any, summary?: string): FormattedResult;
59
- /**
60
- * Format a list with both human summary and structured JSON
61
- */
62
- export declare function formatStructuredList<T>(items: T[], entityName: string, metadata?: Record<string, any>): FormattedResult;
63
- export declare function guardResponseSize(text: string, toolName: string): string;
64
- //# sourceMappingURL=formatting.d.ts.map
@@ -1 +0,0 @@
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,CAQvD;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;AAWD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAkBxE"}
@@ -1,153 +0,0 @@
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
- // Round-trip through JSON to ensure structuredContent is a plain object
7
- // (raw API responses may contain class instances or Date objects that fail MCP validation)
8
- const serialized = JSON.stringify(data, null, 2);
9
- return {
10
- content: [{ type: "text", text: serialized }],
11
- structuredContent: JSON.parse(serialized),
12
- };
13
- }
14
- /**
15
- * Format success message, with optional completion hints for the guided loop.
16
- *
17
- * Completion hints are structured data appended to the response so the LLM
18
- * can naturally suggest the next step without PICA dictating the conversation.
19
- * If no hints are provided, the response is identical to the old format.
20
- */
21
- export function formatSuccess(message, data, completionHints) {
22
- const response = {
23
- success: true,
24
- message,
25
- };
26
- if (data !== undefined) {
27
- response.data = data;
28
- }
29
- if (completionHints && completionHints.length > 0) {
30
- response.completion_hints = completionHints;
31
- // Append a human-readable summary so all LLMs can see the hints
32
- const hintLines = completionHints
33
- .map((h) => `- ${h.suggestion}${h.count ? ` (${h.count} works)` : ""}`)
34
- .join("\n");
35
- message += `\n\nNext steps you could take:\n${hintLines}`;
36
- response.message = message; // Keep structuredContent in sync with text
37
- }
38
- const jsonText = JSON.stringify(response, null, 2);
39
- return {
40
- content: [{ type: "text", text: `${message}\n\n${jsonText}` }],
41
- structuredContent: response,
42
- };
43
- }
44
- /**
45
- * Map raw gap objects from the completeness API into CompletionHints.
46
- * The API response shape varies — this handles the known field names.
47
- */
48
- export function mapGapsToHints(gaps, limit = 5) {
49
- if (!Array.isArray(gaps))
50
- return [];
51
- return gaps.slice(0, limit).map((g) => ({
52
- gap: g.key || g.field || g.type || "unknown",
53
- suggestion: g.suggestion || g.label || g.description || "",
54
- severity: g.severity || "important",
55
- }));
56
- }
57
- /**
58
- * Format array of items with count
59
- */
60
- export function formatList(items, metadata) {
61
- const response = {
62
- count: items.length,
63
- items,
64
- };
65
- if (metadata) {
66
- response.metadata = metadata;
67
- }
68
- const summary = `Found ${items.length} item${items.length !== 1 ? "s" : ""}.`;
69
- const jsonText = JSON.stringify(response, null, 2);
70
- return {
71
- content: [
72
- {
73
- type: "text",
74
- text: `${summary}\n\n${jsonText}`,
75
- },
76
- ],
77
- structuredContent: response,
78
- };
79
- }
80
- /**
81
- * Truncate text to max length
82
- */
83
- export function truncate(text, maxLength = 1000) {
84
- if (text.length <= maxLength) {
85
- return text;
86
- }
87
- return text.substring(0, maxLength) + "... (truncated)";
88
- }
89
- /**
90
- * Format validation error
91
- */
92
- export function formatValidationError(fields) {
93
- const structured = {
94
- error: "VALIDATION_ERROR",
95
- message: "Validation failed",
96
- fields,
97
- };
98
- return {
99
- content: [{ type: "text", text: JSON.stringify(structured, null, 2) }],
100
- structuredContent: structured,
101
- };
102
- }
103
- /**
104
- * Format structured response with dual content blocks:
105
- * - Human-readable text (includes full JSON so all MCP clients can read it)
106
- * - Machine-parseable structuredContent object
107
- */
108
- export function formatStructured(data, summary) {
109
- const jsonText = JSON.stringify(data, null, 2);
110
- return {
111
- content: [
112
- {
113
- type: "text",
114
- text: summary ? `${summary}\n\n${jsonText}` : jsonText,
115
- },
116
- ],
117
- structuredContent: data,
118
- };
119
- }
120
- /**
121
- * Format a list with both human summary and structured JSON
122
- */
123
- export function formatStructuredList(items, entityName, metadata) {
124
- const count = items.length;
125
- const summary = `Found ${count} ${entityName}${count !== 1 ? "s" : ""}${metadata?.query ? ` matching "${metadata.query}"` : ""}.`;
126
- return formatStructured({ count, items, ...metadata }, summary);
127
- }
128
- /**
129
- * Guard against oversized tool responses that would blow the agent's context window.
130
- * Block playbook: "Check byte size before returning text."
131
- * Lowin: "Respect the token budget."
132
- *
133
- * Threshold: 100KB (~25K tokens). Truncates with recovery instructions.
134
- */
135
- const MAX_RESPONSE_BYTES = 100_000;
136
- export function guardResponseSize(text, toolName) {
137
- const byteSize = Buffer.byteLength(text, "utf8");
138
- if (byteSize <= MAX_RESPONSE_BYTES) {
139
- return text;
140
- }
141
- // Truncate by chars (conservative — multi-byte chars mean fewer chars than bytes)
142
- const truncated = text.substring(0, MAX_RESPONSE_BYTES);
143
- const recovery = [
144
- "\n\n---",
145
- `TRUNCATED: Response from ${toolName} exceeded 100KB (was ${Math.round(byteSize / 1024)}KB).`,
146
- "To get complete results, narrow your query:",
147
- "- Use a smaller 'limit' parameter (e.g. limit=10)",
148
- "- Add search/filter parameters to reduce results",
149
- '- Use a more specific tool (e.g. pica_works_inspect with sections: ["basic"] instead of pica_works_query)',
150
- ].join("\n");
151
- return truncated + recovery;
152
- }
153
- //# sourceMappingURL=formatting.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"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"}