revclamp-mcp 1.20.10 → 1.20.11
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/README.md +6 -6
- package/index.mjs +1 -1
- package/local_engine.mjs +149 -27
- package/mcp-config.json +1 -1
- package/package.json +3 -3
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
**`revclamp-mcp`** is a standalone, zero-dependency **Open-Source Model Context Protocol (MCP) Server & CLI** (`index.mjs` + `local_engine.mjs`) implementing **9 deterministic B2B FinOps, Stripe `2025-03-31.basil`, Visa CE 3.0, EU/XI VIES VAT, Shopify Plus B2B Net-15/30/60, and Webhook Security tools** in pure Node.js.
|
|
6
6
|
|
|
7
7
|
- **100% Local In-Process Execution (Default — Zero Network / Zero API Key Required):** All 9 MCP tools (`initialize`, `tools/list`, and `tools/call`) execute locally in-process inside [`local_engine.mjs`](./local_engine.mjs) using pure Node.js (`node:crypto` HMAC-SHA256 verification, integer-cent double-entry accounting, 72-hour webhook replay state machines, and `18,000` UTF-16 code unit CE 3.0 linting). Zero network calls are ever made unless `REVCLAMP_API_KEY` or `REVCLAMP_MCP_URL` is explicitly configured.
|
|
8
|
-
- **Optional Hosted Cloud Workspace Sync (`REVCLAMP_API_KEY`):** When `REVCLAMP_API_KEY` (`rg_live_...`) is configured, `revclamp-mcp` connects to [**RevClamp Enterprise**](https://revclamp.com) (`https://api.revclamp.com/api/mcp`) to unlock the **90-day
|
|
8
|
+
- **Optional Hosted Cloud Workspace Sync (`REVCLAMP_API_KEY`):** When `REVCLAMP_API_KEY` (`rg_live_...`) is configured, `revclamp-mcp` connects to [**RevClamp Enterprise**](https://revclamp.com) (`https://api.revclamp.com/api/mcp`) to unlock the **90-day durable transactional usage & audit ledger**, **24/7 autonomous Stripe dispute & entitlement webhook outbox**, and **real-time EU Commission VIES SOAP gateway consultation numbers**.
|
|
9
9
|
|
|
10
10
|
## Local Open-Core (`local_engine.mjs`) vs. Hosted Cloud (`REVCLAMP_API_KEY`)
|
|
11
11
|
|
|
12
12
|
| Capability | Local Open-Core Default (Zero API Key) | Hosted Cloud (`REVCLAMP_API_KEY`) |
|
|
13
13
|
| :--- | :--- | :--- |
|
|
14
14
|
| **Execution & Network** | 100% in-process (`local_engine.mjs`), zero network calls | HTTPS JSON-RPC to `https://api.revclamp.com/api/mcp` (`redirect: "error"`) |
|
|
15
|
-
| **Usage & Audit Storage** | Stateless evaluation of caller-supplied JSON snapshots | **Persistent 90-day
|
|
15
|
+
| **Usage & Audit Storage** | Stateless evaluation of caller-supplied JSON snapshots | **Persistent 90-day durable transactional ledger** + Stripe historical backfill |
|
|
16
16
|
| **Dispute & Entitlement Action** | Returns non-destructive `submit: false` draft & `revoke_entitlement` decision | **24/7 autonomous Stripe webhook outbox** (`disputes.update` & signed revoke webhooks) |
|
|
17
17
|
| **EU & `XI` B2B VAT (`VIES`)** | Deterministic syntax & `GR -> EL` normalization (`FORMAT_ONLY` default, `valid: null`) | **Live EU Commission VIES SOAP consultation IDs** + circuit-breaker retry queue (`viesMode: "LIVE"` + `REVCLAMP_API_KEY`) |
|
|
18
18
|
| **Monthly Event Tiers** | Unlimited local in-process evaluations (0 network cost) | **Free Sandbox** (`5,000` events/mo) · **Starter $19/mo** (`100k`) · **Growth $59/mo** (`1M`) · **Scale $199/mo** (`5M`) |
|
|
19
|
-
| **Data Privacy
|
|
19
|
+
| **Data Minimization & Privacy** | Nothing ever leaves your machine | Only explicit `tools/call` arguments are sent over TLS after local live-secret scrubbing (blocks `sk_live_`, non-test `whsec_`, and `shpat_` locally before any network request) |
|
|
20
20
|
|
|
21
21
|
## Open-Source MCP Tools Implemented in `local_engine.mjs` (9)
|
|
22
22
|
|
|
@@ -59,13 +59,13 @@ curl -sS -X POST https://api.revclamp.com/api/mcp \
|
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
# Run a <60s local CLI smoke check (verifies all 9 tool schemas & executes a local_engine.mjs sample audit with zero API key)
|
|
62
|
-
npx -y github:lhphong09t2/revclamp-mcp#v1.20.
|
|
62
|
+
npx -y github:lhphong09t2/revclamp-mcp#v1.20.11 --self-test
|
|
63
63
|
|
|
64
64
|
# Provision a free Cloud Workspace (or reuse REVCLAMP_API_KEY) & send a 6-digit login OTP
|
|
65
|
-
npx -y revclamp-mcp@1.20.
|
|
65
|
+
npx -y revclamp-mcp@1.20.11 --init-workspace you@company.com
|
|
66
66
|
|
|
67
67
|
# Verify the 6-digit OTP using REVCLAMP_API_KEY from environment
|
|
68
|
-
REVCLAMP_API_KEY="rg_live_..." npx -y revclamp-mcp@1.20.
|
|
68
|
+
REVCLAMP_API_KEY="rg_live_..." npx -y revclamp-mcp@1.20.11 --verify-otp you@company.com 123456
|
|
69
69
|
|
|
70
70
|
# List all 9 MCP tools and JSON schemas (runs locally in-process)
|
|
71
71
|
node index.mjs --list-tools
|
package/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@ export {
|
|
|
33
33
|
executeLocalMcpJsonRpc,
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
export const PACKAGE_VERSION = "1.20.
|
|
36
|
+
export const PACKAGE_VERSION = "1.20.11";
|
|
37
37
|
export const DEFAULT_MCP_ENDPOINT = "https://api.revclamp.com/api/mcp";
|
|
38
38
|
export const ALLOWED_MCP_ORIGINS = Object.freeze(
|
|
39
39
|
new Set([
|
package/local_engine.mjs
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* caller-supplied payloads. Never fabricates live consultation IDs or card-network
|
|
13
13
|
* dispute evidence unless `demo: true` is explicitly passed (`sample: true`).
|
|
14
14
|
* - Cloud Workspace Mode (`REVCLAMP_API_KEY` on https://api.revclamp.com/api/mcp):
|
|
15
|
-
* Unlocks the 90-day
|
|
15
|
+
* Unlocks the 90-day durable transactional usage ledger, 24/7 autonomous Stripe dispute &
|
|
16
16
|
* entitlement webhook outbox, and live European Commission VIES consultation IDs.
|
|
17
17
|
*/
|
|
18
18
|
|
|
@@ -145,7 +145,7 @@ export const LOCAL_MCP_RESOURCES = Object.freeze([
|
|
|
145
145
|
uri: "revclamp://docs/open-core-capabilities",
|
|
146
146
|
name: "RevClamp Open-Core vs Hosted Cloud Capabilities",
|
|
147
147
|
description:
|
|
148
|
-
"Reference summary of the 9 local deterministic MCP tools vs. hosted REVCLAMP_API_KEY capabilities (90-day
|
|
148
|
+
"Reference summary of the 9 local deterministic MCP tools vs. hosted REVCLAMP_API_KEY capabilities (90-day durable transactional ledger, 24/7 Stripe webhook outbox, and live EU VIES consultation IDs).",
|
|
149
149
|
mimeType: "application/json",
|
|
150
150
|
}),
|
|
151
151
|
]);
|
|
@@ -189,7 +189,7 @@ const EU_VIES_FORMAT_RULES = Object.freeze({
|
|
|
189
189
|
DK: /^DK\d{8}$/,
|
|
190
190
|
EE: /^EE\d{9}$/,
|
|
191
191
|
EL: /^EL\d{9}$/,
|
|
192
|
-
ES: /^ES[A-
|
|
192
|
+
ES: /^ES(?:[A-Z]\d{7}[A-Z0-9]|[0-9]\d{7}[A-Z])$/,
|
|
193
193
|
FI: /^FI\d{8}$/,
|
|
194
194
|
FR: /^FR[A-HJ-NP-Z0-9]{2}\d{9}$/,
|
|
195
195
|
HR: /^HR\d{11}$/,
|
|
@@ -655,14 +655,20 @@ export function validateArgsAgainstSchema(schema, args) {
|
|
|
655
655
|
function normalizeCountryCode(raw) {
|
|
656
656
|
const clean = String(raw || "")
|
|
657
657
|
.trim()
|
|
658
|
-
.toUpperCase()
|
|
659
|
-
|
|
658
|
+
.toUpperCase()
|
|
659
|
+
.replace(/[\s.\-/:_]+/g, "");
|
|
660
|
+
if (clean === "GR") return "EL";
|
|
661
|
+
if (clean === "GBNIR") return "XI";
|
|
662
|
+
return clean;
|
|
660
663
|
}
|
|
661
664
|
|
|
662
665
|
function normalizeVatId(rawVat) {
|
|
663
|
-
|
|
666
|
+
let compact = String(rawVat || "")
|
|
664
667
|
.toUpperCase()
|
|
665
|
-
.replace(/[\s.\-/:]+/g, "");
|
|
668
|
+
.replace(/[\s.\-/:_]+/g, "");
|
|
669
|
+
if (compact.startsWith("GBNIR")) {
|
|
670
|
+
compact = `XI${compact.slice(5)}`;
|
|
671
|
+
}
|
|
666
672
|
if (compact.length < 4) {
|
|
667
673
|
return { validFormat: false, memberState: "", vatNumber: "", fullVatId: compact };
|
|
668
674
|
}
|
|
@@ -1008,14 +1014,37 @@ function evaluateLocalGhostUsage(subscriptionsEnv, usageEvent, dunningGracePerio
|
|
|
1008
1014
|
reason: "UNMATCHED_CUSTOMER_ID",
|
|
1009
1015
|
};
|
|
1010
1016
|
}
|
|
1017
|
+
const hasPositiveCustomerIdMatch = Boolean(evCustomerId && subCus && subCus === evCustomerId);
|
|
1018
|
+
const hasPositiveEmailMatch = Boolean(evEmail && subEmail && subEmail === evEmail);
|
|
1019
|
+
if (!hasPositiveCustomerIdMatch && !hasPositiveEmailMatch) {
|
|
1020
|
+
return {
|
|
1021
|
+
ok: true,
|
|
1022
|
+
executionMode: "local_open_source_engine",
|
|
1023
|
+
isGhostUsage: false,
|
|
1024
|
+
decision: "HOLD_CUSTOMER_MISMATCH",
|
|
1025
|
+
reason: subCus ? "UNMATCHED_CUSTOMER_ID" : "UNMATCHED_CUSTOMER_EMAIL",
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1011
1028
|
const st = sub.status.trim();
|
|
1012
1029
|
if (ENTITLED_SUB_STATUSES.has(st)) {
|
|
1030
|
+
const collectionPaused = Boolean(
|
|
1031
|
+
sub.pause_collection && typeof sub.pause_collection === "object"
|
|
1032
|
+
);
|
|
1013
1033
|
return {
|
|
1014
1034
|
ok: true,
|
|
1015
1035
|
executionMode: "local_open_source_engine",
|
|
1016
1036
|
isGhostUsage: false,
|
|
1017
1037
|
decision: "ALLOW_ENTITLED",
|
|
1018
1038
|
reason: "ACTIVE_SUBSCRIPTION_PRESENT",
|
|
1039
|
+
...(collectionPaused
|
|
1040
|
+
? {
|
|
1041
|
+
collectionPaused: true,
|
|
1042
|
+
pauseCollectionBehavior:
|
|
1043
|
+
typeof sub.pause_collection.behavior === "string"
|
|
1044
|
+
? sub.pause_collection.behavior
|
|
1045
|
+
: "void",
|
|
1046
|
+
}
|
|
1047
|
+
: {}),
|
|
1019
1048
|
};
|
|
1020
1049
|
}
|
|
1021
1050
|
if (sub.items?.has_more === true) {
|
|
@@ -1152,7 +1181,36 @@ function parseStrictIpv4Octets(str) {
|
|
|
1152
1181
|
|
|
1153
1182
|
function normalizeIpForCe3Correlation(ip) {
|
|
1154
1183
|
if (typeof ip !== "string") return null;
|
|
1155
|
-
|
|
1184
|
+
let raw = ip.trim().toLowerCase();
|
|
1185
|
+
if (!raw || raw.includes(",")) return null;
|
|
1186
|
+
if (raw.startsWith("ipv4:")) {
|
|
1187
|
+
raw = raw.slice(5).trim();
|
|
1188
|
+
} else if (raw.startsWith("ipv6_64:")) {
|
|
1189
|
+
const v6Match = raw.match(
|
|
1190
|
+
/^ipv6_64:([0-9a-f]{1,4}):([0-9a-f]{1,4}):([0-9a-f]{1,4}):([0-9a-f]{1,4})$/
|
|
1191
|
+
);
|
|
1192
|
+
if (!v6Match) return null;
|
|
1193
|
+
return `ipv6_64:${v6Match
|
|
1194
|
+
.slice(1, 5)
|
|
1195
|
+
.map((w) => Number.parseInt(w, 16).toString(16).padStart(4, "0"))
|
|
1196
|
+
.join(":")}`;
|
|
1197
|
+
}
|
|
1198
|
+
const bracketPortMatch = raw.match(/^\[([^\]]+)\](?::(\d{1,5}))?$/);
|
|
1199
|
+
if (bracketPortMatch) {
|
|
1200
|
+
if (bracketPortMatch[2] !== undefined) {
|
|
1201
|
+
const portNum = Number(bracketPortMatch[2]);
|
|
1202
|
+
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) return null;
|
|
1203
|
+
}
|
|
1204
|
+
raw = bracketPortMatch[1];
|
|
1205
|
+
} else {
|
|
1206
|
+
const v4PortMatch = raw.match(/^(\d{1,3}(?:\.\d{1,3}){3}):(\d{1,5})$/);
|
|
1207
|
+
if (v4PortMatch) {
|
|
1208
|
+
const portNum = Number(v4PortMatch[2]);
|
|
1209
|
+
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) return null;
|
|
1210
|
+
raw = v4PortMatch[1];
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const clean = raw.replace(/^\[|\]$/g, "").replace(/%[^\s%\]]+$/, "").trim();
|
|
1156
1214
|
if (!clean) return null;
|
|
1157
1215
|
const directV4 = parseStrictIpv4Octets(clean);
|
|
1158
1216
|
if (directV4) return `ipv4:${directV4.join(".")}`;
|
|
@@ -1283,14 +1341,30 @@ function extractNormalizedCe3Identifiers(tx) {
|
|
|
1283
1341
|
|
|
1284
1342
|
function extractPaymentCredential(tx) {
|
|
1285
1343
|
if (!tx || typeof tx !== "object") return "";
|
|
1286
|
-
const
|
|
1287
|
-
tx.card_fingerprint
|
|
1288
|
-
tx.payment_method_fingerprint
|
|
1289
|
-
tx.
|
|
1290
|
-
tx.
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1344
|
+
const fpCandidates = [
|
|
1345
|
+
tx.card_fingerprint,
|
|
1346
|
+
tx.payment_method_fingerprint,
|
|
1347
|
+
tx.payment_method_details?.card?.fingerprint,
|
|
1348
|
+
tx.payment_method && typeof tx.payment_method === "object"
|
|
1349
|
+
? tx.payment_method.card?.fingerprint
|
|
1350
|
+
: "",
|
|
1351
|
+
tx.card?.fingerprint,
|
|
1352
|
+
tx.source?.card?.fingerprint,
|
|
1353
|
+
];
|
|
1354
|
+
for (const cand of fpCandidates) {
|
|
1355
|
+
if (typeof cand === "string" && cand.trim()) {
|
|
1356
|
+
return sanitizeLogToken(cand.trim(), 96);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
const pmId =
|
|
1360
|
+
typeof tx.payment_method === "string"
|
|
1361
|
+
? tx.payment_method
|
|
1362
|
+
: tx.payment_method &&
|
|
1363
|
+
typeof tx.payment_method === "object" &&
|
|
1364
|
+
typeof tx.payment_method.id === "string"
|
|
1365
|
+
? tx.payment_method.id
|
|
1366
|
+
: "";
|
|
1367
|
+
return sanitizeLogToken(pmId, 96);
|
|
1294
1368
|
}
|
|
1295
1369
|
|
|
1296
1370
|
function evaluateLocalVisaCe3Qualification(disputeReason, disputedTransaction, priorTransactions) {
|
|
@@ -1436,7 +1510,7 @@ export const LOCAL_STATELESS_CLOUD_UPGRADE_HINT = Object.freeze({
|
|
|
1436
1510
|
message:
|
|
1437
1511
|
"Running in stateless local mode. Provision a free or paid Cloud Workspace for 90-day event persistence, automated webhook revocation, and Slack/Email alerts.",
|
|
1438
1512
|
command: "npx --yes revclamp-mcp --init-workspace <work_email>",
|
|
1439
|
-
cliActivateCommand: "npx -y revclamp-mcp@1.20.
|
|
1513
|
+
cliActivateCommand: "npx -y revclamp-mcp@1.20.11 --init-workspace you@company.com",
|
|
1440
1514
|
upgradeUrl: "https://revclamp.com/pricing?source=mcp_cli",
|
|
1441
1515
|
});
|
|
1442
1516
|
|
|
@@ -2527,7 +2601,18 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2527
2601
|
};
|
|
2528
2602
|
}
|
|
2529
2603
|
|
|
2530
|
-
|
|
2604
|
+
const TRANSIENT_SIM_MODES = new Set([
|
|
2605
|
+
"MS_UNAVAILABLE",
|
|
2606
|
+
"GLOBAL_MAX_CONCURRENT_REQ",
|
|
2607
|
+
"MS_MAX_CONCURRENT_REQ",
|
|
2608
|
+
"MS_MAX_CONCURRENT_REQ_TIME",
|
|
2609
|
+
"GLOBAL_MAX_CONCURRENT_REQ_TIME",
|
|
2610
|
+
"SERVICE_UNAVAILABLE",
|
|
2611
|
+
"TIMEOUT",
|
|
2612
|
+
"SERVER_BUSY",
|
|
2613
|
+
"NETWORK_ERROR",
|
|
2614
|
+
]);
|
|
2615
|
+
if (TRANSIENT_SIM_MODES.has(viesMode)) {
|
|
2531
2616
|
return {
|
|
2532
2617
|
ok: true,
|
|
2533
2618
|
executionMode: "local_open_source_engine",
|
|
@@ -2545,7 +2630,25 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2545
2630
|
};
|
|
2546
2631
|
}
|
|
2547
2632
|
|
|
2548
|
-
if (viesMode === "
|
|
2633
|
+
if (viesMode === "INVALID_REQUESTER_INFO" || viesMode === "IP_BLOCKED") {
|
|
2634
|
+
return {
|
|
2635
|
+
ok: true,
|
|
2636
|
+
executionMode: "local_open_source_engine",
|
|
2637
|
+
sample: true,
|
|
2638
|
+
valid: null,
|
|
2639
|
+
formatValid: true,
|
|
2640
|
+
status: "HOLD_UNVERIFIED_VIES_FAULT",
|
|
2641
|
+
reason: `VIES_GATEWAY_FAULT_${viesMode}`,
|
|
2642
|
+
sellerCountry,
|
|
2643
|
+
normalizedVatId: norm.fullVatId,
|
|
2644
|
+
memberState: norm.memberState,
|
|
2645
|
+
reverseChargeEligible: false,
|
|
2646
|
+
zeroRateAllowed: false,
|
|
2647
|
+
consultationId: null,
|
|
2648
|
+
};
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
if (viesMode === "INVALID" || viesMode === "VAT_BLOCKED" || viesMode === "INVALID_INPUT") {
|
|
2549
2652
|
return {
|
|
2550
2653
|
ok: true,
|
|
2551
2654
|
executionMode: "local_open_source_engine",
|
|
@@ -2553,7 +2656,25 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2553
2656
|
valid: false,
|
|
2554
2657
|
formatValid: true,
|
|
2555
2658
|
status: "HOLD_INVALID_VAT",
|
|
2556
|
-
reason: "VIES_DEFINITE_INVALID"
|
|
2659
|
+
reason: viesMode === "INVALID" ? "VIES_DEFINITE_INVALID" : `VIES_${viesMode}`,
|
|
2660
|
+
sellerCountry,
|
|
2661
|
+
normalizedVatId: norm.fullVatId,
|
|
2662
|
+
memberState: norm.memberState,
|
|
2663
|
+
reverseChargeEligible: false,
|
|
2664
|
+
zeroRateAllowed: false,
|
|
2665
|
+
consultationId: null,
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
if (viesMode !== "VALID" && viesMode !== "VERIFIED") {
|
|
2670
|
+
return {
|
|
2671
|
+
ok: true,
|
|
2672
|
+
executionMode: "local_open_source_engine",
|
|
2673
|
+
sample: true,
|
|
2674
|
+
valid: null,
|
|
2675
|
+
formatValid: true,
|
|
2676
|
+
status: "HOLD_UNVERIFIED_VIES_FAULT",
|
|
2677
|
+
reason: "UNRECOGNIZED_VIES_SIMULATION_MODE",
|
|
2557
2678
|
sellerCountry,
|
|
2558
2679
|
normalizedVatId: norm.fullVatId,
|
|
2559
2680
|
memberState: norm.memberState,
|
|
@@ -2670,20 +2791,21 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2670
2791
|
|
|
2671
2792
|
const effectiveTotalCents = Math.max(0, orderTotalCents - creditNotesCents);
|
|
2672
2793
|
const hasExplicitDepositCents = args.requiredDepositCents !== undefined;
|
|
2673
|
-
const
|
|
2794
|
+
const rawRequiredDepositCents = hasExplicitDepositCents
|
|
2674
2795
|
? args.requiredDepositCents
|
|
2675
2796
|
: Math.ceil((effectiveTotalCents * requiredDepositPercent) / 100);
|
|
2676
2797
|
if (
|
|
2677
|
-
!Number.isSafeInteger(
|
|
2678
|
-
|
|
2679
|
-
|
|
2798
|
+
!Number.isSafeInteger(rawRequiredDepositCents) ||
|
|
2799
|
+
rawRequiredDepositCents < 0 ||
|
|
2800
|
+
rawRequiredDepositCents > orderTotalCents
|
|
2680
2801
|
) {
|
|
2681
2802
|
const err = new Error(
|
|
2682
|
-
"INVALID_REQUIRED_DEPOSIT_CENTS: requiredDepositCents must be an integer between 0 and
|
|
2803
|
+
"INVALID_REQUIRED_DEPOSIT_CENTS: requiredDepositCents must be an integer between 0 and totalOrderCents."
|
|
2683
2804
|
);
|
|
2684
2805
|
err.code = -32602;
|
|
2685
2806
|
throw err;
|
|
2686
2807
|
}
|
|
2808
|
+
const requiredDepositCents = Math.min(rawRequiredDepositCents, effectiveTotalCents);
|
|
2687
2809
|
|
|
2688
2810
|
const shortfallRawCents = Math.max(0, effectiveTotalCents - paidAmountCents);
|
|
2689
2811
|
const overpaidCents = Math.max(0, paidAmountCents - effectiveTotalCents);
|
|
@@ -3341,7 +3463,7 @@ function toSafeLocalRpcId(rawId) {
|
|
|
3341
3463
|
|
|
3342
3464
|
export function executeLocalMcpJsonRpc(
|
|
3343
3465
|
rpcRequest,
|
|
3344
|
-
packageVersion = "1.20.
|
|
3466
|
+
packageVersion = "1.20.11",
|
|
3345
3467
|
options = {}
|
|
3346
3468
|
) {
|
|
3347
3469
|
if (!rpcRequest || typeof rpcRequest !== "object" || Array.isArray(rpcRequest)) {
|
|
@@ -3457,7 +3579,7 @@ export function executeLocalMcpJsonRpc(
|
|
|
3457
3579
|
version: packageVersion,
|
|
3458
3580
|
localExecution: "9 deterministic tools in local_engine.mjs (0 network calls by default)",
|
|
3459
3581
|
cloudCapabilities: [
|
|
3460
|
-
"90-day
|
|
3582
|
+
"90-day durable transactional usage & audit ledger",
|
|
3461
3583
|
"24/7 autonomous Stripe dispute & entitlement webhook outbox",
|
|
3462
3584
|
"Live EU Commission VIES SOAP consultation numbers (viesMode: 'LIVE')",
|
|
3463
3585
|
],
|
package/mcp-config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "revclamp-mcp",
|
|
3
|
-
"mcpName": "
|
|
4
|
-
"version": "1.20.
|
|
3
|
+
"mcpName": "com.revclamp/revclamp-mcp",
|
|
4
|
+
"version": "1.20.11",
|
|
5
5
|
"description": "Model Context Protocol (MCP) server and CLI for Stripe 2025-03-31.basil entitlement checks, Visa CE 3.0 dispute staging (submit: false), EU/XI VIES VAT validation, Shopify Plus B2B Net-15/30/60 reconciliation, webhook HMAC-SHA256 verification, 0% take-rate ROI calculation, 72-hour webhook replay & out-of-order state-machine simulation, and Stripe dispute evidence 18,000 UTF-16 code unit & CE 3.0 completeness linting.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./index.mjs",
|
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
"node": ">=20.0.0"
|
|
47
47
|
},
|
|
48
48
|
"revclamp": {
|
|
49
|
-
"engineSha256": "
|
|
49
|
+
"engineSha256": "806f9291517805e75ce55636ad1e704e30c1b2a840bd1162c87ba7e92bd9a053"
|
|
50
50
|
}
|
|
51
51
|
}
|
package/server.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
-
"name": "
|
|
3
|
+
"name": "com.revclamp/revclamp-mcp",
|
|
4
4
|
"title": "RevClamp MCP Server",
|
|
5
5
|
"description": "Zero-take-rate Stripe 2025-03-31.basil, Visa CE 3.0 & EU/XI VIES VAT guardrails MCP server.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "https://github.com/lhphong09t2/revclamp-mcp",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.20.
|
|
10
|
+
"version": "1.20.11",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "revclamp-mcp",
|
|
16
|
-
"version": "1.20.
|
|
16
|
+
"version": "1.20.11",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|