create-solvapay 0.7.0 → 0.7.1

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/README.md CHANGED
@@ -24,6 +24,13 @@ From scratch (single placeholder tool):
24
24
  npm create solvapay@latest my-mcp-app -- --type mcp --no-openapi
25
25
  ```
26
26
 
27
+ Next.js + Auth0 starter:
28
+
29
+ ```bash
30
+ npm create solvapay@latest my-app -- --type next-auth0
31
+ # equivalent: npm create solvapay@latest my-app -- --auth auth0
32
+ ```
33
+
27
34
  ### Skills for coding agents
28
35
 
29
36
  > **Already in an agent session?** Run `npx skills add solvapay/skills` and ask to create a paid MCP app — the agent routes to `create-mcp-app` and runs the scaffold for you.
@@ -61,7 +68,8 @@ npm run deploy # Cloudflare Workers deploy
61
68
 
62
69
  | Flag | Description |
63
70
  | --- | --- |
64
- | `--type <kind>` | Project type (`mcp` today). Required in non-interactive mode. |
71
+ | `--type <kind>` | Project type (`mcp` or `next-auth0`). Required in non-interactive mode. |
72
+ | `--auth <provider>` | Shortcut for auth-focused starters. `--auth auth0` selects `--type next-auth0`. |
65
73
  | `-y`, `--yes` | Non-interactive: accept all defaults |
66
74
  | `--product <ref>` | Pre-fill `SOLVAPAY_PRODUCT_REF` (skip the picker) |
67
75
  | `--non-interactive` | Alias for `--yes`; fail fast on missing prompt input |
@@ -78,7 +86,7 @@ npm run deploy # Cloudflare Workers deploy
78
86
  | `--no-openapi` | From-scratch mode with a placeholder paid tool |
79
87
  | `--tool-name <camel>` | Placeholder tool name in from-scratch mode (default: `helloTool`) |
80
88
 
81
- Run `npm create solvapay my-app -- --type mcp --help` for MCP-specific help.
89
+ Run `npm create solvapay@latest my-app -- --type mcp --help` for MCP-specific help.
82
90
 
83
91
  ## Integration paths
84
92
 
@@ -88,6 +96,7 @@ Run `npm create solvapay my-app -- --type mcp --help` for MCP-specific help.
88
96
  | Next.js checkout | `npx solvapay init` | `@solvapay/next` + `@solvapay/react` | [checkout-demo](https://github.com/solvapay/solvapay-sdk/tree/main/examples/checkout-demo) | [Next.js](https://docs.solvapay.com/sdks/typescript/guides/nextjs), [React](https://docs.solvapay.com/sdks/typescript/guides/react) |
89
97
  | Hosted checkout | `npx solvapay init` | `@solvapay/next` | [hosted-checkout-demo](https://github.com/solvapay/solvapay-sdk/tree/main/examples/hosted-checkout-demo) | [Purchase management](https://docs.solvapay.com/sdks/typescript/guides/purchase-management) |
90
98
  | Supabase Edge | `npx solvapay init` | `@solvapay/server/fetch` + `@solvapay/react` | [supabase-edge](https://github.com/solvapay/solvapay-sdk/tree/main/examples/supabase-edge) | [Supabase Edge](https://docs.solvapay.com/sdks/typescript/guides/supabase-edge) |
99
+ | Next.js + Auth0 | **`npm create solvapay@latest <name> -- --type next-auth0`** | `@solvapay/next` + `@auth0/nextjs-auth0` | scaffold template | [Customer linkage](https://docs.solvapay.com/sdks/typescript/guides/customer-linkage) |
91
100
  | **MCP app (server + UI)** | **`npm create solvapay@latest <name> -- --type mcp`** | `@solvapay/mcp` + `@solvapay/react/mcp` + `@solvapay/server` | scaffold template | [MCP](https://docs.solvapay.com/sdks/typescript/guides/mcp), [MCP app](https://docs.solvapay.com/sdks/typescript/guides/mcp-app) |
92
101
  | MCP App UI (advanced) | manual on existing server | `@solvapay/mcp` + `@solvapay/react/mcp` | [mcp-checkout-app](https://github.com/solvapay/solvapay-sdk/tree/main/examples/mcp-checkout-app) | [MCP app](https://docs.solvapay.com/sdks/typescript/guides/mcp-app) |
93
102
  | Existing MCP server | `npx solvapay init` | `@solvapay/server` + `@solvapay/mcp-core` | [mcp-oauth-bridge](https://github.com/solvapay/solvapay-sdk/tree/main/examples/mcp-oauth-bridge) | [MCP](https://docs.solvapay.com/sdks/typescript/guides/mcp) |
@@ -240,7 +240,7 @@ function printConnectionSnippets(options) {
240
240
  out(` Cursor \u2014 add to \`~/.cursor/mcp.json\` (or the workspace's \`.cursor/mcp.json\`):`);
