@withpica/mcp-server 2.33.0 → 2.39.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 (64) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/dist/apps/release.d.ts +2 -0
  3. package/dist/apps/release.d.ts.map +1 -0
  4. package/dist/apps/release.js +69 -0
  5. package/dist/apps/release.js.map +1 -0
  6. package/dist/resources/index.d.ts.map +1 -1
  7. package/dist/resources/index.js +16 -0
  8. package/dist/resources/index.js.map +1 -1
  9. package/dist/server-instructions.d.ts +28 -0
  10. package/dist/server-instructions.d.ts.map +1 -1
  11. package/dist/server-instructions.js +34 -0
  12. package/dist/server-instructions.js.map +1 -1
  13. package/dist/server.d.ts.map +1 -1
  14. package/dist/server.js +11 -2
  15. package/dist/server.js.map +1 -1
  16. package/dist/tools/app-tools.d.ts.map +1 -1
  17. package/dist/tools/app-tools.js +39 -18
  18. package/dist/tools/app-tools.js.map +1 -1
  19. package/dist/tools/credits.d.ts +23 -0
  20. package/dist/tools/credits.d.ts.map +1 -1
  21. package/dist/tools/credits.js +199 -0
  22. package/dist/tools/credits.js.map +1 -1
  23. package/dist/tools/discovery.d.ts.map +1 -1
  24. package/dist/tools/discovery.js +24 -2
  25. package/dist/tools/discovery.js.map +1 -1
  26. package/dist/tools/index.d.ts +15 -6
  27. package/dist/tools/index.d.ts.map +1 -1
  28. package/dist/tools/index.js +64 -9
  29. package/dist/tools/index.js.map +1 -1
  30. package/dist/tools/metadata.d.ts.map +1 -1
  31. package/dist/tools/metadata.js +39 -0
  32. package/dist/tools/metadata.js.map +1 -1
  33. package/dist/tools/public-filter.d.ts.map +1 -1
  34. package/dist/tools/public-filter.js +2 -0
  35. package/dist/tools/public-filter.js.map +1 -1
  36. package/dist/tools/recording-attribution-hints.d.ts +24 -0
  37. package/dist/tools/recording-attribution-hints.d.ts.map +1 -0
  38. package/dist/tools/recording-attribution-hints.js +27 -0
  39. package/dist/tools/recording-attribution-hints.js.map +1 -0
  40. package/dist/tools/recordings.d.ts.map +1 -1
  41. package/dist/tools/recordings.js +30 -3
  42. package/dist/tools/recordings.js.map +1 -1
  43. package/dist/tools/release-rich.d.ts +31 -0
  44. package/dist/tools/release-rich.d.ts.map +1 -0
  45. package/dist/tools/release-rich.js +240 -0
  46. package/dist/tools/release-rich.js.map +1 -0
  47. package/dist/tools/signup.d.ts +26 -0
  48. package/dist/tools/signup.d.ts.map +1 -0
  49. package/dist/tools/signup.js +265 -0
  50. package/dist/tools/signup.js.map +1 -0
  51. package/dist/tools/subscription.d.ts +60 -0
  52. package/dist/tools/subscription.d.ts.map +1 -0
  53. package/dist/tools/subscription.js +440 -0
  54. package/dist/tools/subscription.js.map +1 -0
  55. package/package.json +3 -3
  56. package/server.json +2 -2
  57. package/dist/__mocks__/mppx-mcp-sdk-server.d.ts +0 -6
  58. package/dist/__mocks__/mppx-mcp-sdk-server.d.ts.map +0 -1
  59. package/dist/__mocks__/mppx-mcp-sdk-server.js +0 -6
  60. package/dist/__mocks__/mppx-mcp-sdk-server.js.map +0 -1
  61. package/dist/__mocks__/mppx-server.d.ts +0 -12
  62. package/dist/__mocks__/mppx-server.d.ts.map +0 -1
  63. package/dist/__mocks__/mppx-server.js +0 -12
  64. package/dist/__mocks__/mppx-server.js.map +0 -1
