@absolutejs/mcp 0.12.0 → 0.13.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 +13 -0
- package/README.md +48 -0
- package/changelog.json +22 -0
- package/dist/commerce.js +173 -0
- package/dist/index.js +230 -24
- package/dist/manifest.js +126 -126
- package/dist/src/commerce.d.ts +50 -0
- package/dist/src/creditStatus.d.ts +13 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/types.d.ts +9 -0
- package/docs/commerce-host-rules.md +266 -0
- package/package.json +17 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@absolutejs/mcp`.
|
|
4
|
+
|
|
5
|
+
This file is generated by `absolute-changelog` from the entries in
|
|
6
|
+
`changelog/`. Edit an entry, not this file — and add new ones under
|
|
7
|
+
`changelog/unreleased/`.
|
|
8
|
+
|
|
9
|
+
## 0.13.0 — 2026-09-11
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Add reviewed host commerce eligibility, execution guards, and reusable credit status tools** (`McpServerConfig`, `McpTool`, `evaluateCommerce`, `createCreditBalanceTool`)
|
package/README.md
CHANGED
|
@@ -13,6 +13,54 @@ authorization server. The default negotiated revision is the current finalized
|
|
|
13
13
|
`2025-11-25` specification; older finalized revisions remain available when
|
|
14
14
|
explicitly requested.
|
|
15
15
|
|
|
16
|
+
## Commerce across AI hosts
|
|
17
|
+
|
|
18
|
+
See [Commerce host rules and shared package design](docs/commerce-host-rules.md)
|
|
19
|
+
for the dated host-policy survey, checkout restrictions, secure handoffs, and
|
|
20
|
+
reusable AbsoluteJS package boundaries. Host eligibility is implemented;
|
|
21
|
+
checkout sessions, payment adapters and commerce UI remain planned.
|
|
22
|
+
|
|
23
|
+
### Enforce host commerce eligibility
|
|
24
|
+
|
|
25
|
+
`@absolutejs/mcp/commerce` exports `evaluateCommerce`, typed requirements and
|
|
26
|
+
review evidence. Tag every commerce tool with `commerce`; the server hides
|
|
27
|
+
ineligible tools and checks again before execution (including delayed tasks).
|
|
28
|
+
Tools without a commerce tag keep their existing behavior.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
mcpServer<Caller>({
|
|
32
|
+
// Existing authorize, issuer, path, serverInfo and agency configuration…
|
|
33
|
+
commerce: ({ caller }) => resolveReviewedDeployment(caller),
|
|
34
|
+
tools: () => ({
|
|
35
|
+
open_checkout: {
|
|
36
|
+
commerce: { action: "external_checkout", categories: ["usage_credits"] },
|
|
37
|
+
description: "Open a secure checkout for service credits",
|
|
38
|
+
inputSchema: { type: "object", properties: {} },
|
|
39
|
+
handler: () => createSecureCheckoutHandoff(),
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`resolveReviewedDeployment` and `createSecureCheckoutHandoff` above are consumer
|
|
46
|
+
integration callbacks, not package exports. Return a `CommerceContext` based on
|
|
47
|
+
trusted server configuration, never the tool arguments or a claimed client name.
|
|
48
|
+
Unknown channels and missing/expired reviews fail closed. A deployment review
|
|
49
|
+
cannot override the bundled ChatGPT digital-sales, Claude interactive-purchase,
|
|
50
|
+
or Cursor marketplace paid-access restrictions. Ambiguous profiles intersect.
|
|
51
|
+
|
|
52
|
+
Reviews must bind the profile, actions, product categories, source URLs and
|
|
53
|
+
validity window. Capabilities such as external links are checked independently.
|
|
54
|
+
Classify every possible cart category server-side; never trust a model-supplied
|
|
55
|
+
product category. `meta.commerceDecision` records the result for `onCall`.
|
|
56
|
+
|
|
57
|
+
This gate is **host eligibility only**: preserve ownership checks, Agency action
|
|
58
|
+
authorization, exact purchase confirmation and provider reconciliation. It does
|
|
59
|
+
not inspect arbitrary text, prompts, resources or untagged tools for sales links.
|
|
60
|
+
Consumers must use the same evaluator for those surfaces until shared renderers
|
|
61
|
+
are implemented. An informational-link classification must never redirect users
|
|
62
|
+
to a transaction. No live sales path is enabled by installing this package.
|
|
63
|
+
|
|
16
64
|
## Agent action enforcement
|
|
17
65
|
|
|
18
66
|
Tools carrying manifest contract 2 `authorization` metadata fail closed unless
|
package/changelog.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contract": 1,
|
|
3
|
+
"name": "@absolutejs/mcp",
|
|
4
|
+
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"kind": "added",
|
|
9
|
+
"summary": "Add reviewed host commerce eligibility, execution guards, and reusable credit status tools",
|
|
10
|
+
"symbols": [
|
|
11
|
+
"McpServerConfig",
|
|
12
|
+
"McpTool",
|
|
13
|
+
"evaluateCommerce",
|
|
14
|
+
"createCreditBalanceTool"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"date": "2026-09-11",
|
|
19
|
+
"version": "0.13.0"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
package/dist/commerce.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/creditStatus.ts
|
|
18
|
+
var createCreditBalanceTool = (options) => ({
|
|
19
|
+
annotations: {
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
destructiveHint: false,
|
|
22
|
+
openWorldHint: false,
|
|
23
|
+
title: "Credit balance"
|
|
24
|
+
},
|
|
25
|
+
commerce: { action: "entitlement_status", categories: ["usage_credits"] },
|
|
26
|
+
description: "Read this account's service-credit allowance, consumption and remaining balance. Does not purchase credits or report the AI assistant's own token usage.",
|
|
27
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
28
|
+
outputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
required: ["allowance", "consumed", "remaining", "periodEnd", "unit"],
|
|
31
|
+
properties: {
|
|
32
|
+
allowance: { type: "integer", minimum: 0 },
|
|
33
|
+
consumed: { type: "integer", minimum: 0 },
|
|
34
|
+
remaining: { type: "integer", minimum: 0 },
|
|
35
|
+
periodEnd: { type: ["string", "null"] },
|
|
36
|
+
unit: { const: "service_credits" }
|
|
37
|
+
},
|
|
38
|
+
additionalProperties: false
|
|
39
|
+
},
|
|
40
|
+
handler: async () => {
|
|
41
|
+
const balance = await options.read();
|
|
42
|
+
if (![balance.allowance, balance.consumed, balance.remaining].every((n) => Number.isSafeInteger(n) && n >= 0) || balance.periodEnd !== null && !Number.isFinite(Date.parse(balance.periodEnd)))
|
|
43
|
+
throw new Error("Credit balance is unavailable");
|
|
44
|
+
const summary = {
|
|
45
|
+
allowance: balance.allowance,
|
|
46
|
+
consumed: balance.consumed,
|
|
47
|
+
remaining: balance.remaining,
|
|
48
|
+
periodEnd: balance.periodEnd,
|
|
49
|
+
unit: "service_credits"
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: `${summary.remaining} service credits remaining; ${summary.consumed} consumed.`
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
structuredContent: summary
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// src/commerce.ts
|
|
64
|
+
var COMMERCE_POLICY_VERSION = "2026-09-10.1";
|
|
65
|
+
var COMMERCE_POLICY_SOURCES = Object.freeze({
|
|
66
|
+
claude: "https://support.claude.com/en/articles/13454812-use-interactive-connectors-in-claude",
|
|
67
|
+
chatgpt: "https://developers.openai.com/plugins/app-guidelines#commerce-and-monetization",
|
|
68
|
+
chatgptCheckout: "https://developers.openai.com/plugins/build/monetization",
|
|
69
|
+
cursorMarketplace: "https://cursor.com/marketplace-publisher-terms"
|
|
70
|
+
});
|
|
71
|
+
var actions = new Set([
|
|
72
|
+
"entitlement_status",
|
|
73
|
+
"informational_link",
|
|
74
|
+
"paid_access",
|
|
75
|
+
"pricing",
|
|
76
|
+
"external_checkout",
|
|
77
|
+
"saved_method_purchase",
|
|
78
|
+
"new_method_collection",
|
|
79
|
+
"subscription",
|
|
80
|
+
"automatic_refill"
|
|
81
|
+
]);
|
|
82
|
+
var categories = new Set([
|
|
83
|
+
"physical_goods",
|
|
84
|
+
"digital_service",
|
|
85
|
+
"usage_credits",
|
|
86
|
+
"subscription"
|
|
87
|
+
]);
|
|
88
|
+
var profiles = new Set([
|
|
89
|
+
"claude-interactive",
|
|
90
|
+
"chatgpt-plugin",
|
|
91
|
+
"cursor-marketplace",
|
|
92
|
+
"direct-mcp",
|
|
93
|
+
"self-hosted",
|
|
94
|
+
"unknown"
|
|
95
|
+
]);
|
|
96
|
+
var sales = new Set([
|
|
97
|
+
"pricing",
|
|
98
|
+
"external_checkout",
|
|
99
|
+
"saved_method_purchase",
|
|
100
|
+
"new_method_collection",
|
|
101
|
+
"subscription",
|
|
102
|
+
"automatic_refill"
|
|
103
|
+
]);
|
|
104
|
+
var decision = (status, reason, sourceUrls = [], reviewIds = []) => ({
|
|
105
|
+
allowed: status === "permitted",
|
|
106
|
+
status,
|
|
107
|
+
reason,
|
|
108
|
+
policyVersion: COMMERCE_POLICY_VERSION,
|
|
109
|
+
sourceUrls,
|
|
110
|
+
reviewIds
|
|
111
|
+
});
|
|
112
|
+
var validSource = (source) => {
|
|
113
|
+
try {
|
|
114
|
+
const url = new URL(source);
|
|
115
|
+
return url.protocol === "https:" && !url.username && !url.password;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var reviewed = (review, profile, req, now) => typeof review.id === "string" && review.id.trim().length > 0 && review.profile === profile && Array.isArray(review.actions) && review.actions.includes(req.action) && Array.isArray(review.categories) && req.categories.every((c) => review.categories.includes(c)) && Number.isFinite(Date.parse(review.reviewedAt)) && Date.parse(review.reviewedAt) <= now && Number.isFinite(Date.parse(review.expiresAt)) && Date.parse(review.expiresAt) > now && Array.isArray(review.sourceUrls) && review.sourceUrls.length > 0 && review.sourceUrls.every(validSource);
|
|
121
|
+
var evaluateCommerce = (req, context, now = new Date) => {
|
|
122
|
+
if (!req || !actions.has(req.action) || !Array.isArray(req.categories) || req.categories.length === 0 || req.categories.some((c) => !categories.has(c)) || !context || !Array.isArray(context.profiles) || context.profiles.length === 0 || context.profiles.some((p) => !profiles.has(p)) || !Number.isFinite(now.getTime()))
|
|
123
|
+
return decision("unverified", "invalid_commerce_context");
|
|
124
|
+
const results = context.profiles.map((profile) => {
|
|
125
|
+
const digital = req.categories.some((c) => c !== "physical_goods");
|
|
126
|
+
if (profile === "chatgpt-plugin" && digital && sales.has(req.action))
|
|
127
|
+
return decision("restricted", "chatgpt_digital_commerce", [
|
|
128
|
+
COMMERCE_POLICY_SOURCES.chatgpt
|
|
129
|
+
]);
|
|
130
|
+
if (profile === "claude-interactive" && [
|
|
131
|
+
"saved_method_purchase",
|
|
132
|
+
"new_method_collection",
|
|
133
|
+
"subscription",
|
|
134
|
+
"automatic_refill"
|
|
135
|
+
].includes(req.action))
|
|
136
|
+
return decision("restricted", "claude_interactive_purchases", [
|
|
137
|
+
COMMERCE_POLICY_SOURCES.claude
|
|
138
|
+
]);
|
|
139
|
+
if (profile === "cursor-marketplace" && req.action === "paid_access")
|
|
140
|
+
return decision("restricted", "cursor_marketplace_paid_access", [
|
|
141
|
+
COMMERCE_POLICY_SOURCES.cursorMarketplace
|
|
142
|
+
]);
|
|
143
|
+
if (req.action === "entitlement_status")
|
|
144
|
+
return decision("permitted", "non_transactional_status");
|
|
145
|
+
if (req.action === "informational_link" && profile === "chatgpt-plugin")
|
|
146
|
+
return decision("permitted", "chatgpt_entitlement_information", [
|
|
147
|
+
COMMERCE_POLICY_SOURCES.chatgpt
|
|
148
|
+
]);
|
|
149
|
+
if (profile === "unknown")
|
|
150
|
+
return decision("unverified", "unknown_host_channel");
|
|
151
|
+
const review = context.reviews?.find((r) => reviewed(r, profile, req, now.getTime()));
|
|
152
|
+
return review ? decision("permitted", "reviewed_deployment", [...review.sourceUrls], [review.id]) : decision("unverified", "commerce_review_required");
|
|
153
|
+
});
|
|
154
|
+
const blocked = results.find((r) => r.status === "restricted") ?? results.find((r) => !r.allowed);
|
|
155
|
+
if (blocked)
|
|
156
|
+
return blocked;
|
|
157
|
+
const caps = context.capabilities;
|
|
158
|
+
if ((req.action === "external_checkout" || req.action === "informational_link") && caps?.externalLinks !== true)
|
|
159
|
+
return decision("unverified", "external_links_unavailable");
|
|
160
|
+
if ((req.action === "saved_method_purchase" || req.action === "new_method_collection") && caps?.interactiveUi !== true)
|
|
161
|
+
return decision("unverified", "interactive_ui_unavailable");
|
|
162
|
+
if (req.action === "new_method_collection" && context.profiles.includes("chatgpt-plugin") && caps?.nativePaymentSheet !== true)
|
|
163
|
+
return decision("restricted", "chatgpt_native_payment_sheet_required", [
|
|
164
|
+
COMMERCE_POLICY_SOURCES.chatgptCheckout
|
|
165
|
+
]);
|
|
166
|
+
return decision("permitted", "host_commerce_eligible", [...new Set(results.flatMap((r) => r.sourceUrls))], [...new Set(results.flatMap((r) => r.reviewIds))]);
|
|
167
|
+
};
|
|
168
|
+
export {
|
|
169
|
+
COMMERCE_POLICY_SOURCES,
|
|
170
|
+
COMMERCE_POLICY_VERSION,
|
|
171
|
+
createCreditBalanceTool,
|
|
172
|
+
evaluateCommerce
|
|
173
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,158 @@ var __export = (target, all) => {
|
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
// src/creditStatus.ts
|
|
18
|
+
var createCreditBalanceTool = (options) => ({
|
|
19
|
+
annotations: {
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
destructiveHint: false,
|
|
22
|
+
openWorldHint: false,
|
|
23
|
+
title: "Credit balance"
|
|
24
|
+
},
|
|
25
|
+
commerce: { action: "entitlement_status", categories: ["usage_credits"] },
|
|
26
|
+
description: "Read this account's service-credit allowance, consumption and remaining balance. Does not purchase credits or report the AI assistant's own token usage.",
|
|
27
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
28
|
+
outputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
required: ["allowance", "consumed", "remaining", "periodEnd", "unit"],
|
|
31
|
+
properties: {
|
|
32
|
+
allowance: { type: "integer", minimum: 0 },
|
|
33
|
+
consumed: { type: "integer", minimum: 0 },
|
|
34
|
+
remaining: { type: "integer", minimum: 0 },
|
|
35
|
+
periodEnd: { type: ["string", "null"] },
|
|
36
|
+
unit: { const: "service_credits" }
|
|
37
|
+
},
|
|
38
|
+
additionalProperties: false
|
|
39
|
+
},
|
|
40
|
+
handler: async () => {
|
|
41
|
+
const balance = await options.read();
|
|
42
|
+
if (![balance.allowance, balance.consumed, balance.remaining].every((n) => Number.isSafeInteger(n) && n >= 0) || balance.periodEnd !== null && !Number.isFinite(Date.parse(balance.periodEnd)))
|
|
43
|
+
throw new Error("Credit balance is unavailable");
|
|
44
|
+
const summary = {
|
|
45
|
+
allowance: balance.allowance,
|
|
46
|
+
consumed: balance.consumed,
|
|
47
|
+
remaining: balance.remaining,
|
|
48
|
+
periodEnd: balance.periodEnd,
|
|
49
|
+
unit: "service_credits"
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: `${summary.remaining} service credits remaining; ${summary.consumed} consumed.`
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
structuredContent: summary
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// src/commerce.ts
|
|
64
|
+
var COMMERCE_POLICY_VERSION = "2026-09-10.1";
|
|
65
|
+
var COMMERCE_POLICY_SOURCES = Object.freeze({
|
|
66
|
+
claude: "https://support.claude.com/en/articles/13454812-use-interactive-connectors-in-claude",
|
|
67
|
+
chatgpt: "https://developers.openai.com/plugins/app-guidelines#commerce-and-monetization",
|
|
68
|
+
chatgptCheckout: "https://developers.openai.com/plugins/build/monetization",
|
|
69
|
+
cursorMarketplace: "https://cursor.com/marketplace-publisher-terms"
|
|
70
|
+
});
|
|
71
|
+
var actions = new Set([
|
|
72
|
+
"entitlement_status",
|
|
73
|
+
"informational_link",
|
|
74
|
+
"paid_access",
|
|
75
|
+
"pricing",
|
|
76
|
+
"external_checkout",
|
|
77
|
+
"saved_method_purchase",
|
|
78
|
+
"new_method_collection",
|
|
79
|
+
"subscription",
|
|
80
|
+
"automatic_refill"
|
|
81
|
+
]);
|
|
82
|
+
var categories = new Set([
|
|
83
|
+
"physical_goods",
|
|
84
|
+
"digital_service",
|
|
85
|
+
"usage_credits",
|
|
86
|
+
"subscription"
|
|
87
|
+
]);
|
|
88
|
+
var profiles = new Set([
|
|
89
|
+
"claude-interactive",
|
|
90
|
+
"chatgpt-plugin",
|
|
91
|
+
"cursor-marketplace",
|
|
92
|
+
"direct-mcp",
|
|
93
|
+
"self-hosted",
|
|
94
|
+
"unknown"
|
|
95
|
+
]);
|
|
96
|
+
var sales = new Set([
|
|
97
|
+
"pricing",
|
|
98
|
+
"external_checkout",
|
|
99
|
+
"saved_method_purchase",
|
|
100
|
+
"new_method_collection",
|
|
101
|
+
"subscription",
|
|
102
|
+
"automatic_refill"
|
|
103
|
+
]);
|
|
104
|
+
var decision = (status, reason, sourceUrls = [], reviewIds = []) => ({
|
|
105
|
+
allowed: status === "permitted",
|
|
106
|
+
status,
|
|
107
|
+
reason,
|
|
108
|
+
policyVersion: COMMERCE_POLICY_VERSION,
|
|
109
|
+
sourceUrls,
|
|
110
|
+
reviewIds
|
|
111
|
+
});
|
|
112
|
+
var validSource = (source) => {
|
|
113
|
+
try {
|
|
114
|
+
const url = new URL(source);
|
|
115
|
+
return url.protocol === "https:" && !url.username && !url.password;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var reviewed = (review, profile, req, now) => typeof review.id === "string" && review.id.trim().length > 0 && review.profile === profile && Array.isArray(review.actions) && review.actions.includes(req.action) && Array.isArray(review.categories) && req.categories.every((c) => review.categories.includes(c)) && Number.isFinite(Date.parse(review.reviewedAt)) && Date.parse(review.reviewedAt) <= now && Number.isFinite(Date.parse(review.expiresAt)) && Date.parse(review.expiresAt) > now && Array.isArray(review.sourceUrls) && review.sourceUrls.length > 0 && review.sourceUrls.every(validSource);
|
|
121
|
+
var evaluateCommerce = (req, context, now = new Date) => {
|
|
122
|
+
if (!req || !actions.has(req.action) || !Array.isArray(req.categories) || req.categories.length === 0 || req.categories.some((c) => !categories.has(c)) || !context || !Array.isArray(context.profiles) || context.profiles.length === 0 || context.profiles.some((p) => !profiles.has(p)) || !Number.isFinite(now.getTime()))
|
|
123
|
+
return decision("unverified", "invalid_commerce_context");
|
|
124
|
+
const results = context.profiles.map((profile) => {
|
|
125
|
+
const digital = req.categories.some((c) => c !== "physical_goods");
|
|
126
|
+
if (profile === "chatgpt-plugin" && digital && sales.has(req.action))
|
|
127
|
+
return decision("restricted", "chatgpt_digital_commerce", [
|
|
128
|
+
COMMERCE_POLICY_SOURCES.chatgpt
|
|
129
|
+
]);
|
|
130
|
+
if (profile === "claude-interactive" && [
|
|
131
|
+
"saved_method_purchase",
|
|
132
|
+
"new_method_collection",
|
|
133
|
+
"subscription",
|
|
134
|
+
"automatic_refill"
|
|
135
|
+
].includes(req.action))
|
|
136
|
+
return decision("restricted", "claude_interactive_purchases", [
|
|
137
|
+
COMMERCE_POLICY_SOURCES.claude
|
|
138
|
+
]);
|
|
139
|
+
if (profile === "cursor-marketplace" && req.action === "paid_access")
|
|
140
|
+
return decision("restricted", "cursor_marketplace_paid_access", [
|
|
141
|
+
COMMERCE_POLICY_SOURCES.cursorMarketplace
|
|
142
|
+
]);
|
|
143
|
+
if (req.action === "entitlement_status")
|
|
144
|
+
return decision("permitted", "non_transactional_status");
|
|
145
|
+
if (req.action === "informational_link" && profile === "chatgpt-plugin")
|
|
146
|
+
return decision("permitted", "chatgpt_entitlement_information", [
|
|
147
|
+
COMMERCE_POLICY_SOURCES.chatgpt
|
|
148
|
+
]);
|
|
149
|
+
if (profile === "unknown")
|
|
150
|
+
return decision("unverified", "unknown_host_channel");
|
|
151
|
+
const review = context.reviews?.find((r) => reviewed(r, profile, req, now.getTime()));
|
|
152
|
+
return review ? decision("permitted", "reviewed_deployment", [...review.sourceUrls], [review.id]) : decision("unverified", "commerce_review_required");
|
|
153
|
+
});
|
|
154
|
+
const blocked = results.find((r) => r.status === "restricted") ?? results.find((r) => !r.allowed);
|
|
155
|
+
if (blocked)
|
|
156
|
+
return blocked;
|
|
157
|
+
const caps = context.capabilities;
|
|
158
|
+
if ((req.action === "external_checkout" || req.action === "informational_link") && caps?.externalLinks !== true)
|
|
159
|
+
return decision("unverified", "external_links_unavailable");
|
|
160
|
+
if ((req.action === "saved_method_purchase" || req.action === "new_method_collection") && caps?.interactiveUi !== true)
|
|
161
|
+
return decision("unverified", "interactive_ui_unavailable");
|
|
162
|
+
if (req.action === "new_method_collection" && context.profiles.includes("chatgpt-plugin") && caps?.nativePaymentSheet !== true)
|
|
163
|
+
return decision("restricted", "chatgpt_native_payment_sheet_required", [
|
|
164
|
+
COMMERCE_POLICY_SOURCES.chatgptCheckout
|
|
165
|
+
]);
|
|
166
|
+
return decision("permitted", "host_commerce_eligible", [...new Set(results.flatMap((r) => r.sourceUrls))], [...new Set(results.flatMap((r) => r.reviewIds))]);
|
|
167
|
+
};
|
|
168
|
+
|
|
17
169
|
// src/guards.ts
|
|
18
170
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
171
|
|
|
@@ -834,9 +986,23 @@ var initialize = async (config, id, params, context) => {
|
|
|
834
986
|
response.headers.set("Mcp-Session-Id", sessionId);
|
|
835
987
|
return response;
|
|
836
988
|
};
|
|
989
|
+
var commerceDecision = async (config, caller, name, tool) => {
|
|
990
|
+
if (tool.commerce === undefined)
|
|
991
|
+
return;
|
|
992
|
+
try {
|
|
993
|
+
return evaluateCommerce(tool.commerce, config.commerce ? await config.commerce({ caller, name }) : { profiles: [] });
|
|
994
|
+
} catch {
|
|
995
|
+
return evaluateCommerce(tool.commerce, { profiles: [] });
|
|
996
|
+
}
|
|
997
|
+
};
|
|
837
998
|
var toolsList = async (config, caller, scopes, id, params, protocolVersion) => {
|
|
838
999
|
const tools = await config.tools({ caller, meta: {} });
|
|
839
|
-
const
|
|
1000
|
+
const eligible = await Promise.all(Object.entries(tools).map(async ([name, tool]) => ({
|
|
1001
|
+
name,
|
|
1002
|
+
allowed: (await commerceDecision(config, caller, name, tool))?.allowed !== false
|
|
1003
|
+
})));
|
|
1004
|
+
const commerceVisible = new Set(eligible.filter((entry) => entry.allowed).map((entry) => entry.name));
|
|
1005
|
+
const visible = Object.entries(tools).filter(([name, tool]) => commerceVisible.has(name) && scopeAllows(tool, scopes) && agencyAllows(config, tool, scopes)).map(([name, tool]) => ({
|
|
840
1006
|
annotations: tool.annotations,
|
|
841
1007
|
...tool.coaz === undefined ? {} : { coaz: tool.coaz },
|
|
842
1008
|
description: tool.description,
|
|
@@ -870,9 +1036,45 @@ var runTool = async (config, caller, scopes, id, name, args, meta, tool, context
|
|
|
870
1036
|
let ok = false;
|
|
871
1037
|
let payload;
|
|
872
1038
|
try {
|
|
873
|
-
const invoke = async () =>
|
|
1039
|
+
const invoke = async () => {
|
|
1040
|
+
const eligibility2 = await commerceDecision(config, caller, name, tool);
|
|
1041
|
+
if (eligibility2)
|
|
1042
|
+
meta.commerceDecision = eligibility2;
|
|
1043
|
+
if (eligibility2?.allowed === false)
|
|
1044
|
+
return {
|
|
1045
|
+
content: [
|
|
1046
|
+
{
|
|
1047
|
+
type: "text",
|
|
1048
|
+
text: "This commerce action is unavailable in this connection."
|
|
1049
|
+
}
|
|
1050
|
+
],
|
|
1051
|
+
isError: true,
|
|
1052
|
+
structuredContent: {
|
|
1053
|
+
type: "absolute.commerce_decision",
|
|
1054
|
+
...eligibility2
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
return normalizeResult(await tool.handler(args, context));
|
|
1058
|
+
};
|
|
874
1059
|
let result;
|
|
875
|
-
|
|
1060
|
+
const eligibility = await commerceDecision(config, caller, name, tool);
|
|
1061
|
+
if (eligibility)
|
|
1062
|
+
meta.commerceDecision = eligibility;
|
|
1063
|
+
if (eligibility?.allowed === false) {
|
|
1064
|
+
result = {
|
|
1065
|
+
content: [
|
|
1066
|
+
{
|
|
1067
|
+
type: "text",
|
|
1068
|
+
text: "This commerce action is unavailable in this connection."
|
|
1069
|
+
}
|
|
1070
|
+
],
|
|
1071
|
+
isError: true,
|
|
1072
|
+
structuredContent: {
|
|
1073
|
+
type: "absolute.commerce_decision",
|
|
1074
|
+
...eligibility
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
} else if (tool.authorization === undefined) {
|
|
876
1078
|
result = await invoke();
|
|
877
1079
|
} else {
|
|
878
1080
|
const agency = config.agency;
|
|
@@ -1763,26 +1965,30 @@ var createPostgresMcpSessionStore = ({
|
|
|
1763
1965
|
};
|
|
1764
1966
|
};
|
|
1765
1967
|
export {
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
parseMcpAuthorizationChallenge,
|
|
1770
|
-
metadataPathFor,
|
|
1771
|
-
mcpServer,
|
|
1772
|
-
mcpPostgresSchemaSql,
|
|
1773
|
-
feedbackTools,
|
|
1774
|
-
dispatchMcp,
|
|
1775
|
-
discoverMcpAuthorization,
|
|
1776
|
-
createSessionRegistry,
|
|
1777
|
-
createPostgresMcpTaskStore,
|
|
1778
|
-
createPostgresMcpSessionStore,
|
|
1779
|
-
createMemoryMcpTaskStore,
|
|
1780
|
-
createMemoryMcpOAuthTokenStore,
|
|
1781
|
-
createMcpOAuthProvider,
|
|
1782
|
-
createMcpHandler,
|
|
1783
|
-
createMcpClient,
|
|
1784
|
-
createMcpAuthorizationRequest,
|
|
1785
|
-
McpClientError,
|
|
1968
|
+
COMMERCE_POLICY_SOURCES,
|
|
1969
|
+
COMMERCE_POLICY_VERSION,
|
|
1970
|
+
FEEDBACK_INSTRUCTIONS,
|
|
1786
1971
|
MCP_LATEST_PROTOCOL_VERSION,
|
|
1787
|
-
|
|
1972
|
+
McpClientError,
|
|
1973
|
+
createCreditBalanceTool,
|
|
1974
|
+
createMcpAuthorizationRequest,
|
|
1975
|
+
createMcpClient,
|
|
1976
|
+
createMcpHandler,
|
|
1977
|
+
createMcpOAuthProvider,
|
|
1978
|
+
createMemoryMcpOAuthTokenStore,
|
|
1979
|
+
createMemoryMcpTaskStore,
|
|
1980
|
+
createPostgresMcpSessionStore,
|
|
1981
|
+
createPostgresMcpTaskStore,
|
|
1982
|
+
createSessionRegistry,
|
|
1983
|
+
discoverMcpAuthorization,
|
|
1984
|
+
dispatchMcp,
|
|
1985
|
+
evaluateCommerce,
|
|
1986
|
+
feedbackTools,
|
|
1987
|
+
mcpPostgresSchemaSql,
|
|
1988
|
+
mcpServer,
|
|
1989
|
+
metadataPathFor,
|
|
1990
|
+
parseMcpAuthorizationChallenge,
|
|
1991
|
+
protectedResourceMetadata,
|
|
1992
|
+
publicMcpTask,
|
|
1993
|
+
verifyBearer
|
|
1788
1994
|
};
|
package/dist/manifest.js
CHANGED
|
@@ -63,22 +63,22 @@ var TypeSystemPolicy;
|
|
|
63
63
|
// node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
|
|
64
64
|
var exports_value = {};
|
|
65
65
|
__export(exports_value, {
|
|
66
|
-
|
|
67
|
-
IsUint8Array: () => IsUint8Array,
|
|
68
|
-
IsSymbol: () => IsSymbol,
|
|
69
|
-
IsString: () => IsString,
|
|
70
|
-
IsRegExp: () => IsRegExp,
|
|
71
|
-
IsObject: () => IsObject2,
|
|
72
|
-
IsNumber: () => IsNumber2,
|
|
73
|
-
IsNull: () => IsNull,
|
|
74
|
-
IsIterator: () => IsIterator,
|
|
75
|
-
IsFunction: () => IsFunction,
|
|
76
|
-
IsDate: () => IsDate,
|
|
77
|
-
IsBoolean: () => IsBoolean,
|
|
78
|
-
IsBigInt: () => IsBigInt,
|
|
79
|
-
IsAsyncIterator: () => IsAsyncIterator,
|
|
66
|
+
HasPropertyKey: () => HasPropertyKey,
|
|
80
67
|
IsArray: () => IsArray2,
|
|
81
|
-
|
|
68
|
+
IsAsyncIterator: () => IsAsyncIterator,
|
|
69
|
+
IsBigInt: () => IsBigInt,
|
|
70
|
+
IsBoolean: () => IsBoolean,
|
|
71
|
+
IsDate: () => IsDate,
|
|
72
|
+
IsFunction: () => IsFunction,
|
|
73
|
+
IsIterator: () => IsIterator,
|
|
74
|
+
IsNull: () => IsNull,
|
|
75
|
+
IsNumber: () => IsNumber2,
|
|
76
|
+
IsObject: () => IsObject2,
|
|
77
|
+
IsRegExp: () => IsRegExp,
|
|
78
|
+
IsString: () => IsString,
|
|
79
|
+
IsSymbol: () => IsSymbol,
|
|
80
|
+
IsUint8Array: () => IsUint8Array,
|
|
81
|
+
IsUndefined: () => IsUndefined2
|
|
82
82
|
});
|
|
83
83
|
function HasPropertyKey(value, key) {
|
|
84
84
|
return key in value;
|
|
@@ -1097,57 +1097,57 @@ function Unknown(options) {
|
|
|
1097
1097
|
// node_modules/@sinclair/typebox/build/esm/type/guard/type.mjs
|
|
1098
1098
|
var exports_type = {};
|
|
1099
1099
|
__export(exports_type, {
|
|
1100
|
-
|
|
1101
|
-
IsVoid: () => IsVoid2,
|
|
1102
|
-
IsUnsafe: () => IsUnsafe2,
|
|
1103
|
-
IsUnknown: () => IsUnknown2,
|
|
1104
|
-
IsUnionLiteral: () => IsUnionLiteral,
|
|
1105
|
-
IsUnion: () => IsUnion2,
|
|
1106
|
-
IsUndefined: () => IsUndefined4,
|
|
1107
|
-
IsUint8Array: () => IsUint8Array3,
|
|
1108
|
-
IsTuple: () => IsTuple2,
|
|
1109
|
-
IsTransform: () => IsTransform2,
|
|
1110
|
-
IsThis: () => IsThis2,
|
|
1111
|
-
IsTemplateLiteral: () => IsTemplateLiteral2,
|
|
1112
|
-
IsSymbol: () => IsSymbol3,
|
|
1113
|
-
IsString: () => IsString3,
|
|
1114
|
-
IsSchema: () => IsSchema2,
|
|
1115
|
-
IsRegExp: () => IsRegExp3,
|
|
1116
|
-
IsRef: () => IsRef2,
|
|
1117
|
-
IsRecursive: () => IsRecursive,
|
|
1118
|
-
IsRecord: () => IsRecord2,
|
|
1119
|
-
IsReadonly: () => IsReadonly2,
|
|
1120
|
-
IsProperties: () => IsProperties,
|
|
1121
|
-
IsPromise: () => IsPromise2,
|
|
1122
|
-
IsOptional: () => IsOptional2,
|
|
1123
|
-
IsObject: () => IsObject4,
|
|
1124
|
-
IsNumber: () => IsNumber4,
|
|
1125
|
-
IsNull: () => IsNull3,
|
|
1126
|
-
IsNot: () => IsNot2,
|
|
1127
|
-
IsNever: () => IsNever2,
|
|
1128
|
-
IsMappedResult: () => IsMappedResult2,
|
|
1129
|
-
IsMappedKey: () => IsMappedKey2,
|
|
1130
|
-
IsLiteralValue: () => IsLiteralValue2,
|
|
1131
|
-
IsLiteralString: () => IsLiteralString,
|
|
1132
|
-
IsLiteralNumber: () => IsLiteralNumber,
|
|
1133
|
-
IsLiteralBoolean: () => IsLiteralBoolean,
|
|
1134
|
-
IsLiteral: () => IsLiteral2,
|
|
1135
|
-
IsKindOf: () => IsKindOf2,
|
|
1136
|
-
IsKind: () => IsKind2,
|
|
1137
|
-
IsIterator: () => IsIterator3,
|
|
1138
|
-
IsIntersect: () => IsIntersect2,
|
|
1139
|
-
IsInteger: () => IsInteger2,
|
|
1140
|
-
IsImport: () => IsImport,
|
|
1141
|
-
IsFunction: () => IsFunction3,
|
|
1142
|
-
IsDate: () => IsDate3,
|
|
1143
|
-
IsConstructor: () => IsConstructor2,
|
|
1144
|
-
IsComputed: () => IsComputed2,
|
|
1145
|
-
IsBoolean: () => IsBoolean3,
|
|
1146
|
-
IsBigInt: () => IsBigInt3,
|
|
1147
|
-
IsAsyncIterator: () => IsAsyncIterator3,
|
|
1148
|
-
IsArray: () => IsArray4,
|
|
1100
|
+
IsAny: () => IsAny2,
|
|
1149
1101
|
IsArgument: () => IsArgument2,
|
|
1150
|
-
|
|
1102
|
+
IsArray: () => IsArray4,
|
|
1103
|
+
IsAsyncIterator: () => IsAsyncIterator3,
|
|
1104
|
+
IsBigInt: () => IsBigInt3,
|
|
1105
|
+
IsBoolean: () => IsBoolean3,
|
|
1106
|
+
IsComputed: () => IsComputed2,
|
|
1107
|
+
IsConstructor: () => IsConstructor2,
|
|
1108
|
+
IsDate: () => IsDate3,
|
|
1109
|
+
IsFunction: () => IsFunction3,
|
|
1110
|
+
IsImport: () => IsImport,
|
|
1111
|
+
IsInteger: () => IsInteger2,
|
|
1112
|
+
IsIntersect: () => IsIntersect2,
|
|
1113
|
+
IsIterator: () => IsIterator3,
|
|
1114
|
+
IsKind: () => IsKind2,
|
|
1115
|
+
IsKindOf: () => IsKindOf2,
|
|
1116
|
+
IsLiteral: () => IsLiteral2,
|
|
1117
|
+
IsLiteralBoolean: () => IsLiteralBoolean,
|
|
1118
|
+
IsLiteralNumber: () => IsLiteralNumber,
|
|
1119
|
+
IsLiteralString: () => IsLiteralString,
|
|
1120
|
+
IsLiteralValue: () => IsLiteralValue2,
|
|
1121
|
+
IsMappedKey: () => IsMappedKey2,
|
|
1122
|
+
IsMappedResult: () => IsMappedResult2,
|
|
1123
|
+
IsNever: () => IsNever2,
|
|
1124
|
+
IsNot: () => IsNot2,
|
|
1125
|
+
IsNull: () => IsNull3,
|
|
1126
|
+
IsNumber: () => IsNumber4,
|
|
1127
|
+
IsObject: () => IsObject4,
|
|
1128
|
+
IsOptional: () => IsOptional2,
|
|
1129
|
+
IsPromise: () => IsPromise2,
|
|
1130
|
+
IsProperties: () => IsProperties,
|
|
1131
|
+
IsReadonly: () => IsReadonly2,
|
|
1132
|
+
IsRecord: () => IsRecord2,
|
|
1133
|
+
IsRecursive: () => IsRecursive,
|
|
1134
|
+
IsRef: () => IsRef2,
|
|
1135
|
+
IsRegExp: () => IsRegExp3,
|
|
1136
|
+
IsSchema: () => IsSchema2,
|
|
1137
|
+
IsString: () => IsString3,
|
|
1138
|
+
IsSymbol: () => IsSymbol3,
|
|
1139
|
+
IsTemplateLiteral: () => IsTemplateLiteral2,
|
|
1140
|
+
IsThis: () => IsThis2,
|
|
1141
|
+
IsTransform: () => IsTransform2,
|
|
1142
|
+
IsTuple: () => IsTuple2,
|
|
1143
|
+
IsUint8Array: () => IsUint8Array3,
|
|
1144
|
+
IsUndefined: () => IsUndefined4,
|
|
1145
|
+
IsUnion: () => IsUnion2,
|
|
1146
|
+
IsUnionLiteral: () => IsUnionLiteral,
|
|
1147
|
+
IsUnknown: () => IsUnknown2,
|
|
1148
|
+
IsUnsafe: () => IsUnsafe2,
|
|
1149
|
+
IsVoid: () => IsVoid2,
|
|
1150
|
+
TypeGuardUnknownTypeError: () => TypeGuardUnknownTypeError
|
|
1151
1151
|
});
|
|
1152
1152
|
class TypeGuardUnknownTypeError extends TypeBoxError {
|
|
1153
1153
|
}
|
|
@@ -2498,68 +2498,68 @@ function Void(options) {
|
|
|
2498
2498
|
// node_modules/@sinclair/typebox/build/esm/type/type/type.mjs
|
|
2499
2499
|
var exports_type2 = {};
|
|
2500
2500
|
__export(exports_type2, {
|
|
2501
|
-
|
|
2502
|
-
Uppercase: () => Uppercase,
|
|
2503
|
-
Unsafe: () => Unsafe,
|
|
2504
|
-
Unknown: () => Unknown,
|
|
2505
|
-
Union: () => Union,
|
|
2506
|
-
Undefined: () => Undefined,
|
|
2507
|
-
Uncapitalize: () => Uncapitalize,
|
|
2508
|
-
Uint8Array: () => Uint8Array2,
|
|
2509
|
-
Tuple: () => Tuple,
|
|
2510
|
-
Transform: () => Transform,
|
|
2511
|
-
TemplateLiteral: () => TemplateLiteral,
|
|
2512
|
-
Symbol: () => Symbol2,
|
|
2513
|
-
String: () => String2,
|
|
2514
|
-
ReturnType: () => ReturnType,
|
|
2515
|
-
Rest: () => Rest,
|
|
2516
|
-
Required: () => Required,
|
|
2517
|
-
RegExp: () => RegExp2,
|
|
2518
|
-
Ref: () => Ref,
|
|
2519
|
-
Recursive: () => Recursive,
|
|
2520
|
-
Record: () => Record,
|
|
2521
|
-
ReadonlyOptional: () => ReadonlyOptional,
|
|
2522
|
-
Readonly: () => Readonly,
|
|
2523
|
-
Promise: () => Promise2,
|
|
2524
|
-
Pick: () => Pick,
|
|
2525
|
-
Partial: () => Partial,
|
|
2526
|
-
Parameters: () => Parameters,
|
|
2527
|
-
Optional: () => Optional,
|
|
2528
|
-
Omit: () => Omit,
|
|
2529
|
-
Object: () => Object2,
|
|
2530
|
-
Number: () => Number2,
|
|
2531
|
-
Null: () => Null,
|
|
2532
|
-
Not: () => Not,
|
|
2533
|
-
Never: () => Never,
|
|
2534
|
-
Module: () => Module,
|
|
2535
|
-
Mapped: () => Mapped,
|
|
2536
|
-
Lowercase: () => Lowercase,
|
|
2537
|
-
Literal: () => Literal,
|
|
2538
|
-
KeyOf: () => KeyOf,
|
|
2539
|
-
Iterator: () => Iterator,
|
|
2540
|
-
Intersect: () => Intersect,
|
|
2541
|
-
Integer: () => Integer,
|
|
2542
|
-
Instantiate: () => Instantiate,
|
|
2543
|
-
InstanceType: () => InstanceType,
|
|
2544
|
-
Index: () => Index,
|
|
2545
|
-
Function: () => Function,
|
|
2546
|
-
Extract: () => Extract,
|
|
2547
|
-
Extends: () => Extends,
|
|
2548
|
-
Exclude: () => Exclude,
|
|
2549
|
-
Enum: () => Enum,
|
|
2550
|
-
Date: () => Date2,
|
|
2551
|
-
ConstructorParameters: () => ConstructorParameters,
|
|
2552
|
-
Constructor: () => Constructor,
|
|
2553
|
-
Const: () => Const,
|
|
2554
|
-
Composite: () => Composite,
|
|
2555
|
-
Capitalize: () => Capitalize,
|
|
2556
|
-
Boolean: () => Boolean2,
|
|
2557
|
-
BigInt: () => BigInt,
|
|
2558
|
-
Awaited: () => Awaited,
|
|
2559
|
-
AsyncIterator: () => AsyncIterator,
|
|
2560
|
-
Array: () => Array2,
|
|
2501
|
+
Any: () => Any,
|
|
2561
2502
|
Argument: () => Argument,
|
|
2562
|
-
|
|
2503
|
+
Array: () => Array2,
|
|
2504
|
+
AsyncIterator: () => AsyncIterator,
|
|
2505
|
+
Awaited: () => Awaited,
|
|
2506
|
+
BigInt: () => BigInt,
|
|
2507
|
+
Boolean: () => Boolean2,
|
|
2508
|
+
Capitalize: () => Capitalize,
|
|
2509
|
+
Composite: () => Composite,
|
|
2510
|
+
Const: () => Const,
|
|
2511
|
+
Constructor: () => Constructor,
|
|
2512
|
+
ConstructorParameters: () => ConstructorParameters,
|
|
2513
|
+
Date: () => Date2,
|
|
2514
|
+
Enum: () => Enum,
|
|
2515
|
+
Exclude: () => Exclude,
|
|
2516
|
+
Extends: () => Extends,
|
|
2517
|
+
Extract: () => Extract,
|
|
2518
|
+
Function: () => Function,
|
|
2519
|
+
Index: () => Index,
|
|
2520
|
+
InstanceType: () => InstanceType,
|
|
2521
|
+
Instantiate: () => Instantiate,
|
|
2522
|
+
Integer: () => Integer,
|
|
2523
|
+
Intersect: () => Intersect,
|
|
2524
|
+
Iterator: () => Iterator,
|
|
2525
|
+
KeyOf: () => KeyOf,
|
|
2526
|
+
Literal: () => Literal,
|
|
2527
|
+
Lowercase: () => Lowercase,
|
|
2528
|
+
Mapped: () => Mapped,
|
|
2529
|
+
Module: () => Module,
|
|
2530
|
+
Never: () => Never,
|
|
2531
|
+
Not: () => Not,
|
|
2532
|
+
Null: () => Null,
|
|
2533
|
+
Number: () => Number2,
|
|
2534
|
+
Object: () => Object2,
|
|
2535
|
+
Omit: () => Omit,
|
|
2536
|
+
Optional: () => Optional,
|
|
2537
|
+
Parameters: () => Parameters,
|
|
2538
|
+
Partial: () => Partial,
|
|
2539
|
+
Pick: () => Pick,
|
|
2540
|
+
Promise: () => Promise2,
|
|
2541
|
+
Readonly: () => Readonly,
|
|
2542
|
+
ReadonlyOptional: () => ReadonlyOptional,
|
|
2543
|
+
Record: () => Record,
|
|
2544
|
+
Recursive: () => Recursive,
|
|
2545
|
+
Ref: () => Ref,
|
|
2546
|
+
RegExp: () => RegExp2,
|
|
2547
|
+
Required: () => Required,
|
|
2548
|
+
Rest: () => Rest,
|
|
2549
|
+
ReturnType: () => ReturnType,
|
|
2550
|
+
String: () => String2,
|
|
2551
|
+
Symbol: () => Symbol2,
|
|
2552
|
+
TemplateLiteral: () => TemplateLiteral,
|
|
2553
|
+
Transform: () => Transform,
|
|
2554
|
+
Tuple: () => Tuple,
|
|
2555
|
+
Uint8Array: () => Uint8Array2,
|
|
2556
|
+
Uncapitalize: () => Uncapitalize,
|
|
2557
|
+
Undefined: () => Undefined,
|
|
2558
|
+
Union: () => Union,
|
|
2559
|
+
Unknown: () => Unknown,
|
|
2560
|
+
Unsafe: () => Unsafe,
|
|
2561
|
+
Uppercase: () => Uppercase,
|
|
2562
|
+
Void: () => Void
|
|
2563
2563
|
});
|
|
2564
2564
|
|
|
2565
2565
|
// node_modules/@sinclair/typebox/build/esm/type/type/index.mjs
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Host commerce eligibility, not payment authorization. All inputs are
|
|
2
|
+
* server-owned; never derive a permissive profile from clientInfo alone. */
|
|
3
|
+
export declare const COMMERCE_POLICY_VERSION = "2026-09-10.1";
|
|
4
|
+
export declare const COMMERCE_POLICY_SOURCES: Readonly<{
|
|
5
|
+
claude: "https://support.claude.com/en/articles/13454812-use-interactive-connectors-in-claude";
|
|
6
|
+
chatgpt: "https://developers.openai.com/plugins/app-guidelines#commerce-and-monetization";
|
|
7
|
+
chatgptCheckout: "https://developers.openai.com/plugins/build/monetization";
|
|
8
|
+
cursorMarketplace: "https://cursor.com/marketplace-publisher-terms";
|
|
9
|
+
}>;
|
|
10
|
+
export type CommerceAction = "entitlement_status" | "informational_link" | "paid_access" | "pricing" | "external_checkout" | "saved_method_purchase" | "new_method_collection" | "subscription" | "automatic_refill";
|
|
11
|
+
export type CommerceCategory = "physical_goods" | "digital_service" | "usage_credits" | "subscription";
|
|
12
|
+
export type CommerceProfile = "claude-interactive" | "chatgpt-plugin" | "cursor-marketplace" | "direct-mcp" | "self-hosted" | "unknown";
|
|
13
|
+
export type CommerceRequirement = {
|
|
14
|
+
action: CommerceAction;
|
|
15
|
+
/** All product categories this tool can expose, including every cart line.
|
|
16
|
+
* Dynamic catalogs must be classified by the server before registration. */
|
|
17
|
+
categories: readonly CommerceCategory[];
|
|
18
|
+
};
|
|
19
|
+
export type CommerceReview = {
|
|
20
|
+
id: string;
|
|
21
|
+
profile: CommerceProfile;
|
|
22
|
+
actions: readonly CommerceAction[];
|
|
23
|
+
categories: readonly CommerceCategory[];
|
|
24
|
+
reviewedAt: string;
|
|
25
|
+
expiresAt: string;
|
|
26
|
+
sourceUrls: readonly string[];
|
|
27
|
+
};
|
|
28
|
+
export type CommerceContext = {
|
|
29
|
+
/** Ambiguous channels are evaluated as the intersection of their rules. */
|
|
30
|
+
profiles: readonly CommerceProfile[];
|
|
31
|
+
reviews?: readonly CommerceReview[];
|
|
32
|
+
/** Reviewed and tested capabilities; these do not establish permission. */
|
|
33
|
+
capabilities?: {
|
|
34
|
+
externalLinks?: boolean;
|
|
35
|
+
interactiveUi?: boolean;
|
|
36
|
+
nativePaymentSheet?: boolean;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export type CommerceDecision = {
|
|
40
|
+
allowed: boolean;
|
|
41
|
+
status: "permitted" | "restricted" | "unverified";
|
|
42
|
+
reason: string;
|
|
43
|
+
policyVersion: string;
|
|
44
|
+
sourceUrls: string[];
|
|
45
|
+
reviewIds: string[];
|
|
46
|
+
};
|
|
47
|
+
/** Published restrictions cannot be overridden by a deployment review.
|
|
48
|
+
* Unverified paths need explicit, fresh server-side review evidence. */
|
|
49
|
+
export declare const evaluateCommerce: (req: CommerceRequirement, context: CommerceContext, now?: Date) => CommerceDecision;
|
|
50
|
+
export { createCreditBalanceTool, type McpCreditBalance } from "./creditStatus";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { McpTool } from "./types";
|
|
2
|
+
/** Service credits, not currency or the host model's token usage. */
|
|
3
|
+
export type McpCreditBalance = {
|
|
4
|
+
allowance: number;
|
|
5
|
+
consumed: number;
|
|
6
|
+
remaining: number;
|
|
7
|
+
periodEnd: string | null;
|
|
8
|
+
};
|
|
9
|
+
/** Account identity belongs in the bound reader, never model input. Keep this
|
|
10
|
+
* tool outside paid-work balance gates so exhausted users can recover. */
|
|
11
|
+
export declare const createCreditBalanceTool: (options: {
|
|
12
|
+
read: () => McpCreditBalance | Promise<McpCreditBalance>;
|
|
13
|
+
}) => McpTool;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -42,3 +42,5 @@ export { createSessionRegistry, type SessionRegistry } from "./sessions";
|
|
|
42
42
|
export { createMemoryMcpTaskStore, publicMcpTask } from "./tasks";
|
|
43
43
|
export { createPostgresMcpSessionStore, createPostgresMcpTaskStore, mcpPostgresSchemaSql, type McpSqlClient, type McpSqlResult, } from "./postgres";
|
|
44
44
|
export type { McpAgencyOptions, McpAudioContent, McpElicitAnswer, McpElicitationRequest, McpElicitBus, McpElicitResult, McpFormElicitationRequest, McpSessionStore, McpAuthResult, McpCallGate, McpCallMeta, McpContent, McpImageContent, McpPromptArgument, McpPromptDefinition, McpPrompts, McpResource, McpResourceLink, McpResources, McpServerConfig, McpServerInfo, McpTextContent, McpTask, McpTaskStatus, McpTaskStore, McpTasksOptions, McpTool, McpToolAnnotations, McpToolCallContext, McpToolContext, McpToolRegistry, McpToolResult, McpToolReturn, McpUrlElicitationRequest, } from "./types";
|
|
45
|
+
export * from "./commerce";
|
|
46
|
+
export { createCreditBalanceTool, type McpCreditBalance } from "./creditStatus";
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CommerceContext, CommerceRequirement } from "./commerce";
|
|
1
2
|
import type { Agency, AgentActor } from "@absolutejs/agency";
|
|
2
3
|
import type { ToolAuthorization } from "@absolutejs/manifest";
|
|
3
4
|
/** MCP behaviour hints, passed straight through to the client on `tools/list`.
|
|
@@ -122,6 +123,8 @@ export type McpToolCallContext = {
|
|
|
122
123
|
};
|
|
123
124
|
/** One callable tool. `inputSchema` is a JSON Schema object. */
|
|
124
125
|
export type McpTool = {
|
|
126
|
+
/** Server-owned commerce classification; fails closed without commerce context. */
|
|
127
|
+
commerce?: CommerceRequirement;
|
|
125
128
|
annotations?: McpToolAnnotations;
|
|
126
129
|
/** OpenID AuthZEN COAZ opt-in marker. When true, inputSchema MUST carry an
|
|
127
130
|
* `x-coaz-mapping`; hosts should evaluate it before invoking the handler. */
|
|
@@ -265,6 +268,12 @@ export type McpServerInfo = {
|
|
|
265
268
|
version: string;
|
|
266
269
|
};
|
|
267
270
|
export type McpServerConfig<Caller> = {
|
|
271
|
+
/** Resolve trusted deployment policy afresh for discovery and execution.
|
|
272
|
+
* Does not replace agency approval, ownership, or payment confirmation. */
|
|
273
|
+
commerce?: (context: {
|
|
274
|
+
caller: Caller;
|
|
275
|
+
name: string;
|
|
276
|
+
}) => CommerceContext | Promise<CommerceContext>;
|
|
268
277
|
/** Per-tool action policy enforcement, approval, leases, and receipts. */
|
|
269
278
|
agency?: McpAgencyOptions<Caller>;
|
|
270
279
|
/** Resolve the request into a caller, or a reason for the 401. The package
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Commerce through MCP: host rules and shared package design
|
|
2
|
+
|
|
3
|
+
Reviewed: **2026-09-10**. Owner: `@absolutejs/mcp`, with shared services in the AbsoluteJS ecosystem. Status: **host-eligibility foundation implemented; remaining commerce architecture is a design, not a certification**.
|
|
4
|
+
|
|
5
|
+
## Scope and evidence
|
|
6
|
+
|
|
7
|
+
This is the shared reference for selling physical goods, digital services and usage credits through MCP. It covers 23 named host/surface groups below, plus an unknown-host fallback. It is a dated survey of published first-party documentation, not a claim to enumerate every MCP client or every contractual clause. Recheck the exact host, distribution channel, product category and region before enabling sales. None of these integrations was exercised in a live host during this research.
|
|
8
|
+
|
|
9
|
+
Each finding distinguishes:
|
|
10
|
+
|
|
11
|
+
- **Documented:** the linked source establishes the capability or rule.
|
|
12
|
+
- **Restricted:** a published rule excludes the particular flow or requires conditions.
|
|
13
|
+
- **Unverified:** the inspected sources do not establish permission or capability. This does not mean forbidden, and it does not mean allowed.
|
|
14
|
+
- **Package default:** our proposed engineering choice, not a statement that the host requires it.
|
|
15
|
+
|
|
16
|
+
The executable policy must eventually have separate decisions for: access to an already-paid service, entitlement explanations, informational links, catalog/pricing display, direct checkout links, saved-card purchases, new-card collection, subscriptions and automatic refill. “Supports payments” is too ambiguous to be a useful boolean.
|
|
17
|
+
|
|
18
|
+
## Host rules and our treatment
|
|
19
|
+
|
|
20
|
+
For every row marked unverified commerce, the initial package behavior is to expose authorized existing-service functionality and factual entitlement status, with no sales CTA until that channel is reviewed. Even an informational external link requires a permitted destination. This is our conservative default, not a discovered universal ban. Interactive non-commerce results can still be enabled when supported.
|
|
21
|
+
|
|
22
|
+
| # | Host / distribution surface | Documented capability or constraint | Commerce treatment for package consumers |
|
|
23
|
+
| --- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
24
|
+
| 1 | Claude web, Desktop, mobile and Cowork interactive connectors | Inline/fullscreen Apps; purchases through interactive connectors are unsupported. External links are supported; declared owned origins can avoid the external-link prompt. [C1][C2] | No embedded purchase/card-collection flow. Direct external credit checkout remains **unverified**, despite link support. Obtain clarification for that exact flow before enabling it. |
|
|
25
|
+
| 2 | Claude Code terminal / remote surfaces | Form and URL elicitation are documented. URL mode opens a browser. Certain approval annotations force human interaction on supported versions. [C3] | Use supported non-sensitive prompts; do not copy chat UI assumptions to the terminal. Commerce permission remains unverified. Do not bypass approval through hooks or permissive tool settings. |
|
|
26
|
+
| 3 | ChatGPT hosted apps/plugins | Digital products/services, subscriptions, tokens and credits cannot be sold; direct checkout and transaction-initiation links are excluded. Existing paid subscriptions can be used; informational entitlement links are permitted. [O1] | For digital credits: entitlement explanation and informational page only. No upgrade plans, buy button, saved-card charge, checkout link or hidden redirect. Confirm how existing prepaid entitlements fit the published subscription wording. |
|
|
27
|
+
| 4 | ChatGPT eligible physical-goods commerce | External checkout is generally available for eligible goods. Saved-method checkout is documented. Collecting new methods requires the ChatGPT payment sheet, available to selected partners. [O2] | Enable only for eligible goods and the merchant's approved integration. No generic hosted-card iframe for collecting new methods. Physical-goods eligibility never authorizes digital-credit sales or mixed-cart circumvention. |
|
|
28
|
+
| 5 | Direct Codex MCP: CLI, IDE and configured desktop connections | MCP tools, HTTP/STDIO and OAuth documented; local connections differ from hosted plugin tools. [O3] | Embedded payment support and third-party commerce permission remain unverified. Key rules by actual surface and channel; do not assume all OpenAI surfaces share the same capability set or that direct MCP is exempt from applicable terms. |
|
|
29
|
+
| 6 | Cursor directly configured MCP / Agents | Tools, elicitation and MCP Apps are documented, with normal-result fallback. [U1] | Technical candidate for richer UI. URL elicitation specifically and credit commerce remain unverified; negotiate modes rather than interpreting generic elicitation as URL support. |
|
|
30
|
+
| 7 | Cursor Marketplace plugins | Publisher terms §3.1 disallow direct or indirect fees for access to or use of a marketplace plugin. [U2] | Treat paid plugin access as restricted. Clarify external paid-service/credit treatment before listing a metered connector. “The plugin is free” is not enough to dismiss the indirect-fee wording. Direct configuration is a separate channel, not automatic permission. |
|
|
31
|
+
| 8 | VS Code native GitHub Copilot chat | MCP Apps render interactive tool results. Server trust and organization controls apply. [V1][V2] | Enable tested result/approval Apps; purchases and checkout links remain unverified. Respect host confirmation and enterprise allowlists. |
|
|
32
|
+
| 9 | GitHub Copilot CLI | MCP configuration and tool permissions are documented. [G1] | Terminal fallback; no assumed iframe UI or checkout permission. Do not infer a permission to charge from an allow-tools setting. |
|
|
33
|
+
| 10 | GitHub Copilot hosted/cloud agents | GitHub documents MCP support and organization policy controls; support varies by client. [G2] | Separate profile from VS Code and CLI. Use durable handoff-required results if no person is present; no unattended purchase absent an independently valid mandate and host permission. |
|
|
34
|
+
| 11 | Gemini Spark custom connected apps | Custom MCP URLs, account linking and manual confirmation for writes are documented. Availability is limited by age, geography, account type and Spark access. [J1] | Check eligibility; preserve write confirmations. Apps rendering and credit commerce remain unverified. Do not apply Gemini CLI findings to consumer Gemini. |
|
|
35
|
+
| 12 | Gemini CLI | Local/remote MCP tools, resources and transport/auth configuration documented. [J2] | Standard tool/result fallback; no verified embedded checkout or credit-commerce allowance. Verify each elicitation capability from the client. |
|
|
36
|
+
| 13 | Google Antigravity | MCP connections to developer tools and external services documented. [J3] | Treat as its own client, not Gemini CLI. Interactive checkout and digital sales remain unverified. |
|
|
37
|
+
| 14 | Windsurf / Cascade | Former Windsurf documentation redirects to Devin's Cascade documentation and describes MCP integration. [W1] | Preserve a distinct Cascade profile and source redirect history. Do not infer identical behavior to Devin cloud. Commerce and Apps checkout remain unverified. |
|
|
38
|
+
| 15 | Devin hosted agent | MCP server/marketplace integration documented. [D1] | Separate interactive and unattended execution. Keep funding recovery resumable; no assumption a hosted job can display an embedded checkout or ask a present user. Commerce unverified. |
|
|
39
|
+
| 16 | Perplexity local and remote connectors | Local and remote MCP integration documented. [P1] | Verify the user's surface/account configuration. Do not infer third-party credit sales from Perplexity's separate shopping products. Apps checkout and credit commerce unverified. |
|
|
40
|
+
| 17 | JetBrains AI Assistant | STDIO, Streamable HTTP and legacy SSE documented; administrators can constrain configured servers. [B1] | Native assistant and externally hosted agents need separate profiles. Tools support does not establish Apps/payment support; commerce unverified. |
|
|
41
|
+
| 18 | Kiro | MCP tools, prompts and resource templates documented; enterprise MCP allowlists exist. [K1][K2] | Distinguish CLI and graphical surfaces during testing. Respect governance; Apps checkout and commerce unverified. |
|
|
42
|
+
| 19 | Zed native agent / external agents | Native MCP tools and prompts documented. External agent behavior is a separate integration. [Z1] | Native baseline is ordinary tools/results. Do not assume an external agent inherits native UI or vice versa. Commerce unverified. |
|
|
43
|
+
| 20 | Cline, Roo Code and Continue | Each documents MCP integration. Continue's documented MCP use requires agent mode. [L1][L2][L3] | Maintain separate client records despite this grouped baseline. No inherited VS Code Apps capability just because an extension runs there. Commerce unverified for each. |
|
|
44
|
+
| 21 | goose Desktop / CLI | Desktop supports interactive MCP Apps. Documentation distinguishes live interactive Apps and standalone App behavior. [H1] | Desktop is a candidate for a controlled pilot, not a payment certification. CLI needs its own fallback. Operator/model-provider requirements still apply. |
|
|
45
|
+
| 22 | Self-hosted Open WebUI / LibreChat | Both document MCP integration; Open WebUI documents OAuth-backed connections. [H2][H3] | Operator review can establish deployment-specific rules. Do not equate self-hosting with unrestricted commerce or assume all deployments render Apps. Keep separate product/version records. |
|
|
46
|
+
| 23 | Microsoft Copilot Studio / deployed agents | MCP connections use Power Platform connectors and configured authentication. [M1] | Treat each published channel as its own rendering/runtime surface. Respect tenant governance; native payment UI and credit-commerce permission remain unverified. |
|
|
47
|
+
|
|
48
|
+
Missing/new hosts, forks, embedded agents and SDK-built products use an explicit `unknown` profile. A protocol client catalogue can identify additional coverage candidates, but is not commerce-policy evidence. The named groups above are the researched launch inventory, not a permanently complete list.
|
|
49
|
+
|
|
50
|
+
## Cross-host rules that matter
|
|
51
|
+
|
|
52
|
+
### Protocol and UI boundaries
|
|
53
|
+
|
|
54
|
+
MCP form elicitation must not request passwords, API keys, bearer tokens or payment credentials. Sensitive elicitation uses URL mode; only send modes the client advertises. An empty elicitation capability means form support, not URL support. Connector authorization remains the separate OAuth flow. Bind state to authenticated identity, not session ID alone. [S1][S2]
|
|
55
|
+
|
|
56
|
+
There is a documentation conflict worth preserving: Claude Code's form example mentions a password, while the normative MCP elicitation specification prohibits password collection in forms. Our shared implementation follows the stricter protocol requirement; no password/card form examples. [C3][S1]
|
|
57
|
+
|
|
58
|
+
MCP Apps uses UI resources, metadata and host messaging. Preserve `_meta.ui.resourceUri`, UI resource metadata and the correct MIME type through listing, resource reads and results. Negotiate capabilities; provide text alternatives. UI-only tool visibility is useful but is not server authorization. Host CSP/frame restrictions and provider requirements must both permit any embedded content. [S3]
|
|
59
|
+
|
|
60
|
+
Package recommendation: use reviewed components and typed data for account setup, previews, approvals and balances. Do not execute model-generated code as a trusted checkout. Treat all tool results and transcripts as potentially retained or shared; UI metadata is not a secret vault.
|
|
61
|
+
|
|
62
|
+
### Distribution and product categories
|
|
63
|
+
|
|
64
|
+
A marketplace policy, direct connection, enterprise deployment and self-hosted installation can have different rules. A consumer choosing an underlying Claude model in another host is not necessarily using Claude's interactive connector product; nevertheless applicable provider terms still matter. Check the real service and distribution arrangement.
|
|
65
|
+
|
|
66
|
+
Product classification is server-owned: `physical_goods`, `digital_service`, `usage_credits`, `subscription`, or a specifically reviewed category. Classify every mixed-cart line; a restricted line cannot be hidden inside an eligible physical product. User consent, merchant consent, provider support and host commerce permission are separate requirements. None substitutes for the others.
|
|
67
|
+
|
|
68
|
+
The survey does not authorize regulated goods, money transmission, investment transactions or cryptocurrency commerce. They require a separate category review; a prepaid service-credit balance is not a general-purpose transferable wallet.
|
|
69
|
+
|
|
70
|
+
### Honest recovery behavior
|
|
71
|
+
|
|
72
|
+
No credit balance or subscription should be required merely to inspect the user's existing balance, receipts, owned results or support case, subject to account authorization and bounded resource use. A purchase-capable host can show a top-up path. A restricted host shows only the permitted entitlement explanation or informational destination. Never disguise a checkout as support, documentation, account recovery, a QR code, an attachment or a generic link.
|
|
73
|
+
|
|
74
|
+
Reauthorization resolves authentication, not insufficient credits. An OAuth scope is not approval to charge. “Open external link” approval is not payment confirmation. An elicitation acceptance, a closed window or a user report is not proof of payment.
|
|
75
|
+
|
|
76
|
+
## Package architecture: implement once, configure per consumer
|
|
77
|
+
|
|
78
|
+
The following are proposed additions and composition boundaries, **not existing exports**. Existing package responsibilities were inspected in their READMEs/source before assigning work.
|
|
79
|
+
|
|
80
|
+
| Package | Shared responsibility | Consumer configuration only |
|
|
81
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
82
|
+
| `@absolutejs/mcp` | Optional commerce integration; host/surface capability adapter; shared tool definitions and Apps; safe result projection; policy-aware recovery; versioned host rule catalogue | Brand, domain, selected products, adapter/store instances, deployment profile |
|
|
83
|
+
| `@absolutejs/policy` | Reuse immutable rule versions, digests, activation, simulation and recorded decisions for host-commerce policy evaluation | Reviewed profile and deployment restrictions; no ad hoc host-name branches |
|
|
84
|
+
| `@absolutejs/agency` | Existing exact-input action approval, execution leases and receipts | Actor resolution, business permissions and spending mandates |
|
|
85
|
+
| `@absolutejs/auth` | OAuth identity and consent; reusable narrow checkout-session exchange primitive if missing | Identity store and owned routes/origins; subscription policy stays outside auth |
|
|
86
|
+
| `@absolutejs/commerce` | Purchase/quote lifecycle, canonical totals and provider-neutral checkout evidence; extend existing contracts for service-credit purchases where needed | Product catalogue, tax/refund configuration and entitlement fulfillment |
|
|
87
|
+
| `@absolutejs/commerce-adapters` | Provider-specific hosted checkout, tokenization, verification, refunds and reconciliation | Merchant credentials stored server-side; use actual independently published provider packages |
|
|
88
|
+
| `@absolutejs/billing` | Usage-credit accounting, persistent purchased grants versus periodic allowances, reservations and settlement contracts | Rates, allowance policy, credit denomination and DB store |
|
|
89
|
+
| `@absolutejs/wallet` | Reuse existing agent spend mandates, caps and journal/reservation patterns where monetary wallets are appropriate | Explicit wallet policy; do not adopt its marketplace dollar limits/fees or conflate cents with usage credits |
|
|
90
|
+
| `@absolutejs/handoff` | Existing external-operation correlation, evidence and reconciliation; extend shared workflow resume coordination | Durable store and provider callbacks; this package is not currently an authentication-token issuer |
|
|
91
|
+
| `@absolutejs/ai` | Typed presentation models and result summaries reusable across the portal and MCP | Business labels and supported view types; no provider-specific payment secrets |
|
|
92
|
+
|
|
93
|
+
Keep the core MCP protocol usable without billing dependencies. Prefer an optional, versioned commerce subpath/integration in the MCP package; final exported names require API review. Consume existing packages rather than copying their ledgers or policy engines. A new provider adapter belongs in the adapter repository, not a project's MCP handler.
|
|
94
|
+
|
|
95
|
+
Shared components should include: setup progress, work preview with budget, exact-action approval, job status, results, credit balance, usage and receipts, and a host-permitted billing entry. Consumers supply validated domain view models and fulfillment adapters. A product may retain its own portal layout; it must not implement its own checkout security or host restrictions.
|
|
96
|
+
|
|
97
|
+
### Rule catalogue and evaluator
|
|
98
|
+
|
|
99
|
+
Each rule record should contain:
|
|
100
|
+
|
|
101
|
+
- Stable rule ID, revision, reviewed date, next-review date and owning maintainer.
|
|
102
|
+
- Host, surface, distribution channel, applicable version range, region/account scope and product category.
|
|
103
|
+
- Source URL, section, effective date if available, concise finding, evidence status and review rationale.
|
|
104
|
+
- Separate decisions for paid access, pricing display, informational links, external checkout, saved-method execution, new-method collection, subscription changes and automatic refill.
|
|
105
|
+
- Required capabilities, origin declarations, merchant enrollment, user interaction and approval evidence.
|
|
106
|
+
- Resolution path for unknowns; superseded-rule relationship and test fixtures.
|
|
107
|
+
|
|
108
|
+
Proposed decision vocabulary: `permitted`, `restricted`, `unverified`, `not_applicable`. Return the selected presentation, blocked actions, reason IDs, policy digest and evidence references. A human-readable explanation must remain available for consumers and reviewers. Do not bake conclusions into model prompts only.
|
|
109
|
+
|
|
110
|
+
Evaluation order:
|
|
111
|
+
|
|
112
|
+
1. Authenticate account/tenant and resolve a deployment's trusted profile. Treat `clientInfo` and arbitrary headers as hints, not authenticated identity.
|
|
113
|
+
2. Resolve actual product category, distribution constraints and current versioned policy.
|
|
114
|
+
3. Apply merchant/provider/region and account permissions, then intersect with negotiated capabilities.
|
|
115
|
+
4. Select the best permitted experience: native payment UI → approved merchant embedding → approved external handoff → permitted informational recovery → explanation only.
|
|
116
|
+
5. Recheck at action execution, including approvals, quote expiry and current account state. Tool discovery or a previously rendered card cannot grant authority.
|
|
117
|
+
|
|
118
|
+
A server cannot reliably distinguish every marketplace install from every manual connection. Use trusted deployment configuration and verified client-registration relationships where available. If channel identity is ambiguous, apply the intersection of possible restrictions. Never allow a spoofed host name to select a more permissive checkout.
|
|
119
|
+
|
|
120
|
+
The same decision controls tools/list, direct tools/call, prompts, resources, App buttons and text links. Disabled sales paths must not leak through a fallback. Informational pages cannot automatically redirect to checkout. Applying stricter policy should disable new sales while preserving receipts, already-paid fulfillment and reconciliation.
|
|
121
|
+
|
|
122
|
+
Do not silently refresh executable policy from scraped web pages. Review and release rule updates with change history; support rapid restrictive overrides. Proposed operational cadence: review monthly and before releases, with earlier review on host policy/version changes. Stale permissive evidence must not indefinitely authorize new transactions.
|
|
123
|
+
|
|
124
|
+
## Reusable checkout handoff without routine sign-in
|
|
125
|
+
|
|
126
|
+
Where the host permits an external purchase link, the target is a dedicated merchant page, already associated with the authenticated account. The normal flow is one click to the page, explicit amount/payment confirmation, server-verified grant, then resume in the assistant. Bank challenges or expired/risky sessions may still require verification.
|
|
127
|
+
|
|
128
|
+
Proposed shared handoff contract:
|
|
129
|
+
|
|
130
|
+
1. Authorize creation against the MCP identity and current host policy. Mint an opaque, high-entropy, short-lived code; store its hash, tenant/account, intent, permitted scope, expiry and single-use state.
|
|
131
|
+
2. The link grants only limited checkout setup, not a normal account session, receipt history or automatic saved-card access. Loading/previewing a URL never purchases anything. Avoid consuming the code on a preview GET.
|
|
132
|
+
3. Exchange through the dedicated HTTPS page for a Secure, HttpOnly, narrowly scoped session. Remove the code from the visible URL; suppress referrer/cache/analytics leakage and redact server logs. Bind the exchange to the browser context. Do not silently switch an existing browser account.
|
|
133
|
+
4. Validate origin and CSRF protection for mutations. Use server-priced amount/currency, an expiry and operation key. Reveal only the identity detail needed to recognize the purchase destination. A new-card entry stays inside the payment provider's trusted fields on the merchant site.
|
|
134
|
+
5. A copied link can confer its limited bearer capability. It must not alone reveal saved methods or authorize charges. Reuse a matching authenticated browser session or require appropriate verification for sensitive saved-method/account management actions.
|
|
135
|
+
6. Verify completion from provider evidence and deduplicate both charge and grant. Persist uncertain outcomes for reconciliation; do not retry a possibly successful charge blindly.
|
|
136
|
+
7. Resume by durable workflow ID. Refresh the balance/status in the App or next tool call. Expired or changed work requires a new quote/approval; payment completion is not automatic approval of the original outbound action.
|
|
137
|
+
|
|
138
|
+
This is a new shared security primitive to implement, not a promise that an existing project checkout-intent signature provides sign-in or replay protection. Keep link-generation, session exchange, confirmation and reconciliation tests in packages.
|
|
139
|
+
|
|
140
|
+
## Shared financial and action invariants
|
|
141
|
+
|
|
142
|
+
- Separate credit funding from credit consumption and monetary accounting from usage units. An MCP request, a model token and a service credit are different units.
|
|
143
|
+
- Reserve enough credits atomically before paid work; bound maximum spend, settle actual use and release unused reservations. No read-then-spend race. Do not double charge workflow totals and component events.
|
|
144
|
+
- Period rollover replenishes only periodic allowances; it must not replenish spent purchased grants. Cancellation must not destroy unused purchased credits unless an explicit applicable policy requires it.
|
|
145
|
+
- Verify tenant ownership and current permission on each tool/resource/action. Approval binds to exact product/recipient, amount, currency, contents, version and expiry. Use single-use execution leases.
|
|
146
|
+
- Distinguish a user-approved action from a preauthorized recurring mandate. Auto refill is off by default and separately gated by host rules, explicit consent, cap and revocation. Tool auto-approval is not recurring billing consent.
|
|
147
|
+
- Unknown payment status is a durable state, not failure or success. Recover after crashes between charge, ledger write and fulfillment. Refunds/chargebacks produce auditable adjustments.
|
|
148
|
+
- Use domain-specific fulfillment: purchased service credits grant the correct account once; physical orders use their own inventory/fulfillment rules. Credit purchase must not fabricate a subscription.
|
|
149
|
+
- Trace usage to work/results where possible. Revenue attribution, pipeline, collected revenue and profit remain distinct; the host assistant's own charges are not automatically observable.
|
|
150
|
+
|
|
151
|
+
## Implementation sequence and reusable verification
|
|
152
|
+
|
|
153
|
+
### Confirmed launch scope: broad support, including coding agents
|
|
154
|
+
|
|
155
|
+
Broad compatibility is a first-release requirement. Validate conversational hosts, IDE agents, terminal agents and a self-hosted deployment from the start. Initial test targets are Claude, direct Codex, Cursor, VS Code Copilot, Claude Code, Gemini CLI, goose Desktop and a self-hosted client; include ChatGPT's restricted commerce presentation. These are validation targets, not verified compatibility claims.
|
|
156
|
+
|
|
157
|
+
Require passing representative conversational, IDE and terminal clients before launch. Publish exact tested surfaces and versions. All supported clients share account, entitlement, work, result and recovery contracts; interactive rendering and transaction paths depend on each host's capabilities and permitted commerce. A restricted purchase path must not prevent authorized use of existing service entitlements where allowed.
|
|
158
|
+
|
|
159
|
+
Run one reusable package conformance suite across these clients, with at least two independently configured consumer applications. Additional hosts enter the advertised matrix only after their own checks pass. Do not defer the terminal workflow until after a Claude-only release.
|
|
160
|
+
|
|
161
|
+
1. **Policy contracts and host fixtures:** formalize the catalogue and pure decision result; map to existing policy/agency contracts. Ship source references and examples together. No payment behavior changes yet.
|
|
162
|
+
2. **MCP Apps foundation:** metadata end-to-end, capability negotiation, authenticated resources, user interactions, scoped data and text fallback. Test optional features against old clients.
|
|
163
|
+
3. **Commerce handoff and prepaid substrate:** shared narrow sessions, canonical quotes, provider adapter, persistent grants, atomic reservations, idempotency and reconciliation. Extract reusable logic from existing consumers rather than copy it.
|
|
164
|
+
4. **Shared tools and components:** compose onboarding, balance, receipts, billing recovery and approval flows from package services. Keep host-specific presentation inside the package.
|
|
165
|
+
5. **Conformance and releases:** release changed packages in dependency order, then pin versions in consumers. Publish documentation with the package; deployment-specific approval evidence remains private. Verify at least two independently configured consumers to demonstrate there is no onSpark-specific coupling.
|
|
166
|
+
|
|
167
|
+
Acceptance fixtures must cover:
|
|
168
|
+
|
|
169
|
+
| Area | Required cases |
|
|
170
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
171
|
+
| Host rules | ChatGPT digital denial, eligible physical goods, mixed cart rejection, Claude purchase-disabled presentation, Cursor marketplace indirect-fee restriction, unknown host/channel and stale rule versions |
|
|
172
|
+
| Capabilities | Apps absent/disabled, form-only elicitation, URL elicitation, denied external link, CSP/frame failures, terminal/headless mode, mobile return, reconnect and server restart |
|
|
173
|
+
| Bypass resistance | Spoofed client name, hidden direct tool invocation, resources/prompts/text fallback containing forbidden CTA, redirect to transaction from informational page, prompt injection requesting charge |
|
|
174
|
+
| Identity/handoff | Wrong tenant, revoked auth, mismatched browser account, preview crawler, expired/reused/stolen scoped code, CSRF, arbitrary return URL, secret leakage |
|
|
175
|
+
| Money | Duplicate request/callback, ambiguous provider result, crashes around capture/grant, concurrent last-credit jobs, settlement/release, allowance rollover, refund/chargeback, mandate revocation |
|
|
176
|
+
| Human actions | Stale quote, changed recipients/draft/cart, already-executed action, tool auto-approval, repeated click, cancelled checkout, payment succeeds but user declines work |
|
|
177
|
+
|
|
178
|
+
Live verification records must specify host version/surface, connection channel, product category, account eligibility, negotiated capabilities, policy revision and observed result. Sanitized screenshots/traces supplement automated conformance; neither successful rendering nor a test charge proves platform permission. Use provider sandbox/test identities and no real charges for compatibility checks.
|
|
179
|
+
|
|
180
|
+
## Open questions and decisions
|
|
181
|
+
|
|
182
|
+
- Claude: does the interactive connector purchase restriction permit a user-initiated link to a dedicated digital-credit checkout? External-link capability alone leaves this unresolved.
|
|
183
|
+
- Cursor Marketplace: how does §3.1 apply to free connectors backed by metered third-party services? Do not assume an exception.
|
|
184
|
+
- ChatGPT: can existing prepaid service credits be consumed under the existing-paid-account allowance? Digital top-up sales and transaction links remain explicitly restricted regardless.
|
|
185
|
+
- Codex, other proprietary agents and self-hosted deployments: identify applicable commerce/distribution terms and confirm the exact UI before enabling transactions. Open-source code and absence of a documented restriction are not permission from every model/provider.
|
|
186
|
+
- Provider support: validate iframe policy, origin registration, 3DS/wallet behavior and merchant eligibility for each enabled flow. No provider migration is justified solely by host UI support.
|
|
187
|
+
|
|
188
|
+
These questions do not block implementing reusable read-only Apps, policy evaluation, scoped handoff primitives or financial invariants. They block enabling the unresolved sales paths, not the whole product.
|
|
189
|
+
|
|
190
|
+
## Source register
|
|
191
|
+
|
|
192
|
+
All sources below were opened during research on 2026-09-10. Summaries above are deliberately narrow; unverified entries mean the inspected sources do not settle the question. Dynamic documentation and contractual terms require revalidation. Source pages that redirect are cited at the resolved official location where available.
|
|
193
|
+
|
|
194
|
+
- **S1:** [MCP elicitation specification](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation).
|
|
195
|
+
- **S2:** [MCP authorization specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization).
|
|
196
|
+
- **S3:** [MCP Apps specification](https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/2026-01-26/apps.mdx).
|
|
197
|
+
- **C1:** [Claude interactive connectors](https://support.claude.com/en/articles/13454812-use-interactive-connectors-in-claude).
|
|
198
|
+
- **C2:** [Claude directory submission and allowed external links](https://claude.com/docs/connectors/building/submission); [software directory policy](https://support.claude.com/en/articles/13145358-anthropic-software-directory-policy).
|
|
199
|
+
- **C3:** [Claude Code MCP, elicitation and approvals](https://code.claude.com/docs/en/mcp).
|
|
200
|
+
- **O1:** [OpenAI plugin guidelines: commerce and monetization](https://developers.openai.com/plugins/app-guidelines#commerce-and-monetization).
|
|
201
|
+
- **O2:** [OpenAI checkout API and eligibility](https://developers.openai.com/plugins/build/monetization).
|
|
202
|
+
- **O3:** [Codex and ChatGPT MCP surfaces](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
|
|
203
|
+
- **U1:** [Cursor MCP capabilities](https://cursor.com/docs/mcp).
|
|
204
|
+
- **U2:** [Cursor Marketplace Publisher Terms, §3.1](https://cursor.com/marketplace-publisher-terms).
|
|
205
|
+
- **V1:** [VS Code MCP Apps](https://code.visualstudio.com/blogs/2026/01/26/mcp-apps-support).
|
|
206
|
+
- **V2:** [VS Code MCP configuration and trust](https://code.visualstudio.com/docs/agent-customization/mcp-servers).
|
|
207
|
+
- **G1:** [GitHub Copilot CLI reference](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference).
|
|
208
|
+
- **G2:** [GitHub Copilot MCP overview and governance](https://docs.github.com/en/copilot/concepts/context/mcp).
|
|
209
|
+
- **J1:** [Gemini Spark custom apps and eligibility](https://support.google.com/gemini/answer/17209137).
|
|
210
|
+
- **J2:** [Gemini CLI MCP](https://geminicli.com/docs/tools/mcp-server/).
|
|
211
|
+
- **J3:** [Google Antigravity MCP](https://antigravity.google/docs/mcp).
|
|
212
|
+
- **W1:** [Cascade MCP](https://docs.devin.ai/desktop/cascade/mcp), reached through the former Windsurf documentation URL.
|
|
213
|
+
- **D1:** [Devin MCP servers and marketplace](https://docs.devin.ai/work-with-devin/mcp).
|
|
214
|
+
- **M1:** [Copilot Studio MCP integration](https://learn.microsoft.com/en-us/microsoft-copilot-studio/mcp-add-existing-server-to-agent).
|
|
215
|
+
- **P1:** [Perplexity local/remote MCP](https://www.perplexity.ai/help-center/en/articles/11502712-local-and-remote-mcps-for-perplexity).
|
|
216
|
+
- **B1:** [JetBrains AI Assistant MCP](https://www.jetbrains.com/help/ai-assistant/mcp.html).
|
|
217
|
+
- **K1:** [Kiro MCP usage](https://kiro.dev/docs/mcp/usage/).
|
|
218
|
+
- **K2:** [Kiro enterprise MCP governance](https://kiro.dev/docs/enterprise/governance/mcp/).
|
|
219
|
+
- **Z1:** [Zed MCP](https://zed.dev/docs/ai/mcp).
|
|
220
|
+
- **L1:** [Cline MCP](https://docs.cline.bot/mcp/mcp-overview).
|
|
221
|
+
- **L2:** [Roo Code MCP](https://roocodeinc.github.io/Roo-Code/features/mcp/using-mcp-in-roo/).
|
|
222
|
+
- **L3:** [Continue MCP configuration](https://docs.continue.dev/customize/mcp-tools); [Continue agent-mode requirement](https://docs.continue.dev/reference/continue-mcp).
|
|
223
|
+
- **H1:** [goose MCP Apps](https://goose-docs.ai/docs/guides/interactive-chat/mcp-ui/), linked from the project's migrated documentation.
|
|
224
|
+
- **H2:** [Open WebUI MCP](https://docs.openwebui.com/features/extensibility/mcp/).
|
|
225
|
+
- **H3:** [LibreChat MCP](https://www.librechat.ai/docs/features/mcp).
|
|
226
|
+
|
|
227
|
+
[S1]: https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation
|
|
228
|
+
[S2]: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization
|
|
229
|
+
[S3]: https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/2026-01-26/apps.mdx
|
|
230
|
+
[C1]: https://support.claude.com/en/articles/13454812-use-interactive-connectors-in-claude
|
|
231
|
+
[C2]: https://claude.com/docs/connectors/building/submission
|
|
232
|
+
[C3]: https://code.claude.com/docs/en/mcp
|
|
233
|
+
[O1]: https://developers.openai.com/plugins/app-guidelines#commerce-and-monetization
|
|
234
|
+
[O2]: https://developers.openai.com/plugins/build/monetization
|
|
235
|
+
[O3]: https://learn.chatgpt.com/docs/extend/mcp?surface=cli
|
|
236
|
+
[U1]: https://cursor.com/docs/mcp
|
|
237
|
+
[U2]: https://cursor.com/marketplace-publisher-terms
|
|
238
|
+
[V1]: https://code.visualstudio.com/blogs/2026/01/26/mcp-apps-support
|
|
239
|
+
[V2]: https://code.visualstudio.com/docs/agent-customization/mcp-servers
|
|
240
|
+
[G1]: https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference
|
|
241
|
+
[G2]: https://docs.github.com/en/copilot/concepts/context/mcp
|
|
242
|
+
[J1]: https://support.google.com/gemini/answer/17209137
|
|
243
|
+
[J2]: https://geminicli.com/docs/tools/mcp-server/
|
|
244
|
+
[J3]: https://antigravity.google/docs/mcp
|
|
245
|
+
[W1]: https://docs.devin.ai/desktop/cascade/mcp
|
|
246
|
+
[D1]: https://docs.devin.ai/work-with-devin/mcp
|
|
247
|
+
[P1]: https://www.perplexity.ai/help-center/en/articles/11502712-local-and-remote-mcps-for-perplexity
|
|
248
|
+
[B1]: https://www.jetbrains.com/help/ai-assistant/mcp.html
|
|
249
|
+
[K1]: https://kiro.dev/docs/mcp/usage/
|
|
250
|
+
[K2]: https://kiro.dev/docs/enterprise/governance/mcp/
|
|
251
|
+
[Z1]: https://zed.dev/docs/ai/mcp
|
|
252
|
+
[L1]: https://docs.cline.bot/mcp/mcp-overview
|
|
253
|
+
[L2]: https://roocodeinc.github.io/Roo-Code/features/mcp/using-mcp-in-roo/
|
|
254
|
+
[L3]: https://docs.continue.dev/reference/continue-mcp
|
|
255
|
+
[H1]: https://goose-docs.ai/docs/guides/interactive-chat/mcp-ui/
|
|
256
|
+
[H2]: https://docs.openwebui.com/features/extensibility/mcp/
|
|
257
|
+
[H3]: https://www.librechat.ai/docs/features/mcp
|
|
258
|
+
[M1]: https://learn.microsoft.com/en-us/microsoft-copilot-studio/mcp-add-existing-server-to-agent
|
|
259
|
+
|
|
260
|
+
## Implementation progress
|
|
261
|
+
|
|
262
|
+
The first slice exports `evaluateCommerce` through `@absolutejs/mcp/commerce`, adds server-owned `McpTool.commerce` classification and a `McpServerConfig.commerce` resolver, filters tagged tools in discovery, and rechecks eligibility before handler execution. Decisions carry policy version, reason and review evidence into the call audit metadata. No client-name autodetection or live checkout is enabled.
|
|
263
|
+
|
|
264
|
+
The bundled rules cover the explicit restrictions established above; the broad host inventory currently maps to reviewed direct/self-hosted or unknown profiles rather than claiming every host has been verified. Missing policy, malformed categories, ambiguous restrictions, expired reviews and unavailable capabilities block the action. Deployment reviews cannot override bundled restrictions.
|
|
265
|
+
|
|
266
|
+
This slice is not a general content filter: prompts, resources, untagged tools and arbitrary returned links require the shared evaluator at their own presentation boundaries. Shared renderers, native capability plumbing, checkout sessions, prepaid accounting changes and live cross-host conformance remain to implement. Existing Agency enforcement remains independent.
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"description": "Serve a remote Model Context Protocol endpoint (streamable HTTP, stateless) from a tool/prompt/resource registry — OAuth bearer auth, RFC 9728 discovery, and per-call guards are yours to wire, the JSON-RPC protocol is done correctly by construction.",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@absolutejs/agency": "0.7.1",
|
|
6
|
+
"@absolutejs/changelog": "^0.6.0",
|
|
6
7
|
"@types/bun": "latest",
|
|
7
8
|
"elysia": "2.0.0-beta.6",
|
|
8
9
|
"exact-mirror": "1.2.4",
|
|
@@ -33,7 +34,12 @@
|
|
|
33
34
|
"import": "./dist/manifest.js",
|
|
34
35
|
"default": "./dist/manifest.js"
|
|
35
36
|
},
|
|
36
|
-
"./manifest.json": "./dist/manifest.json"
|
|
37
|
+
"./manifest.json": "./dist/manifest.json",
|
|
38
|
+
"./commerce": {
|
|
39
|
+
"types": "./dist/src/commerce.d.ts",
|
|
40
|
+
"import": "./dist/commerce.js",
|
|
41
|
+
"default": "./dist/commerce.js"
|
|
42
|
+
}
|
|
37
43
|
},
|
|
38
44
|
"publishConfig": {
|
|
39
45
|
"access": "public"
|
|
@@ -49,17 +55,22 @@
|
|
|
49
55
|
"url": "https://github.com/absolutejs/mcp/issues"
|
|
50
56
|
},
|
|
51
57
|
"files": [
|
|
52
|
-
"
|
|
58
|
+
"CHANGELOG.md",
|
|
59
|
+
"LICENSE",
|
|
53
60
|
"README.md",
|
|
54
|
-
"
|
|
61
|
+
"changelog.json",
|
|
62
|
+
"dist",
|
|
63
|
+
"docs/commerce-host-rules.md"
|
|
55
64
|
],
|
|
56
65
|
"scripts": {
|
|
57
|
-
"build": "rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --root ./src --target=bun --external @absolutejs/agency --external '@absolutejs/agency/*' --external elysia && tsc --emitDeclarationOnly --project tsconfig.json && absolute-manifest emit",
|
|
66
|
+
"build": "rm -rf dist && bun build src/index.ts src/manifest.ts src/commerce.ts --outdir dist --root ./src --target=bun --external @absolutejs/agency --external '@absolutejs/agency/*' --external elysia && tsc --emitDeclarationOnly --project tsconfig.json && absolute-manifest emit",
|
|
58
67
|
"format": "prettier --write \"./**/*.{ts,json,md}\"",
|
|
59
68
|
"release": "bun run format && bun run test && bun run build && bun publish",
|
|
60
69
|
"test": "bun test",
|
|
61
|
-
"typecheck": "tsc --noEmit --project tsconfig.json"
|
|
70
|
+
"typecheck": "tsc --noEmit --project tsconfig.json",
|
|
71
|
+
"check:package": "absolute-changelog check",
|
|
72
|
+
"prepublishOnly": "bun run check:package"
|
|
62
73
|
},
|
|
63
74
|
"types": "./dist/src/index.d.ts",
|
|
64
|
-
"version": "0.
|
|
75
|
+
"version": "0.13.0"
|
|
65
76
|
}
|