@solvapay/react 1.0.9-preview.1 → 1.0.9
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/CHANGELOG.md +209 -0
- package/CONTRIBUTING.md +117 -0
- package/README.md +426 -24
- package/dist/adapters/auth.d.cts +13 -0
- package/dist/adapters/auth.d.ts +13 -0
- package/dist/adapters/auth.js +1 -0
- package/dist/chunk-37R5NZGF.js +4824 -0
- package/dist/chunk-HWVJL5X6.js +429 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/chunk-R2ZPZ7VM.js +597 -0
- package/dist/chunk-ZAV7CQ4G.js +361 -0
- package/dist/index-WBjulQHf.d.cts +3656 -0
- package/dist/index-onWNU7iT.d.ts +3656 -0
- package/dist/index.cjs +5556 -1143
- package/dist/index.d.cts +618 -708
- package/dist/index.d.ts +618 -708
- package/dist/index.js +597 -1664
- package/dist/mcp/index.cjs +8096 -0
- package/dist/mcp/index.d.cts +1013 -0
- package/dist/mcp/index.d.ts +1013 -0
- package/dist/mcp/index.js +2724 -0
- package/dist/mcp/styles.css +1020 -0
- package/dist/primitives/index.cjs +5316 -0
- package/dist/primitives/index.d.cts +721 -0
- package/dist/primitives/index.d.ts +721 -0
- package/dist/primitives/index.js +232 -0
- package/dist/styles.css +1115 -0
- package/dist/useUsage-BmOYXxgG.d.cts +413 -0
- package/dist/useUsage-nD7zwSbG.d.ts +413 -0
- package/dist/webapi-K5XBCEO6.js +3775 -0
- package/package.json +37 -6
|
@@ -0,0 +1,1013 @@
|
|
|
1
|
+
import { s as SolvaPayTransport, t as PaywallStructuredContent, Q as SolvaPayProviderInitial, x as SolvaPayConfig } from '../index-onWNU7iT.js';
|
|
2
|
+
import { TOOL_FOR_VIEW, SolvaPayMcpViewKind, NudgeSpec, BootstrapMerchant, BootstrapProduct, BootstrapPlan, BootstrapCustomer } from '@solvapay/mcp-core';
|
|
3
|
+
export { MCP_TOOL_NAMES, McpToolName } from '@solvapay/mcp-core';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import '@stripe/stripe-js';
|
|
7
|
+
import '../adapters/auth.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* MCP App adapter — produces a `SolvaPayTransport` that routes every call
|
|
11
|
+
* through `app.callServerTool` instead of HTTP.
|
|
12
|
+
*
|
|
13
|
+
* Use with `SolvaPayProvider` when the React tree is hosted inside an
|
|
14
|
+
* MCP App (where Stripe.js and direct HTTP to your backend are both
|
|
15
|
+
* blocked by the host sandbox):
|
|
16
|
+
*
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { App } from '@modelcontextprotocol/ext-apps'
|
|
19
|
+
* import { SolvaPayProvider } from '@solvapay/react'
|
|
20
|
+
* import { createMcpAppAdapter } from '@solvapay/react/mcp'
|
|
21
|
+
*
|
|
22
|
+
* const app = new App({ name: 'solvapay', version: '1.0.0' })
|
|
23
|
+
* const transport = createMcpAppAdapter(app)
|
|
24
|
+
*
|
|
25
|
+
* <SolvaPayProvider config={{ transport }}>...</SolvaPayProvider>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* The adapter is tool-name-based: unimplemented tools surface as errors from
|
|
29
|
+
* the MCP server, which are re-thrown with the server's text payload as the
|
|
30
|
+
* message. Call sites can feature-detect by catching and matching.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Minimal shape of `@modelcontextprotocol/sdk` `CallToolResult` — kept here
|
|
35
|
+
* so consumers don't need `@modelcontextprotocol/sdk` installed just to
|
|
36
|
+
* satisfy TypeScript when they use the adapter.
|
|
37
|
+
*/
|
|
38
|
+
interface CallToolResultLike$1 {
|
|
39
|
+
isError?: boolean;
|
|
40
|
+
structuredContent?: unknown;
|
|
41
|
+
content?: Array<{
|
|
42
|
+
type: string;
|
|
43
|
+
text?: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Minimal shape of `@modelcontextprotocol/ext-apps` `App` — see the package
|
|
48
|
+
* docs for the full interface. We only depend on `callServerTool`, so any
|
|
49
|
+
* object satisfying this shape works (easier to mock in tests).
|
|
50
|
+
*/
|
|
51
|
+
interface McpAppLike {
|
|
52
|
+
callServerTool: (input: {
|
|
53
|
+
name: string;
|
|
54
|
+
arguments?: Record<string, unknown>;
|
|
55
|
+
}) => Promise<CallToolResultLike$1>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Wrap an MCP App (or any object implementing `callServerTool`) as a
|
|
59
|
+
* `SolvaPayTransport`. Every provider-level data-access call tunnels
|
|
60
|
+
* through `app.callServerTool(toolName, args)`.
|
|
61
|
+
*/
|
|
62
|
+
declare function createMcpAppAdapter(app: McpAppLike): SolvaPayTransport;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Probe whether `@stripe/stripe-js` can mount inside the current MCP host
|
|
66
|
+
* sandbox. Compliant hosts (basic-host, ChatGPT) honour the declared
|
|
67
|
+
* `_meta.ui.csp.frameDomains` and Stripe loads normally; non-compliant
|
|
68
|
+
* hosts (Claude today — see anthropics/claude-ai-mcp#40) hardcode
|
|
69
|
+
* `frame-src 'self' blob: data:` and the nested card iframe is refused.
|
|
70
|
+
*
|
|
71
|
+
* We race `loadStripe()` against a 3s timeout — in the blocked case
|
|
72
|
+
* Stripe.js either throws a ContentSecurityPolicy error or the promise
|
|
73
|
+
* simply never resolves, and the timeout wins.
|
|
74
|
+
*
|
|
75
|
+
* Note on the key: `publishableKey` is SolvaPay's **platform** Stripe pk
|
|
76
|
+
* (same one the backend returns from `create_payment_intent`). It is used
|
|
77
|
+
* here only to satisfy `loadStripe()`'s validator so we can exercise
|
|
78
|
+
* `frameDomains` — we never feed it into `confirmPayment`. The real
|
|
79
|
+
* payment flow re-fetches the pk (and the connected `accountId`) from
|
|
80
|
+
* `create_payment_intent` and boots its own `Stripe` instance via the
|
|
81
|
+
* SDK's `useCheckout`/`useTopup`. SolvaPay is a Stripe Connect direct-
|
|
82
|
+
* charge platform, so all browser-side Stripe calls pair the platform
|
|
83
|
+
* pk with `{ stripeAccount: acct_XXX }`; the connected merchant's own
|
|
84
|
+
* publishable key is never involved.
|
|
85
|
+
*/
|
|
86
|
+
type StripeProbeState = 'loading' | 'ready' | 'blocked';
|
|
87
|
+
declare function useStripeProbe(publishableKey: string | null): StripeProbeState;
|
|
88
|
+
|
|
89
|
+
declare function useHostLocale(): string;
|
|
90
|
+
|
|
91
|
+
interface ToolResultParams {
|
|
92
|
+
isError?: boolean;
|
|
93
|
+
content?: unknown;
|
|
94
|
+
structuredContent?: unknown;
|
|
95
|
+
_meta?: unknown;
|
|
96
|
+
}
|
|
97
|
+
interface AppWithToolResult {
|
|
98
|
+
getHostContext?: () => {
|
|
99
|
+
toolInfo?: {
|
|
100
|
+
tool?: {
|
|
101
|
+
name?: string;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
} | undefined;
|
|
105
|
+
addEventListener?: (evt: string, handler: (params: ToolResultParams) => void) => void;
|
|
106
|
+
removeEventListener?: (evt: string, handler: (params: ToolResultParams) => void) => void;
|
|
107
|
+
ontoolresult?: ((params: ToolResultParams) => void) | undefined;
|
|
108
|
+
}
|
|
109
|
+
interface McpToolResult<T> {
|
|
110
|
+
structuredContent: T | null;
|
|
111
|
+
content: Array<{
|
|
112
|
+
type: string;
|
|
113
|
+
text?: string;
|
|
114
|
+
}>;
|
|
115
|
+
toolName: string | null;
|
|
116
|
+
}
|
|
117
|
+
declare function useMcpToolResult<T = unknown>(app: AppWithToolResult): McpToolResult<T>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Minimal shape of `@modelcontextprotocol/ext-apps` `App` needed by
|
|
121
|
+
* the bridge. Both methods are optional so older hosts (and tests)
|
|
122
|
+
* don't have to stub them — we feature-detect at call time.
|
|
123
|
+
*/
|
|
124
|
+
interface McpBridgeAppLike {
|
|
125
|
+
updateModelContext?: (params: {
|
|
126
|
+
content?: Array<{
|
|
127
|
+
type: 'text';
|
|
128
|
+
text: string;
|
|
129
|
+
}>;
|
|
130
|
+
structuredContent?: Record<string, unknown>;
|
|
131
|
+
}) => Promise<unknown> | void;
|
|
132
|
+
sendMessage?: (params: {
|
|
133
|
+
role: 'user';
|
|
134
|
+
content: Array<{
|
|
135
|
+
type: 'text';
|
|
136
|
+
text: string;
|
|
137
|
+
}>;
|
|
138
|
+
}) => Promise<unknown> | void;
|
|
139
|
+
}
|
|
140
|
+
interface NotifyModelContextParams {
|
|
141
|
+
/** Short, plain-text update ("User selected Pro"). */
|
|
142
|
+
text?: string;
|
|
143
|
+
/**
|
|
144
|
+
* Raw structured content passthrough for richer payloads.
|
|
145
|
+
* Overrides `text` if both are provided.
|
|
146
|
+
*/
|
|
147
|
+
structuredContent?: Record<string, unknown>;
|
|
148
|
+
}
|
|
149
|
+
interface SendMessageParams {
|
|
150
|
+
/** User-visible follow-up copy ("Topped up $18. Ready to keep working."). */
|
|
151
|
+
text: string;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Success events the MCP bridge knows how to follow up in chat on.
|
|
155
|
+
* Extended via the `messageOnSuccess` prop — merchants return
|
|
156
|
+
* alternate copy (or `null` to suppress) per event.
|
|
157
|
+
*/
|
|
158
|
+
type McpSuccessEvent = {
|
|
159
|
+
kind: 'topup';
|
|
160
|
+
amountMinor: number;
|
|
161
|
+
currency: string;
|
|
162
|
+
} | {
|
|
163
|
+
kind: 'plan-activated';
|
|
164
|
+
planName: string | null;
|
|
165
|
+
};
|
|
166
|
+
type McpMessageOnSuccess = (evt: McpSuccessEvent) => string | null;
|
|
167
|
+
interface McpBridgeValue {
|
|
168
|
+
/**
|
|
169
|
+
* Emit `ui/update-model-context` to the host. Feature-detected —
|
|
170
|
+
* resolves as a no-op on hosts that don't implement the method.
|
|
171
|
+
* Errors are swallowed: a failed host update shouldn't break the
|
|
172
|
+
* committed user action that triggered it.
|
|
173
|
+
*/
|
|
174
|
+
notifyModelContext: (params: NotifyModelContextParams) => Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Emit `ui/message` to the host. Feature-detected and error-safe
|
|
177
|
+
* for the same reason.
|
|
178
|
+
*/
|
|
179
|
+
sendMessage: (params: SendMessageParams) => Promise<void>;
|
|
180
|
+
/**
|
|
181
|
+
* Phase 5 — post a user-visible follow-up after a committed success
|
|
182
|
+
* (topup completed, plan activated). Resolves the copy via the
|
|
183
|
+
* merchant's `messageOnSuccess` override (or a built-in default)
|
|
184
|
+
* and forwards to `sendMessage`. Returning `null` from
|
|
185
|
+
* `messageOnSuccess` suppresses the follow-up.
|
|
186
|
+
*/
|
|
187
|
+
notifySuccess: (evt: McpSuccessEvent) => Promise<void>;
|
|
188
|
+
}
|
|
189
|
+
interface McpBridgeProviderProps {
|
|
190
|
+
app: McpBridgeAppLike;
|
|
191
|
+
/**
|
|
192
|
+
* Per-event override for the Phase-5 success follow-up copy.
|
|
193
|
+
* Return `null` to suppress the follow-up for that event. Defaults
|
|
194
|
+
* are provided for `topup` and `plan-activated`; hosts that don't
|
|
195
|
+
* support `ui/message` silently no-op via the feature-detect in
|
|
196
|
+
* `sendMessage`.
|
|
197
|
+
*/
|
|
198
|
+
messageOnSuccess?: McpMessageOnSuccess;
|
|
199
|
+
children: React.ReactNode;
|
|
200
|
+
}
|
|
201
|
+
declare function McpBridgeProvider({ app, messageOnSuccess, children }: McpBridgeProviderProps): react_jsx_runtime.JSX.Element;
|
|
202
|
+
declare function useMcpBridge(): McpBridgeValue;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Bootstrap helper for SolvaPay MCP Apps.
|
|
206
|
+
*
|
|
207
|
+
* `fetchMcpBootstrap(app)` — kicks off the MCP session by invoking the
|
|
208
|
+
* `open_*` tool matching the host's invocation context and returns the
|
|
209
|
+
* view discriminator + bootstrap payload every view needs (merchant,
|
|
210
|
+
* product, plans, and customer snapshot).
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @deprecated Use `SolvaPayMcpViewKind` from `@solvapay/mcp-core` directly.
|
|
215
|
+
* Kept as a type alias so existing consumers don't break.
|
|
216
|
+
*/
|
|
217
|
+
type McpView = SolvaPayMcpViewKind;
|
|
218
|
+
/**
|
|
219
|
+
* Bootstrap payload returned from `fetchMcpBootstrap`. Structurally
|
|
220
|
+
* compatible with `BootstrapPayload` from `@solvapay/mcp-core` but narrows
|
|
221
|
+
* `paywall` to the server-owned `PaywallStructuredContent` union so
|
|
222
|
+
* the client-side views can discriminate on `kind`.
|
|
223
|
+
*/
|
|
224
|
+
interface McpBootstrap {
|
|
225
|
+
view: SolvaPayMcpViewKind;
|
|
226
|
+
productRef: string;
|
|
227
|
+
stripePublishableKey: string | null;
|
|
228
|
+
returnUrl: string;
|
|
229
|
+
/**
|
|
230
|
+
* Set when the MCP host invokes `open_paywall` — the structured
|
|
231
|
+
* content gets forwarded on the bootstrap payload so the client
|
|
232
|
+
* doesn't have to re-fetch it. Only populated for `view: 'paywall'`.
|
|
233
|
+
*/
|
|
234
|
+
paywall?: PaywallStructuredContent;
|
|
235
|
+
/**
|
|
236
|
+
* Upsell strip spec attached when `view: 'nudge'`. `McpNudgeView`
|
|
237
|
+
* renders `McpUpsellStrip` using this.
|
|
238
|
+
*/
|
|
239
|
+
nudge?: NudgeSpec;
|
|
240
|
+
/**
|
|
241
|
+
* Merchant tool result data embedded alongside a nudge so the shell
|
|
242
|
+
* can preview it without a follow-up tool call. Only populated when
|
|
243
|
+
* `view: 'nudge'`.
|
|
244
|
+
*/
|
|
245
|
+
data?: unknown;
|
|
246
|
+
/** Product-scoped snapshot — always present. */
|
|
247
|
+
merchant: BootstrapMerchant;
|
|
248
|
+
product: BootstrapProduct;
|
|
249
|
+
plans: BootstrapPlan[];
|
|
250
|
+
/** Per-customer snapshot — null when the bootstrap call was unauthenticated. */
|
|
251
|
+
customer: BootstrapCustomer | null;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Extended `McpAppLike` shape used by `fetchMcpBootstrap` — the base adapter
|
|
255
|
+
* only needs `callServerTool`, but the bootstrap helper also reads the
|
|
256
|
+
* host context to infer which `open_*` tool the host invoked.
|
|
257
|
+
*
|
|
258
|
+
* The return type is intentionally loose so the real
|
|
259
|
+
* `@modelcontextprotocol/ext-apps` `McpUiHostContext` is structurally
|
|
260
|
+
* assignable without forcing consumers into our narrower shape.
|
|
261
|
+
*/
|
|
262
|
+
interface McpAppBootstrapLike extends McpAppLike {
|
|
263
|
+
getHostContext: () => McpHostContextLike | undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Structural shape of `McpUiHostContext` for the fields `fetchMcpBootstrap`
|
|
267
|
+
* reads. Loose on purpose — we only need `toolInfo?.tool?.name`.
|
|
268
|
+
*/
|
|
269
|
+
interface McpHostContextLike {
|
|
270
|
+
toolInfo?: {
|
|
271
|
+
tool?: {
|
|
272
|
+
name?: string;
|
|
273
|
+
};
|
|
274
|
+
};
|
|
275
|
+
[key: string]: unknown;
|
|
276
|
+
}
|
|
277
|
+
interface CallToolResultLike {
|
|
278
|
+
isError?: boolean;
|
|
279
|
+
structuredContent?: unknown;
|
|
280
|
+
content?: Array<{
|
|
281
|
+
type: string;
|
|
282
|
+
text?: string;
|
|
283
|
+
}>;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Names of the SolvaPay transport tools whose results resolve through
|
|
287
|
+
* the adapter promise returned by `callServerTool(...)`. `ui/notifications/
|
|
288
|
+
* tool-result` payloads for these tools are already awaited by the
|
|
289
|
+
* caller, so `<McpApp>` ignores them to avoid double-applying state.
|
|
290
|
+
*
|
|
291
|
+
* Derived from `MCP_TOOL_NAMES` minus the intent tools in
|
|
292
|
+
* `TOOL_FOR_VIEW`, so adding a new transport tool requires exactly one
|
|
293
|
+
* edit (in `@solvapay/mcp-core/tool-names`).
|
|
294
|
+
*/
|
|
295
|
+
declare const SOLVAPAY_TRANSPORT_TOOL_NAMES: ReadonlySet<string>;
|
|
296
|
+
/**
|
|
297
|
+
* True when `name` is one of SolvaPay's transport tools (payments,
|
|
298
|
+
* sessions, renewal, activation). `<McpApp>` uses this to gate its live
|
|
299
|
+
* `toolresult` subscription — transport tool notifications are ignored
|
|
300
|
+
* because the `callServerTool` adapter promise already carries the
|
|
301
|
+
* authoritative result.
|
|
302
|
+
*/
|
|
303
|
+
declare function isTransportToolName(name: string): boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Classification of the host-invoked tool that opened the widget iframe.
|
|
306
|
+
* Drives `<McpApp>`'s mount branching:
|
|
307
|
+
*
|
|
308
|
+
* - `intent` — one of `upgrade` / `manage_account` / `topup`. Call
|
|
309
|
+
* the corresponding tool via `fetchMcpBootstrap`.
|
|
310
|
+
* - `data` — a merchant-registered paywalled tool (e.g.
|
|
311
|
+
* `search_knowledge`). The host opened the widget from
|
|
312
|
+
* its paywall/nudge result; wait for the initial
|
|
313
|
+
* `ui/notifications/tool-result` instead of re-calling
|
|
314
|
+
* the tool (which would consume another unit).
|
|
315
|
+
* - `other` — no tool info, or a SolvaPay transport tool as the
|
|
316
|
+
* iframe entry point (rare). Fall back to the `upgrade`
|
|
317
|
+
* intent tool for a fresh snapshot.
|
|
318
|
+
*/
|
|
319
|
+
type HostEntryClassification = {
|
|
320
|
+
kind: 'intent';
|
|
321
|
+
toolName: string;
|
|
322
|
+
view: keyof typeof TOOL_FOR_VIEW;
|
|
323
|
+
} | {
|
|
324
|
+
kind: 'data';
|
|
325
|
+
toolName: string;
|
|
326
|
+
} | {
|
|
327
|
+
kind: 'other';
|
|
328
|
+
toolName?: string;
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* Classify the host-invoked tool that opened the iframe. Reads
|
|
332
|
+
* `app.getHostContext()?.toolInfo?.tool?.name` and consults the
|
|
333
|
+
* `VIEW_FOR_TOOL` / `SOLVAPAY_TRANSPORT_TOOL_NAMES` tables.
|
|
334
|
+
*
|
|
335
|
+
* Exported so integrators who own their `<McpApp>` mount (or who build
|
|
336
|
+
* fully custom widgets) can branch the same way.
|
|
337
|
+
*/
|
|
338
|
+
declare function classifyHostEntry(app: McpAppBootstrapLike): HostEntryClassification;
|
|
339
|
+
/**
|
|
340
|
+
* Kick off the MCP session by calling the `open_*` tool that matches the
|
|
341
|
+
* host's invocation context. Returns the bootstrap payload every view
|
|
342
|
+
* needs (product ref, publishable key, return url) along with the view
|
|
343
|
+
* discriminator so the top-level router can pick the right screen.
|
|
344
|
+
*
|
|
345
|
+
* Used for intent-tool iframe entries and for `refreshInitial` after a
|
|
346
|
+
* committed action (purchase, topup, etc.). Data-tool iframe entries
|
|
347
|
+
* (paywall/nudge) bypass this helper; `<McpApp>` consumes the initial
|
|
348
|
+
* `ui/notifications/tool-result` directly via
|
|
349
|
+
* `parseBootstrapFromToolResult` so the merchant tool is not re-called.
|
|
350
|
+
*/
|
|
351
|
+
declare function fetchMcpBootstrap(app: McpAppBootstrapLike): Promise<McpBootstrap>;
|
|
352
|
+
/**
|
|
353
|
+
* Parse a raw `CallToolResult`-shaped payload into an `McpBootstrap`.
|
|
354
|
+
*
|
|
355
|
+
* Shared between `fetchMcpBootstrap` (client-initiated) and the live
|
|
356
|
+
* `ui/notifications/tool-result` subscription (`<McpApp>` Phase 3).
|
|
357
|
+
* Throws on missing product ref / invalid return URL so callers can
|
|
358
|
+
* surface the error to `onInitError` instead of half-applying state.
|
|
359
|
+
*/
|
|
360
|
+
declare function parseBootstrapFromToolResult(result: CallToolResultLike, toolName: string, fallbackView: SolvaPayMcpViewKind): McpBootstrap;
|
|
361
|
+
/**
|
|
362
|
+
* Shape of the `ui/notifications/tool-result` params we care about.
|
|
363
|
+
* Loose on purpose — `McpUiToolResultNotification['params']` is
|
|
364
|
+
* structurally compatible.
|
|
365
|
+
*/
|
|
366
|
+
interface ToolResultNotificationParams {
|
|
367
|
+
isError?: boolean;
|
|
368
|
+
content?: Array<{
|
|
369
|
+
type: string;
|
|
370
|
+
text?: string;
|
|
371
|
+
}>;
|
|
372
|
+
structuredContent?: unknown;
|
|
373
|
+
_meta?: unknown;
|
|
374
|
+
}
|
|
375
|
+
type ToolResultListener = (params: ToolResultNotificationParams) => void;
|
|
376
|
+
/**
|
|
377
|
+
* Subset of `@modelcontextprotocol/ext-apps` `App` events that
|
|
378
|
+
* `waitForInitialToolResult` subscribes to. Mirrors the contract in
|
|
379
|
+
* `hooks/useMcpToolResult.ts` so either entry point works with
|
|
380
|
+
* composable `addEventListener` hosts or legacy `ontoolresult` mocks.
|
|
381
|
+
*/
|
|
382
|
+
interface AppToolResultEvents {
|
|
383
|
+
addEventListener?: (evt: string, handler: ToolResultListener) => void;
|
|
384
|
+
removeEventListener?: (evt: string, handler: ToolResultListener) => void;
|
|
385
|
+
ontoolresult?: ToolResultListener | undefined;
|
|
386
|
+
}
|
|
387
|
+
interface WaitForInitialToolResultOptions {
|
|
388
|
+
/**
|
|
389
|
+
* How long to wait (ms) for the first non-error, non-transport
|
|
390
|
+
* `toolresult` notification before giving up. Defaults to 2000ms —
|
|
391
|
+
* the host is expected to fire the initial notification immediately
|
|
392
|
+
* after `ui/initialize`, so 2s is a generous budget.
|
|
393
|
+
*/
|
|
394
|
+
timeoutMs?: number;
|
|
395
|
+
/**
|
|
396
|
+
* Optional signal to cancel the wait (e.g. component unmount). When
|
|
397
|
+
* aborted, the returned promise resolves with `timedOut: true`.
|
|
398
|
+
*/
|
|
399
|
+
signal?: AbortSignal;
|
|
400
|
+
/**
|
|
401
|
+
* Fallback `view` passed to `parseBootstrapFromToolResult` when the
|
|
402
|
+
* incoming payload doesn't carry a `structuredContent.view`. Defaults
|
|
403
|
+
* to `'paywall'` since data-tool entries are paywall/nudge by
|
|
404
|
+
* construction.
|
|
405
|
+
*/
|
|
406
|
+
fallbackView?: SolvaPayMcpViewKind;
|
|
407
|
+
}
|
|
408
|
+
type WaitForInitialToolResultResult = {
|
|
409
|
+
timedOut: false;
|
|
410
|
+
bootstrap: McpBootstrap;
|
|
411
|
+
toolName: string | null;
|
|
412
|
+
params: ToolResultNotificationParams;
|
|
413
|
+
} | {
|
|
414
|
+
timedOut: true;
|
|
415
|
+
bootstrap: null;
|
|
416
|
+
toolName: null;
|
|
417
|
+
params: null;
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* One-shot helper: subscribes to `toolresult`, resolves with the first
|
|
421
|
+
* non-error, non-transport payload parsed into an `McpBootstrap`, and
|
|
422
|
+
* unsubscribes.
|
|
423
|
+
*
|
|
424
|
+
* Intended for integrators who mount their own shell on top of
|
|
425
|
+
* `createMcpAppAdapter` and need the same "consume the initial
|
|
426
|
+
* tool-result payload" semantics `<McpApp>` uses internally. Subscribe
|
|
427
|
+
* **before** calling `app.connect()` to avoid missing the initial
|
|
428
|
+
* notification the host fires after `ui/initialize`.
|
|
429
|
+
*
|
|
430
|
+
* Parse errors are surfaced via the returned promise's rejection; a
|
|
431
|
+
* timeout resolves with `timedOut: true` rather than throwing.
|
|
432
|
+
*/
|
|
433
|
+
declare function waitForInitialToolResult(app: McpAppBootstrapLike & AppToolResultEvents, options?: WaitForInitialToolResultOptions): Promise<WaitForInitialToolResultResult>;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Seed the module-level hook caches (`merchantCache`, `productCache`,
|
|
437
|
+
* `plansCache`, `paymentMethodCache`) from a `SolvaPayProviderInitial`
|
|
438
|
+
* snapshot so the MCP App shell never fires a first-mount fetch.
|
|
439
|
+
*
|
|
440
|
+
* Called from `<McpApp>` before rendering `<SolvaPayProvider>`. The
|
|
441
|
+
* seeded entries share the same 5-minute TTL as normal fetches — once
|
|
442
|
+
* expired the caches fall back to their existing behaviour (which, for
|
|
443
|
+
* MCP, returns the seeded value because the hooks' fetchers become
|
|
444
|
+
* no-ops after the read tools are dropped).
|
|
445
|
+
*/
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Pre-populate the hook caches with the snapshot from the bootstrap
|
|
449
|
+
* payload. The caller passes the live `SolvaPayConfig` (the same object
|
|
450
|
+
* it hands to `<SolvaPayProvider>`) so every cache key is computed with
|
|
451
|
+
* the identical `createTransportCacheKey` logic the hooks use — that way
|
|
452
|
+
* the seeded entries match the keys `useMerchant` / `useProduct` /
|
|
453
|
+
* `usePlans` / `usePaymentMethod` read on first render.
|
|
454
|
+
*/
|
|
455
|
+
declare function seedMcpCaches(initial: SolvaPayProviderInitial, config: SolvaPayConfig): void;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Per-element className overrides for `<Mcp*View>` primitives.
|
|
459
|
+
*
|
|
460
|
+
* Mirrors the `CurrentPlanCardClassNames` pattern — every key is optional,
|
|
461
|
+
* and any empty string falls through to the default `solvapay-mcp-*` class
|
|
462
|
+
* defined in `@solvapay/react/mcp/styles.css`. Integrators who ship their
|
|
463
|
+
* own CSS can disable defaults per-slot by assigning `''`.
|
|
464
|
+
*/
|
|
465
|
+
interface McpViewClassNames {
|
|
466
|
+
card?: string;
|
|
467
|
+
stack?: string;
|
|
468
|
+
heading?: string;
|
|
469
|
+
muted?: string;
|
|
470
|
+
button?: string;
|
|
471
|
+
linkButton?: string;
|
|
472
|
+
notice?: string;
|
|
473
|
+
error?: string;
|
|
474
|
+
awaitingHeader?: string;
|
|
475
|
+
balanceRow?: string;
|
|
476
|
+
amountPicker?: string;
|
|
477
|
+
amountOptions?: string;
|
|
478
|
+
amountOption?: string;
|
|
479
|
+
amountCustom?: string;
|
|
480
|
+
topupForm?: string;
|
|
481
|
+
activationFlow?: string;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Resolve a `McpViewClassNames` partial against the defaults — consumer
|
|
485
|
+
* overrides win when defined, empty strings disable a slot's class entirely,
|
|
486
|
+
* unset keys fall through to the default.
|
|
487
|
+
*/
|
|
488
|
+
declare function resolveMcpClassNames(overrides: McpViewClassNames | undefined): Required<McpViewClassNames>;
|
|
489
|
+
|
|
490
|
+
interface McpAccountViewProps {
|
|
491
|
+
classNames?: McpViewClassNames;
|
|
492
|
+
/**
|
|
493
|
+
* Called when the user clicks the "Top up" link inside the balance
|
|
494
|
+
* row or Customer details card. The `<McpAppShell>` wires this to a
|
|
495
|
+
* tab switch so nothing re-mounts; consumers outside the shell can
|
|
496
|
+
* leave it unset.
|
|
497
|
+
*/
|
|
498
|
+
onTopup?: () => void;
|
|
499
|
+
/**
|
|
500
|
+
* Called when the user clicks "Pick a plan" from the empty state or
|
|
501
|
+
* "Change plan" / "Upgrade" on the plan card. Wired by the shell to
|
|
502
|
+
* switch to the Plan tab.
|
|
503
|
+
*/
|
|
504
|
+
onChangePlan?: () => void;
|
|
505
|
+
/**
|
|
506
|
+
* Skip the Customer + Seller detail cards. `<McpAppShell>` sets this
|
|
507
|
+
* to `true` at the `xl` breakpoint because the same cards render in
|
|
508
|
+
* the persistent right-hand sidebar.
|
|
509
|
+
*/
|
|
510
|
+
hideDetailCards?: boolean;
|
|
511
|
+
}
|
|
512
|
+
declare function McpAccountView({ classNames, onTopup, onChangePlan, hideDetailCards, }: McpAccountViewProps): react_jsx_runtime.JSX.Element;
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Shared types and pure helpers for the MCP checkout state machine.
|
|
516
|
+
*
|
|
517
|
+
* The plan → amount → payment → success flow is used by both
|
|
518
|
+
* `<McpCheckoutView>` (the `activate_plan` surface) and
|
|
519
|
+
* `<McpPaywallView>` (the paywall surface) so the helpers live in a
|
|
520
|
+
* dedicated module to keep the state machine and step components slim.
|
|
521
|
+
*/
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Structural subset of a bootstrap plan. Kept here so step components
|
|
525
|
+
* can type against it without pulling in the full `@solvapay/mcp`
|
|
526
|
+
* bootstrap types (which would create a dep cycle).
|
|
527
|
+
*/
|
|
528
|
+
interface BootstrapPlanLike {
|
|
529
|
+
reference?: string;
|
|
530
|
+
name?: string;
|
|
531
|
+
type?: string;
|
|
532
|
+
planType?: string;
|
|
533
|
+
price?: number;
|
|
534
|
+
currency?: string;
|
|
535
|
+
billingCycle?: string | null;
|
|
536
|
+
meterRef?: string | null;
|
|
537
|
+
creditsPerUnit?: number | null;
|
|
538
|
+
requiresPayment?: boolean;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
interface McpCheckoutViewProps {
|
|
542
|
+
productRef: string;
|
|
543
|
+
/**
|
|
544
|
+
* Stripe publishable key used by `useStripeProbe` to detect CSP-blocked
|
|
545
|
+
* hosts. Pass `null` to skip the probe and render the hosted fallback
|
|
546
|
+
* directly (useful for tests or hosts known to refuse `js.stripe.com`).
|
|
547
|
+
*/
|
|
548
|
+
publishableKey?: string | null;
|
|
549
|
+
returnUrl: string;
|
|
550
|
+
onPurchaseSuccess?: () => void;
|
|
551
|
+
/**
|
|
552
|
+
* Called when the view wants to bounce the customer to the
|
|
553
|
+
* dedicated Top up surface. Unused by the new activation flow
|
|
554
|
+
* (PAYG top-ups happen inline here) but kept as a prop for
|
|
555
|
+
* backward compatibility with integrators that wired it up.
|
|
556
|
+
*/
|
|
557
|
+
onRequestTopup?: () => void;
|
|
558
|
+
/**
|
|
559
|
+
* True when the checkout view was reached via the paywall takeover.
|
|
560
|
+
* Drives the amber "Upgrade to continue" banner and the
|
|
561
|
+
* `"Stay on Free"` dismiss link on the plan-selection step. The
|
|
562
|
+
* brief's §6 invariant: "banner appears iff the customer hit the
|
|
563
|
+
* paywall."
|
|
564
|
+
*/
|
|
565
|
+
fromPaywall?: boolean;
|
|
566
|
+
/**
|
|
567
|
+
* Paywall kind surfaced from `bootstrap.paywall.kind` when
|
|
568
|
+
* `fromPaywall` is true. Selects between the two banner copies:
|
|
569
|
+
* `'payment_required'` → quota-exhausted language;
|
|
570
|
+
* `'activation_required'` → tool-needs-a-paid-plan language.
|
|
571
|
+
*/
|
|
572
|
+
paywallKind?: 'payment_required' | 'activation_required';
|
|
573
|
+
/**
|
|
574
|
+
* Product plans snapshot from `bootstrap.plans`. Used to locate
|
|
575
|
+
* the PAYG plan for the `popular` / `recommended` tag and sort
|
|
576
|
+
* the plan cards (PAYG first, then recurring ascending). Falls
|
|
577
|
+
* back to `PlanSelector`'s own `usePlans` fetch when omitted.
|
|
578
|
+
*/
|
|
579
|
+
plans?: readonly BootstrapPlanLike[];
|
|
580
|
+
/**
|
|
581
|
+
* Invoked at the end of a successful activation — chained before
|
|
582
|
+
* `onClose()` so the host sees a re-seeded bootstrap if it
|
|
583
|
+
* re-invokes the original tool.
|
|
584
|
+
*/
|
|
585
|
+
onRefreshBootstrap?: () => void | Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* Ask the host to unmount the MCP app. Wired by `<McpApp>` to
|
|
588
|
+
* `app.requestTeardown()`. Used by `"Back to chat"` on the success
|
|
589
|
+
* surface and the `"Stay on Free"` dismiss link. When omitted,
|
|
590
|
+
* those affordances disappear.
|
|
591
|
+
*/
|
|
592
|
+
onClose?: () => void;
|
|
593
|
+
classNames?: McpViewClassNames;
|
|
594
|
+
children?: React.ReactNode;
|
|
595
|
+
}
|
|
596
|
+
declare function McpCheckoutView({ productRef, publishableKey, returnUrl, onPurchaseSuccess, onRequestTopup: _onRequestTopup, fromPaywall, paywallKind, plans, onRefreshBootstrap, onClose, classNames, children, }: McpCheckoutViewProps): react_jsx_runtime.JSX.Element;
|
|
597
|
+
|
|
598
|
+
interface McpPaywallViewProps {
|
|
599
|
+
content: PaywallStructuredContent;
|
|
600
|
+
/**
|
|
601
|
+
* Stripe publishable key. Passing a key enables the embedded checkout
|
|
602
|
+
* path once `useStripeProbe` reports `'ready'`. `null` forces the
|
|
603
|
+
* hosted-link fallback.
|
|
604
|
+
*/
|
|
605
|
+
publishableKey?: string | null;
|
|
606
|
+
returnUrl: string;
|
|
607
|
+
classNames?: McpViewClassNames;
|
|
608
|
+
/** Consumers typically pass a function that dismisses the view after resolution. */
|
|
609
|
+
onResolved?: () => void;
|
|
610
|
+
/**
|
|
611
|
+
* Product plans snapshot from `bootstrap.plans`. Threaded through to
|
|
612
|
+
* the shared `EmbeddedCheckout` so the paywall surfaces the same
|
|
613
|
+
* PAYG-first sorted grid and `popular` tag as `McpCheckoutView`.
|
|
614
|
+
*/
|
|
615
|
+
plans?: readonly BootstrapPlanLike[];
|
|
616
|
+
/**
|
|
617
|
+
* Secondary "Upgrade to <plan> — <price>" CTA rendered below the
|
|
618
|
+
* paywall's primary (top-up) flow. When set, the paywall view
|
|
619
|
+
* exposes two routes out of the gate — stay on usage-based by
|
|
620
|
+
* topping up, or switch to a recurring plan.
|
|
621
|
+
*
|
|
622
|
+
* `onClick` fires with the plan the shell derived from
|
|
623
|
+
* `bootstrap.plans` (first recurring, non-usage-based plan);
|
|
624
|
+
* consumers typically open `<McpCheckoutView>` for that plan.
|
|
625
|
+
*/
|
|
626
|
+
upgradeCta?: {
|
|
627
|
+
label: string;
|
|
628
|
+
onClick: () => void;
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
declare function McpPaywallView({ content, publishableKey, returnUrl, classNames, onResolved, plans, upgradeCta, }: McpPaywallViewProps): react_jsx_runtime.JSX.Element;
|
|
632
|
+
|
|
633
|
+
interface McpTopupViewProps {
|
|
634
|
+
publishableKey?: string | null;
|
|
635
|
+
returnUrl: string;
|
|
636
|
+
/**
|
|
637
|
+
* Called when the Stripe confirm succeeds. Receives the topped-up amount
|
|
638
|
+
* in minor units (respects zero-decimal currencies — yen not yen×100).
|
|
639
|
+
*/
|
|
640
|
+
onTopupSuccess?: (amountMinor: number) => void;
|
|
641
|
+
/**
|
|
642
|
+
* Called when the user picks "Back to my account" at any step.
|
|
643
|
+
* Wired by the shell to switch tabs. `undefined` (the paywall
|
|
644
|
+
* branch) hides the outer back-link.
|
|
645
|
+
*/
|
|
646
|
+
onBack?: () => void;
|
|
647
|
+
classNames?: McpViewClassNames;
|
|
648
|
+
}
|
|
649
|
+
declare function McpTopupView({ publishableKey, returnUrl, onTopupSuccess, onBack, classNames, }: McpTopupViewProps): react_jsx_runtime.JSX.Element;
|
|
650
|
+
|
|
651
|
+
interface McpNudgeViewProps {
|
|
652
|
+
/**
|
|
653
|
+
* Full bootstrap snapshot with `nudge` + `data` populated by
|
|
654
|
+
* `buildPayableHandler`'s success branch.
|
|
655
|
+
*/
|
|
656
|
+
bootstrap: McpBootstrap;
|
|
657
|
+
/** Invoked when the user clicks the upsell CTA. */
|
|
658
|
+
onCta?: () => void;
|
|
659
|
+
/** Invoked when the user dismisses the strip. */
|
|
660
|
+
onDismiss?: () => void;
|
|
661
|
+
classNames?: McpViewClassNames;
|
|
662
|
+
}
|
|
663
|
+
declare function McpNudgeView({ bootstrap, onCta, onDismiss, classNames }: McpNudgeViewProps): react_jsx_runtime.JSX.Element;
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* The set of surfaces the MCP shell can route to. Lives in its own tiny
|
|
667
|
+
* file so any module that needs the discriminated union can import it
|
|
668
|
+
* without cycling through `McpAppShell`.
|
|
669
|
+
*
|
|
670
|
+
* `bootstrap.view` (from the server's `open_*` tool response) is the
|
|
671
|
+
* load-bearing dispatch signal — the shell locks the rendered surface
|
|
672
|
+
* to whatever the bootstrap named for the invocation's lifetime. The
|
|
673
|
+
* only in-session surface mutation is the paywall/nudge CTA → checkout
|
|
674
|
+
* flip, modelled explicitly by the shell's `overrideView` state.
|
|
675
|
+
*/
|
|
676
|
+
type McpViewKind = 'checkout' | 'account' | 'topup' | 'paywall' | 'nudge';
|
|
677
|
+
/**
|
|
678
|
+
* @deprecated Use `McpViewKind`. This alias exists for one minor
|
|
679
|
+
* version to give internal callers a grace window on the rename; the
|
|
680
|
+
* tab metaphor is gone — the shell is surface-routed now.
|
|
681
|
+
*/
|
|
682
|
+
type McpTabKind = McpViewKind;
|
|
683
|
+
|
|
684
|
+
interface McpAppShellProps {
|
|
685
|
+
bootstrap: McpBootstrap;
|
|
686
|
+
views?: McpAppViewOverrides;
|
|
687
|
+
classNames?: McpViewClassNames;
|
|
688
|
+
/** Render the footer? Defaults to `true` when the merchant has any of support/terms/privacy URLs. */
|
|
689
|
+
footer?: boolean;
|
|
690
|
+
/**
|
|
691
|
+
* Refresh the bootstrap snapshot. Wired by `<McpApp>` to
|
|
692
|
+
* `SolvaPayProvider.refreshInitial`. The shell calls this once on
|
|
693
|
+
* mount so stale caches get re-seeded when the user re-opens the
|
|
694
|
+
* MCP app after backgrounding it. Errors are swallowed (soft signal).
|
|
695
|
+
*/
|
|
696
|
+
onRefreshBootstrap?: () => void | Promise<void>;
|
|
697
|
+
/**
|
|
698
|
+
* Ask the host to unmount the MCP app. Wired by `<McpApp>` to
|
|
699
|
+
* `app.requestTeardown()`. The checkout view uses this for its
|
|
700
|
+
* `"Back to chat"` success CTA and the `"Stay on Free"` dismiss
|
|
701
|
+
* link. `undefined` hides those affordances so integrators that own
|
|
702
|
+
* their own mount can opt out.
|
|
703
|
+
*/
|
|
704
|
+
onClose?: () => void;
|
|
705
|
+
}
|
|
706
|
+
declare function McpAppShell({ bootstrap, views, classNames, footer, onRefreshBootstrap, onClose, }: McpAppShellProps): react_jsx_runtime.JSX.Element;
|
|
707
|
+
interface McpViewRouterProps {
|
|
708
|
+
/** Surface to render. */
|
|
709
|
+
view: McpViewKind;
|
|
710
|
+
bootstrap: McpBootstrap;
|
|
711
|
+
views?: McpAppViewOverrides;
|
|
712
|
+
classNames?: McpViewClassNames;
|
|
713
|
+
/** Whether the shell already renders the customer/seller cards in a sidebar. */
|
|
714
|
+
suppressDetailCards?: boolean;
|
|
715
|
+
/**
|
|
716
|
+
* True when the checkout view was reached via the paywall takeover
|
|
717
|
+
* (or the shell mounted with `bootstrap.view === 'paywall'`). Drives
|
|
718
|
+
* the "Upgrade to continue" banner and `"Stay on Free"` dismiss link
|
|
719
|
+
* inside `McpCheckoutView`.
|
|
720
|
+
*/
|
|
721
|
+
fromPaywall?: boolean;
|
|
722
|
+
/**
|
|
723
|
+
* Called when a surface asks to swap to another surface in-session
|
|
724
|
+
* (only used by the paywall-dismiss and nudge-CTA handlers). The
|
|
725
|
+
* shell wires this to its `overrideView` state.
|
|
726
|
+
*/
|
|
727
|
+
onSurfaceChange?: (next: McpViewKind) => void;
|
|
728
|
+
/**
|
|
729
|
+
* Paywall-specific upgrade handler forwarded as `upgradeCta.onClick`
|
|
730
|
+
* on `<McpPaywallView>`. Defaults to `onSurfaceChange?.('checkout')`.
|
|
731
|
+
*/
|
|
732
|
+
onPaywallUpgrade?: () => void;
|
|
733
|
+
/** Nudge-specific CTA handler; defaults to `onSurfaceChange?.('checkout')`. */
|
|
734
|
+
onNudgeCta?: () => void;
|
|
735
|
+
/**
|
|
736
|
+
* Invoked when the account view's "Change plan" affordance fires.
|
|
737
|
+
* Clears the `fromPaywall` flag before swapping to `'checkout'` so
|
|
738
|
+
* the banner doesn't render in the change-plan flow.
|
|
739
|
+
*/
|
|
740
|
+
onChangePlan?: () => void;
|
|
741
|
+
/**
|
|
742
|
+
* Forwarded to `McpCheckoutView`'s `"Back to chat"` success CTA so
|
|
743
|
+
* the shell can reseed its caches before the host unmounts.
|
|
744
|
+
*/
|
|
745
|
+
onRefreshBootstrap?: () => void | Promise<void>;
|
|
746
|
+
/**
|
|
747
|
+
* Forwarded to `McpCheckoutView`'s `"Back to chat"` and
|
|
748
|
+
* `"Stay on Free"` affordances. Wired by `<McpApp>` to
|
|
749
|
+
* `app.requestTeardown()`.
|
|
750
|
+
*/
|
|
751
|
+
onClose?: () => void;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Single `switch` on `McpViewKind` that resolves each view from the
|
|
755
|
+
* `views` override map and threads `bootstrap`-derived props through.
|
|
756
|
+
* Exported so integrators that own their own shell + provider mount
|
|
757
|
+
* can still get view dispatch for free.
|
|
758
|
+
*/
|
|
759
|
+
declare function McpViewRouter({ view, bootstrap, views, classNames, suppressDetailCards, fromPaywall, onSurfaceChange, onPaywallUpgrade, onNudgeCta, onChangePlan, onRefreshBootstrap, onClose, }: McpViewRouterProps): React.ReactNode;
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Minimal host-context shape `<McpApp>` reads. Kept loose so the real
|
|
763
|
+
* `@modelcontextprotocol/ext-apps` `McpUiHostContext` is structurally
|
|
764
|
+
* assignable; consumers pass the helpers from `ext-apps` via
|
|
765
|
+
* `applyContext` instead of depending on this shape directly.
|
|
766
|
+
*/
|
|
767
|
+
type McpUiHostContextLike = any;
|
|
768
|
+
/**
|
|
769
|
+
* Subset of `@modelcontextprotocol/ext-apps` `App` that `<McpApp>` needs.
|
|
770
|
+
*
|
|
771
|
+
* Declared loosely so the real `App` is structurally assignable without
|
|
772
|
+
* forcing consumers to match our stricter internal typing. Any object
|
|
773
|
+
* satisfying these call signatures works (handy for tests).
|
|
774
|
+
*/
|
|
775
|
+
interface McpAppFull extends McpAppBootstrapLike, McpAppLike, McpBridgeAppLike {
|
|
776
|
+
connect: () => Promise<void>;
|
|
777
|
+
onhostcontextchanged?: any;
|
|
778
|
+
onteardown?: any;
|
|
779
|
+
/**
|
|
780
|
+
* Composable event subscription exposed by
|
|
781
|
+
* `@modelcontextprotocol/ext-apps` `App` (via `ProtocolWithEvents`).
|
|
782
|
+
* `<McpApp>` uses this to subscribe to `toolresult` so it can re-route
|
|
783
|
+
* when the host re-invokes an intent tool against a mounted widget.
|
|
784
|
+
* Kept optional so minimal test adapters can omit it — the code falls
|
|
785
|
+
* back to the legacy `ontoolresult` setter.
|
|
786
|
+
*/
|
|
787
|
+
addEventListener?: (evt: string, handler: (params: any) => void) => void;
|
|
788
|
+
removeEventListener?: (evt: string, handler: (params: any) => void) => void;
|
|
789
|
+
ontoolresult?: any;
|
|
790
|
+
/**
|
|
791
|
+
* Fire-and-forget request asking the host to unmount the app. When
|
|
792
|
+
* approved, the host sends `ui/resource-teardown` back via
|
|
793
|
+
* `onteardown`. Exposed by the real `@modelcontextprotocol/ext-apps`
|
|
794
|
+
* `App` class — kept optional in the structural type so tests and
|
|
795
|
+
* minimal adapters don't have to stub it.
|
|
796
|
+
*/
|
|
797
|
+
requestTeardown?: () => Promise<void> | void;
|
|
798
|
+
}
|
|
799
|
+
interface McpAppViewOverrides {
|
|
800
|
+
checkout?: React.ComponentType<McpCheckoutViewProps>;
|
|
801
|
+
account?: React.ComponentType<McpAccountViewProps>;
|
|
802
|
+
topup?: React.ComponentType<McpTopupViewProps>;
|
|
803
|
+
paywall?: React.ComponentType<McpPaywallViewProps>;
|
|
804
|
+
nudge?: React.ComponentType<McpNudgeViewProps>;
|
|
805
|
+
}
|
|
806
|
+
interface McpAppProps {
|
|
807
|
+
app: McpAppFull;
|
|
808
|
+
/**
|
|
809
|
+
* Optional override for the product ref returned by `fetchMcpBootstrap`.
|
|
810
|
+
* Useful when the client knows which product to target before the
|
|
811
|
+
* server bootstrap resolves — rarely needed.
|
|
812
|
+
*/
|
|
813
|
+
productRef?: string;
|
|
814
|
+
/** Per-view component overrides, e.g. to replace just `account`. */
|
|
815
|
+
views?: McpAppViewOverrides;
|
|
816
|
+
/** Per-slot className overrides — forwarded to every built-in view. */
|
|
817
|
+
classNames?: McpViewClassNames;
|
|
818
|
+
/** Override the shell-level footer visibility heuristic. */
|
|
819
|
+
footer?: boolean;
|
|
820
|
+
/**
|
|
821
|
+
* Called with the bootstrap error if `app.connect()` or the `open_*`
|
|
822
|
+
* tool call fails. Consumers typically log it; the default UI already
|
|
823
|
+
* renders a human-readable error card.
|
|
824
|
+
*/
|
|
825
|
+
onInitError?: (err: Error) => void;
|
|
826
|
+
/**
|
|
827
|
+
* Optional hook to apply host context updates (theme, fonts, safe-area
|
|
828
|
+
* insets). Defaults to a no-op; pass the helpers from
|
|
829
|
+
* `@modelcontextprotocol/ext-apps` when you want the turnkey behaviour.
|
|
830
|
+
*
|
|
831
|
+
* Kept as a prop instead of a hard import so the SDK doesn't depend on
|
|
832
|
+
* `@modelcontextprotocol/ext-apps` — host-context primitives live there.
|
|
833
|
+
*/
|
|
834
|
+
applyContext?: (ctx: McpUiHostContextLike | undefined) => void;
|
|
835
|
+
/**
|
|
836
|
+
* Override for the shell's "close this app" handler. Defaults to
|
|
837
|
+
* `() => app.requestTeardown()`, which asks the host to unmount the
|
|
838
|
+
* iframe (see `@modelcontextprotocol/ext-apps` `App.requestTeardown`).
|
|
839
|
+
* Used by the checkout view's `"Back to chat"` and `"Stay on Free"`
|
|
840
|
+
* affordances; passing `undefined` hides those affordances.
|
|
841
|
+
*/
|
|
842
|
+
onClose?: () => void;
|
|
843
|
+
/**
|
|
844
|
+
* Phase 5 — override the user-visible follow-up copy posted to the
|
|
845
|
+
* chat after a committed success (topup completed, plan activated).
|
|
846
|
+
* Return `null` to suppress a specific event; omit the prop entirely
|
|
847
|
+
* to use the SDK defaults. Hosts that don't support `ui/message`
|
|
848
|
+
* silently no-op regardless.
|
|
849
|
+
*/
|
|
850
|
+
messageOnSuccess?: McpMessageOnSuccess;
|
|
851
|
+
}
|
|
852
|
+
declare function McpApp({ app, productRef: productRefOverride, views, classNames, footer, onInitError, applyContext, onClose, messageOnSuccess, }: McpAppProps): react_jsx_runtime.JSX.Element;
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Pure derivation helpers that map a plan / active purchase onto the
|
|
856
|
+
* activation strategy + action-affordance shape the shell renders per
|
|
857
|
+
* plan type.
|
|
858
|
+
*
|
|
859
|
+
* Keeping these in a standalone module lets the hosted manage page
|
|
860
|
+
* share the same matrix as the MCP shell — "one plan-shape matrix,
|
|
861
|
+
* two surfaces" — and makes the 4 × 2 × 3 test matrix from the plan a
|
|
862
|
+
* pure-function target (no RTL needed).
|
|
863
|
+
*/
|
|
864
|
+
type PlanShape = 'free' | 'trial' | 'usage-based' | 'recurring-unlimited' | 'recurring-metered';
|
|
865
|
+
/**
|
|
866
|
+
* Strategy the Plan tab uses when the user clicks a plan card:
|
|
867
|
+
* - `activate` — free / trial / free-priced recurring: instant activation
|
|
868
|
+
* via `ActivationFlow.Summary` + `ActivateButton`.
|
|
869
|
+
* - `topup-first` — usage-based: ActivationFlow's `AmountPicker`
|
|
870
|
+
* branch.
|
|
871
|
+
* - `paid-checkout` — recurring with a non-zero price: mount
|
|
872
|
+
* `PaymentFormGate` + `PaymentForm.*` for inline Stripe Elements.
|
|
873
|
+
*/
|
|
874
|
+
type ActivationStrategy = 'activate' | 'topup-first' | 'paid-checkout';
|
|
875
|
+
interface PlanLike {
|
|
876
|
+
/** `'free' | 'trial' | 'usage-based' | 'recurring'`. */
|
|
877
|
+
planType?: string | null;
|
|
878
|
+
price?: number | null;
|
|
879
|
+
currency?: string | null;
|
|
880
|
+
meterRef?: string | null;
|
|
881
|
+
meterId?: string | null;
|
|
882
|
+
limit?: number | null;
|
|
883
|
+
}
|
|
884
|
+
interface PurchaseSnapshotLike {
|
|
885
|
+
planSnapshot?: PlanLike | null;
|
|
886
|
+
/** Whether the customer has a payment method on file. */
|
|
887
|
+
hasPaymentMethod?: boolean;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Map a `BootstrapPlan` / `PlanSnapshot` to its concrete shape. The
|
|
891
|
+
* four shapes are distinct in UX: each drives a different summary
|
|
892
|
+
* string, a different set of CTAs, and a different activity-strip
|
|
893
|
+
* variant.
|
|
894
|
+
*/
|
|
895
|
+
declare function resolvePlanShape(plan: PlanLike | null | undefined): PlanShape | null;
|
|
896
|
+
/**
|
|
897
|
+
* Pick the activation strategy for a plan the user just clicked.
|
|
898
|
+
*
|
|
899
|
+
* Rules match the plan's pressure-test: free / trial activate instantly;
|
|
900
|
+
* usage-based always tops up first; zero-priced recurring activates
|
|
901
|
+
* instantly; paid recurring goes to Stripe checkout.
|
|
902
|
+
*/
|
|
903
|
+
declare function resolveActivationStrategy(plan: PlanLike | null | undefined): ActivationStrategy;
|
|
904
|
+
/**
|
|
905
|
+
* Per-variant action flags for the Plan-active card. Only flags that
|
|
906
|
+
* are `true` render affordances — this collapses the "should we show
|
|
907
|
+
* Cancel?" boolean maze into a single resolver call.
|
|
908
|
+
*
|
|
909
|
+
* Rules from the plan:
|
|
910
|
+
* - `topUp` — only on usage-based purchases.
|
|
911
|
+
* - `cancel` — recurring (paid subscription) and free plans. PAYG
|
|
912
|
+
* has no renewal to cancel.
|
|
913
|
+
* - `changePlan` — always, when the product exposes more than one
|
|
914
|
+
* plan.
|
|
915
|
+
* - `managePortal` — only when the customer has a payment method on
|
|
916
|
+
* file. Free plans that never charged a card skip this.
|
|
917
|
+
* - `upgrade` — shown *instead of* `changePlan` when the active plan
|
|
918
|
+
* is free AND at least one paid plan exists.
|
|
919
|
+
*/
|
|
920
|
+
interface PlanActions {
|
|
921
|
+
topUp: boolean;
|
|
922
|
+
cancel: boolean;
|
|
923
|
+
changePlan: boolean;
|
|
924
|
+
managePortal: boolean;
|
|
925
|
+
upgrade: boolean;
|
|
926
|
+
}
|
|
927
|
+
interface PlanActionsInput {
|
|
928
|
+
purchase: PurchaseSnapshotLike | null | undefined;
|
|
929
|
+
/** Total plans exposed on the product. */
|
|
930
|
+
planCount: number;
|
|
931
|
+
/** Number of paid plans (price > 0, not free) on the product. */
|
|
932
|
+
paidPlanCount: number;
|
|
933
|
+
}
|
|
934
|
+
declare function resolvePlanActions({ purchase, planCount, paidPlanCount }: PlanActionsInput): PlanActions;
|
|
935
|
+
/**
|
|
936
|
+
* "Your activity" strip variant shown at the top of a surface when a
|
|
937
|
+
* returning customer has an active purchase. Hidden when the customer
|
|
938
|
+
* has no active purchase.
|
|
939
|
+
*/
|
|
940
|
+
type ActivityStripKind = 'none' | 'payg-balance' | 'recurring-unlimited-renew' | 'recurring-metered-usage' | 'free-usage';
|
|
941
|
+
declare function resolveActivityStrip(purchase: PurchaseSnapshotLike | null | undefined): ActivityStripKind;
|
|
942
|
+
|
|
943
|
+
interface BackLinkProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
|
944
|
+
/** Visible label; typically `"Back to my account"` or `"Change amount"`. */
|
|
945
|
+
label: string;
|
|
946
|
+
/** Optional override for the arrow glyph (defaults to `←`). */
|
|
947
|
+
glyph?: string;
|
|
948
|
+
}
|
|
949
|
+
declare function BackLink({ label, glyph, className, onClick, ...rest }: BackLinkProps): react_jsx_runtime.JSX.Element;
|
|
950
|
+
|
|
951
|
+
interface McpCustomerDetailsCardProps {
|
|
952
|
+
classNames?: McpViewClassNames;
|
|
953
|
+
/**
|
|
954
|
+
* When provided, a "Top up" text button is rendered next to the
|
|
955
|
+
* Credit balance row. Typically wired to switch the active tab in
|
|
956
|
+
* the `<McpAppShell>` so the in-iframe navigation stays shell-local.
|
|
957
|
+
*/
|
|
958
|
+
onTopup?: () => void;
|
|
959
|
+
/**
|
|
960
|
+
* Hides the credit balance row even when a non-zero balance is
|
|
961
|
+
* present. Useful on an unlimited-plan customer whose `balance` is
|
|
962
|
+
* populated but semantically meaningless.
|
|
963
|
+
*/
|
|
964
|
+
hideBalance?: boolean;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Customer details — name, email, customer reference (monospaced, the
|
|
968
|
+
* value users paste into support tickets). The credit balance row is
|
|
969
|
+
* only rendered when `balance > 0` to avoid a "0 credits" row on a
|
|
970
|
+
* brand-new account.
|
|
971
|
+
*/
|
|
972
|
+
declare function McpCustomerDetailsCard({ classNames, onTopup, hideBalance, }: McpCustomerDetailsCardProps): react_jsx_runtime.JSX.Element;
|
|
973
|
+
interface McpSellerDetailsCardProps {
|
|
974
|
+
classNames?: McpViewClassNames;
|
|
975
|
+
/** Render the "Verified seller" trust badge next to the heading. */
|
|
976
|
+
showVerifiedBadge?: boolean;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Seller details — company name, legal entity, support email/URL,
|
|
980
|
+
* terms link. Compliance-relevant: a customer paying through the
|
|
981
|
+
* iframe should see who they're actually paying, to the same level of
|
|
982
|
+
* detail as hosted checkout.
|
|
983
|
+
*
|
|
984
|
+
* Currently pulls from `useMerchant()` only (no org number, postal
|
|
985
|
+
* address, or public website — those fields aren't on the SDK's
|
|
986
|
+
* `SdkMerchantResponseDto`). If / when the backend surfaces them, add
|
|
987
|
+
* them here.
|
|
988
|
+
*/
|
|
989
|
+
declare function McpSellerDetailsCard({ classNames, showVerifiedBadge, }: McpSellerDetailsCardProps): react_jsx_runtime.JSX.Element | null;
|
|
990
|
+
|
|
991
|
+
interface McpUpsellStripProps {
|
|
992
|
+
nudge: NudgeSpec;
|
|
993
|
+
/**
|
|
994
|
+
* Invoked when the user clicks the CTA. Default CTA per kind is
|
|
995
|
+
* "Upgrade" / "Renew"; consumers wire this to `openUpgrade()` in
|
|
996
|
+
* their MCP App shell.
|
|
997
|
+
*/
|
|
998
|
+
onCta?: () => void;
|
|
999
|
+
/**
|
|
1000
|
+
* Invoked when the user dismisses the strip. The strip hides locally
|
|
1001
|
+
* regardless of whether a handler is wired.
|
|
1002
|
+
*/
|
|
1003
|
+
onDismiss?: () => void;
|
|
1004
|
+
/** Suppress the dismiss button for sticky nudges. Defaults to false. */
|
|
1005
|
+
hideDismiss?: boolean;
|
|
1006
|
+
/** Override the default CTA label. */
|
|
1007
|
+
ctaLabel?: string;
|
|
1008
|
+
/** Override the root element class (intentionally narrow hook). */
|
|
1009
|
+
className?: string;
|
|
1010
|
+
}
|
|
1011
|
+
declare function McpUpsellStrip({ nudge, onCta, onDismiss, hideDismiss, ctaLabel, className, }: McpUpsellStripProps): react_jsx_runtime.JSX.Element | null;
|
|
1012
|
+
|
|
1013
|
+
export { type ActivationStrategy, type ActivityStripKind, type AppToolResultEvents, BackLink, type BackLinkProps, type HostEntryClassification, McpAccountView, type McpAccountViewProps, McpApp, type McpAppBootstrapLike, type McpAppFull, type McpAppLike, type McpAppProps, McpAppShell, type McpAppShellProps, type McpAppViewOverrides, type McpBootstrap, type McpBridgeAppLike, McpBridgeProvider, type McpBridgeProviderProps, type McpBridgeValue, McpCheckoutView, type McpCheckoutViewProps, McpCustomerDetailsCard, type McpCustomerDetailsCardProps, type McpMessageOnSuccess, McpNudgeView, type McpNudgeViewProps, McpPaywallView, type McpPaywallViewProps, McpSellerDetailsCard, type McpSellerDetailsCardProps, type McpSuccessEvent, type McpTabKind, type McpToolResult, McpTopupView, type McpTopupViewProps, type McpUiHostContextLike, McpUpsellStrip, type McpUpsellStripProps, type McpView, type McpViewClassNames, type McpViewKind, McpViewRouter, type McpViewRouterProps, type NotifyModelContextParams, type PlanActions, type PlanActionsInput, type PlanLike, type PlanShape, type PurchaseSnapshotLike, SOLVAPAY_TRANSPORT_TOOL_NAMES, type SendMessageParams, type StripeProbeState, type WaitForInitialToolResultOptions, type WaitForInitialToolResultResult, classifyHostEntry, createMcpAppAdapter, fetchMcpBootstrap, isTransportToolName, parseBootstrapFromToolResult, resolveActivationStrategy, resolveActivityStrip, resolveMcpClassNames, resolvePlanActions, resolvePlanShape, seedMcpCaches, useHostLocale, useMcpBridge, useMcpToolResult, useStripeProbe, waitForInitialToolResult };
|