@@ -0,0 +1,265 @@
1
+ // Copyright (c) 2024-2026 Withpica Ltd. All rights reserved.
2
+ /**
3
+ * Signup Tools — `pica_signup_start` (ADR-211 Phase 1).
4
+ *
5
+ * The single MCP-discoverable signup verb. Available unauthenticated on
6
+ * BOTH transports (stdio binary's lobby + HTTP `/api/mcp` anonymous mode)
7
+ * per ADR-211 § Primitive A (amended 2026-04-30 to expose alongside
8
+ * `pica_sign_in` / `pica_sign_out` rather than replace them in Phase 1).
9
+ *
10
+ * Mints nothing locally — every invocation calls the public backend
11
+ * endpoint `POST /api/public/onboarding/signup-start`. The signing secret
12
+ * (`ONBOARDING_TOKEN_SECRET`) lives only on the backend; customer-
13
+ * distributed `npx @withpica/mcp-server` binaries can never see it. Same
14
+ * pattern that `pica_sign_in` (auth.ts) uses to call the public
15
+ * `/api/public/mcp-auth/authorize` magic-link endpoint.
16
+ *
17
+ * Returns the JWT-bound URL via:
18
+ * - `resource_link` (universal floor — every MCP client can render this)
19
+ * - capability-gated `elicitation/create url` (mode: "url"; for clients
20
+ * advertising `capabilities.elicitation.url`, server-issued consent
21
+ * prompt to open the link in-line). See ADR-200 + `pica_upload`.
22
+ *
23
+ * Construction takes the API base URL + transport + optional DCR
24
+ * client_id. The stdio binary stamps `transport: "stdio"`; the HTTP
25
+ * carve-out in `app/api/mcp/route.ts` stamps `transport: "http"` and
26
+ * passes `client_id` from the OAuth-protected-resource discovery context
27
+ * when one is present.
28
+ */
29
+ import { randomUUID } from "node:crypto";
30
+ import { clientSupportsUrlElicitation } from "@withpica/mcp-utils";
31
+ const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
32
+ export class SignupTools {
33
+ apiUrl;
34
+ transport;
35
+ clientId;
36
+ constructor(config) {
37
+ if (!config.apiUrl) {
38
+ throw new Error("SignupTools requires apiUrl");
39
+ }
40
+ if (config.transport !== "stdio" && config.transport !== "http") {
41
+ throw new Error(`SignupTools.transport must be "stdio" or "http" (got: ${config.transport})`);
42
+ }
43
+ if (config.transport === "stdio" && config.clientId) {
44
+ // stdio has no DCR client identifier. Constructor enforces the
45
+ // invariant locally so the public endpoint never sees a confused
46
+ // pairing in the first place.
47
+ throw new Error("clientId must be null for stdio transport");
48
+ }
49
+ this.apiUrl = config.apiUrl.replace(/\/+$/, "");
50
+ this.transport = config.transport;
51
+ this.clientId = config.clientId ?? null;
52
+ }
53
+ getTools() {
54
+ return [
55
+ {
56
+ definition: {
57
+ name: "pica_signup_start",
58
+ description: "Sign up for withPICA from inside the agent, without leaving the chat. " +
59
+ "Use this when the user wants to create a new withPICA account / catalog " +
60
+ "and you're talking to them through an unauthenticated MCP connection " +
61
+ "(stdio without an API key, or HTTP without a Bearer token). The tool " +
62
+ "mints a single-use signup link valid for 15 minutes — surface the URL " +
63
+ "to the user as a clickable resource_link. The link opens a page that " +
64
+ "verifies their email by magic-link, creates their organisation, starts " +
65
+ "the 14-day free trial, and (for stdio) shows a connection key to paste " +
66
+ "into Claude Desktop's MCP config or (for HTTP) resumes the OAuth flow. " +
67
+ "ADR-211 Phase 1. For existing users, prefer pica_sign_in.",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ email: {
72
+ type: "string",
73
+ description: "The user's email address. The signup link is sent to this " +
74
+ "inbox; the user clicks it to verify ownership before any " +
75
+ "account is created. Required.",
76
+ },
77
+ org_name: {
78
+ type: "string",
79
+ description: "Optional human name for the user's catalog/organisation. " +
80
+ "Defaults to '<email-localpart>'s catalog' if omitted. " +
81
+ "Editable later in settings.",
82
+ },
83
+ purpose: {
84
+ type: "string",
85
+ description: "Optional free-text — what the user is trying to do with " +
86
+ "PICA, captured for product analytics (e.g. 'managing my " +
87
+ "first album credits', 'exporting royalty statements'). " +
88
+ "Not surfaced to the user.",
89
+ },
90
+ },
91
+ required: ["email"],
92
+ },
93
+ },
94
+ executor: this.signupStart.bind(this),
95
+ },
96
+ ];
97
+ }
98
+ async signupStart(args, ctx) {
99
+ const email = typeof args.email === "string" ? args.email.trim().toLowerCase() : "";
100
+ if (!email || !EMAIL_REGEX.test(email)) {
101
+ return {
102
+ content: [
103
+ {
104
+ type: "text",
105
+ text: "that doesn't look like an email address — please ask the user to confirm and try again.",
106
+ },
107
+ ],
108
+ isError: true,
109
+ };
110
+ }
111
+ const orgName = typeof args.org_name === "string" && args.org_name.trim().length > 0
112
+ ? args.org_name.trim()
113
+ : undefined;
114
+ const purpose = typeof args.purpose === "string" && args.purpose.trim().length > 0
115
+ ? args.purpose.trim()
116
+ : undefined;
117
+ // The public endpoint is unauthenticated — same fetch shape as
118
+ // pica_sign_in's call to /api/public/mcp-auth/authorize.
119
+ const endpoint = `${this.apiUrl}/public/onboarding/signup-start`;
120
+ let response;
121
+ try {
122
+ response = await fetch(endpoint, {
123
+ method: "POST",
124
+ headers: { "Content-Type": "application/json" },
125
+ body: JSON.stringify({
126
+ email,
127
+ ...(orgName ? { org_name: orgName } : {}),
128
+ ...(purpose ? { purpose } : {}),
129
+ transport: this.transport,
130
+ ...(this.clientId ? { client_id: this.clientId } : {}),
131
+ }),
132
+ });
133
+ }
134
+ catch (err) {
135
+ const message = err instanceof Error ? err.message : "network error";
136
+ return {
137
+ content: [
138
+ {
139
+ type: "text",
140
+ text: `couldn't reach withPICA to mint your signup link (${message}). check your internet connection and try again.`,
141
+ },
142
+ ],
143
+ isError: true,
144
+ };
145
+ }
146
+ if (response.status === 429) {
147
+ const retryAfter = response.headers.get("Retry-After") ?? "a few minutes";
148
+ return {
149
+ content: [
150
+ {
151
+ type: "text",
152
+ text: `too many signup attempts — please wait ${retryAfter} seconds before trying again. if the user just requested a link, ask them to check their inbox first.`,
153
+ },
154
+ ],
155
+ isError: true,
156
+ };
157
+ }
158
+ if (!response.ok) {
159
+ let detail = "unknown error";
160
+ try {
161
+ const body = (await response.json());
162
+ if (typeof body.error === "string")
163
+ detail = body.error;
164
+ }
165
+ catch {
166
+ // body wasn't JSON — fall back to status text
167
+ detail = response.statusText || detail;
168
+ }
169
+ return {
170
+ content: [
171
+ {
172
+ type: "text",
173
+ text: `couldn't mint your signup link: ${detail}. please try again or report this if it keeps happening.`,
174
+ },
175
+ ],
176
+ isError: true,
177
+ };
178
+ }
179
+ let body;
180
+ try {
181
+ body = (await response.json());
182
+ }
183
+ catch {
184
+ return {
185
+ content: [
186
+ {
187
+ type: "text",
188
+ text: "the signup endpoint returned a malformed response. please try again.",
189
+ },
190
+ ],
191
+ isError: true,
192
+ };
193
+ }
194
+ if (!body.url || !body.expires_at) {
195
+ return {
196
+ content: [
197
+ {
198
+ type: "text",
199
+ text: "the signup endpoint returned an incomplete response. please try again.",
200
+ },
201
+ ],
202
+ isError: true,
203
+ };
204
+ }
205
+ const url = body.url;
206
+ const expiresAt = body.expires_at;
207
+ const textSummary = `signup link minted for ${email}. surface this URL to the user — they should click it to verify ownership of the email, ` +
208
+ `pick an organisation name, and start their 14-day trial. the link expires at ${expiresAt} (15 minutes from now). ` +
209
+ (this.transport === "stdio"
210
+ ? "after they finish signup the page will show a connection key to paste into Claude Desktop's MCP config; they'll then need to reconnect the PICA MCP server."
211
+ : "after they finish signup the OAuth flow resumes automatically.");
212
+ const resourceLink = {
213
+ type: "resource_link",
214
+ uri: url,
215
+ name: "Sign up for withPICA",
216
+ description: "Open this link to verify your email, create your catalog, and start a 14-day trial.",
217
+ mimeType: "text/html",
218
+ };
219
+ const baseContent = [
220
+ {
221
+ type: "text",
222
+ text: JSON.stringify({
223
+ text_summary: textSummary,
224
+ signup_url: url,
225
+ expires_at: expiresAt,
226
+ surface: body.surface ?? "onboarding",
227
+ }),
228
+ },
229
+ resourceLink,
230
+ ];
231
+ // Capability-gated `elicitation/create url` — clients advertising
232
+ // `capabilities.elicitation.url` get a server-issued consent prompt
233
+ // to open the link in-line. Without the gate, calling elicitInput
234
+ // against a non-supporter throws synchronously per
235
+ // `feedback_mcp_sdk_capability_gates_elicitation.md`.
236
+ if (clientSupportsUrlElicitation(ctx?.server)) {
237
+ try {
238
+ await ctx.server.elicitInput({
239
+ mode: "url",
240
+ url,
241
+ elicitationId: `pica-signup-${randomUUID()}`,
242
+ message: `Open this URL to finish signing up for withPICA. Expires at ${expiresAt}.`,
243
+ }, { timeout: 60_000 });
244
+ }
245
+ catch {
246
+ // user declined / cancelled / timed out — `resource_link` remains
247
+ // usable so we degrade silently rather than fail the tool.
248
+ }
249
+ }
250
+ return {
251
+ content: baseContent,
252
+ structuredContent: {
253
+ kind: "pica.card.signup_start",
254
+ version: 1,
255
+ data: {
256
+ signup_url: url,
257
+ expires_at: expiresAt,
258
+ email,
259
+ transport: this.transport,
260
+ },
261
+ },
262
+ };
263
+ }
264
+ }
265
+ //# sourceMappingURL=signup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/tools/signup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { PicaClient, type BillingTier, type SubscriptionStatusResponse } from "@withpica/mcp-sdk";
2
+ import { ToolDefinition, ToolExecutor } from "./index.js";
3
+ interface SubscriptionStatusFlat {
4
+ billing_state: "trial" | "active" | "hibernated";
5
+ trial_days_remaining: number | null;
6
+ trial_ends_at: string | null;
7
+ current_tier: BillingTier | null;
8
+ capacity_used: number;
9
+ capacity_limit: number | null;
10
+ capacity_pct: number;
11
+ recommended_tier: BillingTier | null;
12
+ summary: string;
13
+ }
14
+ /**
15
+ * Compose the flat 9-field response from the existing GET admin route's
16
+ * shape. Mirrors `getOrgBillingSlice`'s "no meaningful cap" rule for
17
+ * `capacity_pct` (0 whenever current_tier is null OR enterprise) and
18
+ * carries through `overflow.recommendedTier` (already
19
+ * `inferTierFromCount`-derived) per Stage 1 Q2.
20
+ *
21
+ * Exported for unit tests.
22
+ */
23
+ export declare function flattenStatus(status: SubscriptionStatusResponse): SubscriptionStatusFlat;
24
+ /**
25
+ * Server-side template per Stage 1 Q1 option A. Predictable wording,
26
+ * less variance across connectors. Phase 2.5 may add agent
27
+ * paraphrasing if telemetry shows demand.
28
+ *
29
+ * Exported for unit tests.
30
+ */
31
+ export declare function composeSummary(fields: {
32
+ billing_state: "trial" | "active" | "hibernated";
33
+ trial_days_remaining: number | null;
34
+ current_tier: BillingTier | null;
35
+ capacity_used: number;
36
+ capacity_limit: number | null;
37
+ recommended_tier: BillingTier | null;
38
+ }): string;
39
+ export declare class SubscriptionTools {
40
+ private pica;
41
+ constructor(pica: PicaClient);
42
+ getTools(): Array<{
43
+ definition: ToolDefinition;
44
+ executor: ToolExecutor;
45
+ }>;
46
+ private status;
47
+ private manage;
48
+ /**
49
+ * Universal-floor return per ADR-200 Phase 1: every successful manage
50
+ * response carries a `resource_link` so any compliant MCP client can
51
+ * render or open the URL. Clients that advertise
52
+ * `capabilities.elicitation.url` additionally receive a server-issued
53
+ * elicitation/create request — the gate is mandatory because
54
+ * `elicitInput` with `mode: "url"` throws synchronously against
55
+ * non-supporters (`feedback_mcp_sdk_capability_gates_elicitation.md`).
56
+ */
57
+ private buildLinkResult;
58
+ }
59
+ export {};
60
+ //# sourceMappingURL=subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/tools/subscription.ts"],"names":[],"mappings":"AA8BA,OAAO,EACL,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,0BAA0B,EAChC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,cAAc,EACd,YAAY,EAGb,MAAM,YAAY,CAAC;AAoBpB,UAAU,sBAAsB;IAC9B,aAAa,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,CAAC;IACjD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,0BAA0B,GACjC,sBAAsB,CA+CxB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,aAAa,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,CAAC;IACjD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,WAAW,GAAG,IAAI,CAAC;CACtC,GAAG,MAAM,CA6CT;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,KAAK,CAAC;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;YAmF3D,MAAM;YAkCN,MAAM;IA4JpB;;;;;;;;OAQG;YACW,eAAe;CA2D9B"}