241
241
  out(" {");
242
242
  out(' "mcpServers": {');
243
- out(` "${projectName}": { "url": "${workerUrl}/" }`);
243
+ out(` "${projectName}": { "url": "${workerUrl}/mcp" }`);
244
244
  out(" }");
245
245
  out(" }");
246
246
  out("");
@@ -249,26 +249,27 @@ function printConnectionSnippets(options) {
249
249
  out(' "mcpServers": {');
250
250
  out(` "${projectName}": {`);
251
251
  out(' "command": "npx",');
252
- out(` "args": ["mcp-remote", "${workerUrl}/"]`);
252
+ out(` "args": ["mcp-remote", "${workerUrl}/mcp"]`);
253
253
  out(" }");
254
254
  out(" }");
255
255
  out(" }");
256
256
  out("");
257
257
  out(" ChatGPT (Custom Connectors) \u2014 add a Custom MCP Connector with:");
258
- out(` URL: ${workerUrl}/`);
258
+ out(` URL: ${workerUrl}/mcp`);
259
259
  out(" Note: ChatGPT needs a reachable (deployed or tunneled) URL \u2014");
260
260
  out(" localhost only works for native-scheme hosts. Use `npm run deploy`");
261
261
  out(" and point ChatGPT at the *.workers.dev URL once available.");
262
262
  out("");
263
263
  out(" MCP Inspector \u2014 explore tools locally:");
264
264
  out(" npx @modelcontextprotocol/inspector");
265
- out(` (set the server URL to ${workerUrl}/)`);
265
+ out(` (set the server URL to ${workerUrl}/mcp)`);
266
266
  out("");
267
267
  }
268
268
  var SOLVAPAY_RUNTIME_DEPS = Object.freeze([
269
- { name: "@solvapay/mcp", fallback: "0.3.0" },
270
- { name: "@solvapay/server", fallback: "1.1.0" },
271
- { name: "@solvapay/react", fallback: "1.2.0" }
269
+ { name: "@solvapay/mcp", fallback: "0.4.3" },
270
+ { name: "@solvapay/mcp-core", fallback: "0.4.4" },
271
+ { name: "@solvapay/server", fallback: "2.8.0" },
272
+ { name: "@solvapay/react", fallback: "2.3.1" }
272
273
  ]);
