@decionis/mcp 0.1.0 → 0.1.2
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/LICENSE +199 -10
- package/README.md +19 -1
- package/dist/AgentHookCli.js +2 -2
- package/dist/ManagedAgentHookCli.js +835 -26
- package/dist/agent/AgentIndex.js +2 -2
- package/dist/{chunk-UN67W5FH.js → chunk-2C62WFX2.js} +2 -2
- package/dist/{chunk-QSCP7MRQ.js → chunk-KY5AVRL6.js} +836 -27
- package/dist/chunk-KY5AVRL6.js.map +1 -0
- package/dist/index.js +35 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/dist/chunk-QSCP7MRQ.js.map +0 -1
- /package/dist/{chunk-UN67W5FH.js.map → chunk-2C62WFX2.js.map} +0 -0
|
@@ -36770,7 +36770,7 @@ var MCP_PROTOCOL_VERSIONS = [
|
|
|
36770
36770
|
"2025-03-26",
|
|
36771
36771
|
"2024-11-05"
|
|
36772
36772
|
];
|
|
36773
|
-
var MCP_DEFAULT_PROTOCOL_VERSION = "2025-
|
|
36773
|
+
var MCP_DEFAULT_PROTOCOL_VERSION = "2025-11-25";
|
|
36774
36774
|
var DEFAULT_PUBLIC_BASE_URL = "https://protocol.decionis.com";
|
|
36775
36775
|
var MCP_HTTP_PATHS = ["/mcp", "/v1/protocol/mcp"];
|
|
36776
36776
|
|
|
@@ -36974,7 +36974,7 @@ var McpAuthGuard = class {
|
|
|
36974
36974
|
return auth?.kind === "org_api_key";
|
|
36975
36975
|
}
|
|
36976
36976
|
static findTargetOrgIdForTool(name, args) {
|
|
36977
|
-
if (name === "decionis.evaluate_decision" || name === "evaluate_decision" || name === "decionis.agentic_checkout_authorize" || name === "agentic_checkout_authorize" || name === "decionis.evaluate_webex_agent_intent" || name === "evaluate_webex_agent_intent" || name === "decionis.get_decision_dossier" || name === "get_decision_dossier" || name === "decionis.list_enforcement_rollouts" || name === "list_enforcement_rollouts" || name === "decionis.upsert_enforcement_rollout" || name === "upsert_enforcement_rollout" || name === "decionis.resolve_vertical_pack" || name === "resolve_vertical_pack" || name === "decionis.run_shadow_decisioning" || name === "run_shadow_decisioning") {
|
|
36977
|
+
if (name === "decionis.evaluate_decision" || name === "evaluate_decision" || name === "decionis.agentic_checkout_authorize" || name === "agentic_checkout_authorize" || name === "decionis.evaluate_webex_agent_intent" || name === "evaluate_webex_agent_intent" || name === "decionis.get_decision_dossier" || name === "get_decision_dossier" || name === "decionis.get_decision_chain" || name === "get_decision_chain" || name === "decionis.list_enforcement_rollouts" || name === "list_enforcement_rollouts" || name === "decionis.upsert_enforcement_rollout" || name === "upsert_enforcement_rollout" || name === "decionis.resolve_vertical_pack" || name === "resolve_vertical_pack" || name === "decionis.run_shadow_decisioning" || name === "run_shadow_decisioning") {
|
|
36978
36978
|
return asString(args.org_id);
|
|
36979
36979
|
}
|
|
36980
36980
|
return null;
|
|
@@ -36983,7 +36983,7 @@ var McpAuthGuard = class {
|
|
|
36983
36983
|
if (name === "decionis.evaluate_decision" || name === "evaluate_decision" || name === "decionis.agentic_checkout_authorize" || name === "agentic_checkout_authorize" || name === "decionis.evaluate_webex_agent_intent" || name === "evaluate_webex_agent_intent" || name === "decionis.run_shadow_decisioning" || name === "run_shadow_decisioning") {
|
|
36984
36984
|
return ["decision:run", "decision:*", "org:*"];
|
|
36985
36985
|
}
|
|
36986
|
-
if (name === "decionis.get_decision_dossier" || name === "get_decision_dossier" || name === "decionis.list_enforcement_rollouts" || name === "list_enforcement_rollouts" || name === "decionis.resolve_vertical_pack" || name === "resolve_vertical_pack") {
|
|
36986
|
+
if (name === "decionis.get_decision_dossier" || name === "get_decision_dossier" || name === "decionis.get_decision_chain" || name === "get_decision_chain" || name === "decionis.list_enforcement_rollouts" || name === "list_enforcement_rollouts" || name === "decionis.resolve_vertical_pack" || name === "resolve_vertical_pack") {
|
|
36987
36987
|
return ["decision:read", "org:read", "decision:*", "org:*"];
|
|
36988
36988
|
}
|
|
36989
36989
|
if (name === "decionis.upsert_enforcement_rollout" || name === "upsert_enforcement_rollout") {
|
|
@@ -37080,6 +37080,539 @@ function authorizeResourceRead(auth, uri) {
|
|
|
37080
37080
|
// ../protocol/src/mcp/McpRoutes.ts
|
|
37081
37081
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
37082
37082
|
|
|
37083
|
+
// ../../packages/shared/src/Connectors/ConnectorRegistry.ts
|
|
37084
|
+
var SITE = "https://decionis.com";
|
|
37085
|
+
var connectors = [
|
|
37086
|
+
// ── Commerce ──────────────────────────────────────────────────────────
|
|
37087
|
+
{
|
|
37088
|
+
// Live Shopify App Store listing (sweep 2026-08-10, also pinned by
|
|
37089
|
+
// apps/web ShopifyAppStore.listingUrl + the distributionSameAs sweep).
|
|
37090
|
+
// Copy scoped to the published listing description.
|
|
37091
|
+
slug: "shopify",
|
|
37092
|
+
name: "Decionis for Shopify",
|
|
37093
|
+
vendor: "Shopify",
|
|
37094
|
+
category: "commerce",
|
|
37095
|
+
status: "production",
|
|
37096
|
+
summary: "Deterministic policy enforcement on refunds, discounts, oversells, and risky orders at Shopify checkout \u2014 every governed action becomes a signed Decision Dossier with a public verification link.",
|
|
37097
|
+
capabilities: [
|
|
37098
|
+
"margin-floor-enforcement",
|
|
37099
|
+
"checkout-policy-enforcement",
|
|
37100
|
+
"signed-decision-dossier"
|
|
37101
|
+
],
|
|
37102
|
+
decisionsSupported: ["refund", "discount", "oversell", "risky-order"],
|
|
37103
|
+
installation: [
|
|
37104
|
+
{
|
|
37105
|
+
kind: "marketplace",
|
|
37106
|
+
url: "https://apps.shopify.com/decionis-checkout-gate",
|
|
37107
|
+
label: "Shopify App Store"
|
|
37108
|
+
}
|
|
37109
|
+
],
|
|
37110
|
+
// Shopify predates the marketplace-target program (it is the original
|
|
37111
|
+
// commerce wedge with its own app workspace), so it deliberately has no
|
|
37112
|
+
// `marketplaceTarget` join — /commerce is its owning page.
|
|
37113
|
+
documentation: `${SITE}/commerce`,
|
|
37114
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
37115
|
+
activation: { method: "marketplace_install", requiresWorkspace: true },
|
|
37116
|
+
presenceSupport: "planned",
|
|
37117
|
+
marketplaceListingId: "shopify-app",
|
|
37118
|
+
providerId: "SHOPIFY"
|
|
37119
|
+
},
|
|
37120
|
+
{
|
|
37121
|
+
// Published in the WordPress.org plugin directory (slug `decionis`,
|
|
37122
|
+
// 1.0.0) — sweep 2026-08-10 via the distributionSameAs verification.
|
|
37123
|
+
// Copy reuses the shared readiness provenance: verified end to end on a
|
|
37124
|
+
// staging store before the listing went live; shadow first,
|
|
37125
|
+
// enforcement opt-in.
|
|
37126
|
+
slug: "woo",
|
|
37127
|
+
name: "Decionis for WooCommerce",
|
|
37128
|
+
vendor: "WooCommerce",
|
|
37129
|
+
category: "commerce",
|
|
37130
|
+
status: "production",
|
|
37131
|
+
version: "1.0.0",
|
|
37132
|
+
summary: "Margin floors enforced at WooCommerce checkout \u2014 Block and classic, using core COGS, with a signed Decision Dossier per evaluation. New stores start in shadow mode; enforcement is opt-in.",
|
|
37133
|
+
capabilities: [
|
|
37134
|
+
"margin-floor-enforcement",
|
|
37135
|
+
"checkout-policy-enforcement",
|
|
37136
|
+
"shadow-mode",
|
|
37137
|
+
"signed-decision-dossier"
|
|
37138
|
+
],
|
|
37139
|
+
decisionsSupported: ["checkout-order"],
|
|
37140
|
+
installation: [
|
|
37141
|
+
{
|
|
37142
|
+
kind: "marketplace",
|
|
37143
|
+
url: "https://wordpress.org/plugins/decionis/",
|
|
37144
|
+
label: "WordPress.org Plugin Directory"
|
|
37145
|
+
}
|
|
37146
|
+
],
|
|
37147
|
+
documentation: `${SITE}/marketplace/woo`,
|
|
37148
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
37149
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
37150
|
+
presenceSupport: "planned",
|
|
37151
|
+
marketplaceTarget: "woo",
|
|
37152
|
+
marketplaceListingId: "woo-plugin",
|
|
37153
|
+
providerId: "WOO"
|
|
37154
|
+
},
|
|
37155
|
+
{
|
|
37156
|
+
// eBay approved the app for production and the connector is deployed and
|
|
37157
|
+
// marketplace-account-deletion compliant; the first read-only Fulfillment
|
|
37158
|
+
// probe passed against a live seller account (docs/marketplace/ebay/
|
|
37159
|
+
// evidence/latest.json). No public eBay listing directory exists, so the
|
|
37160
|
+
// channel is the guided OAuth connect — and enforcement stays honest:
|
|
37161
|
+
// shadow dossiers today, write-scope approval pending.
|
|
37162
|
+
slug: "ebay",
|
|
37163
|
+
name: "Decionis for eBay",
|
|
37164
|
+
vendor: "eBay",
|
|
37165
|
+
category: "commerce",
|
|
37166
|
+
status: "installable",
|
|
37167
|
+
summary: "Margin and promo-hygiene guardrails for eBay Sell-API listings, orders, and promotions \u2014 eBay OAuth connect, production-approved, shadow-mode dossiers with enforcement pending write-scope approval.",
|
|
37168
|
+
capabilities: ["margin-guardrails", "promo-hygiene", "shadow-mode", "signed-decision-dossier"],
|
|
37169
|
+
decisionsSupported: ["listing-change", "order-fulfillment", "promotion"],
|
|
37170
|
+
installation: [
|
|
37171
|
+
{
|
|
37172
|
+
kind: "guided",
|
|
37173
|
+
url: `${SITE}/marketplace/ebay`,
|
|
37174
|
+
label: "eBay OAuth connect (guided)"
|
|
37175
|
+
}
|
|
37176
|
+
],
|
|
37177
|
+
documentation: `${SITE}/marketplace/ebay`,
|
|
37178
|
+
verification: {
|
|
37179
|
+
validatedBy: "eBay production approval + Decionis live verification",
|
|
37180
|
+
evidence: "eBay approved the app for production; read-only Fulfillment probe verified against a live seller account (docs/marketplace/ebay/evidence/latest.json, deployment 2026-07-14).",
|
|
37181
|
+
lastValidated: "2026-07-14"
|
|
37182
|
+
},
|
|
37183
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
37184
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37185
|
+
presenceSupport: "planned",
|
|
37186
|
+
marketplaceTarget: "ebay",
|
|
37187
|
+
providerId: "EBAY"
|
|
37188
|
+
},
|
|
37189
|
+
{
|
|
37190
|
+
// Passed ALL Adobe Commerce Marketplace technical review phases (SID
|
|
37191
|
+
// qv4l7d2ak6): automated EQP 2026-07-08, full technical-review
|
|
37192
|
+
// confirmation received 2026-08-10 (tested by Adobe on Magento 2.4.9
|
|
37193
|
+
// EE + CE, PHP 8.5.5). Marketplace release awaits the remaining
|
|
37194
|
+
// marketing review, and the gate has not been validated against a live
|
|
37195
|
+
// merchant store — so no channels yet; the customer-deployable kit
|
|
37196
|
+
// ships next (docs/claims DECIONIS-CLM-022).
|
|
37197
|
+
slug: "adobe-commerce",
|
|
37198
|
+
name: "Decionis Connector for Adobe Commerce",
|
|
37199
|
+
vendor: "Adobe",
|
|
37200
|
+
category: "commerce",
|
|
37201
|
+
status: "validated",
|
|
37202
|
+
version: "1.0.0",
|
|
37203
|
+
summary: "Synchronous checkout-webhook enforcement for Adobe Commerce / Magento \u2014 halts a margin-breaching order (op:exception) or lets it through, failing open on any engine error, with promo-hygiene checks and federated signed Decision Dossiers.",
|
|
37204
|
+
capabilities: [
|
|
37205
|
+
"margin-floor-enforcement",
|
|
37206
|
+
"checkout-policy-enforcement",
|
|
37207
|
+
"promo-hygiene",
|
|
37208
|
+
"fail-open-checkout-gate",
|
|
37209
|
+
"signed-decision-dossier"
|
|
37210
|
+
],
|
|
37211
|
+
decisionsSupported: ["checkout-order", "pricing-change", "promotion"],
|
|
37212
|
+
installation: [
|
|
37213
|
+
{
|
|
37214
|
+
// The kit page hosts the reviewed composer module + checksum,
|
|
37215
|
+
// manifest, and SBOM — shipped in the same change that makes the URL
|
|
37216
|
+
// resolve (rule 1.1 by construction).
|
|
37217
|
+
kind: "hosted_download",
|
|
37218
|
+
url: `${SITE}/marketplace/adobe-commerce/connector-kit`,
|
|
37219
|
+
label: "Connector kit (guided deployment)"
|
|
37220
|
+
}
|
|
37221
|
+
],
|
|
37222
|
+
package: {
|
|
37223
|
+
artifact: "/marketplace/adobe-commerce/connector-kit/decionis-module-checkout-guardrail-1.0.0.zip",
|
|
37224
|
+
sha256Path: "/marketplace/adobe-commerce/connector-kit/decionis-module-checkout-guardrail-1.0.0.sha256.txt",
|
|
37225
|
+
manifestPath: "/marketplace/adobe-commerce/connector-kit/manifest.json",
|
|
37226
|
+
sbomPath: "/marketplace/adobe-commerce/connector-kit/SBOM.json",
|
|
37227
|
+
format: "magento2-module"
|
|
37228
|
+
},
|
|
37229
|
+
documentation: `${SITE}/marketplace/adobe-commerce`,
|
|
37230
|
+
verification: {
|
|
37231
|
+
validatedBy: "Adobe Commerce Marketplace technical review (EQP)",
|
|
37232
|
+
evidence: "Passed all technical review phases (SID qv4l7d2ak6): automated EQP pass 2026-07-08, full technical-review confirmation 2026-08-10, tested by Adobe on Magento 2.4.9 Enterprise + Community Edition (PHP 8.5.5). Not yet validated against a live merchant store.",
|
|
37233
|
+
lastValidated: "2026-08-10"
|
|
37234
|
+
},
|
|
37235
|
+
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
37236
|
+
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
37237
|
+
presenceSupport: "planned",
|
|
37238
|
+
marketplaceTarget: "adobe-commerce",
|
|
37239
|
+
providerId: "ADOBE_COMMERCE"
|
|
37240
|
+
},
|
|
37241
|
+
{
|
|
37242
|
+
// SP-API connector built and unit-tested; shadow-mode first while live
|
|
37243
|
+
// seller validation completes (homepage Beta tile is the owning copy).
|
|
37244
|
+
slug: "amazon",
|
|
37245
|
+
name: "Decionis for Amazon",
|
|
37246
|
+
vendor: "Amazon",
|
|
37247
|
+
category: "commerce",
|
|
37248
|
+
status: "validated",
|
|
37249
|
+
summary: "Margin and pricing guardrails for Amazon SP-API listings and orders \u2014 Login with Amazon connect, shadow-mode first while live seller validation completes.",
|
|
37250
|
+
capabilities: ["margin-guardrails", "shadow-mode", "signed-decision-dossier"],
|
|
37251
|
+
decisionsSupported: ["listing-change", "order"],
|
|
37252
|
+
installation: [],
|
|
37253
|
+
documentation: `${SITE}/marketplace/amazon`,
|
|
37254
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37255
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37256
|
+
presenceSupport: "planned",
|
|
37257
|
+
marketplaceTarget: "amazon",
|
|
37258
|
+
providerId: "AMAZON"
|
|
37259
|
+
},
|
|
37260
|
+
{
|
|
37261
|
+
// Post-purchase fulfillment circuit breaker — OAuth + refresh, signed
|
|
37262
|
+
// Open API, webhook intake/verification, margin gate, Ship-Package
|
|
37263
|
+
// release built and unit-tested; TikTok App Store review not submitted
|
|
37264
|
+
// (shared readiness provenance).
|
|
37265
|
+
slug: "tiktok",
|
|
37266
|
+
name: "Decionis for TikTok Shop",
|
|
37267
|
+
vendor: "TikTok Shop",
|
|
37268
|
+
category: "commerce",
|
|
37269
|
+
status: "validated",
|
|
37270
|
+
summary: "Post-purchase fulfillment circuit breaker for TikTok Shop \u2014 orders clear a margin gate before Ship-Package release, with signed Decision Dossiers per governed order.",
|
|
37271
|
+
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
37272
|
+
decisionsSupported: ["order-fulfillment"],
|
|
37273
|
+
installation: [],
|
|
37274
|
+
documentation: `${SITE}/marketplace/tiktok`,
|
|
37275
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37276
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37277
|
+
presenceSupport: "planned",
|
|
37278
|
+
marketplaceTarget: "tiktok",
|
|
37279
|
+
providerId: "TIKTOK_SHOP"
|
|
37280
|
+
},
|
|
37281
|
+
{
|
|
37282
|
+
// Solution Provider OAuth, PO-created webhook intake with HMAC
|
|
37283
|
+
// verification, margin gate, Acknowledge-Order release/hold — built and
|
|
37284
|
+
// unit-tested; Solution Provider approval and live seller verification
|
|
37285
|
+
// remain (shared readiness provenance).
|
|
37286
|
+
slug: "walmart",
|
|
37287
|
+
name: "Decionis for Walmart Marketplace",
|
|
37288
|
+
vendor: "Walmart",
|
|
37289
|
+
category: "commerce",
|
|
37290
|
+
status: "validated",
|
|
37291
|
+
summary: "Post-purchase fulfillment circuit breaker for Walmart Marketplace \u2014 purchase orders clear a margin gate (COGS + referral fee + shipping) before Acknowledge-Order release.",
|
|
37292
|
+
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
37293
|
+
decisionsSupported: ["order-acknowledgement"],
|
|
37294
|
+
installation: [],
|
|
37295
|
+
documentation: `${SITE}/marketplace/walmart`,
|
|
37296
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37297
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37298
|
+
presenceSupport: "planned",
|
|
37299
|
+
marketplaceTarget: "walmart",
|
|
37300
|
+
providerId: "WALMART_MARKETPLACE"
|
|
37301
|
+
},
|
|
37302
|
+
{
|
|
37303
|
+
// Vendor Center GOP integration — centralized Mastershop OAuth, durable
|
|
37304
|
+
// order polling, multi-market margin/COD/SLA evaluation, guarded
|
|
37305
|
+
// fulfillment; live Vendor Center verification still required before
|
|
37306
|
+
// enforcement (shared readiness provenance).
|
|
37307
|
+
slug: "jumia",
|
|
37308
|
+
name: "Decionis for Jumia",
|
|
37309
|
+
vendor: "Jumia",
|
|
37310
|
+
category: "commerce",
|
|
37311
|
+
status: "validated",
|
|
37312
|
+
summary: "Guarded fulfillment for Jumia Vendor Center \u2014 multi-market margin, COD, and SLA evaluation before order release, with signed Decision Dossiers per governed order.",
|
|
37313
|
+
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
37314
|
+
decisionsSupported: ["order-fulfillment"],
|
|
37315
|
+
installation: [],
|
|
37316
|
+
documentation: `${SITE}/marketplace/jumia`,
|
|
37317
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37318
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37319
|
+
presenceSupport: "planned",
|
|
37320
|
+
marketplaceTarget: "jumia",
|
|
37321
|
+
providerId: "JUMIA"
|
|
37322
|
+
},
|
|
37323
|
+
{
|
|
37324
|
+
// Headless / Open Checkout gate built and unit-tested; not live-store
|
|
37325
|
+
// validated (rotated off the homepage tiles in favour of WooCommerce).
|
|
37326
|
+
slug: "bigcommerce",
|
|
37327
|
+
name: "Decionis for BigCommerce",
|
|
37328
|
+
vendor: "BigCommerce",
|
|
37329
|
+
category: "commerce",
|
|
37330
|
+
status: "validated",
|
|
37331
|
+
summary: "Checkout margin gate for BigCommerce headless and Open Checkout storefronts \u2014 built and unit-tested, pending validation against a live store.",
|
|
37332
|
+
capabilities: ["margin-floor-enforcement", "checkout-policy-enforcement"],
|
|
37333
|
+
decisionsSupported: ["checkout-order"],
|
|
37334
|
+
installation: [],
|
|
37335
|
+
documentation: `${SITE}/marketplace/bigcommerce`,
|
|
37336
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37337
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
37338
|
+
presenceSupport: "planned",
|
|
37339
|
+
marketplaceTarget: "bigcommerce"
|
|
37340
|
+
},
|
|
37341
|
+
{
|
|
37342
|
+
// Shopware 6 App System handshake, shop-signed webhooks, fail-open
|
|
37343
|
+
// synchronous checkout gate — built and unit-tested, not yet validated
|
|
37344
|
+
// against a live Shopware store (docs/claims DECIONIS-CLM-023).
|
|
37345
|
+
slug: "shopware",
|
|
37346
|
+
name: "Decionis for Shopware",
|
|
37347
|
+
vendor: "Shopware",
|
|
37348
|
+
category: "commerce",
|
|
37349
|
+
status: "validated",
|
|
37350
|
+
summary: "Fail-open synchronous checkout gate for Shopware 6 \u2014 App System registration handshake, shop-signed webhooks, and promo-hygiene checks, pending validation against a live store.",
|
|
37351
|
+
capabilities: [
|
|
37352
|
+
"margin-floor-enforcement",
|
|
37353
|
+
"checkout-policy-enforcement",
|
|
37354
|
+
"promo-hygiene",
|
|
37355
|
+
"fail-open-checkout-gate"
|
|
37356
|
+
],
|
|
37357
|
+
decisionsSupported: ["checkout-order", "promotion"],
|
|
37358
|
+
installation: [],
|
|
37359
|
+
documentation: `${SITE}/marketplace/shopware`,
|
|
37360
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37361
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
37362
|
+
presenceSupport: "planned",
|
|
37363
|
+
marketplaceTarget: "shopware"
|
|
37364
|
+
},
|
|
37365
|
+
// ── Enterprise ────────────────────────────────────────────────────────
|
|
37366
|
+
{
|
|
37367
|
+
// SAP PartnerEdge Solution Review approved 2026-06-22 (solution id
|
|
37368
|
+
// 2004368, docs/marketplace/sap/solution-hub-listing.md). The PartnerEdge
|
|
37369
|
+
// solution URL is partner-gated (anonymous fetch 404s — sweep
|
|
37370
|
+
// 2026-08-10), so it is deliberately NOT an install channel here; the
|
|
37371
|
+
// customer-deployable BTP deployment kit ships next. Dual-gate wording
|
|
37372
|
+
// from the owning listing copy.
|
|
37373
|
+
slug: "sap",
|
|
37374
|
+
name: "Decionis Governed Execution Gate for SAP",
|
|
37375
|
+
vendor: "SAP",
|
|
37376
|
+
category: "enterprise",
|
|
37377
|
+
status: "validated",
|
|
37378
|
+
version: "0.1.0",
|
|
37379
|
+
summary: "Dual-gate governed execution for SAP S/4HANA, BTP, and CAP-side workflows \u2014 vendor payment release, procurement approval, and finance controls checked before they execute, with a signed Decision Dossier written back to the governed document.",
|
|
37380
|
+
capabilities: [
|
|
37381
|
+
"dual-gate-execution",
|
|
37382
|
+
"segregation-of-duties",
|
|
37383
|
+
"three-way-match",
|
|
37384
|
+
"s4hana-write-back",
|
|
37385
|
+
"signed-decision-dossier"
|
|
37386
|
+
],
|
|
37387
|
+
decisionsSupported: [
|
|
37388
|
+
"vendor-payment-release",
|
|
37389
|
+
"procurement-approval",
|
|
37390
|
+
"finance-control-change"
|
|
37391
|
+
],
|
|
37392
|
+
installation: [
|
|
37393
|
+
{
|
|
37394
|
+
// Customer-deployed BTP kit (curated CAP source, mbt build →
|
|
37395
|
+
// cf deploy) — shipped in the same change that makes the URL resolve
|
|
37396
|
+
// (rule 1.1 by construction).
|
|
37397
|
+
kind: "hosted_download",
|
|
37398
|
+
url: `${SITE}/marketplace/sap/deployment-kit`,
|
|
37399
|
+
label: "SAP BTP deployment kit (customer-deployed)"
|
|
37400
|
+
}
|
|
37401
|
+
],
|
|
37402
|
+
package: {
|
|
37403
|
+
artifact: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.zip",
|
|
37404
|
+
sha256Path: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.sha256.txt",
|
|
37405
|
+
manifestPath: "/marketplace/sap/deployment-kit/manifest.json",
|
|
37406
|
+
sbomPath: "/marketplace/sap/deployment-kit/SBOM.json",
|
|
37407
|
+
format: "sap-mta-deployment-kit"
|
|
37408
|
+
},
|
|
37409
|
+
documentation: `${SITE}/marketplace/sap`,
|
|
37410
|
+
verification: {
|
|
37411
|
+
validatedBy: "SAP PartnerEdge Solution Review",
|
|
37412
|
+
evidence: "Solution Review completed and approved 2026-06-22 (SAP PartnerEdge solution id 2004368); SAP Store content listing is the next, contract-gated step.",
|
|
37413
|
+
lastValidated: "2026-06-22"
|
|
37414
|
+
},
|
|
37415
|
+
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
37416
|
+
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
37417
|
+
presenceSupport: "planned",
|
|
37418
|
+
providerId: "SAP"
|
|
37419
|
+
},
|
|
37420
|
+
{
|
|
37421
|
+
// Scoped app x_dec_decionis (tables, script includes, Flow Designer
|
|
37422
|
+
// verify-intent action, shadow observers, workspace dossier panel,
|
|
37423
|
+
// scoped REST API). Self-attested platform evidence — tenant mapping,
|
|
37424
|
+
// ACLs, live policy-check execution, workflow trigger routing — is
|
|
37425
|
+
// recorded in the packaged evidence exports (docs/marketplace/servicenow
|
|
37426
|
+
// submission checklist, evidence refreshed as of the 2026-08-10 sweep).
|
|
37427
|
+
// Store publication deliberately deferred. The customer-deploy kit
|
|
37428
|
+
// CONTENT exists (full-app update-set XML + coverage manifest + INSTALL
|
|
37429
|
+
// under docs/marketplace/servicenow/connector-kit), but the public
|
|
37430
|
+
// download channel + `installable` flip are gated on a real
|
|
37431
|
+
// dev-instance import validation — a user-owned step; never claim the
|
|
37432
|
+
// install before it passes (rule 1.1 on the install claim itself).
|
|
37433
|
+
slug: "servicenow",
|
|
37434
|
+
name: "Decionis Connector for ServiceNow",
|
|
37435
|
+
vendor: "ServiceNow",
|
|
37436
|
+
category: "enterprise",
|
|
37437
|
+
status: "validated",
|
|
37438
|
+
summary: "Scoped ServiceNow app (x_dec_decionis) that wires Decision Dossiers and Decision Drift evidence into incident, change, and risk-case workflows \u2014 a Flow Designer verify-intent action with shadow-mode observers.",
|
|
37439
|
+
capabilities: [
|
|
37440
|
+
"flow-designer-verify-intent",
|
|
37441
|
+
"shadow-mode",
|
|
37442
|
+
"decision-drift-evidence",
|
|
37443
|
+
"signed-decision-dossier"
|
|
37444
|
+
],
|
|
37445
|
+
decisionsSupported: ["itsm-change", "incident-action", "risk-case-action"],
|
|
37446
|
+
installation: [],
|
|
37447
|
+
documentation: `${SITE}/marketplace/servicenow`,
|
|
37448
|
+
verification: {
|
|
37449
|
+
validatedBy: "Decionis platform evidence (self-attested)",
|
|
37450
|
+
evidence: "Live vendor-instance evidence exports: tenant mapping, ACLs and ACL-role links, live policy-check execution against the authenticated Decionis API, and workflow trigger routing (docs/marketplace/servicenow, evidence current as of 2026-08-10).",
|
|
37451
|
+
lastValidated: "2026-08-10"
|
|
37452
|
+
},
|
|
37453
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37454
|
+
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
37455
|
+
presenceSupport: "planned",
|
|
37456
|
+
marketplaceTarget: "servicenow",
|
|
37457
|
+
providerId: "SERVICENOW"
|
|
37458
|
+
},
|
|
37459
|
+
{
|
|
37460
|
+
// Customer-deployed starter package (Apex Action Gate, LWC, platform
|
|
37461
|
+
// event, permission set) served as committed zips with checksums;
|
|
37462
|
+
// AppExchange Security Review in progress, so no marketplace channel is
|
|
37463
|
+
// claimed (homepage Beta tile is the owning copy).
|
|
37464
|
+
slug: "salesforce",
|
|
37465
|
+
name: "Decionis Action Gate for Salesforce",
|
|
37466
|
+
vendor: "Salesforce",
|
|
37467
|
+
category: "enterprise",
|
|
37468
|
+
status: "installable",
|
|
37469
|
+
summary: "Pre-execution Action Gate for Salesforce \u2014 Flow, Apex, and Agentforce actions checked before they run (allow / hold / escalate) with signed Decision Dossiers on the record. Customer-deployed starter package, shadow-first rollout.",
|
|
37470
|
+
capabilities: [
|
|
37471
|
+
"pre-execution-action-gate",
|
|
37472
|
+
"shadow-mode",
|
|
37473
|
+
"agentforce-governance",
|
|
37474
|
+
"signed-decision-dossier"
|
|
37475
|
+
],
|
|
37476
|
+
decisionsSupported: ["flow-action", "apex-action", "agentforce-action"],
|
|
37477
|
+
installation: [
|
|
37478
|
+
{
|
|
37479
|
+
kind: "hosted_download",
|
|
37480
|
+
url: `${SITE}/marketplace/salesforce/starter-package`,
|
|
37481
|
+
label: "Salesforce starter package (customer-deployed)"
|
|
37482
|
+
}
|
|
37483
|
+
],
|
|
37484
|
+
package: {
|
|
37485
|
+
artifact: "/marketplace/salesforce/starter-package/decionis-salesforce-starter-package.zip",
|
|
37486
|
+
sha256Path: "/marketplace/salesforce/starter-package/decionis-salesforce-starter-package.sha256.txt",
|
|
37487
|
+
format: "salesforce-metadata-source"
|
|
37488
|
+
},
|
|
37489
|
+
documentation: `${SITE}/marketplace/salesforce`,
|
|
37490
|
+
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
37491
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
37492
|
+
presenceSupport: "planned",
|
|
37493
|
+
marketplaceTarget: "salesforce",
|
|
37494
|
+
marketplaceListingId: "salesforce-app",
|
|
37495
|
+
providerId: "SALESFORCE"
|
|
37496
|
+
},
|
|
37497
|
+
// ── Automation ────────────────────────────────────────────────────────
|
|
37498
|
+
{
|
|
37499
|
+
// Live Zapier app-directory listing (sweep 2026-08-10: page resolves and
|
|
37500
|
+
// shows the Decionis app with the Create Decision Dossier action).
|
|
37501
|
+
slug: "zapier",
|
|
37502
|
+
name: "Decionis for Zapier",
|
|
37503
|
+
vendor: "Zapier",
|
|
37504
|
+
category: "automation",
|
|
37505
|
+
status: "production",
|
|
37506
|
+
summary: "Create a governed decision and signed Decision Dossier inside any Zap \u2014 OAuth connection, Shadow Mode by default, and idempotent replay for temporary service failures.",
|
|
37507
|
+
capabilities: ["automation-step-governance", "shadow-mode", "signed-decision-dossier"],
|
|
37508
|
+
decisionsSupported: ["automation-step"],
|
|
37509
|
+
installation: [
|
|
37510
|
+
{
|
|
37511
|
+
kind: "marketplace",
|
|
37512
|
+
url: "https://zapier.com/apps/decionis/integrations",
|
|
37513
|
+
label: "Zapier app directory"
|
|
37514
|
+
}
|
|
37515
|
+
],
|
|
37516
|
+
documentation: `${SITE}/docs/zapier`,
|
|
37517
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
37518
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37519
|
+
presenceSupport: "planned",
|
|
37520
|
+
marketplaceListingId: "zapier"
|
|
37521
|
+
},
|
|
37522
|
+
{
|
|
37523
|
+
// The native Make app is built with its OAuth on-ramp live, but the Make
|
|
37524
|
+
// listing is private in review — so the installable path today is the
|
|
37525
|
+
// documented HTTP recipe (AutomationConnectors owning copy, status
|
|
37526
|
+
// `preview`).
|
|
37527
|
+
slug: "make",
|
|
37528
|
+
name: "Decionis for Make",
|
|
37529
|
+
vendor: "Make",
|
|
37530
|
+
category: "automation",
|
|
37531
|
+
status: "installable",
|
|
37532
|
+
summary: "Evaluate an Action before the protected module runs \u2014 the native Decionis app is in Make listing review, and the documented HTTP recipe calls the same gate and returns the same signed Decision Dossier today.",
|
|
37533
|
+
capabilities: ["automation-step-governance", "signed-decision-dossier"],
|
|
37534
|
+
decisionsSupported: ["automation-step"],
|
|
37535
|
+
installation: [
|
|
37536
|
+
{
|
|
37537
|
+
kind: "docs",
|
|
37538
|
+
url: `${SITE}/docs/automation-connectors#make`,
|
|
37539
|
+
label: "HTTP recipe (native app listing in review)"
|
|
37540
|
+
}
|
|
37541
|
+
],
|
|
37542
|
+
documentation: `${SITE}/docs/automation-connectors#make`,
|
|
37543
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37544
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
37545
|
+
presenceSupport: "planned"
|
|
37546
|
+
},
|
|
37547
|
+
{
|
|
37548
|
+
// Community node published on npm (registry sweep 2026-08-10:
|
|
37549
|
+
// n8n-nodes-decionis@0.1.0).
|
|
37550
|
+
slug: "n8n",
|
|
37551
|
+
name: "Decionis for n8n",
|
|
37552
|
+
vendor: "n8n",
|
|
37553
|
+
category: "automation",
|
|
37554
|
+
status: "production",
|
|
37555
|
+
version: "0.1.0",
|
|
37556
|
+
summary: "Every automation step asks permission before it executes \u2014 install the n8n community node from npm, or start from the HTTP Request recipe and four importable example workflows.",
|
|
37557
|
+
capabilities: ["automation-step-governance", "signed-decision-dossier"],
|
|
37558
|
+
decisionsSupported: ["automation-step"],
|
|
37559
|
+
installation: [
|
|
37560
|
+
{
|
|
37561
|
+
kind: "npm",
|
|
37562
|
+
url: "https://www.npmjs.com/package/n8n-nodes-decionis",
|
|
37563
|
+
label: "n8n community node on npm"
|
|
37564
|
+
}
|
|
37565
|
+
],
|
|
37566
|
+
documentation: `${SITE}/docs/automation-connectors#n8n`,
|
|
37567
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37568
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
37569
|
+
presenceSupport: "planned"
|
|
37570
|
+
},
|
|
37571
|
+
// ── Platform ──────────────────────────────────────────────────────────
|
|
37572
|
+
{
|
|
37573
|
+
// The standard webhook path into the protocol — the same Gate 1
|
|
37574
|
+
// admission check, any backend (owning copy: ERP & Webhooks tile +
|
|
37575
|
+
// /docs/webhooks).
|
|
37576
|
+
// `installable`, not `production`: the webhook path is live product
|
|
37577
|
+
// capability, but there is no public marketplace/registry listing to
|
|
37578
|
+
// install it from — you wire it from the documented recipe.
|
|
37579
|
+
slug: "webhooks",
|
|
37580
|
+
name: "ERP & Webhooks",
|
|
37581
|
+
vendor: "Any system of record",
|
|
37582
|
+
category: "platform",
|
|
37583
|
+
status: "installable",
|
|
37584
|
+
summary: "Cross-verify cost basis and inventory against your system of record via standard webhooks \u2014 the same Gate 1 admission check, any backend.",
|
|
37585
|
+
capabilities: ["erp-cross-verification", "webhook-intake"],
|
|
37586
|
+
decisionsSupported: ["cost-basis-verification", "inventory-verification"],
|
|
37587
|
+
installation: [
|
|
37588
|
+
{ kind: "docs", url: `${SITE}/docs/webhooks`, label: "Webhook integration guide" }
|
|
37589
|
+
],
|
|
37590
|
+
documentation: `${SITE}/docs/webhooks`,
|
|
37591
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
37592
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
37593
|
+
presenceSupport: "planned",
|
|
37594
|
+
providerId: "WEBHOOK"
|
|
37595
|
+
}
|
|
37596
|
+
];
|
|
37597
|
+
var ConnectorRegistry = class {
|
|
37598
|
+
static connectors = connectors;
|
|
37599
|
+
static bySlug(slug) {
|
|
37600
|
+
return connectors.find((connector) => connector.slug === slug);
|
|
37601
|
+
}
|
|
37602
|
+
static byCategory(category) {
|
|
37603
|
+
return connectors.filter((connector) => connector.category === category);
|
|
37604
|
+
}
|
|
37605
|
+
static byStatus(status) {
|
|
37606
|
+
return connectors.filter((connector) => connector.status === status);
|
|
37607
|
+
}
|
|
37608
|
+
static slugs() {
|
|
37609
|
+
return connectors.map((connector) => connector.slug);
|
|
37610
|
+
}
|
|
37611
|
+
};
|
|
37612
|
+
var CONNECTOR_REGISTRY = ConnectorRegistry.connectors;
|
|
37613
|
+
var getConnector = ConnectorRegistry.bySlug;
|
|
37614
|
+
var CONNECTOR_SLUGS = ConnectorRegistry.slugs();
|
|
37615
|
+
|
|
37083
37616
|
// ../protocol/src/mcp/McpResources.ts
|
|
37084
37617
|
var McpResources = class {
|
|
37085
37618
|
static buildStaticResources(publicBaseUrl, serviceName, serviceVersion) {
|
|
@@ -37119,6 +37652,13 @@ var McpResources = class {
|
|
|
37119
37652
|
description: "Available vertical packs and workflow overlays exposed by Decionis Protocol.",
|
|
37120
37653
|
mimeType: "application/json"
|
|
37121
37654
|
},
|
|
37655
|
+
{
|
|
37656
|
+
uri: "decionis://connectors/registry",
|
|
37657
|
+
name: "connector_registry",
|
|
37658
|
+
title: "Decionis Connector Registry",
|
|
37659
|
+
description: "Every Decionis connector with availability status, install channels, governed actions, and verification evidence \u2014 the same registry that generates decionis.com/integrations.",
|
|
37660
|
+
mimeType: "application/json"
|
|
37661
|
+
},
|
|
37122
37662
|
{
|
|
37123
37663
|
uri: "decionis://protocol/webex-mcp-registration",
|
|
37124
37664
|
name: "webex_mcp_registration",
|
|
@@ -37341,7 +37881,8 @@ var McpResources = class {
|
|
|
37341
37881
|
"resources/read -> decionis://protocol/webex-agent-intent-contract",
|
|
37342
37882
|
"resources/read -> decionis://protocol/webex-reviewer-scenarios",
|
|
37343
37883
|
"tools/call -> decionis.evaluate_webex_agent_intent",
|
|
37344
|
-
"tools/call -> decionis.get_decision_dossier"
|
|
37884
|
+
"tools/call -> decionis.get_decision_dossier",
|
|
37885
|
+
"tools/call -> decionis.get_decision_chain"
|
|
37345
37886
|
]
|
|
37346
37887
|
}
|
|
37347
37888
|
};
|
|
@@ -37367,10 +37908,34 @@ var McpResources = class {
|
|
|
37367
37908
|
});
|
|
37368
37909
|
return { mimeType: "application/json", value: response.body };
|
|
37369
37910
|
}
|
|
37911
|
+
if (uri === "decionis://connectors/registry") {
|
|
37912
|
+
return {
|
|
37913
|
+
mimeType: "application/json",
|
|
37914
|
+
value: {
|
|
37915
|
+
registry: "decionis-connectors",
|
|
37916
|
+
statuses: {
|
|
37917
|
+
production: "generally available today through a live public channel",
|
|
37918
|
+
installable: "customer-deployable today outside public marketplaces",
|
|
37919
|
+
validated: "built and verified (see each connector's verification); downloadable when a package is listed",
|
|
37920
|
+
planned: "roadmap; never carries install channels"
|
|
37921
|
+
},
|
|
37922
|
+
connectors: CONNECTOR_REGISTRY,
|
|
37923
|
+
human_catalogue: "https://decionis.com/integrations"
|
|
37924
|
+
}
|
|
37925
|
+
};
|
|
37926
|
+
}
|
|
37370
37927
|
const parsed = new URL(uri);
|
|
37371
37928
|
if (parsed.protocol !== "decionis:") {
|
|
37372
37929
|
throw new Error(`Unsupported resource URI '${uri}'`);
|
|
37373
37930
|
}
|
|
37931
|
+
if (parsed.hostname === "connectors") {
|
|
37932
|
+
const slug = decodeURIComponent(parsed.pathname.replace(/^\//, ""));
|
|
37933
|
+
const connector = getConnector(slug);
|
|
37934
|
+
if (!connector) {
|
|
37935
|
+
throw new Error(`Unknown connector '${slug}'`);
|
|
37936
|
+
}
|
|
37937
|
+
return { mimeType: "application/json", value: connector };
|
|
37938
|
+
}
|
|
37374
37939
|
if (parsed.hostname === "marketplaces" && parsed.pathname.startsWith("/targets/")) {
|
|
37375
37940
|
const target = decodeURIComponent(parsed.pathname.replace("/targets/", ""));
|
|
37376
37941
|
const response = await invokeProtocolRoute(app, {
|
|
@@ -37640,7 +38205,7 @@ var McpTools = class {
|
|
|
37640
38205
|
return cart && typeof cart.amount === "number" ? cart.amount : void 0;
|
|
37641
38206
|
}
|
|
37642
38207
|
static buildTools(app) {
|
|
37643
|
-
|
|
38208
|
+
const tools = [
|
|
37644
38209
|
{
|
|
37645
38210
|
name: "decionis.evaluate_decision",
|
|
37646
38211
|
aliases: ["evaluate_decision"],
|
|
@@ -37896,6 +38461,37 @@ var McpTools = class {
|
|
|
37896
38461
|
return response.body;
|
|
37897
38462
|
}
|
|
37898
38463
|
},
|
|
38464
|
+
{
|
|
38465
|
+
name: "decionis.get_decision_chain",
|
|
38466
|
+
aliases: ["get_decision_chain"],
|
|
38467
|
+
title: "Get Decision Chain",
|
|
38468
|
+
description: "Read the workflow lineage for linked Decionis decisions: the chain summary of evaluations, their outcomes, and the dossiers each sealed. The read-only status view for a multi-step workflow an agent is participating in.",
|
|
38469
|
+
inputSchema: {
|
|
38470
|
+
type: "object",
|
|
38471
|
+
required: ["org_id", "chain_id"],
|
|
38472
|
+
additionalProperties: false,
|
|
38473
|
+
properties: {
|
|
38474
|
+
org_id: { type: "string", description: "Org UUID." },
|
|
38475
|
+
chain_id: { type: "string", description: "Decision chain UUID." }
|
|
38476
|
+
}
|
|
38477
|
+
},
|
|
38478
|
+
outputSchema: { type: "object", additionalProperties: true },
|
|
38479
|
+
async handler(args) {
|
|
38480
|
+
const orgId = asString(args.org_id);
|
|
38481
|
+
const chainId = asString(args.chain_id);
|
|
38482
|
+
if (!orgId || !chainId) {
|
|
38483
|
+
throw new Error("org_id and chain_id are required");
|
|
38484
|
+
}
|
|
38485
|
+
const response = await invokeProtocolRoute(app, {
|
|
38486
|
+
method: "GET",
|
|
38487
|
+
url: `/v1/protocol/decision-chains/${encodeURIComponent(chainId)}?org_id=${encodeURIComponent(orgId)}`
|
|
38488
|
+
});
|
|
38489
|
+
if (!response.ok) {
|
|
38490
|
+
throw new Error(`Decision chain lookup failed (${response.statusCode})`);
|
|
38491
|
+
}
|
|
38492
|
+
return response.body;
|
|
38493
|
+
}
|
|
38494
|
+
},
|
|
37899
38495
|
{
|
|
37900
38496
|
name: "decionis.list_enforcement_rollouts",
|
|
37901
38497
|
aliases: ["list_enforcement_rollouts"],
|
|
@@ -38114,6 +38710,29 @@ var McpTools = class {
|
|
|
38114
38710
|
}
|
|
38115
38711
|
}
|
|
38116
38712
|
];
|
|
38713
|
+
const readOnlyTools = /* @__PURE__ */ new Set([
|
|
38714
|
+
"decionis.get_decision_dossier",
|
|
38715
|
+
"decionis.get_decision_chain",
|
|
38716
|
+
"decionis.list_enforcement_rollouts",
|
|
38717
|
+
"decionis.list_marketplace_targets",
|
|
38718
|
+
"decionis.get_marketplace_target",
|
|
38719
|
+
"decionis.list_marketplace_readiness",
|
|
38720
|
+
"decionis.list_vertical_packs",
|
|
38721
|
+
"decionis.resolve_vertical_pack"
|
|
38722
|
+
]);
|
|
38723
|
+
const idempotentWriteTools = /* @__PURE__ */ new Set(["decionis.upsert_enforcement_rollout"]);
|
|
38724
|
+
return tools.map((tool) => {
|
|
38725
|
+
const readOnly = readOnlyTools.has(tool.name);
|
|
38726
|
+
return {
|
|
38727
|
+
...tool,
|
|
38728
|
+
annotations: {
|
|
38729
|
+
readOnlyHint: readOnly,
|
|
38730
|
+
destructiveHint: false,
|
|
38731
|
+
idempotentHint: readOnly || idempotentWriteTools.has(tool.name),
|
|
38732
|
+
openWorldHint: false
|
|
38733
|
+
}
|
|
38734
|
+
};
|
|
38735
|
+
});
|
|
38117
38736
|
}
|
|
38118
38737
|
static buildTextToolResult(value, options) {
|
|
38119
38738
|
const text = toPrettyText(value);
|
|
@@ -38167,6 +38786,37 @@ function findTool(tools, name) {
|
|
|
38167
38786
|
}
|
|
38168
38787
|
|
|
38169
38788
|
// ../protocol/src/mcp/McpRoutes.ts
|
|
38789
|
+
async function recordTelemetry(app, sink, event) {
|
|
38790
|
+
if (!sink) return;
|
|
38791
|
+
try {
|
|
38792
|
+
await sink.record(event);
|
|
38793
|
+
} catch (err) {
|
|
38794
|
+
app.log.warn({ err, event: event.event }, "MCP telemetry write failed");
|
|
38795
|
+
}
|
|
38796
|
+
}
|
|
38797
|
+
function canonicalAuthorizationOutcome(value) {
|
|
38798
|
+
const record = asRecord(value);
|
|
38799
|
+
const raw = asString(record?.outcome) ?? asString(record?.decision) ?? asString(record?.verdict);
|
|
38800
|
+
if (!raw) return null;
|
|
38801
|
+
switch (raw.trim().toUpperCase()) {
|
|
38802
|
+
case "ALLOW":
|
|
38803
|
+
case "APPROVE":
|
|
38804
|
+
case "AUTO_APPROVE":
|
|
38805
|
+
return "ALLOW";
|
|
38806
|
+
case "BLOCK":
|
|
38807
|
+
case "REJECT":
|
|
38808
|
+
case "AUTO_REJECT":
|
|
38809
|
+
return "BLOCK";
|
|
38810
|
+
case "ESCALATE":
|
|
38811
|
+
return "ESCALATE";
|
|
38812
|
+
case "REVIEW":
|
|
38813
|
+
case "RESTRAIN":
|
|
38814
|
+
case "REQUIRE_REVIEW":
|
|
38815
|
+
return "REVIEW";
|
|
38816
|
+
default:
|
|
38817
|
+
return null;
|
|
38818
|
+
}
|
|
38819
|
+
}
|
|
38170
38820
|
function buildInitializeResult(serviceName, serviceVersion) {
|
|
38171
38821
|
return {
|
|
38172
38822
|
protocolVersion: MCP_DEFAULT_PROTOCOL_VERSION,
|
|
@@ -38180,7 +38830,7 @@ function buildInitializeResult(serviceName, serviceVersion) {
|
|
|
38180
38830
|
title: "Decionis Protocol MCP",
|
|
38181
38831
|
version: serviceVersion
|
|
38182
38832
|
},
|
|
38183
|
-
instructions: "Use Decionis Protocol
|
|
38833
|
+
instructions: "Use Decionis Protocol to evaluate a proposed action before execution and inspect its signed governance evidence. Evaluation tools record Decionis decisions but never perform the downstream mutation. Use read-only dossier, chain, marketplace, and vertical tools for inspection."
|
|
38184
38834
|
};
|
|
38185
38835
|
}
|
|
38186
38836
|
async function handleJsonRpcRequest(app, requestBody, options) {
|
|
@@ -38218,6 +38868,16 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
38218
38868
|
}
|
|
38219
38869
|
const requestedVersion = asString(params.protocolVersion);
|
|
38220
38870
|
const negotiatedVersion = requestedVersion && MCP_PROTOCOL_VERSIONS.includes(requestedVersion) ? requestedVersion : MCP_DEFAULT_PROTOCOL_VERSION;
|
|
38871
|
+
const clientInfo = asRecord(params.clientInfo);
|
|
38872
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38873
|
+
event: "connection_succeeded",
|
|
38874
|
+
connectionId: options.connectionId,
|
|
38875
|
+
clientName: asString(clientInfo?.name),
|
|
38876
|
+
clientVersion: asString(clientInfo?.version),
|
|
38877
|
+
protocolVersion: negotiatedVersion,
|
|
38878
|
+
authMode: options.auth?.kind ?? "none",
|
|
38879
|
+
statusCode: 200
|
|
38880
|
+
});
|
|
38221
38881
|
return {
|
|
38222
38882
|
statusCode: 200,
|
|
38223
38883
|
payload: jsonRpcSuccess(id, {
|
|
@@ -38233,6 +38893,12 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
38233
38893
|
case "ping":
|
|
38234
38894
|
return { statusCode: 200, payload: jsonRpcSuccess(id, {}) };
|
|
38235
38895
|
case "tools/list":
|
|
38896
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38897
|
+
event: "tools_listed",
|
|
38898
|
+
connectionId: options.connectionId,
|
|
38899
|
+
authMode: options.auth?.kind ?? "none",
|
|
38900
|
+
statusCode: 200
|
|
38901
|
+
});
|
|
38236
38902
|
return {
|
|
38237
38903
|
statusCode: 200,
|
|
38238
38904
|
payload: jsonRpcSuccess(id, {
|
|
@@ -38241,7 +38907,8 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
38241
38907
|
title: tool.title,
|
|
38242
38908
|
description: tool.description,
|
|
38243
38909
|
inputSchema: tool.inputSchema,
|
|
38244
|
-
...tool.outputSchema ? { outputSchema: tool.outputSchema } : {}
|
|
38910
|
+
...tool.outputSchema ? { outputSchema: tool.outputSchema } : {},
|
|
38911
|
+
annotations: tool.annotations
|
|
38245
38912
|
}))
|
|
38246
38913
|
})
|
|
38247
38914
|
};
|
|
@@ -38260,15 +38927,61 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
38260
38927
|
payload: jsonRpcError(id, -32601, `Unknown tool '${name}'`)
|
|
38261
38928
|
};
|
|
38262
38929
|
}
|
|
38930
|
+
const toolStartedAt = process.hrtime.bigint();
|
|
38931
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38932
|
+
event: "tool_called",
|
|
38933
|
+
connectionId: options.connectionId,
|
|
38934
|
+
toolName: tool.name,
|
|
38935
|
+
authMode: options.auth?.kind ?? "none"
|
|
38936
|
+
});
|
|
38263
38937
|
const args = asRecord(params.arguments) ?? {};
|
|
38264
38938
|
const authError = authorizeToolInvocation(options.auth, name, args);
|
|
38265
38939
|
if (authError) {
|
|
38940
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38941
|
+
event: "authorization_outcome",
|
|
38942
|
+
connectionId: options.connectionId,
|
|
38943
|
+
toolName: tool.name,
|
|
38944
|
+
outcome: "DENIED",
|
|
38945
|
+
authMode: options.auth?.kind ?? "none",
|
|
38946
|
+
statusCode: 403,
|
|
38947
|
+
durationMs: durationMs(toolStartedAt)
|
|
38948
|
+
});
|
|
38949
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38950
|
+
event: "tool_failed",
|
|
38951
|
+
connectionId: options.connectionId,
|
|
38952
|
+
toolName: tool.name,
|
|
38953
|
+
outcome: "DENIED",
|
|
38954
|
+
authMode: options.auth?.kind ?? "none",
|
|
38955
|
+
statusCode: 403,
|
|
38956
|
+
durationMs: durationMs(toolStartedAt)
|
|
38957
|
+
});
|
|
38266
38958
|
return {
|
|
38267
38959
|
statusCode: 403,
|
|
38268
38960
|
payload: jsonRpcError(id, authError.code, authError.message)
|
|
38269
38961
|
};
|
|
38270
38962
|
}
|
|
38271
38963
|
const result = await handleToolCall(tool, args);
|
|
38964
|
+
const outcome = canonicalAuthorizationOutcome(result.structuredContent);
|
|
38965
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38966
|
+
event: result.isError ? "tool_failed" : "tool_succeeded",
|
|
38967
|
+
connectionId: options.connectionId,
|
|
38968
|
+
toolName: tool.name,
|
|
38969
|
+
outcome,
|
|
38970
|
+
authMode: options.auth?.kind ?? "none",
|
|
38971
|
+
statusCode: 200,
|
|
38972
|
+
durationMs: durationMs(toolStartedAt)
|
|
38973
|
+
});
|
|
38974
|
+
if (outcome) {
|
|
38975
|
+
await recordTelemetry(app, options.telemetry, {
|
|
38976
|
+
event: "authorization_outcome",
|
|
38977
|
+
connectionId: options.connectionId,
|
|
38978
|
+
toolName: tool.name,
|
|
38979
|
+
outcome,
|
|
38980
|
+
authMode: options.auth?.kind ?? "none",
|
|
38981
|
+
statusCode: 200,
|
|
38982
|
+
durationMs: durationMs(toolStartedAt)
|
|
38983
|
+
});
|
|
38984
|
+
}
|
|
38272
38985
|
return {
|
|
38273
38986
|
statusCode: 200,
|
|
38274
38987
|
payload: jsonRpcSuccess(id, result)
|
|
@@ -38284,6 +38997,13 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
38284
38997
|
statusCode: 200,
|
|
38285
38998
|
payload: jsonRpcSuccess(id, {
|
|
38286
38999
|
resourceTemplates: [
|
|
39000
|
+
{
|
|
39001
|
+
uriTemplate: "decionis://connectors/{slug}",
|
|
39002
|
+
name: "connector_detail",
|
|
39003
|
+
title: "Connector Detail",
|
|
39004
|
+
description: "Read one Connector Registry row: status, install channels, governed actions, verification.",
|
|
39005
|
+
mimeType: "application/json"
|
|
39006
|
+
},
|
|
38287
39007
|
{
|
|
38288
39008
|
uriTemplate: "decionis://marketplaces/targets/{target}",
|
|
38289
39009
|
name: "marketplace_target_detail",
|
|
@@ -38445,6 +39165,11 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
38445
39165
|
const auth = await authenticateMcpRequest(req, authLookup);
|
|
38446
39166
|
const authDurationMs = durationMs(authStartedAt);
|
|
38447
39167
|
if (!auth && isAuthenticationRequired(authLookup)) {
|
|
39168
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
39169
|
+
event: "authentication_failed",
|
|
39170
|
+
statusCode: 401,
|
|
39171
|
+
durationMs: authDurationMs
|
|
39172
|
+
});
|
|
38448
39173
|
const maybeId = asRecord(req.body)?.id;
|
|
38449
39174
|
const id = typeof maybeId === "string" || typeof maybeId === "number" ? maybeId : null;
|
|
38450
39175
|
reply.header(
|
|
@@ -38454,6 +39179,10 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
38454
39179
|
stages: { auth_ms: authDurationMs }
|
|
38455
39180
|
})
|
|
38456
39181
|
);
|
|
39182
|
+
reply.header(
|
|
39183
|
+
"www-authenticate",
|
|
39184
|
+
`Bearer resource_metadata="${options.publicBaseUrl}/.well-known/oauth-protected-resource", error="invalid_token"`
|
|
39185
|
+
);
|
|
38457
39186
|
return reply.code(401).send(jsonRpcError(id, -32001, "Unauthorized MCP request"));
|
|
38458
39187
|
}
|
|
38459
39188
|
if (Array.isArray(req.body)) {
|
|
@@ -38468,7 +39197,35 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
38468
39197
|
}
|
|
38469
39198
|
if (isLegacyToolCall(req.body)) {
|
|
38470
39199
|
const rpcStartedAt2 = process.hrtime.bigint();
|
|
39200
|
+
const connectionId2 = asString(req.headers["mcp-session-id"]);
|
|
39201
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
39202
|
+
event: "tool_called",
|
|
39203
|
+
connectionId: connectionId2,
|
|
39204
|
+
toolName: req.body.tool_name,
|
|
39205
|
+
authMode: auth?.kind ?? "none"
|
|
39206
|
+
});
|
|
38471
39207
|
const payload = await handleLegacyToolCall(app, auth, req.body);
|
|
39208
|
+
const outcome = canonicalAuthorizationOutcome(payload.output);
|
|
39209
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
39210
|
+
event: payload.is_error || payload.error ? "tool_failed" : "tool_succeeded",
|
|
39211
|
+
connectionId: connectionId2,
|
|
39212
|
+
toolName: req.body.tool_name,
|
|
39213
|
+
outcome,
|
|
39214
|
+
authMode: auth?.kind ?? "none",
|
|
39215
|
+
statusCode: 200,
|
|
39216
|
+
durationMs: durationMs(rpcStartedAt2)
|
|
39217
|
+
});
|
|
39218
|
+
if (outcome) {
|
|
39219
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
39220
|
+
event: "authorization_outcome",
|
|
39221
|
+
connectionId: connectionId2,
|
|
39222
|
+
toolName: req.body.tool_name,
|
|
39223
|
+
outcome,
|
|
39224
|
+
authMode: auth?.kind ?? "none",
|
|
39225
|
+
statusCode: 200,
|
|
39226
|
+
durationMs: durationMs(rpcStartedAt2)
|
|
39227
|
+
});
|
|
39228
|
+
}
|
|
38472
39229
|
reply.header(
|
|
38473
39230
|
"server-timing",
|
|
38474
39231
|
buildServerTimingHeader({
|
|
@@ -38493,13 +39250,21 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
38493
39250
|
return reply.code(400).send(jsonRpcError(null, -32600, "JSON-RPC request body required"));
|
|
38494
39251
|
}
|
|
38495
39252
|
const rpcStartedAt = process.hrtime.bigint();
|
|
39253
|
+
const requestedMethod = asString(requestBody.method);
|
|
39254
|
+
const incomingSession = asString(req.headers["mcp-session-id"]);
|
|
39255
|
+
const connectionId = requestedMethod === "initialize" ? randomUUID2() : incomingSession;
|
|
38496
39256
|
const result = await handleJsonRpcRequest(app, requestBody, {
|
|
38497
39257
|
publicBaseUrl: options.publicBaseUrl,
|
|
38498
39258
|
serviceName: options.serviceName,
|
|
38499
39259
|
serviceVersion: options.serviceVersion,
|
|
38500
39260
|
auth,
|
|
38501
|
-
authLookup
|
|
39261
|
+
authLookup,
|
|
39262
|
+
telemetry: options.telemetry ?? null,
|
|
39263
|
+
connectionId
|
|
38502
39264
|
});
|
|
39265
|
+
if (requestedMethod === "initialize" && result.statusCode === 200) {
|
|
39266
|
+
reply.header("mcp-session-id", connectionId);
|
|
39267
|
+
}
|
|
38503
39268
|
reply.header(
|
|
38504
39269
|
"server-timing",
|
|
38505
39270
|
buildServerTimingHeader({
|
|
@@ -38529,8 +39294,21 @@ function registerProtocolMcpRoutes(app, options) {
|
|
|
38529
39294
|
endpoint: `${publicBaseUrl}/v1/protocol/mcp`,
|
|
38530
39295
|
endpoint_aliases: MCP_HTTP_PATHS,
|
|
38531
39296
|
supported_protocol_versions: [...MCP_PROTOCOL_VERSIONS],
|
|
38532
|
-
auth
|
|
39297
|
+
auth,
|
|
39298
|
+
oauth: {
|
|
39299
|
+
protected_resource_metadata: `${publicBaseUrl}/.well-known/oauth-protected-resource`,
|
|
39300
|
+
authorization_server_metadata: "https://api.decionis.com/.well-known/oauth-authorization-server"
|
|
39301
|
+
}
|
|
38533
39302
|
};
|
|
39303
|
+
const oauthProtectedResource = {
|
|
39304
|
+
resource: `${publicBaseUrl}/mcp`,
|
|
39305
|
+
authorization_servers: ["https://api.decionis.com"],
|
|
39306
|
+
bearer_methods_supported: ["header"],
|
|
39307
|
+
scopes_supported: ["decision:read", "decision:run", "decision:write"],
|
|
39308
|
+
resource_documentation: "https://decionis.com/docs/protocol-mcp"
|
|
39309
|
+
};
|
|
39310
|
+
app.get("/.well-known/oauth-protected-resource", async () => oauthProtectedResource);
|
|
39311
|
+
app.get("/.well-known/oauth-protected-resource/mcp", async () => oauthProtectedResource);
|
|
38534
39312
|
for (const path2 of MCP_HTTP_PATHS) {
|
|
38535
39313
|
app.get(path2, async () => metadata);
|
|
38536
39314
|
app.delete(path2, async (_req, reply) => reply.code(204).send());
|
|
@@ -38540,7 +39318,8 @@ function registerProtocolMcpRoutes(app, options) {
|
|
|
38540
39318
|
publicBaseUrl,
|
|
38541
39319
|
serviceName: options.serviceName,
|
|
38542
39320
|
serviceVersion: options.serviceVersion,
|
|
38543
|
-
authLookup
|
|
39321
|
+
authLookup,
|
|
39322
|
+
telemetry: options.telemetry ?? null
|
|
38544
39323
|
})
|
|
38545
39324
|
);
|
|
38546
39325
|
}
|
|
@@ -46731,7 +47510,8 @@ function buildDecisionDossierPersistedProofBundle(input) {
|
|
|
46731
47510
|
}
|
|
46732
47511
|
|
|
46733
47512
|
// ../protocol/src/support/PanDetection.ts
|
|
46734
|
-
var PanDetection = class {
|
|
47513
|
+
var PanDetection = class _PanDetection {
|
|
47514
|
+
static UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
46735
47515
|
static toDigits(value) {
|
|
46736
47516
|
if (typeof value !== "string" && typeof value !== "number") return null;
|
|
46737
47517
|
const digits = String(value).replace(/\D/g, "");
|
|
@@ -46753,12 +47533,32 @@ var PanDetection = class {
|
|
|
46753
47533
|
}
|
|
46754
47534
|
return sum % 10 === 0;
|
|
46755
47535
|
}
|
|
47536
|
+
/**
|
|
47537
|
+
* Candidate card numbers inside a value: runs of digits separated only by the
|
|
47538
|
+
* characters a card number is actually written with (spaces and dashes).
|
|
47539
|
+
*
|
|
47540
|
+
* Splitting on everything else is the whole point. Stripping every non-digit
|
|
47541
|
+
* from the value instead — which this used to do — welds unrelated digits
|
|
47542
|
+
* together across letters and punctuation, and a UUID is the case that bites:
|
|
47543
|
+
* discard its letters and roughly 4% of them are a 13-to-19-digit string that
|
|
47544
|
+
* satisfies Luhn. Since we put UUIDs into decision context ourselves (the
|
|
47545
|
+
* duplicate-payment fact carries the prior dossier id), that turned a
|
|
47546
|
+
* legitimate duplicate-payment decision into "raw PAN-like value detected"
|
|
47547
|
+
* about one time in twenty-five.
|
|
47548
|
+
*/
|
|
47549
|
+
static panCandidates(value) {
|
|
47550
|
+
if (typeof value === "number") return [String(value).replace(/[^\d]/g, "")];
|
|
47551
|
+
if (typeof value !== "string") return [];
|
|
47552
|
+
if (_PanDetection.UUID_SHAPE.test(value.trim())) return [];
|
|
47553
|
+
const runs = value.match(/(?<![0-9A-Za-z])\d[\d \-]*\d(?![0-9A-Za-z])/g) ?? [];
|
|
47554
|
+
return runs.map((run) => run.replace(/[^\d]/g, "")).filter((digits) => digits.length > 0);
|
|
47555
|
+
}
|
|
46756
47556
|
static looksLikeRawPan(value) {
|
|
46757
|
-
|
|
46758
|
-
|
|
46759
|
-
|
|
46760
|
-
|
|
46761
|
-
|
|
47557
|
+
return _PanDetection.panCandidates(value).some((digits) => {
|
|
47558
|
+
if (digits.length < 13 || digits.length > 19) return false;
|
|
47559
|
+
if (/^(\d)\1+$/.test(digits)) return false;
|
|
47560
|
+
return isLuhnValid(digits);
|
|
47561
|
+
});
|
|
46762
47562
|
}
|
|
46763
47563
|
static findRawPanPath(value, path2, visited = /* @__PURE__ */ new Set()) {
|
|
46764
47564
|
if (looksLikeRawPan(value)) return path2;
|
|
@@ -46779,9 +47579,6 @@ var PanDetection = class {
|
|
|
46779
47579
|
return null;
|
|
46780
47580
|
}
|
|
46781
47581
|
};
|
|
46782
|
-
function toDigits(value) {
|
|
46783
|
-
return PanDetection.toDigits(value);
|
|
46784
|
-
}
|
|
46785
47582
|
function isLuhnValid(digits) {
|
|
46786
47583
|
return PanDetection.isLuhnValid(digits);
|
|
46787
47584
|
}
|
|
@@ -52057,10 +52854,15 @@ var readiness = {
|
|
|
52057
52854
|
"adobe-commerce": {
|
|
52058
52855
|
target: "adobe-commerce",
|
|
52059
52856
|
protocol_capture: "CAPTURED",
|
|
52857
|
+
// adapter_state stays BUILDING deliberately: Adobe's Marketplace
|
|
52858
|
+
// technical review passed in full (all phases, SID qv4l7d2ak6 — automated
|
|
52859
|
+
// EQP 2026-07-08, final confirmation 2026-08-10, tested on Magento 2.4.9
|
|
52860
|
+
// EE + CE / PHP 8.5.5), but the gate has not yet run against a live
|
|
52861
|
+
// merchant store, and that is the bar LIVE means here.
|
|
52060
52862
|
adapter_state: "BUILDING",
|
|
52061
|
-
docs_state: "
|
|
52863
|
+
docs_state: "BUILDING",
|
|
52062
52864
|
launch_state: "PLANNED",
|
|
52063
|
-
next_milestone: "
|
|
52865
|
+
next_milestone: "All Adobe Marketplace technical review phases passed (SID qv4l7d2ak6); ship the customer-deployable connector kit, onboard a live Adobe Commerce store in shadow, verify the checkout gate, then promote it to enforcement"
|
|
52064
52866
|
},
|
|
52065
52867
|
shopware: {
|
|
52066
52868
|
target: "shopware",
|
|
@@ -52081,10 +52883,16 @@ var readiness = {
|
|
|
52081
52883
|
woo: {
|
|
52082
52884
|
target: "woo",
|
|
52083
52885
|
protocol_capture: "CAPTURED",
|
|
52084
|
-
|
|
52085
|
-
|
|
52086
|
-
|
|
52087
|
-
|
|
52886
|
+
// Truth-up 2026-08-10: the plugin is published in the WordPress.org
|
|
52887
|
+
// directory (slug `decionis`, 1.0.0) and Block + classic checkout,
|
|
52888
|
+
// core COGS, HPOS order CRUD, and the signed dossier were verified end
|
|
52889
|
+
// to end on a staging store — including an admin-enabled ENFORCEMENT
|
|
52890
|
+
// block — before the listing went live (shared readiness provenance).
|
|
52891
|
+
// The previous PLANNED states predated the public listing.
|
|
52892
|
+
adapter_state: "LIVE",
|
|
52893
|
+
docs_state: "LIVE",
|
|
52894
|
+
launch_state: "BUILDING",
|
|
52895
|
+
next_milestone: "WordPress.org listing is live and self-serve; grow installs and collect the first live-store enforcement evidence for the listing's proof section"
|
|
52088
52896
|
},
|
|
52089
52897
|
jumia: {
|
|
52090
52898
|
target: "jumia",
|
|
@@ -52786,7 +53594,8 @@ function buildProtocolApp(options) {
|
|
|
52786
53594
|
registerProtocolMcpRoutes(app, {
|
|
52787
53595
|
serviceName: PROTOCOL_SERVICE,
|
|
52788
53596
|
serviceVersion: PROTOCOL_VERSION,
|
|
52789
|
-
authLookup: options?.mcpAuthLookup ?? null
|
|
53597
|
+
authLookup: options?.mcpAuthLookup ?? null,
|
|
53598
|
+
telemetry: options?.mcpTelemetry ?? null
|
|
52790
53599
|
});
|
|
52791
53600
|
const executionAuthority = createExecutionGatingService(options?.executionGating);
|
|
52792
53601
|
registerExecutionGatingRoutes(app, {
|