@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
|
@@ -549,7 +549,7 @@ var MCP_PROTOCOL_VERSIONS = [
|
|
|
549
549
|
"2025-03-26",
|
|
550
550
|
"2024-11-05"
|
|
551
551
|
];
|
|
552
|
-
var MCP_DEFAULT_PROTOCOL_VERSION = "2025-
|
|
552
|
+
var MCP_DEFAULT_PROTOCOL_VERSION = "2025-11-25";
|
|
553
553
|
var DEFAULT_PUBLIC_BASE_URL = "https://protocol.decionis.com";
|
|
554
554
|
var MCP_HTTP_PATHS = ["/mcp", "/v1/protocol/mcp"];
|
|
555
555
|
|
|
@@ -753,7 +753,7 @@ var McpAuthGuard = class {
|
|
|
753
753
|
return auth?.kind === "org_api_key";
|
|
754
754
|
}
|
|
755
755
|
static findTargetOrgIdForTool(name, args) {
|
|
756
|
-
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") {
|
|
756
|
+
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") {
|
|
757
757
|
return asString(args.org_id);
|
|
758
758
|
}
|
|
759
759
|
return null;
|
|
@@ -762,7 +762,7 @@ var McpAuthGuard = class {
|
|
|
762
762
|
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") {
|
|
763
763
|
return ["decision:run", "decision:*", "org:*"];
|
|
764
764
|
}
|
|
765
|
-
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") {
|
|
765
|
+
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") {
|
|
766
766
|
return ["decision:read", "org:read", "decision:*", "org:*"];
|
|
767
767
|
}
|
|
768
768
|
if (name === "decionis.upsert_enforcement_rollout" || name === "upsert_enforcement_rollout") {
|
|
@@ -859,6 +859,539 @@ function authorizeResourceRead(auth, uri) {
|
|
|
859
859
|
// ../protocol/src/mcp/McpRoutes.ts
|
|
860
860
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
861
861
|
|
|
862
|
+
// ../../packages/shared/src/Connectors/ConnectorRegistry.ts
|
|
863
|
+
var SITE = "https://decionis.com";
|
|
864
|
+
var connectors = [
|
|
865
|
+
// ── Commerce ──────────────────────────────────────────────────────────
|
|
866
|
+
{
|
|
867
|
+
// Live Shopify App Store listing (sweep 2026-08-10, also pinned by
|
|
868
|
+
// apps/web ShopifyAppStore.listingUrl + the distributionSameAs sweep).
|
|
869
|
+
// Copy scoped to the published listing description.
|
|
870
|
+
slug: "shopify",
|
|
871
|
+
name: "Decionis for Shopify",
|
|
872
|
+
vendor: "Shopify",
|
|
873
|
+
category: "commerce",
|
|
874
|
+
status: "production",
|
|
875
|
+
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.",
|
|
876
|
+
capabilities: [
|
|
877
|
+
"margin-floor-enforcement",
|
|
878
|
+
"checkout-policy-enforcement",
|
|
879
|
+
"signed-decision-dossier"
|
|
880
|
+
],
|
|
881
|
+
decisionsSupported: ["refund", "discount", "oversell", "risky-order"],
|
|
882
|
+
installation: [
|
|
883
|
+
{
|
|
884
|
+
kind: "marketplace",
|
|
885
|
+
url: "https://apps.shopify.com/decionis-checkout-gate",
|
|
886
|
+
label: "Shopify App Store"
|
|
887
|
+
}
|
|
888
|
+
],
|
|
889
|
+
// Shopify predates the marketplace-target program (it is the original
|
|
890
|
+
// commerce wedge with its own app workspace), so it deliberately has no
|
|
891
|
+
// `marketplaceTarget` join — /commerce is its owning page.
|
|
892
|
+
documentation: `${SITE}/commerce`,
|
|
893
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
894
|
+
activation: { method: "marketplace_install", requiresWorkspace: true },
|
|
895
|
+
presenceSupport: "planned",
|
|
896
|
+
marketplaceListingId: "shopify-app",
|
|
897
|
+
providerId: "SHOPIFY"
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
// Published in the WordPress.org plugin directory (slug `decionis`,
|
|
901
|
+
// 1.0.0) — sweep 2026-08-10 via the distributionSameAs verification.
|
|
902
|
+
// Copy reuses the shared readiness provenance: verified end to end on a
|
|
903
|
+
// staging store before the listing went live; shadow first,
|
|
904
|
+
// enforcement opt-in.
|
|
905
|
+
slug: "woo",
|
|
906
|
+
name: "Decionis for WooCommerce",
|
|
907
|
+
vendor: "WooCommerce",
|
|
908
|
+
category: "commerce",
|
|
909
|
+
status: "production",
|
|
910
|
+
version: "1.0.0",
|
|
911
|
+
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.",
|
|
912
|
+
capabilities: [
|
|
913
|
+
"margin-floor-enforcement",
|
|
914
|
+
"checkout-policy-enforcement",
|
|
915
|
+
"shadow-mode",
|
|
916
|
+
"signed-decision-dossier"
|
|
917
|
+
],
|
|
918
|
+
decisionsSupported: ["checkout-order"],
|
|
919
|
+
installation: [
|
|
920
|
+
{
|
|
921
|
+
kind: "marketplace",
|
|
922
|
+
url: "https://wordpress.org/plugins/decionis/",
|
|
923
|
+
label: "WordPress.org Plugin Directory"
|
|
924
|
+
}
|
|
925
|
+
],
|
|
926
|
+
documentation: `${SITE}/marketplace/woo`,
|
|
927
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
928
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
929
|
+
presenceSupport: "planned",
|
|
930
|
+
marketplaceTarget: "woo",
|
|
931
|
+
marketplaceListingId: "woo-plugin",
|
|
932
|
+
providerId: "WOO"
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
// eBay approved the app for production and the connector is deployed and
|
|
936
|
+
// marketplace-account-deletion compliant; the first read-only Fulfillment
|
|
937
|
+
// probe passed against a live seller account (docs/marketplace/ebay/
|
|
938
|
+
// evidence/latest.json). No public eBay listing directory exists, so the
|
|
939
|
+
// channel is the guided OAuth connect — and enforcement stays honest:
|
|
940
|
+
// shadow dossiers today, write-scope approval pending.
|
|
941
|
+
slug: "ebay",
|
|
942
|
+
name: "Decionis for eBay",
|
|
943
|
+
vendor: "eBay",
|
|
944
|
+
category: "commerce",
|
|
945
|
+
status: "installable",
|
|
946
|
+
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.",
|
|
947
|
+
capabilities: ["margin-guardrails", "promo-hygiene", "shadow-mode", "signed-decision-dossier"],
|
|
948
|
+
decisionsSupported: ["listing-change", "order-fulfillment", "promotion"],
|
|
949
|
+
installation: [
|
|
950
|
+
{
|
|
951
|
+
kind: "guided",
|
|
952
|
+
url: `${SITE}/marketplace/ebay`,
|
|
953
|
+
label: "eBay OAuth connect (guided)"
|
|
954
|
+
}
|
|
955
|
+
],
|
|
956
|
+
documentation: `${SITE}/marketplace/ebay`,
|
|
957
|
+
verification: {
|
|
958
|
+
validatedBy: "eBay production approval + Decionis live verification",
|
|
959
|
+
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).",
|
|
960
|
+
lastValidated: "2026-07-14"
|
|
961
|
+
},
|
|
962
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
963
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
964
|
+
presenceSupport: "planned",
|
|
965
|
+
marketplaceTarget: "ebay",
|
|
966
|
+
providerId: "EBAY"
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
// Passed ALL Adobe Commerce Marketplace technical review phases (SID
|
|
970
|
+
// qv4l7d2ak6): automated EQP 2026-07-08, full technical-review
|
|
971
|
+
// confirmation received 2026-08-10 (tested by Adobe on Magento 2.4.9
|
|
972
|
+
// EE + CE, PHP 8.5.5). Marketplace release awaits the remaining
|
|
973
|
+
// marketing review, and the gate has not been validated against a live
|
|
974
|
+
// merchant store — so no channels yet; the customer-deployable kit
|
|
975
|
+
// ships next (docs/claims DECIONIS-CLM-022).
|
|
976
|
+
slug: "adobe-commerce",
|
|
977
|
+
name: "Decionis Connector for Adobe Commerce",
|
|
978
|
+
vendor: "Adobe",
|
|
979
|
+
category: "commerce",
|
|
980
|
+
status: "validated",
|
|
981
|
+
version: "1.0.0",
|
|
982
|
+
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.",
|
|
983
|
+
capabilities: [
|
|
984
|
+
"margin-floor-enforcement",
|
|
985
|
+
"checkout-policy-enforcement",
|
|
986
|
+
"promo-hygiene",
|
|
987
|
+
"fail-open-checkout-gate",
|
|
988
|
+
"signed-decision-dossier"
|
|
989
|
+
],
|
|
990
|
+
decisionsSupported: ["checkout-order", "pricing-change", "promotion"],
|
|
991
|
+
installation: [
|
|
992
|
+
{
|
|
993
|
+
// The kit page hosts the reviewed composer module + checksum,
|
|
994
|
+
// manifest, and SBOM — shipped in the same change that makes the URL
|
|
995
|
+
// resolve (rule 1.1 by construction).
|
|
996
|
+
kind: "hosted_download",
|
|
997
|
+
url: `${SITE}/marketplace/adobe-commerce/connector-kit`,
|
|
998
|
+
label: "Connector kit (guided deployment)"
|
|
999
|
+
}
|
|
1000
|
+
],
|
|
1001
|
+
package: {
|
|
1002
|
+
artifact: "/marketplace/adobe-commerce/connector-kit/decionis-module-checkout-guardrail-1.0.0.zip",
|
|
1003
|
+
sha256Path: "/marketplace/adobe-commerce/connector-kit/decionis-module-checkout-guardrail-1.0.0.sha256.txt",
|
|
1004
|
+
manifestPath: "/marketplace/adobe-commerce/connector-kit/manifest.json",
|
|
1005
|
+
sbomPath: "/marketplace/adobe-commerce/connector-kit/SBOM.json",
|
|
1006
|
+
format: "magento2-module"
|
|
1007
|
+
},
|
|
1008
|
+
documentation: `${SITE}/marketplace/adobe-commerce`,
|
|
1009
|
+
verification: {
|
|
1010
|
+
validatedBy: "Adobe Commerce Marketplace technical review (EQP)",
|
|
1011
|
+
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.",
|
|
1012
|
+
lastValidated: "2026-08-10"
|
|
1013
|
+
},
|
|
1014
|
+
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
1015
|
+
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
1016
|
+
presenceSupport: "planned",
|
|
1017
|
+
marketplaceTarget: "adobe-commerce",
|
|
1018
|
+
providerId: "ADOBE_COMMERCE"
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
// SP-API connector built and unit-tested; shadow-mode first while live
|
|
1022
|
+
// seller validation completes (homepage Beta tile is the owning copy).
|
|
1023
|
+
slug: "amazon",
|
|
1024
|
+
name: "Decionis for Amazon",
|
|
1025
|
+
vendor: "Amazon",
|
|
1026
|
+
category: "commerce",
|
|
1027
|
+
status: "validated",
|
|
1028
|
+
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.",
|
|
1029
|
+
capabilities: ["margin-guardrails", "shadow-mode", "signed-decision-dossier"],
|
|
1030
|
+
decisionsSupported: ["listing-change", "order"],
|
|
1031
|
+
installation: [],
|
|
1032
|
+
documentation: `${SITE}/marketplace/amazon`,
|
|
1033
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1034
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
1035
|
+
presenceSupport: "planned",
|
|
1036
|
+
marketplaceTarget: "amazon",
|
|
1037
|
+
providerId: "AMAZON"
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
// Post-purchase fulfillment circuit breaker — OAuth + refresh, signed
|
|
1041
|
+
// Open API, webhook intake/verification, margin gate, Ship-Package
|
|
1042
|
+
// release built and unit-tested; TikTok App Store review not submitted
|
|
1043
|
+
// (shared readiness provenance).
|
|
1044
|
+
slug: "tiktok",
|
|
1045
|
+
name: "Decionis for TikTok Shop",
|
|
1046
|
+
vendor: "TikTok Shop",
|
|
1047
|
+
category: "commerce",
|
|
1048
|
+
status: "validated",
|
|
1049
|
+
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.",
|
|
1050
|
+
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
1051
|
+
decisionsSupported: ["order-fulfillment"],
|
|
1052
|
+
installation: [],
|
|
1053
|
+
documentation: `${SITE}/marketplace/tiktok`,
|
|
1054
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1055
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
1056
|
+
presenceSupport: "planned",
|
|
1057
|
+
marketplaceTarget: "tiktok",
|
|
1058
|
+
providerId: "TIKTOK_SHOP"
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
// Solution Provider OAuth, PO-created webhook intake with HMAC
|
|
1062
|
+
// verification, margin gate, Acknowledge-Order release/hold — built and
|
|
1063
|
+
// unit-tested; Solution Provider approval and live seller verification
|
|
1064
|
+
// remain (shared readiness provenance).
|
|
1065
|
+
slug: "walmart",
|
|
1066
|
+
name: "Decionis for Walmart Marketplace",
|
|
1067
|
+
vendor: "Walmart",
|
|
1068
|
+
category: "commerce",
|
|
1069
|
+
status: "validated",
|
|
1070
|
+
summary: "Post-purchase fulfillment circuit breaker for Walmart Marketplace \u2014 purchase orders clear a margin gate (COGS + referral fee + shipping) before Acknowledge-Order release.",
|
|
1071
|
+
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
1072
|
+
decisionsSupported: ["order-acknowledgement"],
|
|
1073
|
+
installation: [],
|
|
1074
|
+
documentation: `${SITE}/marketplace/walmart`,
|
|
1075
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1076
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
1077
|
+
presenceSupport: "planned",
|
|
1078
|
+
marketplaceTarget: "walmart",
|
|
1079
|
+
providerId: "WALMART_MARKETPLACE"
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
// Vendor Center GOP integration — centralized Mastershop OAuth, durable
|
|
1083
|
+
// order polling, multi-market margin/COD/SLA evaluation, guarded
|
|
1084
|
+
// fulfillment; live Vendor Center verification still required before
|
|
1085
|
+
// enforcement (shared readiness provenance).
|
|
1086
|
+
slug: "jumia",
|
|
1087
|
+
name: "Decionis for Jumia",
|
|
1088
|
+
vendor: "Jumia",
|
|
1089
|
+
category: "commerce",
|
|
1090
|
+
status: "validated",
|
|
1091
|
+
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.",
|
|
1092
|
+
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
1093
|
+
decisionsSupported: ["order-fulfillment"],
|
|
1094
|
+
installation: [],
|
|
1095
|
+
documentation: `${SITE}/marketplace/jumia`,
|
|
1096
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1097
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
1098
|
+
presenceSupport: "planned",
|
|
1099
|
+
marketplaceTarget: "jumia",
|
|
1100
|
+
providerId: "JUMIA"
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
// Headless / Open Checkout gate built and unit-tested; not live-store
|
|
1104
|
+
// validated (rotated off the homepage tiles in favour of WooCommerce).
|
|
1105
|
+
slug: "bigcommerce",
|
|
1106
|
+
name: "Decionis for BigCommerce",
|
|
1107
|
+
vendor: "BigCommerce",
|
|
1108
|
+
category: "commerce",
|
|
1109
|
+
status: "validated",
|
|
1110
|
+
summary: "Checkout margin gate for BigCommerce headless and Open Checkout storefronts \u2014 built and unit-tested, pending validation against a live store.",
|
|
1111
|
+
capabilities: ["margin-floor-enforcement", "checkout-policy-enforcement"],
|
|
1112
|
+
decisionsSupported: ["checkout-order"],
|
|
1113
|
+
installation: [],
|
|
1114
|
+
documentation: `${SITE}/marketplace/bigcommerce`,
|
|
1115
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1116
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
1117
|
+
presenceSupport: "planned",
|
|
1118
|
+
marketplaceTarget: "bigcommerce"
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
// Shopware 6 App System handshake, shop-signed webhooks, fail-open
|
|
1122
|
+
// synchronous checkout gate — built and unit-tested, not yet validated
|
|
1123
|
+
// against a live Shopware store (docs/claims DECIONIS-CLM-023).
|
|
1124
|
+
slug: "shopware",
|
|
1125
|
+
name: "Decionis for Shopware",
|
|
1126
|
+
vendor: "Shopware",
|
|
1127
|
+
category: "commerce",
|
|
1128
|
+
status: "validated",
|
|
1129
|
+
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.",
|
|
1130
|
+
capabilities: [
|
|
1131
|
+
"margin-floor-enforcement",
|
|
1132
|
+
"checkout-policy-enforcement",
|
|
1133
|
+
"promo-hygiene",
|
|
1134
|
+
"fail-open-checkout-gate"
|
|
1135
|
+
],
|
|
1136
|
+
decisionsSupported: ["checkout-order", "promotion"],
|
|
1137
|
+
installation: [],
|
|
1138
|
+
documentation: `${SITE}/marketplace/shopware`,
|
|
1139
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1140
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
1141
|
+
presenceSupport: "planned",
|
|
1142
|
+
marketplaceTarget: "shopware"
|
|
1143
|
+
},
|
|
1144
|
+
// ── Enterprise ────────────────────────────────────────────────────────
|
|
1145
|
+
{
|
|
1146
|
+
// SAP PartnerEdge Solution Review approved 2026-06-22 (solution id
|
|
1147
|
+
// 2004368, docs/marketplace/sap/solution-hub-listing.md). The PartnerEdge
|
|
1148
|
+
// solution URL is partner-gated (anonymous fetch 404s — sweep
|
|
1149
|
+
// 2026-08-10), so it is deliberately NOT an install channel here; the
|
|
1150
|
+
// customer-deployable BTP deployment kit ships next. Dual-gate wording
|
|
1151
|
+
// from the owning listing copy.
|
|
1152
|
+
slug: "sap",
|
|
1153
|
+
name: "Decionis Governed Execution Gate for SAP",
|
|
1154
|
+
vendor: "SAP",
|
|
1155
|
+
category: "enterprise",
|
|
1156
|
+
status: "validated",
|
|
1157
|
+
version: "0.1.0",
|
|
1158
|
+
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.",
|
|
1159
|
+
capabilities: [
|
|
1160
|
+
"dual-gate-execution",
|
|
1161
|
+
"segregation-of-duties",
|
|
1162
|
+
"three-way-match",
|
|
1163
|
+
"s4hana-write-back",
|
|
1164
|
+
"signed-decision-dossier"
|
|
1165
|
+
],
|
|
1166
|
+
decisionsSupported: [
|
|
1167
|
+
"vendor-payment-release",
|
|
1168
|
+
"procurement-approval",
|
|
1169
|
+
"finance-control-change"
|
|
1170
|
+
],
|
|
1171
|
+
installation: [
|
|
1172
|
+
{
|
|
1173
|
+
// Customer-deployed BTP kit (curated CAP source, mbt build →
|
|
1174
|
+
// cf deploy) — shipped in the same change that makes the URL resolve
|
|
1175
|
+
// (rule 1.1 by construction).
|
|
1176
|
+
kind: "hosted_download",
|
|
1177
|
+
url: `${SITE}/marketplace/sap/deployment-kit`,
|
|
1178
|
+
label: "SAP BTP deployment kit (customer-deployed)"
|
|
1179
|
+
}
|
|
1180
|
+
],
|
|
1181
|
+
package: {
|
|
1182
|
+
artifact: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.zip",
|
|
1183
|
+
sha256Path: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.sha256.txt",
|
|
1184
|
+
manifestPath: "/marketplace/sap/deployment-kit/manifest.json",
|
|
1185
|
+
sbomPath: "/marketplace/sap/deployment-kit/SBOM.json",
|
|
1186
|
+
format: "sap-mta-deployment-kit"
|
|
1187
|
+
},
|
|
1188
|
+
documentation: `${SITE}/marketplace/sap`,
|
|
1189
|
+
verification: {
|
|
1190
|
+
validatedBy: "SAP PartnerEdge Solution Review",
|
|
1191
|
+
evidence: "Solution Review completed and approved 2026-06-22 (SAP PartnerEdge solution id 2004368); SAP Store content listing is the next, contract-gated step.",
|
|
1192
|
+
lastValidated: "2026-06-22"
|
|
1193
|
+
},
|
|
1194
|
+
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
1195
|
+
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
1196
|
+
presenceSupport: "planned",
|
|
1197
|
+
providerId: "SAP"
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
// Scoped app x_dec_decionis (tables, script includes, Flow Designer
|
|
1201
|
+
// verify-intent action, shadow observers, workspace dossier panel,
|
|
1202
|
+
// scoped REST API). Self-attested platform evidence — tenant mapping,
|
|
1203
|
+
// ACLs, live policy-check execution, workflow trigger routing — is
|
|
1204
|
+
// recorded in the packaged evidence exports (docs/marketplace/servicenow
|
|
1205
|
+
// submission checklist, evidence refreshed as of the 2026-08-10 sweep).
|
|
1206
|
+
// Store publication deliberately deferred. The customer-deploy kit
|
|
1207
|
+
// CONTENT exists (full-app update-set XML + coverage manifest + INSTALL
|
|
1208
|
+
// under docs/marketplace/servicenow/connector-kit), but the public
|
|
1209
|
+
// download channel + `installable` flip are gated on a real
|
|
1210
|
+
// dev-instance import validation — a user-owned step; never claim the
|
|
1211
|
+
// install before it passes (rule 1.1 on the install claim itself).
|
|
1212
|
+
slug: "servicenow",
|
|
1213
|
+
name: "Decionis Connector for ServiceNow",
|
|
1214
|
+
vendor: "ServiceNow",
|
|
1215
|
+
category: "enterprise",
|
|
1216
|
+
status: "validated",
|
|
1217
|
+
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.",
|
|
1218
|
+
capabilities: [
|
|
1219
|
+
"flow-designer-verify-intent",
|
|
1220
|
+
"shadow-mode",
|
|
1221
|
+
"decision-drift-evidence",
|
|
1222
|
+
"signed-decision-dossier"
|
|
1223
|
+
],
|
|
1224
|
+
decisionsSupported: ["itsm-change", "incident-action", "risk-case-action"],
|
|
1225
|
+
installation: [],
|
|
1226
|
+
documentation: `${SITE}/marketplace/servicenow`,
|
|
1227
|
+
verification: {
|
|
1228
|
+
validatedBy: "Decionis platform evidence (self-attested)",
|
|
1229
|
+
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).",
|
|
1230
|
+
lastValidated: "2026-08-10"
|
|
1231
|
+
},
|
|
1232
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1233
|
+
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
1234
|
+
presenceSupport: "planned",
|
|
1235
|
+
marketplaceTarget: "servicenow",
|
|
1236
|
+
providerId: "SERVICENOW"
|
|
1237
|
+
},
|
|
1238
|
+
{
|
|
1239
|
+
// Customer-deployed starter package (Apex Action Gate, LWC, platform
|
|
1240
|
+
// event, permission set) served as committed zips with checksums;
|
|
1241
|
+
// AppExchange Security Review in progress, so no marketplace channel is
|
|
1242
|
+
// claimed (homepage Beta tile is the owning copy).
|
|
1243
|
+
slug: "salesforce",
|
|
1244
|
+
name: "Decionis Action Gate for Salesforce",
|
|
1245
|
+
vendor: "Salesforce",
|
|
1246
|
+
category: "enterprise",
|
|
1247
|
+
status: "installable",
|
|
1248
|
+
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.",
|
|
1249
|
+
capabilities: [
|
|
1250
|
+
"pre-execution-action-gate",
|
|
1251
|
+
"shadow-mode",
|
|
1252
|
+
"agentforce-governance",
|
|
1253
|
+
"signed-decision-dossier"
|
|
1254
|
+
],
|
|
1255
|
+
decisionsSupported: ["flow-action", "apex-action", "agentforce-action"],
|
|
1256
|
+
installation: [
|
|
1257
|
+
{
|
|
1258
|
+
kind: "hosted_download",
|
|
1259
|
+
url: `${SITE}/marketplace/salesforce/starter-package`,
|
|
1260
|
+
label: "Salesforce starter package (customer-deployed)"
|
|
1261
|
+
}
|
|
1262
|
+
],
|
|
1263
|
+
package: {
|
|
1264
|
+
artifact: "/marketplace/salesforce/starter-package/decionis-salesforce-starter-package.zip",
|
|
1265
|
+
sha256Path: "/marketplace/salesforce/starter-package/decionis-salesforce-starter-package.sha256.txt",
|
|
1266
|
+
format: "salesforce-metadata-source"
|
|
1267
|
+
},
|
|
1268
|
+
documentation: `${SITE}/marketplace/salesforce`,
|
|
1269
|
+
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
1270
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
1271
|
+
presenceSupport: "planned",
|
|
1272
|
+
marketplaceTarget: "salesforce",
|
|
1273
|
+
marketplaceListingId: "salesforce-app",
|
|
1274
|
+
providerId: "SALESFORCE"
|
|
1275
|
+
},
|
|
1276
|
+
// ── Automation ────────────────────────────────────────────────────────
|
|
1277
|
+
{
|
|
1278
|
+
// Live Zapier app-directory listing (sweep 2026-08-10: page resolves and
|
|
1279
|
+
// shows the Decionis app with the Create Decision Dossier action).
|
|
1280
|
+
slug: "zapier",
|
|
1281
|
+
name: "Decionis for Zapier",
|
|
1282
|
+
vendor: "Zapier",
|
|
1283
|
+
category: "automation",
|
|
1284
|
+
status: "production",
|
|
1285
|
+
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.",
|
|
1286
|
+
capabilities: ["automation-step-governance", "shadow-mode", "signed-decision-dossier"],
|
|
1287
|
+
decisionsSupported: ["automation-step"],
|
|
1288
|
+
installation: [
|
|
1289
|
+
{
|
|
1290
|
+
kind: "marketplace",
|
|
1291
|
+
url: "https://zapier.com/apps/decionis/integrations",
|
|
1292
|
+
label: "Zapier app directory"
|
|
1293
|
+
}
|
|
1294
|
+
],
|
|
1295
|
+
documentation: `${SITE}/docs/zapier`,
|
|
1296
|
+
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
1297
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
1298
|
+
presenceSupport: "planned",
|
|
1299
|
+
marketplaceListingId: "zapier"
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
// The native Make app is built with its OAuth on-ramp live, but the Make
|
|
1303
|
+
// listing is private in review — so the installable path today is the
|
|
1304
|
+
// documented HTTP recipe (AutomationConnectors owning copy, status
|
|
1305
|
+
// `preview`).
|
|
1306
|
+
slug: "make",
|
|
1307
|
+
name: "Decionis for Make",
|
|
1308
|
+
vendor: "Make",
|
|
1309
|
+
category: "automation",
|
|
1310
|
+
status: "installable",
|
|
1311
|
+
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.",
|
|
1312
|
+
capabilities: ["automation-step-governance", "signed-decision-dossier"],
|
|
1313
|
+
decisionsSupported: ["automation-step"],
|
|
1314
|
+
installation: [
|
|
1315
|
+
{
|
|
1316
|
+
kind: "docs",
|
|
1317
|
+
url: `${SITE}/docs/automation-connectors#make`,
|
|
1318
|
+
label: "HTTP recipe (native app listing in review)"
|
|
1319
|
+
}
|
|
1320
|
+
],
|
|
1321
|
+
documentation: `${SITE}/docs/automation-connectors#make`,
|
|
1322
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1323
|
+
activation: { method: "oauth", requiresWorkspace: true },
|
|
1324
|
+
presenceSupport: "planned"
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
// Community node published on npm (registry sweep 2026-08-10:
|
|
1328
|
+
// n8n-nodes-decionis@0.1.0).
|
|
1329
|
+
slug: "n8n",
|
|
1330
|
+
name: "Decionis for n8n",
|
|
1331
|
+
vendor: "n8n",
|
|
1332
|
+
category: "automation",
|
|
1333
|
+
status: "production",
|
|
1334
|
+
version: "0.1.0",
|
|
1335
|
+
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.",
|
|
1336
|
+
capabilities: ["automation-step-governance", "signed-decision-dossier"],
|
|
1337
|
+
decisionsSupported: ["automation-step"],
|
|
1338
|
+
installation: [
|
|
1339
|
+
{
|
|
1340
|
+
kind: "npm",
|
|
1341
|
+
url: "https://www.npmjs.com/package/n8n-nodes-decionis",
|
|
1342
|
+
label: "n8n community node on npm"
|
|
1343
|
+
}
|
|
1344
|
+
],
|
|
1345
|
+
documentation: `${SITE}/docs/automation-connectors#n8n`,
|
|
1346
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1347
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
1348
|
+
presenceSupport: "planned"
|
|
1349
|
+
},
|
|
1350
|
+
// ── Platform ──────────────────────────────────────────────────────────
|
|
1351
|
+
{
|
|
1352
|
+
// The standard webhook path into the protocol — the same Gate 1
|
|
1353
|
+
// admission check, any backend (owning copy: ERP & Webhooks tile +
|
|
1354
|
+
// /docs/webhooks).
|
|
1355
|
+
// `installable`, not `production`: the webhook path is live product
|
|
1356
|
+
// capability, but there is no public marketplace/registry listing to
|
|
1357
|
+
// install it from — you wire it from the documented recipe.
|
|
1358
|
+
slug: "webhooks",
|
|
1359
|
+
name: "ERP & Webhooks",
|
|
1360
|
+
vendor: "Any system of record",
|
|
1361
|
+
category: "platform",
|
|
1362
|
+
status: "installable",
|
|
1363
|
+
summary: "Cross-verify cost basis and inventory against your system of record via standard webhooks \u2014 the same Gate 1 admission check, any backend.",
|
|
1364
|
+
capabilities: ["erp-cross-verification", "webhook-intake"],
|
|
1365
|
+
decisionsSupported: ["cost-basis-verification", "inventory-verification"],
|
|
1366
|
+
installation: [
|
|
1367
|
+
{ kind: "docs", url: `${SITE}/docs/webhooks`, label: "Webhook integration guide" }
|
|
1368
|
+
],
|
|
1369
|
+
documentation: `${SITE}/docs/webhooks`,
|
|
1370
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
1371
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
1372
|
+
presenceSupport: "planned",
|
|
1373
|
+
providerId: "WEBHOOK"
|
|
1374
|
+
}
|
|
1375
|
+
];
|
|
1376
|
+
var ConnectorRegistry = class {
|
|
1377
|
+
static connectors = connectors;
|
|
1378
|
+
static bySlug(slug) {
|
|
1379
|
+
return connectors.find((connector) => connector.slug === slug);
|
|
1380
|
+
}
|
|
1381
|
+
static byCategory(category) {
|
|
1382
|
+
return connectors.filter((connector) => connector.category === category);
|
|
1383
|
+
}
|
|
1384
|
+
static byStatus(status) {
|
|
1385
|
+
return connectors.filter((connector) => connector.status === status);
|
|
1386
|
+
}
|
|
1387
|
+
static slugs() {
|
|
1388
|
+
return connectors.map((connector) => connector.slug);
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
var CONNECTOR_REGISTRY = ConnectorRegistry.connectors;
|
|
1392
|
+
var getConnector = ConnectorRegistry.bySlug;
|
|
1393
|
+
var CONNECTOR_SLUGS = ConnectorRegistry.slugs();
|
|
1394
|
+
|
|
862
1395
|
// ../protocol/src/mcp/McpResources.ts
|
|
863
1396
|
var McpResources = class {
|
|
864
1397
|
static buildStaticResources(publicBaseUrl, serviceName, serviceVersion) {
|
|
@@ -898,6 +1431,13 @@ var McpResources = class {
|
|
|
898
1431
|
description: "Available vertical packs and workflow overlays exposed by Decionis Protocol.",
|
|
899
1432
|
mimeType: "application/json"
|
|
900
1433
|
},
|
|
1434
|
+
{
|
|
1435
|
+
uri: "decionis://connectors/registry",
|
|
1436
|
+
name: "connector_registry",
|
|
1437
|
+
title: "Decionis Connector Registry",
|
|
1438
|
+
description: "Every Decionis connector with availability status, install channels, governed actions, and verification evidence \u2014 the same registry that generates decionis.com/integrations.",
|
|
1439
|
+
mimeType: "application/json"
|
|
1440
|
+
},
|
|
901
1441
|
{
|
|
902
1442
|
uri: "decionis://protocol/webex-mcp-registration",
|
|
903
1443
|
name: "webex_mcp_registration",
|
|
@@ -1120,7 +1660,8 @@ var McpResources = class {
|
|
|
1120
1660
|
"resources/read -> decionis://protocol/webex-agent-intent-contract",
|
|
1121
1661
|
"resources/read -> decionis://protocol/webex-reviewer-scenarios",
|
|
1122
1662
|
"tools/call -> decionis.evaluate_webex_agent_intent",
|
|
1123
|
-
"tools/call -> decionis.get_decision_dossier"
|
|
1663
|
+
"tools/call -> decionis.get_decision_dossier",
|
|
1664
|
+
"tools/call -> decionis.get_decision_chain"
|
|
1124
1665
|
]
|
|
1125
1666
|
}
|
|
1126
1667
|
};
|
|
@@ -1146,10 +1687,34 @@ var McpResources = class {
|
|
|
1146
1687
|
});
|
|
1147
1688
|
return { mimeType: "application/json", value: response.body };
|
|
1148
1689
|
}
|
|
1690
|
+
if (uri === "decionis://connectors/registry") {
|
|
1691
|
+
return {
|
|
1692
|
+
mimeType: "application/json",
|
|
1693
|
+
value: {
|
|
1694
|
+
registry: "decionis-connectors",
|
|
1695
|
+
statuses: {
|
|
1696
|
+
production: "generally available today through a live public channel",
|
|
1697
|
+
installable: "customer-deployable today outside public marketplaces",
|
|
1698
|
+
validated: "built and verified (see each connector's verification); downloadable when a package is listed",
|
|
1699
|
+
planned: "roadmap; never carries install channels"
|
|
1700
|
+
},
|
|
1701
|
+
connectors: CONNECTOR_REGISTRY,
|
|
1702
|
+
human_catalogue: "https://decionis.com/integrations"
|
|
1703
|
+
}
|
|
1704
|
+
};
|
|
1705
|
+
}
|
|
1149
1706
|
const parsed = new URL(uri);
|
|
1150
1707
|
if (parsed.protocol !== "decionis:") {
|
|
1151
1708
|
throw new Error(`Unsupported resource URI '${uri}'`);
|
|
1152
1709
|
}
|
|
1710
|
+
if (parsed.hostname === "connectors") {
|
|
1711
|
+
const slug = decodeURIComponent(parsed.pathname.replace(/^\//, ""));
|
|
1712
|
+
const connector = getConnector(slug);
|
|
1713
|
+
if (!connector) {
|
|
1714
|
+
throw new Error(`Unknown connector '${slug}'`);
|
|
1715
|
+
}
|
|
1716
|
+
return { mimeType: "application/json", value: connector };
|
|
1717
|
+
}
|
|
1153
1718
|
if (parsed.hostname === "marketplaces" && parsed.pathname.startsWith("/targets/")) {
|
|
1154
1719
|
const target = decodeURIComponent(parsed.pathname.replace("/targets/", ""));
|
|
1155
1720
|
const response = await invokeProtocolRoute(app, {
|
|
@@ -1419,7 +1984,7 @@ var McpTools = class {
|
|
|
1419
1984
|
return cart && typeof cart.amount === "number" ? cart.amount : void 0;
|
|
1420
1985
|
}
|
|
1421
1986
|
static buildTools(app) {
|
|
1422
|
-
|
|
1987
|
+
const tools = [
|
|
1423
1988
|
{
|
|
1424
1989
|
name: "decionis.evaluate_decision",
|
|
1425
1990
|
aliases: ["evaluate_decision"],
|
|
@@ -1675,6 +2240,37 @@ var McpTools = class {
|
|
|
1675
2240
|
return response.body;
|
|
1676
2241
|
}
|
|
1677
2242
|
},
|
|
2243
|
+
{
|
|
2244
|
+
name: "decionis.get_decision_chain",
|
|
2245
|
+
aliases: ["get_decision_chain"],
|
|
2246
|
+
title: "Get Decision Chain",
|
|
2247
|
+
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.",
|
|
2248
|
+
inputSchema: {
|
|
2249
|
+
type: "object",
|
|
2250
|
+
required: ["org_id", "chain_id"],
|
|
2251
|
+
additionalProperties: false,
|
|
2252
|
+
properties: {
|
|
2253
|
+
org_id: { type: "string", description: "Org UUID." },
|
|
2254
|
+
chain_id: { type: "string", description: "Decision chain UUID." }
|
|
2255
|
+
}
|
|
2256
|
+
},
|
|
2257
|
+
outputSchema: { type: "object", additionalProperties: true },
|
|
2258
|
+
async handler(args) {
|
|
2259
|
+
const orgId = asString(args.org_id);
|
|
2260
|
+
const chainId = asString(args.chain_id);
|
|
2261
|
+
if (!orgId || !chainId) {
|
|
2262
|
+
throw new Error("org_id and chain_id are required");
|
|
2263
|
+
}
|
|
2264
|
+
const response = await invokeProtocolRoute(app, {
|
|
2265
|
+
method: "GET",
|
|
2266
|
+
url: `/v1/protocol/decision-chains/${encodeURIComponent(chainId)}?org_id=${encodeURIComponent(orgId)}`
|
|
2267
|
+
});
|
|
2268
|
+
if (!response.ok) {
|
|
2269
|
+
throw new Error(`Decision chain lookup failed (${response.statusCode})`);
|
|
2270
|
+
}
|
|
2271
|
+
return response.body;
|
|
2272
|
+
}
|
|
2273
|
+
},
|
|
1678
2274
|
{
|
|
1679
2275
|
name: "decionis.list_enforcement_rollouts",
|
|
1680
2276
|
aliases: ["list_enforcement_rollouts"],
|
|
@@ -1893,6 +2489,29 @@ var McpTools = class {
|
|
|
1893
2489
|
}
|
|
1894
2490
|
}
|
|
1895
2491
|
];
|
|
2492
|
+
const readOnlyTools = /* @__PURE__ */ new Set([
|
|
2493
|
+
"decionis.get_decision_dossier",
|
|
2494
|
+
"decionis.get_decision_chain",
|
|
2495
|
+
"decionis.list_enforcement_rollouts",
|
|
2496
|
+
"decionis.list_marketplace_targets",
|
|
2497
|
+
"decionis.get_marketplace_target",
|
|
2498
|
+
"decionis.list_marketplace_readiness",
|
|
2499
|
+
"decionis.list_vertical_packs",
|
|
2500
|
+
"decionis.resolve_vertical_pack"
|
|
2501
|
+
]);
|
|
2502
|
+
const idempotentWriteTools = /* @__PURE__ */ new Set(["decionis.upsert_enforcement_rollout"]);
|
|
2503
|
+
return tools.map((tool) => {
|
|
2504
|
+
const readOnly = readOnlyTools.has(tool.name);
|
|
2505
|
+
return {
|
|
2506
|
+
...tool,
|
|
2507
|
+
annotations: {
|
|
2508
|
+
readOnlyHint: readOnly,
|
|
2509
|
+
destructiveHint: false,
|
|
2510
|
+
idempotentHint: readOnly || idempotentWriteTools.has(tool.name),
|
|
2511
|
+
openWorldHint: false
|
|
2512
|
+
}
|
|
2513
|
+
};
|
|
2514
|
+
});
|
|
1896
2515
|
}
|
|
1897
2516
|
static buildTextToolResult(value, options) {
|
|
1898
2517
|
const text = toPrettyText(value);
|
|
@@ -1946,6 +2565,37 @@ function findTool(tools, name) {
|
|
|
1946
2565
|
}
|
|
1947
2566
|
|
|
1948
2567
|
// ../protocol/src/mcp/McpRoutes.ts
|
|
2568
|
+
async function recordTelemetry(app, sink, event) {
|
|
2569
|
+
if (!sink) return;
|
|
2570
|
+
try {
|
|
2571
|
+
await sink.record(event);
|
|
2572
|
+
} catch (err) {
|
|
2573
|
+
app.log.warn({ err, event: event.event }, "MCP telemetry write failed");
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
function canonicalAuthorizationOutcome(value) {
|
|
2577
|
+
const record = asRecord(value);
|
|
2578
|
+
const raw = asString(record?.outcome) ?? asString(record?.decision) ?? asString(record?.verdict);
|
|
2579
|
+
if (!raw) return null;
|
|
2580
|
+
switch (raw.trim().toUpperCase()) {
|
|
2581
|
+
case "ALLOW":
|
|
2582
|
+
case "APPROVE":
|
|
2583
|
+
case "AUTO_APPROVE":
|
|
2584
|
+
return "ALLOW";
|
|
2585
|
+
case "BLOCK":
|
|
2586
|
+
case "REJECT":
|
|
2587
|
+
case "AUTO_REJECT":
|
|
2588
|
+
return "BLOCK";
|
|
2589
|
+
case "ESCALATE":
|
|
2590
|
+
return "ESCALATE";
|
|
2591
|
+
case "REVIEW":
|
|
2592
|
+
case "RESTRAIN":
|
|
2593
|
+
case "REQUIRE_REVIEW":
|
|
2594
|
+
return "REVIEW";
|
|
2595
|
+
default:
|
|
2596
|
+
return null;
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
1949
2599
|
function buildInitializeResult(serviceName, serviceVersion) {
|
|
1950
2600
|
return {
|
|
1951
2601
|
protocolVersion: MCP_DEFAULT_PROTOCOL_VERSION,
|
|
@@ -1959,7 +2609,7 @@ function buildInitializeResult(serviceName, serviceVersion) {
|
|
|
1959
2609
|
title: "Decionis Protocol MCP",
|
|
1960
2610
|
version: serviceVersion
|
|
1961
2611
|
},
|
|
1962
|
-
instructions: "Use Decionis Protocol
|
|
2612
|
+
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."
|
|
1963
2613
|
};
|
|
1964
2614
|
}
|
|
1965
2615
|
async function handleJsonRpcRequest(app, requestBody, options) {
|
|
@@ -1997,6 +2647,16 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
1997
2647
|
}
|
|
1998
2648
|
const requestedVersion = asString(params.protocolVersion);
|
|
1999
2649
|
const negotiatedVersion = requestedVersion && MCP_PROTOCOL_VERSIONS.includes(requestedVersion) ? requestedVersion : MCP_DEFAULT_PROTOCOL_VERSION;
|
|
2650
|
+
const clientInfo = asRecord(params.clientInfo);
|
|
2651
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2652
|
+
event: "connection_succeeded",
|
|
2653
|
+
connectionId: options.connectionId,
|
|
2654
|
+
clientName: asString(clientInfo?.name),
|
|
2655
|
+
clientVersion: asString(clientInfo?.version),
|
|
2656
|
+
protocolVersion: negotiatedVersion,
|
|
2657
|
+
authMode: options.auth?.kind ?? "none",
|
|
2658
|
+
statusCode: 200
|
|
2659
|
+
});
|
|
2000
2660
|
return {
|
|
2001
2661
|
statusCode: 200,
|
|
2002
2662
|
payload: jsonRpcSuccess(id, {
|
|
@@ -2012,6 +2672,12 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
2012
2672
|
case "ping":
|
|
2013
2673
|
return { statusCode: 200, payload: jsonRpcSuccess(id, {}) };
|
|
2014
2674
|
case "tools/list":
|
|
2675
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2676
|
+
event: "tools_listed",
|
|
2677
|
+
connectionId: options.connectionId,
|
|
2678
|
+
authMode: options.auth?.kind ?? "none",
|
|
2679
|
+
statusCode: 200
|
|
2680
|
+
});
|
|
2015
2681
|
return {
|
|
2016
2682
|
statusCode: 200,
|
|
2017
2683
|
payload: jsonRpcSuccess(id, {
|
|
@@ -2020,7 +2686,8 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
2020
2686
|
title: tool.title,
|
|
2021
2687
|
description: tool.description,
|
|
2022
2688
|
inputSchema: tool.inputSchema,
|
|
2023
|
-
...tool.outputSchema ? { outputSchema: tool.outputSchema } : {}
|
|
2689
|
+
...tool.outputSchema ? { outputSchema: tool.outputSchema } : {},
|
|
2690
|
+
annotations: tool.annotations
|
|
2024
2691
|
}))
|
|
2025
2692
|
})
|
|
2026
2693
|
};
|
|
@@ -2039,15 +2706,61 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
2039
2706
|
payload: jsonRpcError(id, -32601, `Unknown tool '${name}'`)
|
|
2040
2707
|
};
|
|
2041
2708
|
}
|
|
2709
|
+
const toolStartedAt = process.hrtime.bigint();
|
|
2710
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2711
|
+
event: "tool_called",
|
|
2712
|
+
connectionId: options.connectionId,
|
|
2713
|
+
toolName: tool.name,
|
|
2714
|
+
authMode: options.auth?.kind ?? "none"
|
|
2715
|
+
});
|
|
2042
2716
|
const args = asRecord(params.arguments) ?? {};
|
|
2043
2717
|
const authError = authorizeToolInvocation(options.auth, name, args);
|
|
2044
2718
|
if (authError) {
|
|
2719
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2720
|
+
event: "authorization_outcome",
|
|
2721
|
+
connectionId: options.connectionId,
|
|
2722
|
+
toolName: tool.name,
|
|
2723
|
+
outcome: "DENIED",
|
|
2724
|
+
authMode: options.auth?.kind ?? "none",
|
|
2725
|
+
statusCode: 403,
|
|
2726
|
+
durationMs: durationMs(toolStartedAt)
|
|
2727
|
+
});
|
|
2728
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2729
|
+
event: "tool_failed",
|
|
2730
|
+
connectionId: options.connectionId,
|
|
2731
|
+
toolName: tool.name,
|
|
2732
|
+
outcome: "DENIED",
|
|
2733
|
+
authMode: options.auth?.kind ?? "none",
|
|
2734
|
+
statusCode: 403,
|
|
2735
|
+
durationMs: durationMs(toolStartedAt)
|
|
2736
|
+
});
|
|
2045
2737
|
return {
|
|
2046
2738
|
statusCode: 403,
|
|
2047
2739
|
payload: jsonRpcError(id, authError.code, authError.message)
|
|
2048
2740
|
};
|
|
2049
2741
|
}
|
|
2050
2742
|
const result = await handleToolCall(tool, args);
|
|
2743
|
+
const outcome = canonicalAuthorizationOutcome(result.structuredContent);
|
|
2744
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2745
|
+
event: result.isError ? "tool_failed" : "tool_succeeded",
|
|
2746
|
+
connectionId: options.connectionId,
|
|
2747
|
+
toolName: tool.name,
|
|
2748
|
+
outcome,
|
|
2749
|
+
authMode: options.auth?.kind ?? "none",
|
|
2750
|
+
statusCode: 200,
|
|
2751
|
+
durationMs: durationMs(toolStartedAt)
|
|
2752
|
+
});
|
|
2753
|
+
if (outcome) {
|
|
2754
|
+
await recordTelemetry(app, options.telemetry, {
|
|
2755
|
+
event: "authorization_outcome",
|
|
2756
|
+
connectionId: options.connectionId,
|
|
2757
|
+
toolName: tool.name,
|
|
2758
|
+
outcome,
|
|
2759
|
+
authMode: options.auth?.kind ?? "none",
|
|
2760
|
+
statusCode: 200,
|
|
2761
|
+
durationMs: durationMs(toolStartedAt)
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2051
2764
|
return {
|
|
2052
2765
|
statusCode: 200,
|
|
2053
2766
|
payload: jsonRpcSuccess(id, result)
|
|
@@ -2063,6 +2776,13 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
2063
2776
|
statusCode: 200,
|
|
2064
2777
|
payload: jsonRpcSuccess(id, {
|
|
2065
2778
|
resourceTemplates: [
|
|
2779
|
+
{
|
|
2780
|
+
uriTemplate: "decionis://connectors/{slug}",
|
|
2781
|
+
name: "connector_detail",
|
|
2782
|
+
title: "Connector Detail",
|
|
2783
|
+
description: "Read one Connector Registry row: status, install channels, governed actions, verification.",
|
|
2784
|
+
mimeType: "application/json"
|
|
2785
|
+
},
|
|
2066
2786
|
{
|
|
2067
2787
|
uriTemplate: "decionis://marketplaces/targets/{target}",
|
|
2068
2788
|
name: "marketplace_target_detail",
|
|
@@ -2224,6 +2944,11 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
2224
2944
|
const auth = await authenticateMcpRequest(req, authLookup);
|
|
2225
2945
|
const authDurationMs = durationMs(authStartedAt);
|
|
2226
2946
|
if (!auth && isAuthenticationRequired(authLookup)) {
|
|
2947
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
2948
|
+
event: "authentication_failed",
|
|
2949
|
+
statusCode: 401,
|
|
2950
|
+
durationMs: authDurationMs
|
|
2951
|
+
});
|
|
2227
2952
|
const maybeId = asRecord(req.body)?.id;
|
|
2228
2953
|
const id = typeof maybeId === "string" || typeof maybeId === "number" ? maybeId : null;
|
|
2229
2954
|
reply.header(
|
|
@@ -2233,6 +2958,10 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
2233
2958
|
stages: { auth_ms: authDurationMs }
|
|
2234
2959
|
})
|
|
2235
2960
|
);
|
|
2961
|
+
reply.header(
|
|
2962
|
+
"www-authenticate",
|
|
2963
|
+
`Bearer resource_metadata="${options.publicBaseUrl}/.well-known/oauth-protected-resource", error="invalid_token"`
|
|
2964
|
+
);
|
|
2236
2965
|
return reply.code(401).send(jsonRpcError(id, -32001, "Unauthorized MCP request"));
|
|
2237
2966
|
}
|
|
2238
2967
|
if (Array.isArray(req.body)) {
|
|
@@ -2247,7 +2976,35 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
2247
2976
|
}
|
|
2248
2977
|
if (isLegacyToolCall(req.body)) {
|
|
2249
2978
|
const rpcStartedAt2 = process.hrtime.bigint();
|
|
2979
|
+
const connectionId2 = asString(req.headers["mcp-session-id"]);
|
|
2980
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
2981
|
+
event: "tool_called",
|
|
2982
|
+
connectionId: connectionId2,
|
|
2983
|
+
toolName: req.body.tool_name,
|
|
2984
|
+
authMode: auth?.kind ?? "none"
|
|
2985
|
+
});
|
|
2250
2986
|
const payload = await handleLegacyToolCall(app, auth, req.body);
|
|
2987
|
+
const outcome = canonicalAuthorizationOutcome(payload.output);
|
|
2988
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
2989
|
+
event: payload.is_error || payload.error ? "tool_failed" : "tool_succeeded",
|
|
2990
|
+
connectionId: connectionId2,
|
|
2991
|
+
toolName: req.body.tool_name,
|
|
2992
|
+
outcome,
|
|
2993
|
+
authMode: auth?.kind ?? "none",
|
|
2994
|
+
statusCode: 200,
|
|
2995
|
+
durationMs: durationMs(rpcStartedAt2)
|
|
2996
|
+
});
|
|
2997
|
+
if (outcome) {
|
|
2998
|
+
await recordTelemetry(app, options.telemetry ?? null, {
|
|
2999
|
+
event: "authorization_outcome",
|
|
3000
|
+
connectionId: connectionId2,
|
|
3001
|
+
toolName: req.body.tool_name,
|
|
3002
|
+
outcome,
|
|
3003
|
+
authMode: auth?.kind ?? "none",
|
|
3004
|
+
statusCode: 200,
|
|
3005
|
+
durationMs: durationMs(rpcStartedAt2)
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
2251
3008
|
reply.header(
|
|
2252
3009
|
"server-timing",
|
|
2253
3010
|
buildServerTimingHeader({
|
|
@@ -2272,13 +3029,21 @@ async function handleMcpHttpRequest(app, req, reply, options) {
|
|
|
2272
3029
|
return reply.code(400).send(jsonRpcError(null, -32600, "JSON-RPC request body required"));
|
|
2273
3030
|
}
|
|
2274
3031
|
const rpcStartedAt = process.hrtime.bigint();
|
|
3032
|
+
const requestedMethod = asString(requestBody.method);
|
|
3033
|
+
const incomingSession = asString(req.headers["mcp-session-id"]);
|
|
3034
|
+
const connectionId = requestedMethod === "initialize" ? randomUUID2() : incomingSession;
|
|
2275
3035
|
const result = await handleJsonRpcRequest(app, requestBody, {
|
|
2276
3036
|
publicBaseUrl: options.publicBaseUrl,
|
|
2277
3037
|
serviceName: options.serviceName,
|
|
2278
3038
|
serviceVersion: options.serviceVersion,
|
|
2279
3039
|
auth,
|
|
2280
|
-
authLookup
|
|
3040
|
+
authLookup,
|
|
3041
|
+
telemetry: options.telemetry ?? null,
|
|
3042
|
+
connectionId
|
|
2281
3043
|
});
|
|
3044
|
+
if (requestedMethod === "initialize" && result.statusCode === 200) {
|
|
3045
|
+
reply.header("mcp-session-id", connectionId);
|
|
3046
|
+
}
|
|
2282
3047
|
reply.header(
|
|
2283
3048
|
"server-timing",
|
|
2284
3049
|
buildServerTimingHeader({
|
|
@@ -2308,8 +3073,21 @@ function registerProtocolMcpRoutes(app, options) {
|
|
|
2308
3073
|
endpoint: `${publicBaseUrl}/v1/protocol/mcp`,
|
|
2309
3074
|
endpoint_aliases: MCP_HTTP_PATHS,
|
|
2310
3075
|
supported_protocol_versions: [...MCP_PROTOCOL_VERSIONS],
|
|
2311
|
-
auth
|
|
3076
|
+
auth,
|
|
3077
|
+
oauth: {
|
|
3078
|
+
protected_resource_metadata: `${publicBaseUrl}/.well-known/oauth-protected-resource`,
|
|
3079
|
+
authorization_server_metadata: "https://api.decionis.com/.well-known/oauth-authorization-server"
|
|
3080
|
+
}
|
|
3081
|
+
};
|
|
3082
|
+
const oauthProtectedResource = {
|
|
3083
|
+
resource: `${publicBaseUrl}/mcp`,
|
|
3084
|
+
authorization_servers: ["https://api.decionis.com"],
|
|
3085
|
+
bearer_methods_supported: ["header"],
|
|
3086
|
+
scopes_supported: ["decision:read", "decision:run", "decision:write"],
|
|
3087
|
+
resource_documentation: "https://decionis.com/docs/protocol-mcp"
|
|
2312
3088
|
};
|
|
3089
|
+
app.get("/.well-known/oauth-protected-resource", async () => oauthProtectedResource);
|
|
3090
|
+
app.get("/.well-known/oauth-protected-resource/mcp", async () => oauthProtectedResource);
|
|
2313
3091
|
for (const path of MCP_HTTP_PATHS) {
|
|
2314
3092
|
app.get(path, async () => metadata);
|
|
2315
3093
|
app.delete(path, async (_req, reply) => reply.code(204).send());
|
|
@@ -2319,7 +3097,8 @@ function registerProtocolMcpRoutes(app, options) {
|
|
|
2319
3097
|
publicBaseUrl,
|
|
2320
3098
|
serviceName: options.serviceName,
|
|
2321
3099
|
serviceVersion: options.serviceVersion,
|
|
2322
|
-
authLookup
|
|
3100
|
+
authLookup,
|
|
3101
|
+
telemetry: options.telemetry ?? null
|
|
2323
3102
|
})
|
|
2324
3103
|
);
|
|
2325
3104
|
}
|
|
@@ -10510,7 +11289,8 @@ function buildDecisionDossierPersistedProofBundle(input) {
|
|
|
10510
11289
|
}
|
|
10511
11290
|
|
|
10512
11291
|
// ../protocol/src/support/PanDetection.ts
|
|
10513
|
-
var PanDetection = class {
|
|
11292
|
+
var PanDetection = class _PanDetection {
|
|
11293
|
+
static UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10514
11294
|
static toDigits(value) {
|
|
10515
11295
|
if (typeof value !== "string" && typeof value !== "number") return null;
|
|
10516
11296
|
const digits = String(value).replace(/\D/g, "");
|
|
@@ -10532,12 +11312,32 @@ var PanDetection = class {
|
|
|
10532
11312
|
}
|
|
10533
11313
|
return sum % 10 === 0;
|
|
10534
11314
|
}
|
|
11315
|
+
/**
|
|
11316
|
+
* Candidate card numbers inside a value: runs of digits separated only by the
|
|
11317
|
+
* characters a card number is actually written with (spaces and dashes).
|
|
11318
|
+
*
|
|
11319
|
+
* Splitting on everything else is the whole point. Stripping every non-digit
|
|
11320
|
+
* from the value instead — which this used to do — welds unrelated digits
|
|
11321
|
+
* together across letters and punctuation, and a UUID is the case that bites:
|
|
11322
|
+
* discard its letters and roughly 4% of them are a 13-to-19-digit string that
|
|
11323
|
+
* satisfies Luhn. Since we put UUIDs into decision context ourselves (the
|
|
11324
|
+
* duplicate-payment fact carries the prior dossier id), that turned a
|
|
11325
|
+
* legitimate duplicate-payment decision into "raw PAN-like value detected"
|
|
11326
|
+
* about one time in twenty-five.
|
|
11327
|
+
*/
|
|
11328
|
+
static panCandidates(value) {
|
|
11329
|
+
if (typeof value === "number") return [String(value).replace(/[^\d]/g, "")];
|
|
11330
|
+
if (typeof value !== "string") return [];
|
|
11331
|
+
if (_PanDetection.UUID_SHAPE.test(value.trim())) return [];
|
|
11332
|
+
const runs = value.match(/(?<![0-9A-Za-z])\d[\d \-]*\d(?![0-9A-Za-z])/g) ?? [];
|
|
11333
|
+
return runs.map((run) => run.replace(/[^\d]/g, "")).filter((digits) => digits.length > 0);
|
|
11334
|
+
}
|
|
10535
11335
|
static looksLikeRawPan(value) {
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
11336
|
+
return _PanDetection.panCandidates(value).some((digits) => {
|
|
11337
|
+
if (digits.length < 13 || digits.length > 19) return false;
|
|
11338
|
+
if (/^(\d)\1+$/.test(digits)) return false;
|
|
11339
|
+
return isLuhnValid(digits);
|
|
11340
|
+
});
|
|
10541
11341
|
}
|
|
10542
11342
|
static findRawPanPath(value, path, visited = /* @__PURE__ */ new Set()) {
|
|
10543
11343
|
if (looksLikeRawPan(value)) return path;
|
|
@@ -10558,9 +11358,6 @@ var PanDetection = class {
|
|
|
10558
11358
|
return null;
|
|
10559
11359
|
}
|
|
10560
11360
|
};
|
|
10561
|
-
function toDigits(value) {
|
|
10562
|
-
return PanDetection.toDigits(value);
|
|
10563
|
-
}
|
|
10564
11361
|
function isLuhnValid(digits) {
|
|
10565
11362
|
return PanDetection.isLuhnValid(digits);
|
|
10566
11363
|
}
|
|
@@ -15836,10 +16633,15 @@ var readiness = {
|
|
|
15836
16633
|
"adobe-commerce": {
|
|
15837
16634
|
target: "adobe-commerce",
|
|
15838
16635
|
protocol_capture: "CAPTURED",
|
|
16636
|
+
// adapter_state stays BUILDING deliberately: Adobe's Marketplace
|
|
16637
|
+
// technical review passed in full (all phases, SID qv4l7d2ak6 — automated
|
|
16638
|
+
// EQP 2026-07-08, final confirmation 2026-08-10, tested on Magento 2.4.9
|
|
16639
|
+
// EE + CE / PHP 8.5.5), but the gate has not yet run against a live
|
|
16640
|
+
// merchant store, and that is the bar LIVE means here.
|
|
15839
16641
|
adapter_state: "BUILDING",
|
|
15840
|
-
docs_state: "
|
|
16642
|
+
docs_state: "BUILDING",
|
|
15841
16643
|
launch_state: "PLANNED",
|
|
15842
|
-
next_milestone: "
|
|
16644
|
+
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"
|
|
15843
16645
|
},
|
|
15844
16646
|
shopware: {
|
|
15845
16647
|
target: "shopware",
|
|
@@ -15860,10 +16662,16 @@ var readiness = {
|
|
|
15860
16662
|
woo: {
|
|
15861
16663
|
target: "woo",
|
|
15862
16664
|
protocol_capture: "CAPTURED",
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
|
|
15866
|
-
|
|
16665
|
+
// Truth-up 2026-08-10: the plugin is published in the WordPress.org
|
|
16666
|
+
// directory (slug `decionis`, 1.0.0) and Block + classic checkout,
|
|
16667
|
+
// core COGS, HPOS order CRUD, and the signed dossier were verified end
|
|
16668
|
+
// to end on a staging store — including an admin-enabled ENFORCEMENT
|
|
16669
|
+
// block — before the listing went live (shared readiness provenance).
|
|
16670
|
+
// The previous PLANNED states predated the public listing.
|
|
16671
|
+
adapter_state: "LIVE",
|
|
16672
|
+
docs_state: "LIVE",
|
|
16673
|
+
launch_state: "BUILDING",
|
|
16674
|
+
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"
|
|
15867
16675
|
},
|
|
15868
16676
|
jumia: {
|
|
15869
16677
|
target: "jumia",
|
|
@@ -16565,7 +17373,8 @@ function buildProtocolApp(options) {
|
|
|
16565
17373
|
registerProtocolMcpRoutes(app, {
|
|
16566
17374
|
serviceName: PROTOCOL_SERVICE,
|
|
16567
17375
|
serviceVersion: PROTOCOL_VERSION,
|
|
16568
|
-
authLookup: options?.mcpAuthLookup ?? null
|
|
17376
|
+
authLookup: options?.mcpAuthLookup ?? null,
|
|
17377
|
+
telemetry: options?.mcpTelemetry ?? null
|
|
16569
17378
|
});
|
|
16570
17379
|
const executionAuthority = createExecutionGatingService(options?.executionGating);
|
|
16571
17380
|
registerExecutionGatingRoutes(app, {
|
|
@@ -16941,4 +17750,4 @@ export {
|
|
|
16941
17750
|
normalizeVerdict,
|
|
16942
17751
|
PolicyFileRepository
|
|
16943
17752
|
};
|
|
16944
|
-
//# sourceMappingURL=chunk-
|
|
17753
|
+
//# sourceMappingURL=chunk-KY5AVRL6.js.map
|