273
274
  async function resolveLatestSolvapayVersions(deps = SOLVAPAY_RUNTIME_DEPS, options = {}) {
274
275
  const timeoutMs = options.timeoutMs ?? 3e3;
package/dist/cli.js CHANGED
@@ -15,8 +15,8 @@ import { stdin, stdout } from "process";
15
15
 
16
16
  // src/types/registry.ts
17
17
  var PROJECT_TYPES = {
18
- mcp: () => import("./mcp-YJ55XDBZ.js").then((m) => m.mcpProjectType),
19
- "next-auth0": () => import("./next-auth0-YAG227HM.js").then((m) => m.nextAuth0ProjectType)
18
+ mcp: () => import("./mcp-EZUBUZLF.js").then((m) => m.mcpProjectType),
19
+ "next-auth0": () => import("./next-auth0-WNIMA6EQ.js").then((m) => m.nextAuth0ProjectType)
20
20
  // cli: () => import('./cli/index.js').then(m => m.cliProjectType), // future
21
21
  };
22
22
  var PROJECT_TYPE_IDS = Object.keys(PROJECT_TYPES);
@@ -15,7 +15,7 @@ import {
15
15
  printConnectionSnippets,
16
16
  resolveLatestSolvapayVersions,
17
17
  writeBootstrapEnv
18
- } from "./chunk-BH3INHDI.js";
18
+ } from "./chunk-W4KM7GUB.js";
19
19
  import {
20
20
  MCP_HELP_TEXT,
21
21
  inferMcpMode,
@@ -4,7 +4,7 @@ import {
4
4
  copyDir,
5
5
  gitInit,
6
6
  installProjectDependencies
7
- } from "./chunk-BH3INHDI.js";
7
+ } from "./chunk-W4KM7GUB.js";
8
8
  import {
9
9
  toInitOptions
10
10
  } from "./chunk-4LPTJYUF.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-solvapay",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Scaffold SolvaPay-monetized projects — MCP servers on Cloudflare Workers and more.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -71,11 +71,11 @@ Useful URLs printed at startup:
71
71
 
72
72
  | What | URL |
73
73
  | --- | --- |
74
- | Worker MCP endpoint | `http://localhost:8787/` |
74
+ | Worker MCP endpoint | `http://localhost:8787/mcp` |
75
75
  | OAuth discovery | `http://localhost:8787/.well-known/oauth-protected-resource` |
76
76
  | OAuth metadata | `http://localhost:8787/.well-known/oauth-authorization-server` |
77
77
 
78
- Inspect tools with: `npx @modelcontextprotocol/inspector` and point it at `http://localhost:8787/`.
78
+ Inspect tools with: `npx @modelcontextprotocol/inspector` and point it at `http://localhost:8787/mcp`.
79
79
 
80
80
  Other scripts:
81
81
 
@@ -110,7 +110,7 @@ actual header names from the OpenAPI security schemes, for example:
110
110
  UPSTREAM_API_HEADERS={"x-api-client-id":"client-id","x-api-client-secret":"client-secret"}
111
111
  ```
112
112
 
113
- Point an MCP client (MCP Inspector, MCPJam, Claude Desktop, ChatGPT Custom Connectors) at `http://localhost:8787/`.
113
+ Point an MCP client (MCP Inspector, MCPJam, Claude Desktop, ChatGPT Custom Connectors) at `http://localhost:8787/mcp`.
114
114
 
115
115
  ## Deploy
116
116
 
