mcp-scraper 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/api-server.cjs +189 -37
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +3 -3
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +100 -14
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +4 -4
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +3 -3
- package/dist/{chunk-GL4BW4CP.js → chunk-22VEGGTW.js} +21 -9
- package/dist/{chunk-GL4BW4CP.js.map → chunk-22VEGGTW.js.map} +1 -1
- package/dist/{chunk-RUGJE5EB.js → chunk-EJK25QOW.js} +2 -2
- package/dist/chunk-JWIE5NCR.js +284 -0
- package/dist/chunk-JWIE5NCR.js.map +1 -0
- package/dist/{chunk-O2S5TOCG.js → chunk-KE7KE2Q2.js} +102 -16
- package/dist/chunk-KE7KE2Q2.js.map +1 -0
- package/dist/chunk-PZB3TJWK.js +7 -0
- package/dist/chunk-PZB3TJWK.js.map +1 -0
- package/dist/{chunk-D7ZT27HY.js → chunk-UN7VMHZL.js} +2 -2
- package/dist/{chunk-2HDMYW4B.js → chunk-XDFSLSSH.js} +2 -2
- package/dist/{chunk-HE2LQPJ2.js → chunk-ZRKFW5FB.js} +2 -2
- package/dist/{db-LIOTIWVN.js → db-YHZYG7D2.js} +2 -2
- package/dist/{extract-bundle-U4D5LW5W.js → extract-bundle-OSUPAHCE.js} +58 -5
- package/dist/extract-bundle-OSUPAHCE.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{server-VWXDE64Y.js → server-VDWIPV7F.js} +37 -310
- package/dist/server-VDWIPV7F.js.map +1 -0
- package/dist/{site-extract-repository-NVSZH35Y.js → site-extract-repository-GWKGK46Z.js} +3 -3
- package/dist/{worker-AM2DHUWG.js → worker-O5PZTTPY.js} +5 -5
- package/docs/mcp-tool-manifest.generated.json +166 -23
- package/docs/specs/meta-ad-creative-media-resolution-spec.md +3 -3
- package/docs/specs/unified-credit-and-scheduled-execution-billing-spec.md +1007 -0
- package/package.json +1 -1
- package/dist/chunk-O2S5TOCG.js.map +0 -1
- package/dist/chunk-OQHYDW4Q.js +0 -7
- package/dist/chunk-OQHYDW4Q.js.map +0 -1
- package/dist/extract-bundle-U4D5LW5W.js.map +0 -1
- package/dist/server-VWXDE64Y.js.map +0 -1
- /package/dist/{chunk-RUGJE5EB.js.map → chunk-EJK25QOW.js.map} +0 -0
- /package/dist/{chunk-D7ZT27HY.js.map → chunk-UN7VMHZL.js.map} +0 -0
- /package/dist/{chunk-2HDMYW4B.js.map → chunk-XDFSLSSH.js.map} +0 -0
- /package/dist/{chunk-HE2LQPJ2.js.map → chunk-ZRKFW5FB.js.map} +0 -0
- /package/dist/{db-LIOTIWVN.js.map → db-YHZYG7D2.js.map} +0 -0
- /package/dist/{site-extract-repository-NVSZH35Y.js.map → site-extract-repository-GWKGK46Z.js.map} +0 -0
- /package/dist/{worker-AM2DHUWG.js.map → worker-O5PZTTPY.js.map} +0 -0
|
@@ -0,0 +1,1007 @@
|
|
|
1
|
+
# Unified Credits, Integrations, and Scheduled Execution Billing
|
|
2
|
+
|
|
3
|
+
- Status: Proposed canonical implementation spec
|
|
4
|
+
- Spec date: 2026-07-13
|
|
5
|
+
- Primary repos: mcp-scraper, mcp-scraper-scheduler, mcpscraper-web, mcpscraper-sdk
|
|
6
|
+
- Commercial decision: Scheduled Actions is a product capability, not a separate subscription
|
|
7
|
+
- Accounting decision: MCP Scraper's main credit ledger is the only debit authority
|
|
8
|
+
|
|
9
|
+
## Executive decision
|
|
10
|
+
|
|
11
|
+
MCP Scraper will use one visible usage currency: Credits.
|
|
12
|
+
|
|
13
|
+
Integrations, bulk connected-data movement, scheduled execution, model inference, and memory ingestion will all consume the same wallet. Scheduled Actions will no longer be sold as a separate $10-per-month product with a 1,000-run quota.
|
|
14
|
+
|
|
15
|
+
The replacement contract is:
|
|
16
|
+
|
|
17
|
+
1. Every paid MCP Scraper plan includes access to integrations and scheduling.
|
|
18
|
+
2. A customer without a recurring plan may activate metered features with a minimum $10 credit purchase once pay-as-you-go activation exists.
|
|
19
|
+
3. Each scheduled occurrence that successfully reserves Credits and begins execution costs a small fixed execution charge plus the exact work performed.
|
|
20
|
+
4. OpenRouter-backed AI is settled from OpenRouter's actual reported cost, multiplied by 1.5, then converted to Credits.
|
|
21
|
+
5. Token prices may be shown as current per-million-token estimates in Credits, but the reported OpenRouter cost is the invoice truth.
|
|
22
|
+
6. Active connections have a monthly Credit minimum that is offset by their actual eligible connection usage. This pays for OAuth, refresh, provider infrastructure, and idle connection overhead without charging a confusing separate integration subscription.
|
|
23
|
+
7. Every execution path—the public MCP, REST API, SDK, Mastra, background sync, and frontend—uses the same billing adapter and produces the same itemized receipt.
|
|
24
|
+
|
|
25
|
+
This design encourages usage: paid users can immediately connect and schedule work, higher-usage customers naturally consume more Credits, and there is no artificial 1,000-run cliff or add-on product to understand.
|
|
26
|
+
|
|
27
|
+
## What exists today
|
|
28
|
+
|
|
29
|
+
The originally intended scheduler economics are recognizable in the code, but the implementation is not safe enough to keep.
|
|
30
|
+
|
|
31
|
+
### Confirmed historical behavior
|
|
32
|
+
|
|
33
|
+
- Stripe has a $10-per-month Scheduled Actions checkout.
|
|
34
|
+
- The webhook grants a scheduling entitlement with a 1,000-run period quota.
|
|
35
|
+
- The scheduler contains a 1.5 OpenRouter markup constant.
|
|
36
|
+
- The scheduler reads OpenRouter's provider-reported usage cost.
|
|
37
|
+
- Scheduled agent execution attempts to record model usage and a pass-through cost.
|
|
38
|
+
|
|
39
|
+
So the answer to “was $10 meant to open the feature and then AI cost was marked up 50%?” is: substantially yes. The entitlement and the 50% markup both exist.
|
|
40
|
+
|
|
41
|
+
### Current billing defect
|
|
42
|
+
|
|
43
|
+
The effective path does not reliably implement that intended price:
|
|
44
|
+
|
|
45
|
+
1. schedule-execute invokes both meterLlmUsage and billPassThroughCost for the generated result.
|
|
46
|
+
2. Both paths can call recordCost.
|
|
47
|
+
3. recordCost can forward each raw AI cost to the main MCP Scraper AI-debit endpoint.
|
|
48
|
+
4. That endpoint applies the existing 3.0 memory-AI multiplier.
|
|
49
|
+
5. If both HTTP debits succeed, the final-step model cost can therefore produce two 3.0 debits—up to 6.0 times that raw cost—while the scheduler's local usage record describes a 1.5 billable amount.
|
|
50
|
+
6. The current metering client is fail-open, so missing configuration or a failed internal request can instead produce no debit.
|
|
51
|
+
7. The current call uses top-level usage and provider metadata. For a multi-step agent result, this describes the last step, not necessarily the complete run. Earlier model steps can be omitted.
|
|
52
|
+
|
|
53
|
+
The live scheduler environment has the internal MCP Scraper URL, internal debit secret, and OpenRouter key configured. This means the path is wired in production configuration; it is not merely dead local code.
|
|
54
|
+
|
|
55
|
+
### Required immediate interpretation
|
|
56
|
+
|
|
57
|
+
Do not assume existing scheduled-agent charges equal a clean 1.5 markup. Before changing customers or migrating subscriptions, reconcile scheduler usage records against the main credit ledger. Overcharges receive compensating Credits. Historical fail-open undercharges are not collected retroactively.
|
|
58
|
+
|
|
59
|
+
## Canonical Build Spec
|
|
60
|
+
|
|
61
|
+
- **Request:** Replace separate Scheduled Actions billing with a unified Credit wallet; correctly settle connected-service operations, deterministic syncs, and all-step OpenRouter costs; expose clear per-run budgets and receipts on every product surface.
|
|
62
|
+
- **Lane:** Mastra Agentic Development plus MCP/API product billing.
|
|
63
|
+
- **Capability:** Unified Metered Execution.
|
|
64
|
+
- **Audience:** MCP Scraper customers, scheduled-agent users, MCP clients, SDK users, operators, finance, and support.
|
|
65
|
+
- **User-Facing Outcome:** A user connects a service, optionally moves its data into memory, creates a schedule, sees an estimate and spending limit, and pays one itemized Credit charge for each completed or partially completed unit of work.
|
|
66
|
+
- **Target Runtime:** Main MCP Scraper API and credit ledger; Vercel-hosted Mastra scheduler; Inngest workers; Nango connections and Proxy/functions; private Blob artifacts; public MCP; npm/SDK clients.
|
|
67
|
+
- **Inputs:** Authenticated identity, connection ID, tool or sync request, scheduled occurrence, model selection, per-run and monthly Credit limits, actual provider results, OpenRouter usage metadata, bytes and records delivered.
|
|
68
|
+
- **Agents:** Existing Scheduled Action Agent for interpretive work. Deterministic connection_sync workers remain non-agentic. Both use the same billing context.
|
|
69
|
+
- **Workflows:** Connect; direct read/write; bulk export; memory import; schedule estimate; occurrence claim; Credit authorization; execution; incremental settlement; final settlement; receipt; retry/reconciliation.
|
|
70
|
+
- **Tools:** Existing generic connected-service tools, provider-native tools, schedule tools, bulk export/import tools, credits_info, a new schedule estimator, and a shared internal billing adapter.
|
|
71
|
+
- **MCP:** Credit behavior is transport-independent. Tool descriptions state charge categories and estimates, results include receipt summaries, and exact provider tools remain protected by tenant ownership, action switches, and grants.
|
|
72
|
+
- **Signals:** Billing authorization created; low balance; budget threshold; cost pending; settlement complete; insufficient Credits; automatic refill complete/failed; connection minimum due; connection billing paused.
|
|
73
|
+
- **Background Tasks:** Usage aggregation, connection-minimum settlement, pending-cost reconciliation, low-balance notifications, automatic refill, legacy subscription migration, receipt retention, and rate-snapshot refresh.
|
|
74
|
+
- **Guardrails:** Integer microcredit arithmetic, idempotent charges, one debit authority, no model-visible billing credentials, fail closed before externally costly work, action approval independent of price, no prompt or provider credential in billing events.
|
|
75
|
+
- **Observability:** Itemized receipt per run; raw vendor cost; multiplier; model/provider; tokens; bytes; changed records; connection and schedule IDs; idempotency keys; authorization, settlement, and refund state.
|
|
76
|
+
- **Enforcement:** A call cannot bypass the billing adapter by using Mastra, the generic MCP bridge, direct REST, SDK, Nango, or a background job. Duplicate occurrence or HTTP retry cannot debit twice.
|
|
77
|
+
- **Persistence:** The main MCP Scraper/Turso credit ledger owns balances and debits. Scheduler Postgres owns schedule state, occurrence state, and a mirrored receipt reference, not the authoritative wallet.
|
|
78
|
+
- **Deployment:** Main API/ledger first, then scheduler and connection adapters, then public MCP, frontend, SDK/npm/MCPB, generated docs, Stripe migration, and Vercel production.
|
|
79
|
+
- **Done Contract:** A production scheduled run authorizes a budget, records all model steps and connected-service work once, settles one exact Credit receipt, releases unused Credits, and presents the same receipt through the UI, MCP, API, and SDK.
|
|
80
|
+
- **Receipt Requirements:** Code and deployment SHAs; rate-table revision; Stripe migration result; test output; production Vercel IDs; npm/MCPB versions; sample agent and deterministic-sync billing receipts; reconciliation report; public pricing and tool-description parity.
|
|
81
|
+
|
|
82
|
+
## Product contract in plain language
|
|
83
|
+
|
|
84
|
+
### Scheduling is included
|
|
85
|
+
|
|
86
|
+
Scheduled Actions remains a first-class page and capability. It is not a separate product, subscription, or quota bundle.
|
|
87
|
+
|
|
88
|
+
Users with an active paid plan can create schedules immediately. Pay-as-you-go accounts can create schedules after a minimum $10 wallet activation is released. The $10 is a Credit purchase, not an expiring scheduler access fee.
|
|
89
|
+
|
|
90
|
+
Existing scheduled-action subscriptions are migrated; customers do not keep paying a separate scheduler subscription.
|
|
91
|
+
|
|
92
|
+
### Customers pay for a run, not internal loops
|
|
93
|
+
|
|
94
|
+
A scheduled occurrence pays:
|
|
95
|
+
|
|
96
|
+
fixed execution charge
|
|
97
|
+
+ connected-service work
|
|
98
|
+
+ bulk records and bytes delivered
|
|
99
|
+
+ model usage
|
|
100
|
+
+ memory processing
|
|
101
|
+
|
|
102
|
+
Internal pagination, retries, leases, and orchestration steps are not separate “runs.” A retry of the same occurrence cannot pay the fixed charge again.
|
|
103
|
+
|
|
104
|
+
### OpenRouter AI costs are transparent
|
|
105
|
+
|
|
106
|
+
The customer-facing rule is:
|
|
107
|
+
|
|
108
|
+
> AI model use consumes Credits equal to 1.5 times OpenRouter's actual reported cost.
|
|
109
|
+
|
|
110
|
+
MCP Scraper may show a model's current input, output, cached-input, image, and audio prices as estimated Credits per unit. Actual settlement always uses OpenRouter's returned usage.cost across every successful model step. This correctly captures routing, cache discounts, reasoning tokens, media, and provider-specific pricing.
|
|
111
|
+
|
|
112
|
+
### Action safety is not for sale
|
|
113
|
+
|
|
114
|
+
Charging more for a write does not authorize it. Mutations still require:
|
|
115
|
+
|
|
116
|
+
- a tenant-owned active connection;
|
|
117
|
+
- a live upstream tool that intersects source-controlled policy;
|
|
118
|
+
- the connection's action switch;
|
|
119
|
+
- the exact scheduled grant when scheduled;
|
|
120
|
+
- any required confirmation or destructive-action rule.
|
|
121
|
+
|
|
122
|
+
## Credit unit and accounting rules
|
|
123
|
+
|
|
124
|
+
### Canonical units
|
|
125
|
+
|
|
126
|
+
- Internal accounting unit: mc, an integer microcredit.
|
|
127
|
+
- Public accounting unit: Credit.
|
|
128
|
+
- Conversion: 100 mc = 1 Credit.
|
|
129
|
+
- Billing conversion: 2,000,000 mc per $3.00 of vendor cost, represented as an exact rational rather than a floating-point value.
|
|
130
|
+
- Fractional public Credits may be displayed to two decimal places, but all ledger math uses integer mc.
|
|
131
|
+
- Credit lots continue to expire according to the current three-month policy unless a later commercial decision changes it.
|
|
132
|
+
- Debits consume eligible lots using the existing ledger order.
|
|
133
|
+
|
|
134
|
+
The public skill currently says 1 Credit equals 1,000 mc while the source rate table says 1 Credit equals 100 mc. This 10-times documentation discrepancy is a release blocker. All public rates and examples must be generated from the canonical source table.
|
|
135
|
+
|
|
136
|
+
### Current plan grants
|
|
137
|
+
|
|
138
|
+
The current source rate table implies:
|
|
139
|
+
|
|
140
|
+
| Plan | Monthly price | Credits | Approximate Credits per dollar |
|
|
141
|
+
|---|---:|---:|---:|
|
|
142
|
+
| Starter | $12 | 80,000 | 6,666.7 |
|
|
143
|
+
| Growth | $40 | 266,667 | 6,666.7 |
|
|
144
|
+
| Scale | $100 | 800,000 | 8,000 |
|
|
145
|
+
|
|
146
|
+
The Scale grant is a deliberate volume discount. A fixed Credit charge therefore has a lower cash-equivalent markup for a Scale customer. Product copy may say the billing formula is 1.5 times raw OpenRouter cost; it must not promise that every plan produces a 50% cash gross margin after volume discounts.
|
|
147
|
+
|
|
148
|
+
The billing conversion must become an explicit rate-registry constant. It must no longer be derived from a Stripe plan's price or Credit grant. Otherwise an innocent plan-price edit would silently reprice AI work.
|
|
149
|
+
|
|
150
|
+
### One-time activation and refill
|
|
151
|
+
|
|
152
|
+
The old one-time pack mapping must not be reactivated because its $10 pack would grant 110,000 Credits and undercut recurring plans.
|
|
153
|
+
|
|
154
|
+
Recommended pay-as-you-go contract:
|
|
155
|
+
|
|
156
|
+
| Purchase | Credits | Purpose |
|
|
157
|
+
|---|---:|---|
|
|
158
|
+
| $10 minimum activation/refill | 50,000 | Enables metered integrations and schedules for a non-plan account |
|
|
159
|
+
| Customer-selected auto-refill | Same 5,000 Credits per dollar | Prevents interrupted schedules, subject to a monthly dollar cap |
|
|
160
|
+
|
|
161
|
+
Auto-refill is off by default. The customer chooses a threshold and a monthly maximum, and receives a receipt for each Stripe charge.
|
|
162
|
+
|
|
163
|
+
This is intentionally less generous than subscription grants. Plans remain the best value; pay-as-you-go exists for activation and overflow.
|
|
164
|
+
|
|
165
|
+
## Canonical rate table
|
|
166
|
+
|
|
167
|
+
All rates live in one versioned server-side registry. Frontends, MCP descriptions, SDKs, and docs consume generated projections from that registry.
|
|
168
|
+
|
|
169
|
+
### Connection operations
|
|
170
|
+
|
|
171
|
+
Initial launch rates:
|
|
172
|
+
|
|
173
|
+
| Billing class | Charge |
|
|
174
|
+
|---|---:|
|
|
175
|
+
| OAuth connect, reconnect, or consent callback | Free |
|
|
176
|
+
| Successful bounded read | 5 Credits |
|
|
177
|
+
| Successful low-complexity write | 10 Credits |
|
|
178
|
+
| Successful medium-complexity write | 15 Credits |
|
|
179
|
+
| Successful high-risk or high-complexity approved write | 25 Credits |
|
|
180
|
+
| Start a bulk export or sync slice | 25 Credits |
|
|
181
|
+
| Delivered or changed record | 2 Credits each |
|
|
182
|
+
| Transferred content | 10 Credits per started MiB |
|
|
183
|
+
| Provider or MCP Scraper validation failure before provider work | Free |
|
|
184
|
+
| Duplicate page, unchanged delta record, or idempotent replay | Free |
|
|
185
|
+
|
|
186
|
+
Tool manifests classify each action; a caller cannot choose a cheaper class. The provider-policy review owns read/write/risk classification.
|
|
187
|
+
|
|
188
|
+
Charge for the outcome, not raw upstream requests. For example, a 500-item export that requires ten provider pages is one bulk base plus 500 delivered records, not ten separate read charges.
|
|
189
|
+
|
|
190
|
+
A bounded read is limited to one logical object or at most 100 summary records and 1 MiB of structured output. Requests above either threshold use the bulk contract. A provider tool cannot evade bulk rates merely by accepting a very large page size.
|
|
191
|
+
|
|
192
|
+
### Active connection minimum
|
|
193
|
+
|
|
194
|
+
Each active connection has a 20,000-Credit minimum per 30-day billing period, prorated to the time it is active.
|
|
195
|
+
|
|
196
|
+
One tenant-owned credential/account row is one connection. Two Google accounts, two Slack workspaces, or two WordPress sites are separate connections. Disconnected and billing-paused credentials do not accrue a new minimum; active and reauthorization-grace credentials accrue only for the active seconds in the period.
|
|
197
|
+
|
|
198
|
+
Eligible connected-service usage offsets this minimum:
|
|
199
|
+
|
|
200
|
+
- bounded reads and writes;
|
|
201
|
+
- bulk-export base;
|
|
202
|
+
- delivered/changed records;
|
|
203
|
+
- transferred bytes;
|
|
204
|
+
- explicit provider-operation surcharges when later added.
|
|
205
|
+
|
|
206
|
+
The following do not offset the connection minimum:
|
|
207
|
+
|
|
208
|
+
- OpenRouter model inference;
|
|
209
|
+
- scheduled-occurrence base;
|
|
210
|
+
- generic web scraping;
|
|
211
|
+
- memory storage capacity;
|
|
212
|
+
- memory embeddings or other AI processing.
|
|
213
|
+
|
|
214
|
+
The first connection's first 30 days are waived. This creates a real activation path before an idle-connection charge appears.
|
|
215
|
+
|
|
216
|
+
At settlement, only the shortfall is charged:
|
|
217
|
+
|
|
218
|
+
connection minimum debit
|
|
219
|
+
= max(0, prorated minimum - eligible usage already charged)
|
|
220
|
+
|
|
221
|
+
If a wallet cannot cover the minimum:
|
|
222
|
+
|
|
223
|
+
1. Mark the connection billing-paused.
|
|
224
|
+
2. Allow a seven-day read-only recovery window for refill or plan activation.
|
|
225
|
+
3. Block new scheduled use and mutations immediately.
|
|
226
|
+
4. After the grace period, remove or disconnect the stored upstream credential if necessary to stop ongoing vendor charges.
|
|
227
|
+
5. Keep non-secret connection history and explain that reconnection is required.
|
|
228
|
+
|
|
229
|
+
This behavior must be disclosed before connection and in low-balance notices.
|
|
230
|
+
|
|
231
|
+
### Scheduled execution
|
|
232
|
+
|
|
233
|
+
| Billing class | Charge |
|
|
234
|
+
|---|---:|
|
|
235
|
+
| Authorized scheduled occurrence that begins execution | 75 Credits |
|
|
236
|
+
| Duplicate/replayed occurrence | Free |
|
|
237
|
+
| Skipped before execution for insufficient Credits | Free |
|
|
238
|
+
| Work inside the occurrence | Normal applicable rates |
|
|
239
|
+
|
|
240
|
+
The 75-Credit base preserves the rough economics of the former $10-for-1,000-runs product:
|
|
241
|
+
|
|
242
|
+
- 1,000 runs use 75,000 Credits.
|
|
243
|
+
- That is approximately $9.38 of Scale plan Credits or $11.25 of Starter/Growth plan Credits.
|
|
244
|
+
|
|
245
|
+
It also allows a light schedule to remain inexpensive. A schedule running at 8 AM, noon, and 4 PM Mountain executes about 90 times in a 30-day month, using 6,750 Credits in fixed run charges before its data and model work.
|
|
246
|
+
|
|
247
|
+
#### Agent schedule
|
|
248
|
+
|
|
249
|
+
An agent occurrence settles:
|
|
250
|
+
|
|
251
|
+
75-Credit occurrence base
|
|
252
|
+
+ provider tool charges
|
|
253
|
+
+ connected data records/bytes
|
|
254
|
+
+ OpenRouter actual cost times 1.5
|
|
255
|
+
+ memory ingestion or artifact processing
|
|
256
|
+
|
|
257
|
+
#### Deterministic connection sync
|
|
258
|
+
|
|
259
|
+
A connection_sync occurrence settles:
|
|
260
|
+
|
|
261
|
+
75-Credit occurrence base
|
|
262
|
+
+ 25-Credit bulk slice base when a slice starts
|
|
263
|
+
+ changed records
|
|
264
|
+
+ transferred bytes
|
|
265
|
+
+ memory embedding/ingestion processing
|
|
266
|
+
|
|
267
|
+
There is no model charge unless that deterministic pipeline actually invokes a model.
|
|
268
|
+
|
|
269
|
+
### OpenRouter model inference
|
|
270
|
+
|
|
271
|
+
The settlement formula is:
|
|
272
|
+
|
|
273
|
+
raw_cost_usd = sum(OpenRouter usage.cost for every successful model step)
|
|
274
|
+
billable_mc = ceil(raw_cost_usd × 1.5 × canonical_mc_per_usd)
|
|
275
|
+
billable_credits = billable_mc / 100
|
|
276
|
+
|
|
277
|
+
At the current canonical conversion derived from Starter/Growth grants:
|
|
278
|
+
|
|
279
|
+
canonical_mc_per_usd = 2,000,000 / 3
|
|
280
|
+
$1.00 raw OpenRouter cost = 10,000 billed Credits
|
|
281
|
+
|
|
282
|
+
As of this spec, OpenRouter lists MiniMax M3 at $0.30 per million input tokens, $1.20 per million output tokens, and $0.06 per million cached-input tokens for standard providers. The customer-facing estimate is therefore:
|
|
283
|
+
|
|
284
|
+
| MiniMax M3 usage | Estimated Credits |
|
|
285
|
+
|---|---:|
|
|
286
|
+
| 1 million input tokens | 3,000 Credits |
|
|
287
|
+
| 1 million output tokens | 12,000 Credits |
|
|
288
|
+
| 1 million cached-input tokens | 600 Credits |
|
|
289
|
+
|
|
290
|
+
These are display estimates, not a settlement substitute. The rate UI must show the source timestamp and refresh when OpenRouter pricing changes.
|
|
291
|
+
|
|
292
|
+
### Worked examples
|
|
293
|
+
|
|
294
|
+
#### Light scheduled agent
|
|
295
|
+
|
|
296
|
+
Assume one MiniMax M3 run uses 100,000 input tokens, 20,000 output tokens, and one bounded connected-service read:
|
|
297
|
+
|
|
298
|
+
| Line item | Credits |
|
|
299
|
+
|---|---:|
|
|
300
|
+
| Scheduled occurrence | 75 |
|
|
301
|
+
| Connected-service read | 5 |
|
|
302
|
+
| Estimated model input | 300 |
|
|
303
|
+
| Estimated model output | 240 |
|
|
304
|
+
| Estimated total | 620 |
|
|
305
|
+
|
|
306
|
+
The model lines settle from the actual reported OpenRouter cost, so 620 is an estimate until the receipt closes.
|
|
307
|
+
|
|
308
|
+
#### Deterministic bulk sync
|
|
309
|
+
|
|
310
|
+
Assume a sync delivers 500 changed records and 50 MiB:
|
|
311
|
+
|
|
312
|
+
| Line item | Credits |
|
|
313
|
+
|---|---:|
|
|
314
|
+
| Scheduled occurrence | 75 |
|
|
315
|
+
| Bulk slice | 25 |
|
|
316
|
+
| 500 changed records | 1,000 |
|
|
317
|
+
| 50 MiB transferred | 500 |
|
|
318
|
+
| Total before memory processing | 1,600 |
|
|
319
|
+
|
|
320
|
+
### Existing non-scheduler AI classes
|
|
321
|
+
|
|
322
|
+
The unified registry keeps existing product-specific multipliers explicit:
|
|
323
|
+
|
|
324
|
+
| Billing class | Initial multiplier |
|
|
325
|
+
|---|---:|
|
|
326
|
+
| scheduled_agent_llm | 1.5 |
|
|
327
|
+
| memory_ai | 3.0 |
|
|
328
|
+
| site_audit_ai | 1.5 |
|
|
329
|
+
| video_analysis_ai | 1.5 |
|
|
330
|
+
| media_transcription_ai | 3.0 |
|
|
331
|
+
|
|
332
|
+
The caller supplies the billing class, not the multiplier. The main billing server resolves the multiplier from its versioned registry. This prevents a compromised or outdated worker from choosing its own price.
|
|
333
|
+
|
|
334
|
+
## Price display policy
|
|
335
|
+
|
|
336
|
+
The primary display is Credits.
|
|
337
|
+
|
|
338
|
+
Recommended copy:
|
|
339
|
+
|
|
340
|
+
> Integrations and scheduling are included. Each run uses Credits for the work it performs.
|
|
341
|
+
|
|
342
|
+
> AI model use is billed at OpenRouter's actual reported cost plus 50%, converted to Credits.
|
|
343
|
+
|
|
344
|
+
> Estimated MiniMax M3 rate: 3,000 Credits per million input tokens and 12,000 Credits per million output tokens. Exact usage may vary by provider, caching, reasoning, media, and routing.
|
|
345
|
+
|
|
346
|
+
The UI may place raw dollar rates in a secondary tooltip or expandable explanation. A single fixed dollar-per-million claim must not replace actual-cost settlement.
|
|
347
|
+
|
|
348
|
+
## Per-run and monthly budgets
|
|
349
|
+
|
|
350
|
+
Every schedule has:
|
|
351
|
+
|
|
352
|
+
- maxCreditsPerRun, default 5,000 Credits;
|
|
353
|
+
- maxCreditsPerMonth, default 50,000 Credits;
|
|
354
|
+
- lowBalanceBehavior, initially pause;
|
|
355
|
+
- optional model allowlist;
|
|
356
|
+
- optional maximum model steps and output tokens;
|
|
357
|
+
- an estimate produced before activation.
|
|
358
|
+
|
|
359
|
+
The user can edit these limits without recreating the schedule.
|
|
360
|
+
|
|
361
|
+
Before each occurrence:
|
|
362
|
+
|
|
363
|
+
1. Calculate a conservative reservation from the per-run cap and available balance.
|
|
364
|
+
2. If the monthly cap has insufficient headroom, skip with no run-base charge.
|
|
365
|
+
3. If the wallet cannot reserve the required amount, skip with no run-base charge and notify the owner.
|
|
366
|
+
4. Stop further model steps and provider mutations before exceeding the reserved cap.
|
|
367
|
+
5. Release unused reserved Credits after settlement.
|
|
368
|
+
|
|
369
|
+
The current very large max-output-token ceiling cannot function as the spending guard. Budget enforcement must occur during execution, including after each model step.
|
|
370
|
+
|
|
371
|
+
## End-to-end execution contract
|
|
372
|
+
|
|
373
|
+
### Occurrence flow
|
|
374
|
+
|
|
375
|
+
Inngest or scheduler trigger
|
|
376
|
+
-> idempotently claim identity + schedule + scheduledFor
|
|
377
|
+
-> ask main billing service for a Credit reservation
|
|
378
|
+
-> receive opaque billing context and reservation
|
|
379
|
+
-> execute exact schedule grants
|
|
380
|
+
-> attach billing context to internal child calls
|
|
381
|
+
-> accumulate provider, record, byte, model, and memory line items
|
|
382
|
+
-> settle actual integer mc once
|
|
383
|
+
-> release unused reservation
|
|
384
|
+
-> persist itemized receipt reference
|
|
385
|
+
-> expose the same receipt on API, MCP, SDK, and UI
|
|
386
|
+
|
|
387
|
+
The billing context travels in an internal authenticated transport header or server-side execution context. It is never put in the model prompt, tool arguments, provider payload, or public result.
|
|
388
|
+
|
|
389
|
+
### Direct non-scheduled flow
|
|
390
|
+
|
|
391
|
+
Direct MCP, REST, or SDK work follows the same abbreviated path:
|
|
392
|
+
|
|
393
|
+
authorize maximum charge
|
|
394
|
+
-> execute tenant-owned exact tool
|
|
395
|
+
-> settle outcome
|
|
396
|
+
-> return result plus receipt summary
|
|
397
|
+
|
|
398
|
+
The generic MCP bridge and a provider-native MCP tool must produce the same billing class for the same operation.
|
|
399
|
+
|
|
400
|
+
### Multi-step model accounting
|
|
401
|
+
|
|
402
|
+
For Mastra/AI SDK generate results:
|
|
403
|
+
|
|
404
|
+
- top-level usage represents the last step;
|
|
405
|
+
- totalUsage aggregates tokens but does not by itself provide a trustworthy total dollar cost;
|
|
406
|
+
- providerMetadata on each step contains that step's OpenRouter usage.cost in the current runtime.
|
|
407
|
+
|
|
408
|
+
Therefore the scheduler must iterate all result.steps and sum each providerMetadata.openrouter.usage.cost. It must not debit from both a generic usage meter and a pass-through-cost function.
|
|
409
|
+
|
|
410
|
+
When a step has no usage.cost:
|
|
411
|
+
|
|
412
|
+
1. Save the OpenRouter generation ID when available.
|
|
413
|
+
2. Query OpenRouter's generation endpoint for the authoritative cost.
|
|
414
|
+
3. Keep the receipt in cost_pending state until reconciled.
|
|
415
|
+
4. Use a current rate snapshot only for authorization and estimates, never silent final settlement.
|
|
416
|
+
5. Pause later occurrences if pending costs cannot be reconciled within the configured window.
|
|
417
|
+
|
|
418
|
+
## Single debit authority
|
|
419
|
+
|
|
420
|
+
The main MCP Scraper billing service is the only component allowed to mutate the customer's Credit balance.
|
|
421
|
+
|
|
422
|
+
| Component | May do | Must not do |
|
|
423
|
+
|---|---|---|
|
|
424
|
+
| Main billing service | Authorize, reserve, settle, refund, expire, and report Credits | Execute schedules or hold provider credentials |
|
|
425
|
+
| Scheduler | Request authorization, emit line items, mirror receipt status | Directly debit a wallet or apply a multiplier |
|
|
426
|
+
| Mastra agent | Use granted tools within a budget | Receive wallet secrets or price itself |
|
|
427
|
+
| Connected-service adapter | Report classified outcomes, records, and bytes | Create plan-dependent rates |
|
|
428
|
+
| Nango | Authenticate provider calls and return results | Own MCP Scraper pricing or Credits |
|
|
429
|
+
| Frontend/SDK/MCP | Display estimates and receipts from server | Calculate authoritative charges locally |
|
|
430
|
+
|
|
431
|
+
The existing internal memory AI-debit endpoint becomes a compatibility adapter during migration, then routes through the unified billing service. It may not apply an extra 3.0 multiplier to a scheduled_agent_llm event.
|
|
432
|
+
|
|
433
|
+
## Billing data model
|
|
434
|
+
|
|
435
|
+
Names are illustrative; final migrations follow existing repository naming.
|
|
436
|
+
|
|
437
|
+
### billing_events
|
|
438
|
+
|
|
439
|
+
Required fields:
|
|
440
|
+
|
|
441
|
+
- id;
|
|
442
|
+
- identity_id;
|
|
443
|
+
- idempotency_key, globally unique;
|
|
444
|
+
- billing_class;
|
|
445
|
+
- source_surface;
|
|
446
|
+
- schedule_id, nullable;
|
|
447
|
+
- occurrence_id, nullable;
|
|
448
|
+
- connection_id, nullable;
|
|
449
|
+
- tool_name, nullable;
|
|
450
|
+
- model and provider, nullable;
|
|
451
|
+
- generation_id, nullable;
|
|
452
|
+
- raw_cost_usd_nanos or an exact decimal representation, nullable;
|
|
453
|
+
- multiplier_basis_points, nullable;
|
|
454
|
+
- input_tokens, output_tokens, cached_input_tokens, reasoning_tokens, nullable;
|
|
455
|
+
- record_count, nullable;
|
|
456
|
+
- byte_count, nullable;
|
|
457
|
+
- amount_mc;
|
|
458
|
+
- rate_revision;
|
|
459
|
+
- status: estimated, authorized, pending, settled, refunded, void, or cost_pending;
|
|
460
|
+
- safe metadata JSON;
|
|
461
|
+
- created_at and settled_at.
|
|
462
|
+
|
|
463
|
+
Do not store prompts, model responses, provider tokens, OAuth tokens, email bodies, file content, or raw tool arguments.
|
|
464
|
+
|
|
465
|
+
### credit_reservations
|
|
466
|
+
|
|
467
|
+
Required fields:
|
|
468
|
+
|
|
469
|
+
- id;
|
|
470
|
+
- identity_id;
|
|
471
|
+
- idempotency_key, unique;
|
|
472
|
+
- max_amount_mc;
|
|
473
|
+
- consumed_amount_mc;
|
|
474
|
+
- released_amount_mc;
|
|
475
|
+
- status: active, settled, released, expired;
|
|
476
|
+
- expires_at;
|
|
477
|
+
- occurrence_id or request_id;
|
|
478
|
+
- created_at and updated_at.
|
|
479
|
+
|
|
480
|
+
The balance available for new work excludes active reservations.
|
|
481
|
+
|
|
482
|
+
### billing_receipts
|
|
483
|
+
|
|
484
|
+
A receipt groups line items for one direct request, bulk job slice, or scheduled occurrence:
|
|
485
|
+
|
|
486
|
+
- receipt ID;
|
|
487
|
+
- identity;
|
|
488
|
+
- source and run IDs;
|
|
489
|
+
- rate revision;
|
|
490
|
+
- total mc and public Credits;
|
|
491
|
+
- line-item summaries;
|
|
492
|
+
- reserved, settled, and released amounts;
|
|
493
|
+
- status;
|
|
494
|
+
- timestamps;
|
|
495
|
+
- safe failure/refund reason.
|
|
496
|
+
|
|
497
|
+
### connection_billing_periods
|
|
498
|
+
|
|
499
|
+
Required fields:
|
|
500
|
+
|
|
501
|
+
- identity and connection ID;
|
|
502
|
+
- period start/end;
|
|
503
|
+
- active seconds and prorated minimum;
|
|
504
|
+
- eligible usage mc;
|
|
505
|
+
- shortfall mc;
|
|
506
|
+
- settlement event ID;
|
|
507
|
+
- status;
|
|
508
|
+
- grace deadline.
|
|
509
|
+
|
|
510
|
+
## Idempotency and retry rules
|
|
511
|
+
|
|
512
|
+
### Scheduled occurrence key
|
|
513
|
+
|
|
514
|
+
The canonical occurrence key is:
|
|
515
|
+
|
|
516
|
+
schedule:{identityId}:{scheduleId}:{scheduledForIso}
|
|
517
|
+
|
|
518
|
+
It owns at most one occurrence-base event. The base event is created only after the claim obtains a Credit reservation and execution begins. Worker retries, leases, and resumed slices reference that event.
|
|
519
|
+
|
|
520
|
+
### Line-item keys
|
|
521
|
+
|
|
522
|
+
Examples:
|
|
523
|
+
|
|
524
|
+
occurrenceKey:base
|
|
525
|
+
occurrenceKey:llm:{stepId}
|
|
526
|
+
occurrenceKey:connection:{callId}
|
|
527
|
+
occurrenceKey:records:{dataset}:{checkpoint}
|
|
528
|
+
occurrenceKey:bytes:{artifactId}
|
|
529
|
+
request:{requestId}:tool:{toolCallId}
|
|
530
|
+
|
|
531
|
+
The main ledger rejects a second settlement for the same key and returns the existing receipt.
|
|
532
|
+
|
|
533
|
+
### Partial success
|
|
534
|
+
|
|
535
|
+
- Work completed before a provider or user error remains chargeable.
|
|
536
|
+
- No provider-work line is charged for validation failure before the provider call.
|
|
537
|
+
- Changed records already delivered remain charged if a later page fails.
|
|
538
|
+
- Unused reservation is always released.
|
|
539
|
+
- The 75-Credit platform base is refunded when MCP Scraper itself fails before useful execution.
|
|
540
|
+
- The base is not refunded for invalid customer configuration, expired OAuth after a valid start, provider outage after dispatch, or user-authored agent failure unless support policy grants a courtesy refund.
|
|
541
|
+
- Actual OpenRouter cost remains chargeable whenever the provider incurred it, even if the final workflow outcome fails.
|
|
542
|
+
|
|
543
|
+
Refund reasons are structured and support-visible.
|
|
544
|
+
|
|
545
|
+
## Internal billing API
|
|
546
|
+
|
|
547
|
+
The exact route naming may follow current conventions, but the contract must include:
|
|
548
|
+
|
|
549
|
+
### Authorize
|
|
550
|
+
|
|
551
|
+
POST /api/internal/billing/authorizations
|
|
552
|
+
|
|
553
|
+
Input:
|
|
554
|
+
|
|
555
|
+
- identity;
|
|
556
|
+
- idempotency key;
|
|
557
|
+
- billing intent;
|
|
558
|
+
- maximum mc;
|
|
559
|
+
- schedule, occurrence, connection, and request references;
|
|
560
|
+
- rate revision requested or latest.
|
|
561
|
+
|
|
562
|
+
Output:
|
|
563
|
+
|
|
564
|
+
- authorization ID;
|
|
565
|
+
- opaque billing-context token;
|
|
566
|
+
- reserved mc;
|
|
567
|
+
- rate revision;
|
|
568
|
+
- expiry;
|
|
569
|
+
- remaining wallet and monthly-budget summaries.
|
|
570
|
+
|
|
571
|
+
### Add line items
|
|
572
|
+
|
|
573
|
+
POST /api/internal/billing/authorizations/:id/line-items
|
|
574
|
+
|
|
575
|
+
Input is a batch of classified, idempotent measurements. The server applies rates and multipliers. The worker never sends an authoritative final Credit amount for a class whose price is server-owned.
|
|
576
|
+
|
|
577
|
+
### Settle
|
|
578
|
+
|
|
579
|
+
POST /api/internal/billing/authorizations/:id/settle
|
|
580
|
+
|
|
581
|
+
The server atomically debits actual mc, releases the remainder, and returns the final receipt.
|
|
582
|
+
|
|
583
|
+
### Void or refund
|
|
584
|
+
|
|
585
|
+
POST /api/internal/billing/authorizations/:id/void
|
|
586
|
+
|
|
587
|
+
POST /api/internal/billing/receipts/:id/refunds
|
|
588
|
+
|
|
589
|
+
Refunds append compensating ledger events. Settled rows are never silently edited.
|
|
590
|
+
|
|
591
|
+
### Availability policy
|
|
592
|
+
|
|
593
|
+
- If authorization is unavailable, fail closed before externally costly work.
|
|
594
|
+
- If line-item reporting is temporarily unavailable after work starts, persist a durable outbox record.
|
|
595
|
+
- If settlement is pending, mark cost_pending and pause future work that could increase exposure.
|
|
596
|
+
- Never discard a charge measurement because an HTTP request failed.
|
|
597
|
+
|
|
598
|
+
## Public API, MCP, and SDK contract
|
|
599
|
+
|
|
600
|
+
### Existing tools to extend
|
|
601
|
+
|
|
602
|
+
credits_info adds:
|
|
603
|
+
|
|
604
|
+
- canonical Credit conversion;
|
|
605
|
+
- rate revision;
|
|
606
|
+
- connection rates;
|
|
607
|
+
- connection minimum policy;
|
|
608
|
+
- schedule base;
|
|
609
|
+
- current model estimate table;
|
|
610
|
+
- actual-cost language;
|
|
611
|
+
- credit expiry and auto-refill summary.
|
|
612
|
+
|
|
613
|
+
create_scheduled_action adds:
|
|
614
|
+
|
|
615
|
+
- maxCreditsPerRun;
|
|
616
|
+
- maxCreditsPerMonth;
|
|
617
|
+
- estimatedCreditsPerRun;
|
|
618
|
+
- estimate assumptions and warning range.
|
|
619
|
+
|
|
620
|
+
get_schedule_status adds:
|
|
621
|
+
|
|
622
|
+
- month-to-date Credit spend;
|
|
623
|
+
- remaining monthly budget;
|
|
624
|
+
- last authorization and receipt IDs;
|
|
625
|
+
- last itemized Credit summary;
|
|
626
|
+
- paused-for-billing state;
|
|
627
|
+
- pending-cost state.
|
|
628
|
+
|
|
629
|
+
Connection list/status adds:
|
|
630
|
+
|
|
631
|
+
- current billing period;
|
|
632
|
+
- eligible usage toward minimum;
|
|
633
|
+
- projected shortfall;
|
|
634
|
+
- billing-paused/grace state;
|
|
635
|
+
- next settlement date.
|
|
636
|
+
|
|
637
|
+
All connected-service execution tools return a compact billing summary:
|
|
638
|
+
|
|
639
|
+
- receipt ID;
|
|
640
|
+
- Credits charged;
|
|
641
|
+
- line-item category;
|
|
642
|
+
- pending or settled status.
|
|
643
|
+
|
|
644
|
+
### New estimator
|
|
645
|
+
|
|
646
|
+
Add estimate_scheduled_action_cost to the root MCP and corresponding REST/SDK methods.
|
|
647
|
+
|
|
648
|
+
Inputs:
|
|
649
|
+
|
|
650
|
+
- schedule mode;
|
|
651
|
+
- frequency and timezone;
|
|
652
|
+
- selected connections and tools;
|
|
653
|
+
- expected records/bytes when known;
|
|
654
|
+
- model and estimated input/output tokens when agentic;
|
|
655
|
+
- memory destination;
|
|
656
|
+
- proposed budgets.
|
|
657
|
+
|
|
658
|
+
Outputs:
|
|
659
|
+
|
|
660
|
+
- fixed Credits per occurrence and per month;
|
|
661
|
+
- variable estimate range;
|
|
662
|
+
- model rate snapshot;
|
|
663
|
+
- assumptions;
|
|
664
|
+
- recommended maxCreditsPerRun and maxCreditsPerMonth;
|
|
665
|
+
- warning that actual OpenRouter-reported cost controls settlement.
|
|
666
|
+
|
|
667
|
+
Estimation is free and creates no reservation.
|
|
668
|
+
|
|
669
|
+
### Tool-description language
|
|
670
|
+
|
|
671
|
+
Every billable tool schema includes:
|
|
672
|
+
|
|
673
|
+
- its billing class;
|
|
674
|
+
- fixed charge if any;
|
|
675
|
+
- variable units;
|
|
676
|
+
- whether failure can incur provider/model cost;
|
|
677
|
+
- link or pointer to credits_info;
|
|
678
|
+
- whether it participates in a connection minimum.
|
|
679
|
+
|
|
680
|
+
Tool descriptions do not hardcode copied rates by hand. They are generated or injected from the canonical registry.
|
|
681
|
+
|
|
682
|
+
## Mastra integration
|
|
683
|
+
|
|
684
|
+
### Scheduled Action Agent
|
|
685
|
+
|
|
686
|
+
The agent receives:
|
|
687
|
+
|
|
688
|
+
- exact tenant-owned connection toolsets;
|
|
689
|
+
- a server-side Credit budget;
|
|
690
|
+
- a per-step guard;
|
|
691
|
+
- remaining-budget context as trusted runtime metadata, not user prompt content;
|
|
692
|
+
- no access to billing credentials or wallet mutation tools.
|
|
693
|
+
|
|
694
|
+
Use onStepFinish or the current equivalent to:
|
|
695
|
+
|
|
696
|
+
1. capture each model step's OpenRouter usage cost;
|
|
697
|
+
2. append one idempotent line item;
|
|
698
|
+
3. check remaining reserved budget;
|
|
699
|
+
4. stop before the next expensive step when the cap is reached.
|
|
700
|
+
|
|
701
|
+
The final result uses total tool outcomes plus all step records. Remove the dual meterLlmUsage and billPassThroughCost debit behavior.
|
|
702
|
+
|
|
703
|
+
### Connection sync worker
|
|
704
|
+
|
|
705
|
+
The deterministic worker:
|
|
706
|
+
|
|
707
|
+
- claims the same occurrence key;
|
|
708
|
+
- authorizes its budget;
|
|
709
|
+
- reports one bulk-slice base;
|
|
710
|
+
- reports only changed/delivered records;
|
|
711
|
+
- reports content bytes once per stored artifact;
|
|
712
|
+
- reports memory processing through existing explicit classes;
|
|
713
|
+
- checkpoints before settlement so retry behavior is deterministic.
|
|
714
|
+
|
|
715
|
+
The worker never invokes a model merely to paginate or transfer content.
|
|
716
|
+
|
|
717
|
+
## User experience
|
|
718
|
+
|
|
719
|
+
### Pricing page
|
|
720
|
+
|
|
721
|
+
Remove the Scheduled Actions add-on card.
|
|
722
|
+
|
|
723
|
+
Under every paid plan:
|
|
724
|
+
|
|
725
|
+
> Integrations and scheduled work included. Usage draws from your shared Credit balance.
|
|
726
|
+
|
|
727
|
+
Add a concise rate drawer containing:
|
|
728
|
+
|
|
729
|
+
- active connection minimum;
|
|
730
|
+
- read/write/bulk rates;
|
|
731
|
+
- 75-Credit scheduled occurrence;
|
|
732
|
+
- current model estimates in Credits;
|
|
733
|
+
- “actual OpenRouter cost plus 50%” disclosure;
|
|
734
|
+
- expiry, refill, and budget behavior.
|
|
735
|
+
|
|
736
|
+
### Integrations page
|
|
737
|
+
|
|
738
|
+
Each card shows:
|
|
739
|
+
|
|
740
|
+
- connected account count;
|
|
741
|
+
- real callable read/action inventory;
|
|
742
|
+
- action switch;
|
|
743
|
+
- current billing-period usage;
|
|
744
|
+
- minimum progress;
|
|
745
|
+
- next settlement;
|
|
746
|
+
- billing state;
|
|
747
|
+
- a link to import/schedule.
|
|
748
|
+
|
|
749
|
+
OAuth authorization itself remains free.
|
|
750
|
+
|
|
751
|
+
### Scheduling page
|
|
752
|
+
|
|
753
|
+
Keep Scheduling as a prominent feature and navigation destination.
|
|
754
|
+
|
|
755
|
+
The creation flow shows:
|
|
756
|
+
|
|
757
|
+
1. frequency and timezone;
|
|
758
|
+
2. selected connection/data/action;
|
|
759
|
+
3. destination or intended result;
|
|
760
|
+
4. estimated fixed and variable Credits;
|
|
761
|
+
5. per-run and monthly caps;
|
|
762
|
+
6. low-balance behavior;
|
|
763
|
+
7. action confirmation/grants;
|
|
764
|
+
8. activate.
|
|
765
|
+
|
|
766
|
+
The schedule detail view presents an itemized history, not just “one run.”
|
|
767
|
+
|
|
768
|
+
### Usage page
|
|
769
|
+
|
|
770
|
+
Group receipts by:
|
|
771
|
+
|
|
772
|
+
- direct tools;
|
|
773
|
+
- connected-service operations;
|
|
774
|
+
- bulk/import;
|
|
775
|
+
- scheduled occurrences;
|
|
776
|
+
- OpenRouter AI;
|
|
777
|
+
- memory processing;
|
|
778
|
+
- connection minimums;
|
|
779
|
+
- refunds.
|
|
780
|
+
|
|
781
|
+
Users can filter by connection, schedule, model, provider, and date.
|
|
782
|
+
|
|
783
|
+
## Scheduled Actions subscription migration
|
|
784
|
+
|
|
785
|
+
### Customer treatment
|
|
786
|
+
|
|
787
|
+
1. Stop new scheduler-subscription checkout after the unified billing path is proven.
|
|
788
|
+
2. Identify active, trialing, past-due, and cancelled-at-period-end scheduler subscriptions.
|
|
789
|
+
3. Grant a migration Credit amount equal to the unused prepaid portion, with a customer-friendly floor.
|
|
790
|
+
4. Cancel the separate Stripe scheduler subscription at the correct boundary without interrupting saved schedules.
|
|
791
|
+
5. Remove entitlement and 1,000-run quota gates.
|
|
792
|
+
6. Preserve schedule definitions, timezone, encrypted service key, grants, and history.
|
|
793
|
+
7. Assign default per-run and monthly budgets.
|
|
794
|
+
8. Notify customers before the first Credit-billed occurrence.
|
|
795
|
+
|
|
796
|
+
Recommended migration grant:
|
|
797
|
+
|
|
798
|
+
max(prorated unused $10 converted at plan rate, 75,000 Credits for a fully unused current period)
|
|
799
|
+
|
|
800
|
+
The exact grant must be tested against Stripe period data and approved before execution.
|
|
801
|
+
|
|
802
|
+
### Historical billing reconciliation
|
|
803
|
+
|
|
804
|
+
Build a one-time report joining:
|
|
805
|
+
|
|
806
|
+
- scheduler mem_usage_ledger scheduled entries;
|
|
807
|
+
- schedule occurrence/run IDs;
|
|
808
|
+
- raw OpenRouter costs and step metadata where retained;
|
|
809
|
+
- main credit-ledger debit events;
|
|
810
|
+
- Stripe scheduler subscription state.
|
|
811
|
+
|
|
812
|
+
Classify each occurrence:
|
|
813
|
+
|
|
814
|
+
- correctly debited once;
|
|
815
|
+
- potentially duplicated;
|
|
816
|
+
- wrong multiplier;
|
|
817
|
+
- missing earlier model steps;
|
|
818
|
+
- fail-open/no debit;
|
|
819
|
+
- no usable evidence.
|
|
820
|
+
|
|
821
|
+
Issue compensating Credits for defensible overcharges. Do not retroactively debit undercharges. Retain an operator receipt and customer-support note.
|
|
822
|
+
|
|
823
|
+
## Rollout sequence
|
|
824
|
+
|
|
825
|
+
### Gate 0 — freeze unsafe expansion
|
|
826
|
+
|
|
827
|
+
- Do not add more callers to the current scheduled AI debit functions.
|
|
828
|
+
- Add telemetry that identifies both debit paths without changing customer balances.
|
|
829
|
+
- Preserve current schedule service while the replacement is built.
|
|
830
|
+
|
|
831
|
+
### Gate 1 — canonical registry and generated public rates
|
|
832
|
+
|
|
833
|
+
- Move Credit conversion, billing classes, multipliers, and display estimates into one versioned registry.
|
|
834
|
+
- Generate the MCP skill, public rate API, frontend copy data, and SDK constants.
|
|
835
|
+
- Fix the 100-versus-1,000 mc public discrepancy.
|
|
836
|
+
|
|
837
|
+
### Gate 2 — unified ledger and reservation API
|
|
838
|
+
|
|
839
|
+
- Add billing events, reservations, receipts, idempotency constraints, and durable outbox.
|
|
840
|
+
- Wrap existing direct Credit debits behind the service.
|
|
841
|
+
- Keep old endpoints as compatibility adapters.
|
|
842
|
+
|
|
843
|
+
### Gate 3 — shadow scheduler billing
|
|
844
|
+
|
|
845
|
+
- Authorize no real reservations yet.
|
|
846
|
+
- Calculate the proposed 75-Credit base and all-step OpenRouter amount in shadow.
|
|
847
|
+
- Compare against current debits and production receipts.
|
|
848
|
+
- Prove multi-step aggregation and single-debit behavior.
|
|
849
|
+
|
|
850
|
+
### Gate 4 — scheduler cutover
|
|
851
|
+
|
|
852
|
+
- Enable reservations and settlement for internal/test tenants.
|
|
853
|
+
- Remove the duplicate model debit path.
|
|
854
|
+
- Enable per-run/month caps and cost-pending reconciliation.
|
|
855
|
+
- Expand to production cohorts after receipt review.
|
|
856
|
+
|
|
857
|
+
### Gate 5 — deterministic sync and direct connection billing
|
|
858
|
+
|
|
859
|
+
- Route connection_sync and bulk export through the same billing context.
|
|
860
|
+
- Then route generic MCP, REST, and SDK calls.
|
|
861
|
+
- Start active-connection minimums only after a full shadow period and customer notice.
|
|
862
|
+
|
|
863
|
+
### Gate 6 — commercial migration
|
|
864
|
+
|
|
865
|
+
- Stop new schedule add-on sales.
|
|
866
|
+
- Grant migration Credits and cancel old Stripe subscriptions.
|
|
867
|
+
- Remove entitlement/quota enforcement.
|
|
868
|
+
- Activate $10 pay-as-you-go refill only after its Stripe and ledger path is complete.
|
|
869
|
+
|
|
870
|
+
### Gate 7 — full release
|
|
871
|
+
|
|
872
|
+
- Update frontend, pricing, scheduler copy, MCP schemas, npm package, SDKs, MCPB, terms, support docs, and Vercel production.
|
|
873
|
+
- Run production smoke receipts.
|
|
874
|
+
- Publish a customer explanation and migration FAQ.
|
|
875
|
+
|
|
876
|
+
## Required tests
|
|
877
|
+
|
|
878
|
+
### Rate and arithmetic tests
|
|
879
|
+
|
|
880
|
+
- 100 mc equals 1 public Credit everywhere.
|
|
881
|
+
- All charges use integers and defined ceiling rules.
|
|
882
|
+
- Vendor-cost conversion uses exact rational or decimal arithmetic, never binary floating-point ledger math.
|
|
883
|
+
- OpenRouter raw cost times 1.5 yields the exact expected mc.
|
|
884
|
+
- Plan grants do not alter the number of Credits charged for an identical action.
|
|
885
|
+
- MiniMax display estimates are generated from a timestamped rate snapshot.
|
|
886
|
+
|
|
887
|
+
### Model accounting tests
|
|
888
|
+
|
|
889
|
+
- One-step result settles once.
|
|
890
|
+
- Multi-step result sums every step's usage.cost.
|
|
891
|
+
- Top-level final-step metadata alone cannot settle the run.
|
|
892
|
+
- meterLlmUsage and pass-through code cannot each debit the same result.
|
|
893
|
+
- Missing cost becomes cost_pending and reconciles by generation ID.
|
|
894
|
+
- Model failure after incurring cost retains that provider-cost line.
|
|
895
|
+
|
|
896
|
+
### Scheduling tests
|
|
897
|
+
|
|
898
|
+
- A new schedule does not require a scheduler subscription.
|
|
899
|
+
- One occurrence receives one 75-Credit base.
|
|
900
|
+
- Retry and lease replay do not duplicate the base.
|
|
901
|
+
- Insufficient Credits before authorization produces a free skip.
|
|
902
|
+
- Per-run cap stops later model/provider work.
|
|
903
|
+
- Monthly cap pauses future occurrences.
|
|
904
|
+
- Unused reservation is released.
|
|
905
|
+
- agent and connection_sync modes both produce receipts.
|
|
906
|
+
- Existing saved schedules survive entitlement migration.
|
|
907
|
+
|
|
908
|
+
### Connection tests
|
|
909
|
+
|
|
910
|
+
- OAuth callback is free.
|
|
911
|
+
- Bounded reads and approved writes receive correct server-owned classes.
|
|
912
|
+
- Internal pagination is not separately billed.
|
|
913
|
+
- Unchanged incremental records are not charged.
|
|
914
|
+
- Bytes are charged once per artifact.
|
|
915
|
+
- Direct MCP, REST, SDK, Mastra, and background calls produce parity.
|
|
916
|
+
- Connection minimum offsets eligible usage and prorates correctly.
|
|
917
|
+
- First-connection waiver and billing-pause grace work.
|
|
918
|
+
|
|
919
|
+
### Ledger tests
|
|
920
|
+
|
|
921
|
+
- Globally unique idempotency keys prevent double debit.
|
|
922
|
+
- Reservation and settlement are atomic.
|
|
923
|
+
- Refunds append compensating events.
|
|
924
|
+
- Active reservations reduce available balance.
|
|
925
|
+
- Durable outbox survives billing-service interruption.
|
|
926
|
+
- No prompt, result body, OAuth token, or billing secret enters billing metadata.
|
|
927
|
+
|
|
928
|
+
### Product-surface tests
|
|
929
|
+
|
|
930
|
+
- Pricing page no longer sells Scheduled Actions separately.
|
|
931
|
+
- Integrations and Scheduling are in desktop and mobile navigation.
|
|
932
|
+
- credits_info, estimator, schedule status, receipts, UI, and SDK agree.
|
|
933
|
+
- Public skill and source rate table have generated parity.
|
|
934
|
+
- npm, MCPB, hosted MCP, REST, and Vercel production expose the same schemas.
|
|
935
|
+
|
|
936
|
+
## Production proof
|
|
937
|
+
|
|
938
|
+
Before marking complete, capture:
|
|
939
|
+
|
|
940
|
+
1. A tiny direct connected-service read and receipt.
|
|
941
|
+
2. A safe approved connected-service write and receipt.
|
|
942
|
+
3. A two-step scheduled agent run proving both OpenRouter step costs settle once.
|
|
943
|
+
4. A deterministic sync with unchanged and changed records proving delta billing.
|
|
944
|
+
5. An insufficient-balance occurrence proving a free skip.
|
|
945
|
+
6. A retry proving no duplicate base or line item.
|
|
946
|
+
7. A failed MCP Scraper execution proving the correct base refund.
|
|
947
|
+
8. A current model-rate endpoint and matching frontend/MCP display.
|
|
948
|
+
9. A migrated scheduler subscription with saved schedule continuity.
|
|
949
|
+
10. Vercel deployment, npm version, MCPB manifest, SDK version, and generated-doc parity.
|
|
950
|
+
|
|
951
|
+
Receipts must be sanitized. Do not include prompts, connection tokens, API keys, customer content, raw provider arguments, or signed artifact URLs.
|
|
952
|
+
|
|
953
|
+
## Release blockers
|
|
954
|
+
|
|
955
|
+
- Any remaining path that directly mutates Credits outside the main billing service.
|
|
956
|
+
- Any duplicate scheduled model debit.
|
|
957
|
+
- Settlement based only on final-step metadata.
|
|
958
|
+
- Fail-open execution that can incur provider cost without a durable pending charge.
|
|
959
|
+
- Missing idempotency across occurrence, tool call, record batch, or artifact.
|
|
960
|
+
- The public 1 Credit equals 1,000 mc mismatch.
|
|
961
|
+
- Separate scheduling entitlement or 1,000-run quota still enforced on any surface.
|
|
962
|
+
- Frontend, hosted MCP, SDK/npm, MCPB, or public docs showing different rates.
|
|
963
|
+
- A fixed token rate described as authoritative rather than an estimate.
|
|
964
|
+
- Connection minimum enabled without customer notice, waiver, and billing-pause behavior.
|
|
965
|
+
- Commercial migration without a reconciliation and compensating-credit policy.
|
|
966
|
+
|
|
967
|
+
## Decisions locked by this spec
|
|
968
|
+
|
|
969
|
+
- Scheduled Actions is included and metered, not a separate subscription.
|
|
970
|
+
- Credits are the primary customer-facing unit.
|
|
971
|
+
- OpenRouter actual reported cost is the AI settlement source.
|
|
972
|
+
- scheduled_agent_llm uses a 1.5 multiplier.
|
|
973
|
+
- Model token tables are estimates.
|
|
974
|
+
- The fixed scheduled-occurrence charge is 75 Credits.
|
|
975
|
+
- The launch active-connection minimum is 20,000 Credits per 30 days, offset by eligible connection usage.
|
|
976
|
+
- OAuth is free.
|
|
977
|
+
- Main MCP Scraper owns the only mutable Credit ledger.
|
|
978
|
+
- Every product and execution surface produces a shared receipt.
|
|
979
|
+
- Action authorization remains separate from billing.
|
|
980
|
+
|
|
981
|
+
## Decisions that may change only through a rate revision
|
|
982
|
+
|
|
983
|
+
- Exact per-read, per-write, per-record, and per-MiB rates.
|
|
984
|
+
- Connection-minimum amount and waiver duration.
|
|
985
|
+
- Pay-as-you-go Credit grant per dollar.
|
|
986
|
+
- Default per-run and monthly caps.
|
|
987
|
+
- Existing non-scheduler AI multipliers.
|
|
988
|
+
|
|
989
|
+
Changing one of these does not require a protocol redesign, but it requires a new rate revision, generated-surface parity, tests, and customer notice where applicable.
|
|
990
|
+
|
|
991
|
+
## Source references
|
|
992
|
+
|
|
993
|
+
- OpenRouter usage accounting: https://openrouter.ai/docs/cookbook/administration/usage-accounting
|
|
994
|
+
- OpenRouter API usage object: https://openrouter.ai/docs/api/reference/overview
|
|
995
|
+
- Current MiniMax M3 pricing: https://openrouter.ai/minimax/minimax-m3/pricing
|
|
996
|
+
- Current MCP Scraper rate source: src/api/rates.ts
|
|
997
|
+
- Current main AI debit route: src/api/server.ts
|
|
998
|
+
- Current scheduler billing logic: ../mcp-scraper-scheduler/src/mastra/lib/schedule-billing.ts
|
|
999
|
+
- Current scheduled execution path: ../mcp-scraper-scheduler/src/mastra/steps/schedule-execute.ts
|
|
1000
|
+
- Current schedule entitlement re-export: ../mcp-scraper-scheduler/src/mastra/db/schedule-entitlements.ts
|
|
1001
|
+
- Current scheduler usage re-export: ../mcp-scraper-scheduler/src/mastra/db/usage.ts
|
|
1002
|
+
- Installed memory DB entitlement implementation: ../mcp-scraper-scheduler/node_modules/mcpscraper-memory-db/dist/db/schedule-entitlements.js
|
|
1003
|
+
- Installed memory DB usage and debit implementation: ../mcp-scraper-scheduler/node_modules/mcpscraper-memory-db/dist/db/usage.js
|
|
1004
|
+
|
|
1005
|
+
## Final acceptance statement
|
|
1006
|
+
|
|
1007
|
+
The implementation is complete only when a customer can connect a service, schedule or directly invoke work, move data into memory, and receive one understandable Credit receipt whose amount is identical across the live ledger, frontend, MCP, REST, Mastra, and SDK. A local code path, pricing-page change, or scheduler-only implementation does not satisfy this spec.
|