@zackbart/connecta 0.18.2 → 0.19.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/CHANGELOG.md +100 -4
- package/README.md +4 -0
- package/dist/catalog-service.d.ts +20 -13
- package/dist/catalog-service.js +123 -116
- package/dist/catalog.js +29 -46
- package/dist/connector-scope.js +2 -7
- package/dist/connectors/api.d.ts +4 -16
- package/dist/connectors/api.js +19 -46
- package/dist/connectors/guarded-fetch.d.ts +9 -23
- package/dist/connectors/guarded-fetch.js +38 -76
- package/dist/connectors/remote-mcp.js +36 -79
- package/dist/errors.d.ts +6 -27
- package/dist/errors.js +8 -5
- package/dist/execute.d.ts +24 -22
- package/dist/execute.js +98 -145
- package/dist/executor-result.d.ts +1 -0
- package/dist/executor-result.js +4 -11
- package/dist/executors/quickjs-child.js +1 -3
- package/dist/executors/quickjs-runtime.js +1 -3
- package/dist/executors/quickjs.js +1 -3
- package/dist/index.js +27 -57
- package/dist/invocation.js +114 -178
- package/dist/meta-tools.d.ts +15 -28
- package/dist/meta-tools.js +33 -89
- package/dist/providers/cloudflare.d.ts +2 -18
- package/dist/providers/cloudflare.js +1460 -2451
- package/dist/providers/linear.d.ts +4 -41
- package/dist/providers/linear.js +8 -39
- package/dist/providers/mixpanel.d.ts +3 -25
- package/dist/providers/mixpanel.js +7 -22
- package/dist/providers/notion.d.ts +1 -15
- package/dist/providers/notion.js +44 -173
- package/dist/providers/revenuecat.d.ts +4 -57
- package/dist/providers/revenuecat.js +10 -93
- package/dist/providers/stripe.d.ts +1 -12
- package/dist/providers/stripe.js +7 -45
- package/dist/registry.d.ts +16 -34
- package/dist/registry.js +18 -103
- package/dist/result-shapes.d.ts +13 -0
- package/dist/result-shapes.js +331 -0
- package/dist/routes/mcp.js +1 -1
- package/dist/routes/oauth.js +3 -3
- package/dist/routes/shared.d.ts +15 -15
- package/dist/routes/shared.js +1 -3
- package/dist/skills.js +3 -3
- package/dist/timeout.d.ts +8 -7
- package/dist/timeout.js +47 -38
- package/dist/types.d.ts +3 -3
- package/dist/ui.d.ts +1 -25
- package/dist/ui.js +18 -45
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/architecture.md +5 -2
- package/documentation/call-admission.md +1 -1
- package/documentation/cloudflare.md +1 -1
- package/documentation/code-mode.md +13 -13
- package/documentation/connectors.md +34 -1
- package/documentation/linear.md +1 -1
- package/documentation/meta-tools.md +17 -3
- package/documentation/mixpanel.md +1 -1
- package/documentation/notion.md +1 -1
- package/documentation/operations.md +20 -15
- package/documentation/provider-conventions.md +1 -1
- package/documentation/revenuecat.md +1 -1
- package/documentation/stripe.md +1 -1
- package/documentation/upgrading.md +24 -4
- package/ethos.md +74 -120
- package/package.json +3 -4
- package/templates/node/package.json +1 -1
- package/documentation/code-first-exploration.md +0 -292
- package/documentation/mcp-2026-07-28.md +0 -46
- package/documentation/mcp-ui-design.md +0 -382
- package/documentation/program-ui-read-calls.md +0 -213
- package/documentation/provider-audit.md +0 -198
- package/documentation/rich-output-design.md +0 -211
|
@@ -3,15 +3,7 @@ import type { Connector, ConnectorCallAdmissionPolicy } from "../types.js";
|
|
|
3
3
|
/** RevenueCat publishes one hosted MCP endpoint, streamable HTTP. */
|
|
4
4
|
export declare const REVENUECAT_MCP_ENDPOINT = "https://mcp.revenuecat.ai/mcp";
|
|
5
5
|
export interface RevenueCatOptions {
|
|
6
|
-
/**
|
|
7
|
-
* Human-readable display name; defaults to "RevenueCat" for OAuth and
|
|
8
|
-
* "RevenueCat (single project)" for a static API v2 secret key. The scope
|
|
9
|
-
* shape rides the title because it is the one routing fact connecta can
|
|
10
|
-
* know at construction: an `sk_` key reaches exactly one project, an OAuth
|
|
11
|
-
* session reaches every project the account can. *Which* project a key
|
|
12
|
-
* reaches is not knowable here (P10 — no credential test), so the guide's
|
|
13
|
-
* first line carries the operator's stated purpose instead.
|
|
14
|
-
*/
|
|
6
|
+
/** Display name; scope defaults are in `documentation/revenuecat.md`. */
|
|
15
7
|
title?: string;
|
|
16
8
|
/**
|
|
17
9
|
* Which project this connector is for and what decisions it answers. With
|
|
@@ -19,61 +11,16 @@ export interface RevenueCatOptions {
|
|
|
19
11
|
* so it goes in the guide's first line and its summary.
|
|
20
12
|
*/
|
|
21
13
|
purpose: string;
|
|
22
|
-
/**
|
|
23
|
-
* OAuth by default; static headers support a RevenueCat API v2 secret key
|
|
24
|
-
* as `Authorization: Bearer sk_…`. `{ type: "credential" }` is the same
|
|
25
|
-
* single-project scope with the key pasted at `/credentials` instead — which
|
|
26
|
-
* is what two projects on two keys wants, since each is its own connector.
|
|
27
|
-
*/
|
|
14
|
+
/** OAuth or a single-project API v2 key; see `documentation/revenuecat.md`. */
|
|
28
15
|
auth?: RemoteMcpAuth;
|
|
29
16
|
/** Project-specific conventions appended to the maintained provider guide. */
|
|
30
17
|
instructions?: string;
|
|
31
18
|
/** Connector-specific inline result limit; omit to inherit the deployment. */
|
|
32
19
|
maxResultBytes?: number;
|
|
33
|
-
/**
|
|
34
|
-
* Optional per-runtime call-admission policy. Deliberately not defaulted,
|
|
35
|
-
* even though RevenueCat does publish numbers.
|
|
36
|
-
*
|
|
37
|
-
* API v2 meters per *domain*, and the domains disagree by a factor of
|
|
38
|
-
* nineteen: Customer Information 480/min, Virtual Currencies 480/min,
|
|
39
|
-
* Subscription Transactions Refunds 480/min, Audiences 60/min, Project
|
|
40
|
-
* Configuration 60/min, Charts & Metrics 25/min
|
|
41
|
-
* (https://www.revenuecat.com/docs/api-v2#tag/Rate-Limit, read 2026-08-18).
|
|
42
|
-
* A `ConnectorCallAdmissionPolicy` carries exactly one rule, so a
|
|
43
|
-
* connector-wide budget has to pick one of those six numbers for all ninety-
|
|
44
|
-
* five tools. Transcribing 25 would throttle a customer read loop to a
|
|
45
|
-
* nineteenth of its documented allowance; transcribing 480 would leave a
|
|
46
|
-
* chart sweep unprotected. Neither is the provider's limit, and both would
|
|
47
|
-
* look like RevenueCat being flaky.
|
|
48
|
-
*
|
|
49
|
-
* The metering scope says the same thing again: the limit applies per API
|
|
50
|
-
* key for app-level keys and per *developer* for developer-level keys, so
|
|
51
|
-
* an OAuth session shares one budget with everything else that developer
|
|
52
|
-
* does — which a per-runtime counter cannot approximate in either
|
|
53
|
-
* direction. So the number stays with the operator who knows the account,
|
|
54
|
-
* exactly as P12 prescribes; `documentation/revenuecat.md` shows how to
|
|
55
|
-
* supply one.
|
|
56
|
-
*/
|
|
20
|
+
/** Optional per-runtime policy; see `documentation/revenuecat.md#rate-limits`. */
|
|
57
21
|
callAdmission?: ConnectorCallAdmissionPolicy;
|
|
58
22
|
}
|
|
59
|
-
/**
|
|
60
|
-
* The manifest this release reviewed: both lists in one place, which is what
|
|
61
|
-
* makes the classification the connector applies and the drift check that runs
|
|
62
|
-
* beside it the same fact (P13). Ninety-four of the ninety-five tools
|
|
63
|
-
* RevenueCat's reference lists on 2026-08-18 are classified; the ninety-fifth,
|
|
64
|
-
* `render-paywall-screenshot`, has no access column to classify from and fails
|
|
65
|
-
* closed.
|
|
66
|
-
*
|
|
67
|
-
* No schema digests. No release has read RevenueCat's live schemas and written
|
|
68
|
-
* them down — that needs a live project and a maintainer's own `sk_` key — and
|
|
69
|
-
* an invented digest would report a change that never happened.
|
|
70
|
-
* `npm run drift:check -- --record` reads them from a live catalog and prints
|
|
71
|
-
* the block to paste in
|
|
72
|
-
* ([#351](https://github.com/zackbart/connecta/issues/351)).
|
|
73
|
-
*
|
|
74
|
-
* Exported because the maintainer-run check compares against this manifest and
|
|
75
|
-
* *names* what moved, which the runtime check deliberately cannot.
|
|
76
|
-
*/
|
|
23
|
+
/** Release-reviewed manifest; see provider conventions P5 and P13. */
|
|
77
24
|
export declare const REVENUECAT_VETTED_CATALOG: import("../catalog-drift.js").VettedCatalog;
|
|
78
25
|
/** A maintained RevenueCat hosted-MCP connection. */
|
|
79
26
|
export declare function revenuecat(id: string, options: RevenueCatOptions): Connector;
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import { remoteMcp, withCredentialDefaults, } from "../connectors/remote-mcp.js";
|
|
2
2
|
import { vettedCatalog, withVettedCatalog } from "../catalog-drift.js";
|
|
3
|
+
import { defined } from "../connectors/api.js";
|
|
3
4
|
/** RevenueCat publishes one hosted MCP endpoint, streamable HTTP. */
|
|
4
5
|
export const REVENUECAT_MCP_ENDPOINT = "https://mcp.revenuecat.ai/mcp";
|
|
5
|
-
/**
|
|
6
|
-
* Tools whose official contract is observational rather than mutating.
|
|
7
|
-
*
|
|
8
|
-
* Every name here carries `Read` in RevenueCat's own tool reference
|
|
9
|
-
* (https://www.revenuecat.com/docs/tools/mcp/tools-reference, read
|
|
10
|
-
* 2026-08-18). The list is a superset by design (P5): a name a project never
|
|
11
|
-
* serves costs nothing, while an unclassified new one fails closed onto
|
|
12
|
-
* `call_destructive_tool`.
|
|
13
|
-
*/
|
|
6
|
+
/** Reviewed reads; see `documentation/revenuecat.md` and convention P5. */
|
|
14
7
|
const READ_ONLY_TOOLS = new Set([
|
|
15
8
|
// Projects and apps
|
|
16
9
|
"get-account-billing",
|
|
@@ -76,65 +69,26 @@ const READ_ONLY_TOOLS = new Set([
|
|
|
76
69
|
// *start* one are writes and sit below.
|
|
77
70
|
"get-paywall-ai-task",
|
|
78
71
|
]);
|
|
79
|
-
/**
|
|
80
|
-
* The maintained write catalog. `"destructive"` tools modify or remove state
|
|
81
|
-
* that already exists; `"additive"` ones only bring something new into being.
|
|
82
|
-
* Both leave the read-only path — the distinction only decides whether the
|
|
83
|
-
* connection asserts `destructiveHint`, which shapes the host's approval copy.
|
|
84
|
-
*
|
|
85
|
-
* Every name here carries `Write` in RevenueCat's tool reference. The mass
|
|
86
|
-
* verdicts follow the verb: `archive-*` and `unarchive-*` flip an existing
|
|
87
|
-
* object's active state, `update-*` and `delete-*` and `publish-*` and
|
|
88
|
-
* `unpublish-*` and `detach-*` change or remove something that already exists,
|
|
89
|
-
* and a plain `create-*` brings a new object into being beside the old ones.
|
|
90
|
-
*
|
|
91
|
-
* Nine verdicts are not decided by the verb, and each is argued where it sits:
|
|
92
|
-
* `create-product-prices`, `equalize-subscription-prices`,
|
|
93
|
-
* `validate-app-credentials`, `upload-product-store-state-screenshot`,
|
|
94
|
-
* `attach-products-to-entitlement`, `attach-products-to-package`,
|
|
95
|
-
* `duplicate-paywall`, `create-paywall-ai`, and `edit-paywall-ai`.
|
|
96
|
-
*
|
|
97
|
-
* `render-paywall-screenshot` is deliberately on neither list. RevenueCat's
|
|
98
|
-
* reference gives it no access column at all, and a tool nobody has classified
|
|
99
|
-
* fails closed (P5) rather than being guessed into the read path because its
|
|
100
|
-
* name sounds harmless.
|
|
101
|
-
*/
|
|
72
|
+
/** Reviewed writes and verb exceptions: `documentation/revenuecat.md`. */
|
|
102
73
|
const WRITE_TOOLS = new Map([
|
|
103
74
|
// Projects and apps
|
|
104
75
|
["create-app", "additive"],
|
|
105
76
|
["create-project", "additive"],
|
|
106
77
|
["update-app", "destructive"],
|
|
107
78
|
["update-project-ui-config", "destructive"],
|
|
108
|
-
// "Checks one saved App Store or Google Play credential set." RevenueCat
|
|
109
|
-
// files it Write, so it does not reach the read path — but it leaves the
|
|
110
|
-
// credentials themselves alone and only records the outcome of a check.
|
|
111
|
-
// Additive: a verdict comes into being, nothing existing is overwritten.
|
|
112
79
|
["validate-app-credentials", "additive"],
|
|
113
80
|
// Products and prices
|
|
114
81
|
["archive-product", "destructive"],
|
|
115
82
|
["create-product", "additive"],
|
|
116
|
-
// Named `create-`, described "Configure prices for a product". A product's
|
|
117
|
-
// price set already exists, and configuring it replaces what is there
|
|
118
|
-
// rather than adding a second price beside the first. Money-facing and
|
|
119
|
-
// overwriting, so: destructive, whatever the verb says.
|
|
120
83
|
["create-product-prices", "destructive"],
|
|
121
|
-
// "Fills missing App Store subscription territory prices." By RevenueCat's
|
|
122
|
-
// own word it only writes where a price is absent, so nothing already set
|
|
123
|
-
// is changed. Additive.
|
|
124
84
|
["equalize-subscription-prices", "additive"],
|
|
125
85
|
["set-product-store-state", "destructive"],
|
|
126
86
|
["submit-products-to-store", "destructive"],
|
|
127
87
|
["unarchive-product", "destructive"],
|
|
128
88
|
["update-product", "destructive"],
|
|
129
|
-
// "Reserves an App Store Connect review screenshot slot." A new slot comes
|
|
130
|
-
// into being; no existing screenshot is replaced by the reservation.
|
|
131
89
|
["upload-product-store-state-screenshot", "additive"],
|
|
132
90
|
// Entitlements
|
|
133
91
|
["archive-entitlement", "destructive"],
|
|
134
|
-
// Attach adds a product to a membership set and removes nothing;
|
|
135
|
-
// `detach-products-from-entitlement` is its destructive counterpart. Filing
|
|
136
|
-
// both destructive would make the pair read identically in the approval copy
|
|
137
|
-
// a human is shown, which is exactly the inflation P5 warns about.
|
|
138
92
|
["attach-products-to-entitlement", "additive"],
|
|
139
93
|
["create-entitlement", "additive"],
|
|
140
94
|
["detach-products-from-entitlement", "destructive"],
|
|
@@ -142,7 +96,6 @@ const WRITE_TOOLS = new Map([
|
|
|
142
96
|
["update-entitlement", "destructive"],
|
|
143
97
|
// Offerings and packages
|
|
144
98
|
["archive-offering", "destructive"],
|
|
145
|
-
// The same attach/detach argument one level down.
|
|
146
99
|
["attach-products-to-package", "additive"],
|
|
147
100
|
["create-offering", "additive"],
|
|
148
101
|
["create-packages", "additive"],
|
|
@@ -154,19 +107,10 @@ const WRITE_TOOLS = new Map([
|
|
|
154
107
|
["create-audience", "additive"],
|
|
155
108
|
["update-audience", "destructive"],
|
|
156
109
|
// Paywalls
|
|
157
|
-
// "Duplicates an existing paywall's current draft." The original is
|
|
158
|
-
// untouched and a new paywall appears beside it. Additive.
|
|
159
110
|
["duplicate-paywall", "additive"],
|
|
160
111
|
["publish-paywall", "destructive"],
|
|
161
112
|
["unpublish-paywall", "destructive"],
|
|
162
|
-
// Customers and subscriptions
|
|
163
|
-
// removes anything, so the file's own criterion would read them additive.
|
|
164
|
-
// They are destructive on consequence, the way `create_refund` is in
|
|
165
|
-
// `stripe.ts`: `assign-customer-offering` overrides which offering a live
|
|
166
|
-
// customer's app serves, and `grant-customer-entitlement` opens paid access
|
|
167
|
-
// to a real person without a store purchase (the promotional subscription it
|
|
168
|
-
// creates is the mechanism, not the point). Both change what a customer
|
|
169
|
-
// gets today, and both deserve the destructive approval copy.
|
|
113
|
+
// Customers and subscriptions
|
|
170
114
|
["assign-customer-offering", "destructive"],
|
|
171
115
|
["grant-customer-entitlement", "destructive"],
|
|
172
116
|
// Virtual currencies
|
|
@@ -175,39 +119,14 @@ const WRITE_TOOLS = new Map([
|
|
|
175
119
|
["unarchive-virtual-currency", "destructive"],
|
|
176
120
|
["update-virtual-currency", "destructive"],
|
|
177
121
|
// Integrations and webhooks
|
|
178
|
-
// A new integration is a new object, but one that "starts delivering
|
|
179
|
-
// RevenueCat events to the given url" — with filters omitted, every customer
|
|
180
|
-
// event in the project, to a URL the caller typed. That is customer data
|
|
181
|
-
// leaving the account on consequence, which is the `create_refund` argument
|
|
182
|
-
// again: the verb says additive, the effect says destructive, and the
|
|
183
|
-
// approval copy should say the latter.
|
|
184
122
|
["create-webhook-integration", "destructive"],
|
|
185
123
|
["delete-webhook-integration", "destructive"],
|
|
186
124
|
["update-webhook-integration", "destructive"],
|
|
187
|
-
// Paywall editing
|
|
188
|
-
// verdict. Creating a paywall leaves every existing one alone (additive);
|
|
189
|
-
// editing one rewrites a draft that already exists (destructive).
|
|
125
|
+
// Paywall editing
|
|
190
126
|
["create-paywall-ai", "additive"],
|
|
191
127
|
["edit-paywall-ai", "destructive"],
|
|
192
128
|
]);
|
|
193
|
-
/**
|
|
194
|
-
* The manifest this release reviewed: both lists in one place, which is what
|
|
195
|
-
* makes the classification the connector applies and the drift check that runs
|
|
196
|
-
* beside it the same fact (P13). Ninety-four of the ninety-five tools
|
|
197
|
-
* RevenueCat's reference lists on 2026-08-18 are classified; the ninety-fifth,
|
|
198
|
-
* `render-paywall-screenshot`, has no access column to classify from and fails
|
|
199
|
-
* closed.
|
|
200
|
-
*
|
|
201
|
-
* No schema digests. No release has read RevenueCat's live schemas and written
|
|
202
|
-
* them down — that needs a live project and a maintainer's own `sk_` key — and
|
|
203
|
-
* an invented digest would report a change that never happened.
|
|
204
|
-
* `npm run drift:check -- --record` reads them from a live catalog and prints
|
|
205
|
-
* the block to paste in
|
|
206
|
-
* ([#351](https://github.com/zackbart/connecta/issues/351)).
|
|
207
|
-
*
|
|
208
|
-
* Exported because the maintainer-run check compares against this manifest and
|
|
209
|
-
* *names* what moved, which the runtime check deliberately cannot.
|
|
210
|
-
*/
|
|
129
|
+
/** Release-reviewed manifest; see provider conventions P5 and P13. */
|
|
211
130
|
export const REVENUECAT_VETTED_CATALOG = vettedCatalog({
|
|
212
131
|
reads: READ_ONLY_TOOLS,
|
|
213
132
|
writes: WRITE_TOOLS,
|
|
@@ -312,12 +231,10 @@ export function revenuecat(id, options) {
|
|
|
312
231
|
// carries the project-resolution sequence, which is worth reading before
|
|
313
232
|
// a run rather than before every call.
|
|
314
233
|
},
|
|
315
|
-
...(
|
|
316
|
-
|
|
317
|
-
:
|
|
318
|
-
|
|
319
|
-
? { maxResultBytes: options.maxResultBytes }
|
|
320
|
-
: {}),
|
|
234
|
+
...defined({
|
|
235
|
+
callAdmission: options.callAdmission,
|
|
236
|
+
maxResultBytes: options.maxResultBytes,
|
|
237
|
+
}),
|
|
321
238
|
});
|
|
322
239
|
return withVettedCatalog(connector, REVENUECAT_VETTED_CATALOG);
|
|
323
240
|
}
|
|
@@ -38,18 +38,7 @@ export interface StripeHeaderOptions extends StripeCommonOptions {
|
|
|
38
38
|
connectedAccount?: string;
|
|
39
39
|
}
|
|
40
40
|
export type StripeOptions = StripeOAuthOptions | StripeHeaderOptions;
|
|
41
|
-
/**
|
|
42
|
-
* The manifest this release reviewed: both lists in one place, which is what
|
|
43
|
-
* makes the classification the connector applies and the drift check that runs
|
|
44
|
-
* beside it the same fact (P13). No schema digests yet — no release has read
|
|
45
|
-
* Stripe's live schemas and written them down, and an invented digest would
|
|
46
|
-
* report a change that never happened. `npm run drift:check -- --record` reads
|
|
47
|
-
* them from a live account and prints the block to paste in
|
|
48
|
-
* ([#351](https://github.com/zackbart/connecta/issues/351)).
|
|
49
|
-
*
|
|
50
|
-
* Exported because the maintainer-run check compares against this manifest and
|
|
51
|
-
* *names* what moved, which the runtime check deliberately cannot.
|
|
52
|
-
*/
|
|
41
|
+
/** Release-reviewed manifest; see provider conventions P5 and P13. */
|
|
53
42
|
export declare const STRIPE_VETTED_CATALOG: import("../catalog-drift.js").VettedCatalog;
|
|
54
43
|
/** A maintained Stripe hosted-MCP connection. */
|
|
55
44
|
export declare function stripe(id: string, options: StripeOptions): Connector;
|
package/dist/providers/stripe.js
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
import { remoteMcp, withCredentialDefaults, } from "../connectors/remote-mcp.js";
|
|
2
2
|
import { vettedCatalog, withVettedCatalog } from "../catalog-drift.js";
|
|
3
|
+
import { defined } from "../connectors/api.js";
|
|
3
4
|
/** Stripe publishes one hosted MCP endpoint for every account and mode. */
|
|
4
5
|
export const STRIPE_MCP_ENDPOINT = "https://mcp.stripe.com/";
|
|
5
|
-
/**
|
|
6
|
-
* Stripe documents no MCP-specific rate limit, so this transcribes the account
|
|
7
|
-
* limit the MCP server spends: 100 requests per second in live mode, 25 in a
|
|
8
|
-
* sandbox (https://docs.stripe.com/rate-limits). The concurrency bound is
|
|
9
|
-
* connecta's own conservative choice — Stripe documents that per-account and
|
|
10
|
-
* per-endpoint concurrency limits exist and surface as `429` with a
|
|
11
|
-
* `Stripe-Rate-Limited-Reason` of `global-concurrency` or
|
|
12
|
-
* `endpoint-concurrency`, but publishes no number. Declaring `maxConcurrency`
|
|
13
|
-
* is also what earns the right to the queue settings beside it.
|
|
14
|
-
*/
|
|
6
|
+
/** Account limits and local concurrency rationale: `documentation/stripe.md`. */
|
|
15
7
|
const STRIPE_ADMISSION = {
|
|
16
8
|
production: {
|
|
17
9
|
rules: [
|
|
@@ -50,34 +42,14 @@ const READ_ONLY_TOOLS = new Set([
|
|
|
50
42
|
"search_stripe_documentation",
|
|
51
43
|
"stripe_implementation_planner",
|
|
52
44
|
]);
|
|
53
|
-
/**
|
|
54
|
-
* The maintained write catalog. `"destructive"` tools modify or remove state
|
|
55
|
-
* that already exists; `"additive"` ones only bring something new into being.
|
|
56
|
-
* Both leave the read-only path — the distinction only decides whether the
|
|
57
|
-
* connection asserts `destructiveHint`, which shapes the host's approval copy.
|
|
58
|
-
*
|
|
59
|
-
* `create_refund` is filed destructive despite its name: it reverses a
|
|
60
|
-
* settled charge and moves money back out, which is a mutation of something
|
|
61
|
-
* that already exists, not a fresh object appearing beside it.
|
|
62
|
-
*/
|
|
45
|
+
/** Reviewed writes, including refund rationale: `documentation/stripe.md`. */
|
|
63
46
|
const WRITE_TOOLS = new Map([
|
|
64
47
|
["stripe_api_write", "destructive"],
|
|
65
48
|
["create_refund", "destructive"],
|
|
66
49
|
["stripe_report", "additive"],
|
|
67
50
|
["send_stripe_mcp_feedback", "additive"],
|
|
68
51
|
]);
|
|
69
|
-
/**
|
|
70
|
-
* The manifest this release reviewed: both lists in one place, which is what
|
|
71
|
-
* makes the classification the connector applies and the drift check that runs
|
|
72
|
-
* beside it the same fact (P13). No schema digests yet — no release has read
|
|
73
|
-
* Stripe's live schemas and written them down, and an invented digest would
|
|
74
|
-
* report a change that never happened. `npm run drift:check -- --record` reads
|
|
75
|
-
* them from a live account and prints the block to paste in
|
|
76
|
-
* ([#351](https://github.com/zackbart/connecta/issues/351)).
|
|
77
|
-
*
|
|
78
|
-
* Exported because the maintainer-run check compares against this manifest and
|
|
79
|
-
* *names* what moved, which the runtime check deliberately cannot.
|
|
80
|
-
*/
|
|
52
|
+
/** Release-reviewed manifest; see provider conventions P5 and P13. */
|
|
81
53
|
export const STRIPE_VETTED_CATALOG = vettedCatalog({
|
|
82
54
|
reads: READ_ONLY_TOOLS,
|
|
83
55
|
writes: WRITE_TOOLS,
|
|
@@ -85,14 +57,7 @@ export const STRIPE_VETTED_CATALOG = vettedCatalog({
|
|
|
85
57
|
/** Stripe key prefixes carry their own mode; only a clear reading counts. */
|
|
86
58
|
const LIVE_KEY = /\b(?:sk|rk|pk)_live_/;
|
|
87
59
|
const TEST_KEY = /\b(?:sk|rk|pk)_test_/;
|
|
88
|
-
/**
|
|
89
|
-
* Refuse a deployment whose declared mode and supplied key disagree.
|
|
90
|
-
*
|
|
91
|
-
* This is the one half of production/sandbox routing connecta can actually
|
|
92
|
-
* enforce. Nothing here reads or reports key material: an unrecognizable key
|
|
93
|
-
* shape is left alone rather than guessed at, and a mismatch names only the
|
|
94
|
-
* two modes.
|
|
95
|
-
*/
|
|
60
|
+
/** Refuse a recognizable key/mode mismatch; see `documentation/stripe.md`. */
|
|
96
61
|
function assertModeMatchesKey(id, mode, auth) {
|
|
97
62
|
if (auth.type !== "headers")
|
|
98
63
|
return;
|
|
@@ -139,7 +104,6 @@ function resolveAuth(id, options) {
|
|
|
139
104
|
headers: { ...auth.headers, "Stripe-Account": connectedAccount },
|
|
140
105
|
};
|
|
141
106
|
}
|
|
142
|
-
const OAUTH_ADMISSION = STRIPE_ADMISSION.sandbox;
|
|
143
107
|
function oauthUsageGuide(purpose, instructions) {
|
|
144
108
|
const accountInstructions = instructions?.trim();
|
|
145
109
|
return `# Stripe usage
|
|
@@ -233,7 +197,7 @@ export function stripe(id, options) {
|
|
|
233
197
|
: `Stripe payments (${copy?.blurb}) — ${purpose}`,
|
|
234
198
|
auth,
|
|
235
199
|
requireHttps: true,
|
|
236
|
-
callAdmission: mode
|
|
200
|
+
callAdmission: STRIPE_ADMISSION[mode ?? "sandbox"],
|
|
237
201
|
usageGuide: {
|
|
238
202
|
content: mode === undefined
|
|
239
203
|
? oauthUsageGuide(purpose, options.instructions)
|
|
@@ -248,9 +212,7 @@ export function stripe(id, options) {
|
|
|
248
212
|
// Not `required`. The four generic tools are the routing decision; a
|
|
249
213
|
// guide forced into every call would pay for the same prose repeatedly.
|
|
250
214
|
},
|
|
251
|
-
...(options.maxResultBytes
|
|
252
|
-
? { maxResultBytes: options.maxResultBytes }
|
|
253
|
-
: {}),
|
|
215
|
+
...defined({ maxResultBytes: options.maxResultBytes }),
|
|
254
216
|
});
|
|
255
217
|
return withVettedCatalog(connector, STRIPE_VETTED_CATALOG);
|
|
256
218
|
}
|
package/dist/registry.d.ts
CHANGED
|
@@ -43,32 +43,25 @@ export declare function isValidMaxResultBytes(value: number): boolean;
|
|
|
43
43
|
* a broken cap.
|
|
44
44
|
*/
|
|
45
45
|
export declare function resolveMaxResultBytes(value: number | undefined, inherited: number): number;
|
|
46
|
-
export interface HealthObservation {
|
|
47
|
-
lastSuccessAt?: string;
|
|
48
|
-
lastFailureAt?: string;
|
|
49
|
-
lastLatencyMs?: number;
|
|
50
|
-
consecutiveFailures: number;
|
|
51
|
-
lastError?: string;
|
|
52
|
-
}
|
|
53
46
|
export interface RegistryOptions {
|
|
54
47
|
storage: KVStorage;
|
|
55
48
|
logger: Logger;
|
|
56
|
-
credentialVault?: CredentialVault;
|
|
57
|
-
toolCacheTtlSeconds?: number;
|
|
58
|
-
persistToolCatalog?: boolean;
|
|
59
|
-
toolCatalogStaleSeconds?: number;
|
|
49
|
+
credentialVault?: CredentialVault | undefined;
|
|
50
|
+
toolCacheTtlSeconds?: number | undefined;
|
|
51
|
+
persistToolCatalog?: boolean | undefined;
|
|
52
|
+
toolCatalogStaleSeconds?: number | undefined;
|
|
60
53
|
/**
|
|
61
54
|
* Cap on inline result size before truncation + get_result paging. Must be a
|
|
62
55
|
* whole number of bytes >= 1; anything else warns at startup and falls back
|
|
63
56
|
* to the default 50_000.
|
|
64
57
|
*/
|
|
65
|
-
maxResultBytes?: number;
|
|
58
|
+
maxResultBytes?: number | undefined;
|
|
66
59
|
/**
|
|
67
60
|
* Where payload-free catalog-drift observations go. Present only when the
|
|
68
61
|
* deployment configured an activity store; drift is reported through
|
|
69
62
|
* connector status either way.
|
|
70
63
|
*/
|
|
71
|
-
catalogDriftActivity?: Omit<CatalogDriftActivityContext, "logger"
|
|
64
|
+
catalogDriftActivity?: Omit<CatalogDriftActivityContext, "logger"> | undefined;
|
|
72
65
|
}
|
|
73
66
|
export type ConnectorOperationOptions = Pick<ConnectorContext, "signal" | "timeoutMs">;
|
|
74
67
|
/** Agent-only catalog behavior. This never enters a ConnectorContext. */
|
|
@@ -96,8 +89,6 @@ export interface RegistryView {
|
|
|
96
89
|
toolName: string;
|
|
97
90
|
} | null;
|
|
98
91
|
getTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, readOptions?: CatalogReadOptions): Promise<ToolDef[]>;
|
|
99
|
-
refreshTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): Promise<ToolDef[]>;
|
|
100
|
-
peekTools(id: string): ToolDef[] | undefined;
|
|
101
92
|
contextFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): ConnectorContext;
|
|
102
93
|
/** Acquire the connector's shared downstream-call permit. */
|
|
103
94
|
admitCall(id: string, input: {
|
|
@@ -106,13 +97,12 @@ export interface RegistryView {
|
|
|
106
97
|
signal?: AbortSignal;
|
|
107
98
|
}): Promise<CallAdmissionPermit>;
|
|
108
99
|
resultsStorage(): KVStorage;
|
|
109
|
-
recordSuccess(id: string, latencyMs: number): void;
|
|
110
|
-
recordFailure(id: string, latencyMs: number, error: unknown): void;
|
|
111
|
-
healthFor(id: string): HealthObservation | undefined;
|
|
112
|
-
hasObservedSuccess(id: string): boolean;
|
|
113
|
-
observedSuccessAt(id: string): string | undefined;
|
|
114
100
|
/** Local declared-vs-stored credential mismatch, with no downstream I/O. */
|
|
115
101
|
credentialDriftFor(id: string): Promise<string | undefined>;
|
|
102
|
+
/** Value-free shape learned from successful calls, never a provider declaration. */
|
|
103
|
+
observedOutputSchema(connectorId: string, definition: ToolDef): ToolDef["outputSchema"] | undefined;
|
|
104
|
+
/** Passively learn one successful unwrapped result; failures stay isolated. */
|
|
105
|
+
observeOutputShape(connectorId: string, definition: ToolDef, value: unknown): void;
|
|
116
106
|
statusFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): Promise<ConnectorStatus>;
|
|
117
107
|
invalidateStored(id: string): Promise<void>;
|
|
118
108
|
}
|
|
@@ -131,16 +121,16 @@ export declare class Registry implements RegistryView {
|
|
|
131
121
|
private readonly catalogGenerations;
|
|
132
122
|
/** Serialize persisted catalog set/delete operations within this isolate. */
|
|
133
123
|
private readonly catalogMutations;
|
|
134
|
-
/** Same-request cold loads share one promise without retaining the request.
|
|
124
|
+
/** Same-request cold loads share one promise without retaining the request.
|
|
125
|
+
* See documentation/architecture.md#the-two-lifetimes. */
|
|
135
126
|
private readonly requestCatalogLoads;
|
|
136
127
|
/** One live refresh per connector across agent and operator requests. */
|
|
137
128
|
private readonly catalogRefreshes;
|
|
138
129
|
/** Last payload-free agent catalog access in this runtime. */
|
|
139
130
|
private readonly catalogAccess;
|
|
140
|
-
/** Deployment-wide observations — every call, whatever view made it. */
|
|
141
|
-
private readonly health;
|
|
142
131
|
/** Last drift counts reported to activity, per connector, in this runtime. */
|
|
143
132
|
private readonly reportedDrift;
|
|
133
|
+
private readonly observedOutputSchemas;
|
|
144
134
|
private readonly ttlMs;
|
|
145
135
|
private readonly staleMs;
|
|
146
136
|
private readonly persistToolCatalog;
|
|
@@ -203,6 +193,8 @@ export declare class Registry implements RegistryView {
|
|
|
203
193
|
* separate from any connector's `conn:<id>:` namespace. Backs get_result.
|
|
204
194
|
*/
|
|
205
195
|
resultsStorage(): KVStorage;
|
|
196
|
+
observedOutputSchema(connectorId: string, definition: ToolDef): ToolDef["outputSchema"] | undefined;
|
|
197
|
+
observeOutputShape(connectorId: string, definition: ToolDef, value: unknown): void;
|
|
206
198
|
/** Resolve "<connectorId>.<toolName>" → connector + tool name. */
|
|
207
199
|
resolveAddress(address: string): {
|
|
208
200
|
connector: Connector;
|
|
@@ -210,7 +202,6 @@ export declare class Registry implements RegistryView {
|
|
|
210
202
|
} | null;
|
|
211
203
|
private catalogKey;
|
|
212
204
|
private catalogChunkKey;
|
|
213
|
-
private validLegacyCatalog;
|
|
214
205
|
private validCatalogTools;
|
|
215
206
|
private validCatalogManifest;
|
|
216
207
|
private parseCatalogManifest;
|
|
@@ -234,7 +225,7 @@ export declare class Registry implements RegistryView {
|
|
|
234
225
|
*/
|
|
235
226
|
private startCatalogRefresh;
|
|
236
227
|
/** Force a live listTools refresh and replace both catalog cache layers. */
|
|
237
|
-
refreshTools
|
|
228
|
+
private refreshTools;
|
|
238
229
|
private observeCatalogAccess;
|
|
239
230
|
/**
|
|
240
231
|
* Start or join one shared refresh. A newly deferred task owns its scope,
|
|
@@ -253,15 +244,6 @@ export declare class Registry implements RegistryView {
|
|
|
253
244
|
* later callers join only its result, never its request scope.
|
|
254
245
|
*/
|
|
255
246
|
getTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, readOptions?: CatalogReadOptions): Promise<ToolDef[]>;
|
|
256
|
-
/** Return a cached catalog without performing storage or network I/O. */
|
|
257
|
-
peekTools(id: string): ToolDef[] | undefined;
|
|
258
|
-
recordSuccess(id: string, latencyMs: number): void;
|
|
259
|
-
recordFailure(id: string, latencyMs: number, error: unknown): void;
|
|
260
|
-
healthFor(id: string): HealthObservation | undefined;
|
|
261
|
-
/** Whether this deployment has seen a successful call to `id`. */
|
|
262
|
-
hasObservedSuccess(id: string): boolean;
|
|
263
|
-
/** The timestamp behind `hasObservedSuccess`. */
|
|
264
|
-
observedSuccessAt(id: string): string | undefined;
|
|
265
247
|
credentialDriftFor(id: string): Promise<string | undefined>;
|
|
266
248
|
/** Best-effort connector status for the operator UI. */
|
|
267
249
|
statusFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): Promise<ConnectorStatus>;
|