@@ -174,6 +174,24 @@ export function registerMyTool(ctx: AdditionalToolsContext, env: Env) {
174
174
 
175
175
  Then add an import + `registerMyTool(ctx, env)` line to `src/tools/index.ts`. Re-deploy.
176
176
 
177
+ For a per-customer free allowance instead of a per-call charge, use `registerFree` with a `limit` (same handler shape):
178
+
179
+ ```ts
180
+ export function registerPreview(ctx: AdditionalToolsContext) {
181
+ ctx.registerFree('preview', {
182
+ title: 'Preview',
183
+ description: 'Free preview — 5 calls / 30 days, then a plan is required.',
184
+ schema: { input: z.string() },
185
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
186
+ limit: { meter: 'free-previews', cap: 5, scope: 'rolling_window', windowDays: 30 },
187
+ handler: async ({ input }, c) => {
188
+ const data = await doSomething(input)
189
+ return c.respond(data, { text: `Preview for ${input}: …` })
190
+ },
191
+ })
192
+ }
193
+ ```
194
+
177
195
  ## Reference
178
196
 
179
197
  - [`@solvapay/mcp/fetch`](https://www.npmjs.com/package/@solvapay/mcp) — `createSolvaPayMcpFetch` is the entire integration surface.
@@ -17,9 +17,10 @@
17
17
  "@modelcontextprotocol/ext-apps": "^1.7.1",
18
18
  "@modelcontextprotocol/core": "^2.0.0",
19
19
  "@modelcontextprotocol/server": "^2.0.0",
20
- "@solvapay/mcp": "^0.3.0",
21
- "@solvapay/react": "^1.2.0",
22
- "@solvapay/server": "^1.1.0",
20
+ "@solvapay/mcp": "^0.4.3",
21
+ "@solvapay/mcp-core": "^0.4.4",
22
+ "@solvapay/react": "^2.3.1",
23
+ "@solvapay/server": "^2.8.0",
23
24
  "react": "^19.2.5",
24
25
  "react-dom": "^19.2.5",
25
26
  "zod": "^4.3.6"
@@ -633,16 +633,16 @@ function printDeployedConnectionSnippets(publicUrl, workerName) {
633
633
  out('Connect an MCP client to the deployed worker:')
634
634
  out('')
635
635
  out(' Cursor (~/.cursor/mcp.json):')
636
- out(` { "mcpServers": { "${name}": { "url": "${url}/" } } }`)
636
+ out(` { "mcpServers": { "${name}": { "url": "${url}/mcp" } } }`)
637
637
  out('')
638
638
  out(' Claude Desktop (claude_desktop_config.json):')
639
639
  out(
640
- ` { "mcpServers": { "${name}": { "command": "npx", "args": ["mcp-remote", "${url}/"] } } }`,
640
+ ` { "mcpServers": { "${name}": { "command": "npx", "args": ["mcp-remote", "${url}/mcp"] } } }`,
641
641
  )
642
642
  out('')
643
- out(` ChatGPT Custom MCP Connector URL: ${url}/`)
643
+ out(` ChatGPT Custom MCP Connector URL: ${url}/mcp`)
644
644
  out('')
645
- out(` MCP Inspector: npx @modelcontextprotocol/inspector (set URL to ${url}/)`)
645
+ out(` MCP Inspector: npx @modelcontextprotocol/inspector (set URL to ${url}/mcp)`)
646
646
  out('')
647
647
  }
648
648
 
@@ -34,12 +34,12 @@ function printBanner() {
34
34
  const lines = [
35
35
  '',
36
36
  '┌─ SolvaPay MCP — local dev ─────────────────────────────────',
37
- `│ Worker MCP endpoint ${WORKER_URL}/`,
37
+ `│ Worker MCP endpoint ${WORKER_URL}/mcp`,
38
38
  `│ OAuth discovery ${WORKER_URL}/.well-known/oauth-protected-resource`,
39
39
  `│ OAuth metadata ${WORKER_URL}/.well-known/oauth-authorization-server`,
40
40
  '│',
41
41
  '│ Inspect tools npx @modelcontextprotocol/inspector',
42
- `│ (set the server URL to ${WORKER_URL}/)`,
42
+ `│ (set the server URL to ${WORKER_URL}/mcp)`,
43
43
  '│',
44
44
  '│ Verify contract node scripts/verify.mjs ' + WORKER_URL,
45
45
  '└────────────────────────────────────────────────────────────',
@@ -113,7 +113,7 @@ async function main() {
113
113
  : await runIntentToolsTextCheck(base, rpcOptions)
114
114
 
115
115
  // `merchantBootstrap` exercises the SolvaPay bootstrap path by
116
- // calling `manage_account` (an intent tool, always registered) and
116
+ // calling `account` (an intent tool, always registered) and
117
117
  // asserting the response is not an error envelope. Without a bearer
118
118
  // token, the call would gate at the HTTP layer — so it skips. With
119
119
  // a bearer token, a 500 or text containing `"bootstrap"` is a real
@@ -122,12 +122,12 @@ function getHandler(env: Env): (req: Request) => Promise<Response> {
122
122
  responseMode: 'json',
123
123
  // Hide UI-only transport tools from the LLM-facing `tools/list`
124
124
  // (text hosts: Claude Desktop, MCPJam, Cursor) — keeps the model's
125
- // tool catalogue narrow to the four intent tools (`upgrade`,
126
- // `manage_account`, `activate_plan`, `topup`) plus this worker's
127
- // generated tools. ChatGPT-originated tools/list requests are
128
- // auto-detected and receive the full catalog so the iframe's
129
- // `create_payment_intent` calls (plan + topup via `purpose`)
130
- // pass ChatGPT's gateway catalogue check.
125
+ // tool catalogue narrow to the intent tools (`account`,
126
+ // `activate_plan`) plus this worker's generated tools. ChatGPT-
127
+ // originated tools/list requests are auto-detected and receive the
128
+ // full catalog so the iframe's `create_payment_intent` calls
129
+ // (plan + topup via `purpose`) pass ChatGPT's gateway catalogue
130
+ // check.
131
131
  hideToolsByAudience: ['ui'],
132
132
  additionalTools: ctx => registerTools(ctx, env),
133
133
  })
@@ -10,4 +10,5 @@ To add more paid tools later, create a new file under `src/tools/` that
10
10
  exports a `register<ToolName>` function and call it from
11
11
  `src/tools/index.ts`. Each `ctx.registerPayable(...)` call earns the
12
12
  configured paywall amount per invocation against
13
- `SOLVAPAY_PRODUCT_REF`.
13
+ `SOLVAPAY_PRODUCT_REF`. Use `ctx.registerFree(...)` with a `limit` for
14
+ a per-customer free allowance instead of a per-call charge.
@@ -26,7 +26,7 @@ export function register__TOOL_NAME_PASCAL__(ctx: AdditionalToolsContext): void
26
26
  ctx.registerPayable('__TOOL_NAME__', {
27
27
  title: '__TOOL_NAME__',
28
28
  description:
29
- 'Placeholder paid tool — echoes the input message back so you can verify the paywall is wired before writing real logic. 1 credit per call; returns a text-only purchase-required narration naming the `upgrade` or `topup` recovery tool when the customer is out of balance. Replace this description (and the handler) with your tool semantics before going live.',
29
+ 'Placeholder paid tool — echoes the input message back so you can verify the paywall is wired before writing real logic. 1 credit per call; returns a text-only purchase-required narration naming the `account` recovery tool when the customer is out of balance. Replace this description (and the handler) with your tool semantics before going live.',
30
30
  schema: {
31
31
  message: z.string().describe('What the caller wants').optional(),
32
32
  },
@@ -42,6 +42,20 @@ export function register__TOOL_NAME_PASCAL__(ctx: AdditionalToolsContext): void
42
42
  },
43
43
  })
44
44
 
45
+ // Free-allowance sibling — swap `registerPayable` for this when the
46
+ // tool should be free up to a per-customer cap:
47
+ //
48
+ // ctx.registerFree('__TOOL_NAME__', {
49
+ // title: '__TOOL_NAME__',
50
+ // description: 'Free up to 5 calls / 30 days, then a plan is required.',
51
+ // schema: { message: z.string().optional() },
52
+ // annotations: { readOnlyHint: true, openWorldHint: true },
53
+ // limit: { meter: 'free-previews', cap: 5, scope: 'rolling_window', windowDays: 30 },
54
+ // handler: async (input, c) => {
55
+ // return c.respond({ ok: true, echoed: input.message ?? 'hello' })
56
+ // },
57
+ // })
58
+
45
59
  ctx.server.registerPrompt(
46
60
  '__TOOL_NAME__',
47
61
  {