revclamp-mcp 1.20.10 → 1.20.12
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 +676 -32
- 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.12 --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.12 --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.12 --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.12";
|
|
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
|
|
|
@@ -58,6 +58,24 @@ const LOCAL_MCP_TOOL_ARG_ALIAS_GROUPS = Object.freeze({
|
|
|
58
58
|
aliases: Object.freeze(["windowSec", "dedupWindowSec"]),
|
|
59
59
|
}),
|
|
60
60
|
]),
|
|
61
|
+
revclamp_validate_eu_vat_vies: Object.freeze([
|
|
62
|
+
Object.freeze({
|
|
63
|
+
canonical: "sellerCountry",
|
|
64
|
+
aliases: Object.freeze(["sellerCountryCode", "seller_country", "seller_country_code"]),
|
|
65
|
+
}),
|
|
66
|
+
Object.freeze({
|
|
67
|
+
canonical: "buyerVatId",
|
|
68
|
+
aliases: Object.freeze(["vatId", "buyer_vat_id"]),
|
|
69
|
+
}),
|
|
70
|
+
Object.freeze({
|
|
71
|
+
canonical: "viesMode",
|
|
72
|
+
aliases: Object.freeze(["vies_mode"]),
|
|
73
|
+
}),
|
|
74
|
+
Object.freeze({
|
|
75
|
+
canonical: "supplyType",
|
|
76
|
+
aliases: Object.freeze(["supply_type"]),
|
|
77
|
+
}),
|
|
78
|
+
]),
|
|
61
79
|
});
|
|
62
80
|
|
|
63
81
|
export function normalizeMcpToolArgs(toolName, rawArgs) {
|
|
@@ -145,7 +163,7 @@ export const LOCAL_MCP_RESOURCES = Object.freeze([
|
|
|
145
163
|
uri: "revclamp://docs/open-core-capabilities",
|
|
146
164
|
name: "RevClamp Open-Core vs Hosted Cloud Capabilities",
|
|
147
165
|
description:
|
|
148
|
-
"Reference summary of the 9 local deterministic MCP tools vs. hosted REVCLAMP_API_KEY capabilities (90-day
|
|
166
|
+
"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
167
|
mimeType: "application/json",
|
|
150
168
|
}),
|
|
151
169
|
]);
|
|
@@ -189,7 +207,7 @@ const EU_VIES_FORMAT_RULES = Object.freeze({
|
|
|
189
207
|
DK: /^DK\d{8}$/,
|
|
190
208
|
EE: /^EE\d{9}$/,
|
|
191
209
|
EL: /^EL\d{9}$/,
|
|
192
|
-
ES: /^ES[A-
|
|
210
|
+
ES: /^ES(?:[A-Z]\d{7}[A-Z0-9]|[0-9]\d{7}[A-Z])$/,
|
|
193
211
|
FI: /^FI\d{8}$/,
|
|
194
212
|
FR: /^FR[A-HJ-NP-Z0-9]{2}\d{9}$/,
|
|
195
213
|
HR: /^HR\d{11}$/,
|
|
@@ -210,6 +228,384 @@ const EU_VIES_FORMAT_RULES = Object.freeze({
|
|
|
210
228
|
XI: /^XI(?:\d{9}|\d{12}|(?:GD|HA)\d{3})$/,
|
|
211
229
|
});
|
|
212
230
|
|
|
231
|
+
export const EU_VIES_STATUTORY_TERMINOLOGY_MAP = Object.freeze({
|
|
232
|
+
AT: Object.freeze({
|
|
233
|
+
memberState: "AT",
|
|
234
|
+
countryNameEn: "Austria",
|
|
235
|
+
nativeCountryName: "Österreich",
|
|
236
|
+
taxIdAcronym: "UID",
|
|
237
|
+
nativeTaxIdName: "Umsatzsteuer-Identifikationsnummer",
|
|
238
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
239
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
240
|
+
statutoryReverseChargeClause:
|
|
241
|
+
"Steuerschuldnerschaft des Leistungsempfängers – Art. 196 & Art. 226 Nr. 11a MwStSystRL (Directive 2006/112/EC, § 19 UStG) / Reverse charge (B2B services)",
|
|
242
|
+
statutoryGoodsExemptionClause:
|
|
243
|
+
"Steuerfreie innergemeinschaftliche Lieferung – Art. 138 Abs. 1 & Art. 226 Nr. 11 MwStSystRL (Directive 2006/112/EC, Art. 6 Abs. 1 UStG) / Intra-Community exempt supply of goods",
|
|
244
|
+
}),
|
|
245
|
+
BE: Object.freeze({
|
|
246
|
+
memberState: "BE",
|
|
247
|
+
countryNameEn: "Belgium",
|
|
248
|
+
nativeCountryName: "België / Belgique",
|
|
249
|
+
taxIdAcronym: "N° TVA / BTW-nr.",
|
|
250
|
+
nativeTaxIdName: "Numéro de TVA / Btw-identificatienummer",
|
|
251
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
252
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
253
|
+
statutoryReverseChargeClause:
|
|
254
|
+
"Autoliquidation / Btw verlegd – Art. 196 & Art. 226(11a) Directive 2006/112/EC / Reverse charge (B2B services)",
|
|
255
|
+
statutoryGoodsExemptionClause:
|
|
256
|
+
"Livraison intracommunautaire exonérée / Vrijgestelde intracommunautaire levering – Art. 138(1) & Art. 226(11) Directive 2006/112/EC (Art. 39bis CTVA/WBTW) / Intra-Community exempt supply of goods",
|
|
257
|
+
}),
|
|
258
|
+
BG: Object.freeze({
|
|
259
|
+
memberState: "BG",
|
|
260
|
+
countryNameEn: "Bulgaria",
|
|
261
|
+
nativeCountryName: "България",
|
|
262
|
+
taxIdAcronym: "ДДС номер",
|
|
263
|
+
nativeTaxIdName: "Идентификационен номер по ДДС (ЗДДС)",
|
|
264
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
265
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
266
|
+
statutoryReverseChargeClause:
|
|
267
|
+
"Обратно начисляване – чл. 196 и чл. 226, т. 11а от Директива 2006/112/ЕО (чл. 82, ал. 2 ЗДДС) / Reverse charge (B2B services)",
|
|
268
|
+
statutoryGoodsExemptionClause:
|
|
269
|
+
"Освободена вътреобщностна доставка на стоки – чл. 138, пар. 1 и чл. 226, т. 11 от Директива 2006/112/ЕО (чл. 7 и чл. 53 ЗДДС) / Intra-Community exempt supply of goods",
|
|
270
|
+
}),
|
|
271
|
+
CY: Object.freeze({
|
|
272
|
+
memberState: "CY",
|
|
273
|
+
countryNameEn: "Cyprus",
|
|
274
|
+
nativeCountryName: "Κύπρος",
|
|
275
|
+
taxIdAcronym: "ΑΦΜ / ΦΠΑ",
|
|
276
|
+
nativeTaxIdName: "Αριθμός Εγγραφής ΦΠΑ",
|
|
277
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
278
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
279
|
+
statutoryReverseChargeClause:
|
|
280
|
+
"Αντίστροφη επιβάρυνση – Άρθρα 196 & 226(11α) Οδηγίας 2006/112/ΕΚ / Reverse charge (B2B services)",
|
|
281
|
+
statutoryGoodsExemptionClause:
|
|
282
|
+
"Απαλλασσόμενη ενδοκοινοτική παράδοση αγαθών – Άρθρα 138(1) & 226(11) Οδηγίας 2006/112/ΕΚ / Intra-Community exempt supply of goods",
|
|
283
|
+
}),
|
|
284
|
+
CZ: Object.freeze({
|
|
285
|
+
memberState: "CZ",
|
|
286
|
+
countryNameEn: "Czechia",
|
|
287
|
+
nativeCountryName: "Česká republika",
|
|
288
|
+
taxIdAcronym: "DIČ",
|
|
289
|
+
nativeTaxIdName: "Daňové identifikační číslo",
|
|
290
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
291
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
292
|
+
statutoryReverseChargeClause:
|
|
293
|
+
"Daň odvede zákazník – čl. 196 a čl. 226 bod 11a směrnice 2006/112/ES / Reverse charge (B2B services)",
|
|
294
|
+
statutoryGoodsExemptionClause:
|
|
295
|
+
"Osvobozené dodání zboží do jiného členského státu – čl. 138 odst. 1 a čl. 226 bod 11 směrnice 2006/112/ES (§ 64 ZDPH) / Intra-Community exempt supply of goods",
|
|
296
|
+
}),
|
|
297
|
+
DE: Object.freeze({
|
|
298
|
+
memberState: "DE",
|
|
299
|
+
countryNameEn: "Germany",
|
|
300
|
+
nativeCountryName: "Deutschland",
|
|
301
|
+
taxIdAcronym: "USt-IdNr.",
|
|
302
|
+
nativeTaxIdName: "Umsatzsteuer-Identifikationsnummer",
|
|
303
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
304
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
305
|
+
statutoryReverseChargeClause:
|
|
306
|
+
"Steuerschuldnerschaft des Leistungsempfängers – Art. 196 & Art. 226 Nr. 11a MwStSystRL (Directive 2006/112/EC, § 13b UStG) / Reverse charge (B2B services)",
|
|
307
|
+
statutoryGoodsExemptionClause:
|
|
308
|
+
"Steuerfreie innergemeinschaftliche Lieferung – Art. 138 Abs. 1 & Art. 226 Nr. 11 MwStSystRL (Directive 2006/112/EC, § 4 Nr. 1b i.V.m. § 6a UStG) / Intra-Community exempt supply of goods",
|
|
309
|
+
}),
|
|
310
|
+
DK: Object.freeze({
|
|
311
|
+
memberState: "DK",
|
|
312
|
+
countryNameEn: "Denmark",
|
|
313
|
+
nativeCountryName: "Danmark",
|
|
314
|
+
taxIdAcronym: "CVR / SE-nr.",
|
|
315
|
+
nativeTaxIdName: "Momsregistreringsnummer (CVR/SE)",
|
|
316
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
317
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
318
|
+
statutoryReverseChargeClause:
|
|
319
|
+
"Omvendt betalingspligt – Art. 196 & Art. 226, nr. 11a, i direktiv 2006/112/EF / Reverse charge (B2B services)",
|
|
320
|
+
statutoryGoodsExemptionClause:
|
|
321
|
+
"Momsfri EU-vareleverance – Art. 138, stk. 1, og Art. 226, nr. 11, i direktiv 2006/112/EF (ML § 34, stk. 1, nr. 1) / Intra-Community exempt supply of goods",
|
|
322
|
+
}),
|
|
323
|
+
EE: Object.freeze({
|
|
324
|
+
memberState: "EE",
|
|
325
|
+
countryNameEn: "Estonia",
|
|
326
|
+
nativeCountryName: "Eesti",
|
|
327
|
+
taxIdAcronym: "KMKR",
|
|
328
|
+
nativeTaxIdName: "Käibemaksukohustuslase registreerimisnumber",
|
|
329
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
330
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
331
|
+
statutoryReverseChargeClause:
|
|
332
|
+
"Pöördmaksustamine – direktiivi 2006/112/EÜ art 196 ja art 226 p 11a / Reverse charge (B2B services)",
|
|
333
|
+
statutoryGoodsExemptionClause:
|
|
334
|
+
"Ühendusesisene kauba käive (0% KM) – direktiivi 2006/112/EÜ art 138 lg 1 ja art 226 p 11 (KMS § 15 lg 3 p 2) / Intra-Community exempt supply of goods",
|
|
335
|
+
}),
|
|
336
|
+
EL: Object.freeze({
|
|
337
|
+
memberState: "EL",
|
|
338
|
+
countryNameEn: "Greece",
|
|
339
|
+
nativeCountryName: "Ελλάδα",
|
|
340
|
+
taxIdAcronym: "ΑΦΜ",
|
|
341
|
+
nativeTaxIdName: "Αριθμός Φορολογικού Μητρώου (ΦΠΑ)",
|
|
342
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
343
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
344
|
+
statutoryReverseChargeClause:
|
|
345
|
+
"Αντίστροφη επιβάρυνση – Άρθρα 196 & 226(11α) Οδηγίας 2006/112/ΕΚ / Reverse charge (B2B services)",
|
|
346
|
+
statutoryGoodsExemptionClause:
|
|
347
|
+
"Απαλλασσόμενη ενδοκοινοτική παράδοση αγαθών – Άρθρα 138(1) & 226(11) Οδηγίας 2006/112/ΕΚ (Άρθρο 28 Κώδικα ΦΠΑ) / Intra-Community exempt supply of goods",
|
|
348
|
+
}),
|
|
349
|
+
ES: Object.freeze({
|
|
350
|
+
memberState: "ES",
|
|
351
|
+
countryNameEn: "Spain",
|
|
352
|
+
nativeCountryName: "España",
|
|
353
|
+
taxIdAcronym: "NIF-IVA",
|
|
354
|
+
nativeTaxIdName: "Número de Identificación Fiscal (ROI / NIF-IVA)",
|
|
355
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
356
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
357
|
+
statutoryReverseChargeClause:
|
|
358
|
+
"Inversión del sujeto pasivo – Art. 196 y Art. 226.11 bis Directiva 2006/112/CE (Art. 84 LIVA) / Reverse charge (B2B services)",
|
|
359
|
+
statutoryGoodsExemptionClause:
|
|
360
|
+
"Entrega intracomunitaria exenta de bienes – Art. 138.1 y Art. 226.11 Directiva 2006/112/CE (Art. 25 LIVA) / Intra-Community exempt supply of goods",
|
|
361
|
+
}),
|
|
362
|
+
FI: Object.freeze({
|
|
363
|
+
memberState: "FI",
|
|
364
|
+
countryNameEn: "Finland",
|
|
365
|
+
nativeCountryName: "Suomi",
|
|
366
|
+
taxIdAcronym: "ALV-nro",
|
|
367
|
+
nativeTaxIdName: "Arvonlisäverotunniste (Y-tunnus)",
|
|
368
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
369
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
370
|
+
statutoryReverseChargeClause:
|
|
371
|
+
"Käännetty verovelvollisuus – direktiivin 2006/112/EY 196 art. ja 226 art. 11a kohta / Reverse charge (B2B services)",
|
|
372
|
+
statutoryGoodsExemptionClause:
|
|
373
|
+
"Veroton yhteisömyynti – direktiivin 2006/112/EY 138 art. 1 kohta ja 226 art. 11 kohta (AVL 72 a §) / Intra-Community exempt supply of goods",
|
|
374
|
+
}),
|
|
375
|
+
FR: Object.freeze({
|
|
376
|
+
memberState: "FR",
|
|
377
|
+
countryNameEn: "France",
|
|
378
|
+
nativeCountryName: "France",
|
|
379
|
+
taxIdAcronym: "N° TVA",
|
|
380
|
+
nativeTaxIdName: "Numéro de TVA intracommunautaire",
|
|
381
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
382
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
383
|
+
statutoryReverseChargeClause:
|
|
384
|
+
"Autoliquidation – Art. 196 et Art. 226, point 11 bis, de la Directive 2006/112/CE (CGI art. 283-2) / Reverse charge (B2B services)",
|
|
385
|
+
statutoryGoodsExemptionClause:
|
|
386
|
+
"Exonération de TVA – Livraison intracommunautaire de biens – Art. 138, par. 1, et Art. 226, point 11, Directive 2006/112/CE (CGI art. 262 ter I) / Intra-Community exempt supply of goods",
|
|
387
|
+
}),
|
|
388
|
+
HR: Object.freeze({
|
|
389
|
+
memberState: "HR",
|
|
390
|
+
countryNameEn: "Croatia",
|
|
391
|
+
nativeCountryName: "Hrvatska",
|
|
392
|
+
taxIdAcronym: "PDV ID / OIB",
|
|
393
|
+
nativeTaxIdName: "PDV identifikacijski broj (OIB)",
|
|
394
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
395
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
396
|
+
statutoryReverseChargeClause:
|
|
397
|
+
"Prijenos porezne obveze – čl. 196. i čl. 226. t. 11.a Direktive 2006/112/EZ / Reverse charge (B2B services)",
|
|
398
|
+
statutoryGoodsExemptionClause:
|
|
399
|
+
"Oslobođena isporuka dobara unutar EU – čl. 138. st. 1. i čl. 226. t. 11. Direktive 2006/112/EZ (čl. 41. st. 1. Zakona o PDV-u) / Intra-Community exempt supply of goods",
|
|
400
|
+
}),
|
|
401
|
+
HU: Object.freeze({
|
|
402
|
+
memberState: "HU",
|
|
403
|
+
countryNameEn: "Hungary",
|
|
404
|
+
nativeCountryName: "Magyarország",
|
|
405
|
+
taxIdAcronym: "Közösségi adószám",
|
|
406
|
+
nativeTaxIdName: "Közösségi adószám (EU ÁFA)",
|
|
407
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
408
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
409
|
+
statutoryReverseChargeClause:
|
|
410
|
+
"Fordított adózás – a 2006/112/EK irányelv 196. cikke és 226. cikkének 11a. pontja / Reverse charge (B2B services)",
|
|
411
|
+
statutoryGoodsExemptionClause:
|
|
412
|
+
"Adómentes Közösségen belüli termékértékesítés – a 2006/112/EK irányelv 138. cikk (1) bek. és 226. cikk 11. pontja (Áfa tv. 89. §) / Intra-Community exempt supply of goods",
|
|
413
|
+
}),
|
|
414
|
+
IE: Object.freeze({
|
|
415
|
+
memberState: "IE",
|
|
416
|
+
countryNameEn: "Ireland",
|
|
417
|
+
nativeCountryName: "Éire / Ireland",
|
|
418
|
+
taxIdAcronym: "VAT Reg No",
|
|
419
|
+
nativeTaxIdName: "Value Added Tax Registration Number",
|
|
420
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
421
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
422
|
+
statutoryReverseChargeClause:
|
|
423
|
+
"Reverse charge – Art. 196 & Art. 226(11a) Council Directive 2006/112/EC (B2B services)",
|
|
424
|
+
statutoryGoodsExemptionClause:
|
|
425
|
+
"Zero-rated intra-Community supply of goods – Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
426
|
+
}),
|
|
427
|
+
IT: Object.freeze({
|
|
428
|
+
memberState: "IT",
|
|
429
|
+
countryNameEn: "Italy",
|
|
430
|
+
nativeCountryName: "Italia",
|
|
431
|
+
taxIdAcronym: "P.IVA",
|
|
432
|
+
nativeTaxIdName: "Partita IVA intracomunitaria (VIES)",
|
|
433
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
434
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
435
|
+
statutoryReverseChargeClause:
|
|
436
|
+
"Inversione contabile – Art. 196 e Art. 226, punto 11-bis, Direttiva 2006/112/CE (Art. 17 DPR 633/72) / Reverse charge (B2B services)",
|
|
437
|
+
statutoryGoodsExemptionClause:
|
|
438
|
+
"Cessione intracomunitaria non imponibile di beni – Art. 138, par. 1, e Art. 226, punto 11, Direttiva 2006/112/CE (Art. 41 D.L. 331/1993) / Intra-Community exempt supply of goods",
|
|
439
|
+
}),
|
|
440
|
+
LT: Object.freeze({
|
|
441
|
+
memberState: "LT",
|
|
442
|
+
countryNameEn: "Lithuania",
|
|
443
|
+
nativeCountryName: "Lietuva",
|
|
444
|
+
taxIdAcronym: "PVM kodas",
|
|
445
|
+
nativeTaxIdName: "Pridėtinės vertės mokesčio mokėtojo kodas",
|
|
446
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
447
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
448
|
+
statutoryReverseChargeClause:
|
|
449
|
+
"Atvirkštinis apmokestinimas – Direktyvos 2006/112/EB 196 str. ir 226 str. 11a p. / Reverse charge (B2B services)",
|
|
450
|
+
statutoryGoodsExemptionClause:
|
|
451
|
+
"PVM neapmokestinamas prekių tiekimas į kitą ES valstybę narę – Direktyvos 2006/112/EB 138 str. 1 d. ir 226 str. 11 p. (PVMĮ 49 str.) / Intra-Community exempt supply of goods",
|
|
452
|
+
}),
|
|
453
|
+
LU: Object.freeze({
|
|
454
|
+
memberState: "LU",
|
|
455
|
+
countryNameEn: "Luxembourg",
|
|
456
|
+
nativeCountryName: "Lëtzebuerg / Luxembourg",
|
|
457
|
+
taxIdAcronym: "N° TVA",
|
|
458
|
+
nativeTaxIdName: "Numéro d'identification à la TVA",
|
|
459
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
460
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
461
|
+
statutoryReverseChargeClause:
|
|
462
|
+
"Autoliquidation – Art. 196 et Art. 226, point 11 bis, Directive 2006/112/CE / Reverse charge (B2B services)",
|
|
463
|
+
statutoryGoodsExemptionClause:
|
|
464
|
+
"Livraison intracommunautaire de biens exonérée – Art. 138, par. 1, et Art. 226, point 11, Directive 2006/112/CE (Art. 43 LTVA) / Intra-Community exempt supply of goods",
|
|
465
|
+
}),
|
|
466
|
+
LV: Object.freeze({
|
|
467
|
+
memberState: "LV",
|
|
468
|
+
countryNameEn: "Latvia",
|
|
469
|
+
nativeCountryName: "Latvija",
|
|
470
|
+
taxIdAcronym: "PVN Nr.",
|
|
471
|
+
nativeTaxIdName: "Pievienotās vērtības nodokļa reģistrācijas numurs",
|
|
472
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
473
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
474
|
+
statutoryReverseChargeClause:
|
|
475
|
+
"Nodokļa apgrieztā maksāšana – Direktīvas 2006/112/EK 196. pants un 226. panta 11.a punkts / Reverse charge (B2B services)",
|
|
476
|
+
statutoryGoodsExemptionClause:
|
|
477
|
+
"Ar 0% PVN likmi apliekama preču piegāde ES ietvaros – Direktīvas 2006/112/EK 138. panta 1. punkts un 226. panta 11. punkts (PVN likuma 43. pants) / Intra-Community exempt supply of goods",
|
|
478
|
+
}),
|
|
479
|
+
MT: Object.freeze({
|
|
480
|
+
memberState: "MT",
|
|
481
|
+
countryNameEn: "Malta",
|
|
482
|
+
nativeCountryName: "Malta",
|
|
483
|
+
taxIdAcronym: "VAT Reg. No.",
|
|
484
|
+
nativeTaxIdName: "Value Added Tax Registration Number",
|
|
485
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
486
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
487
|
+
statutoryReverseChargeClause:
|
|
488
|
+
"Reverse charge – Art. 196 & Art. 226(11a) Council Directive 2006/112/EC (B2B services)",
|
|
489
|
+
statutoryGoodsExemptionClause:
|
|
490
|
+
"Exempt intra-Community supply of goods – Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
491
|
+
}),
|
|
492
|
+
NL: Object.freeze({
|
|
493
|
+
memberState: "NL",
|
|
494
|
+
countryNameEn: "Netherlands",
|
|
495
|
+
nativeCountryName: "Nederland",
|
|
496
|
+
taxIdAcronym: "Btw-id",
|
|
497
|
+
nativeTaxIdName: "Btw-identificatienummer",
|
|
498
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
499
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
500
|
+
statutoryReverseChargeClause:
|
|
501
|
+
"Btw verlegd – Art. 196 & Art. 226 lid 11 bis Richtlijn 2006/112/EG / Reverse charge (B2B services)",
|
|
502
|
+
statutoryGoodsExemptionClause:
|
|
503
|
+
"Vrijgestelde intracommunautaire levering van goederen (0% btw) – Art. 138 lid 1 & Art. 226 lid 11 Richtlijn 2006/112/EG (Art. 9 lid 2 sub b Wet OB 1968 juncto Tabel II onderdeel a post 6) / Intra-Community exempt supply of goods",
|
|
504
|
+
}),
|
|
505
|
+
PL: Object.freeze({
|
|
506
|
+
memberState: "PL",
|
|
507
|
+
countryNameEn: "Poland",
|
|
508
|
+
nativeCountryName: "Polska",
|
|
509
|
+
taxIdAcronym: "NIP (VAT-UE)",
|
|
510
|
+
nativeTaxIdName: "Numer Identyfikacji Podatkowej (NIP UE)",
|
|
511
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
512
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
513
|
+
statutoryReverseChargeClause:
|
|
514
|
+
"Odwrotne obciążenie – art. 196 i art. 226 pkt 11a dyrektywy 2006/112/WE / Reverse charge (B2B services)",
|
|
515
|
+
statutoryGoodsExemptionClause:
|
|
516
|
+
"Wewnątrzwspólnotowa dostawa towarów (0% VAT) – art. 138 ust. 1 i art. 226 pkt 11 dyrektywy 2006/112/WE (art. 42 ust. 1 ustawy o VAT) / Intra-Community exempt supply of goods",
|
|
517
|
+
}),
|
|
518
|
+
PT: Object.freeze({
|
|
519
|
+
memberState: "PT",
|
|
520
|
+
countryNameEn: "Portugal",
|
|
521
|
+
nativeCountryName: "Portugal",
|
|
522
|
+
taxIdAcronym: "NIF / NIPC",
|
|
523
|
+
nativeTaxIdName: "Número de Identificação Fiscal (IVA)",
|
|
524
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
525
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
526
|
+
statutoryReverseChargeClause:
|
|
527
|
+
"Autoliquidação – Art. 196.º e Art. 226.º, n.º 11-A, da Diretiva 2006/112/CE / Reverse charge (B2B services)",
|
|
528
|
+
statutoryGoodsExemptionClause:
|
|
529
|
+
"Transmissão intracomunitária de bens isenta de IVA – Art. 138.º, n.º 1, e Art. 226.º, n.º 11, da Diretiva 2006/112/CE (Art. 14.º do RITI) / Intra-Community exempt supply of goods",
|
|
530
|
+
}),
|
|
531
|
+
RO: Object.freeze({
|
|
532
|
+
memberState: "RO",
|
|
533
|
+
countryNameEn: "Romania",
|
|
534
|
+
nativeCountryName: "România",
|
|
535
|
+
taxIdAcronym: "CIF / Cod TVA",
|
|
536
|
+
nativeTaxIdName: "Cod de înregistrare în scopuri de TVA",
|
|
537
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
538
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
539
|
+
statutoryReverseChargeClause:
|
|
540
|
+
"Taxare inversă – Art. 196 și Art. 226 pct. 11a din Directiva 2006/112/CE / Reverse charge (B2B services)",
|
|
541
|
+
statutoryGoodsExemptionClause:
|
|
542
|
+
"Livrare intracomunitară de bunuri scutită de TVA – Art. 138 alin. (1) și Art. 226 pct. 11 din Directiva 2006/112/CE (Art. 294 alin. (2) Codul Fiscal) / Intra-Community exempt supply of goods",
|
|
543
|
+
}),
|
|
544
|
+
SE: Object.freeze({
|
|
545
|
+
memberState: "SE",
|
|
546
|
+
countryNameEn: "Sweden",
|
|
547
|
+
nativeCountryName: "Sverige",
|
|
548
|
+
taxIdAcronym: "Momsnr",
|
|
549
|
+
nativeTaxIdName: "Momsregistreringsnummer (SE-nummer)",
|
|
550
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
551
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
552
|
+
statutoryReverseChargeClause:
|
|
553
|
+
"Omvänd betalningsskyldighet – Art. 196 & Art. 226.11a i direktiv 2006/112/EG / Reverse charge (B2B services)",
|
|
554
|
+
statutoryGoodsExemptionClause:
|
|
555
|
+
"Undantagen unionsintern leverans av varor – Art. 138.1 & Art. 226.11 i direktiv 2006/112/EG (10 kap. 42 § ML) / Intra-Community exempt supply of goods",
|
|
556
|
+
}),
|
|
557
|
+
SI: Object.freeze({
|
|
558
|
+
memberState: "SI",
|
|
559
|
+
countryNameEn: "Slovenia",
|
|
560
|
+
nativeCountryName: "Slovenija",
|
|
561
|
+
taxIdAcronym: "ID za DDV",
|
|
562
|
+
nativeTaxIdName: "Identifikacijska številka za DDV",
|
|
563
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
564
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
565
|
+
statutoryReverseChargeClause:
|
|
566
|
+
"Obrnjena davčna obveznost – člen 196 in člen 226(11a) Direktive 2006/112/ES / Reverse charge (B2B services)",
|
|
567
|
+
statutoryGoodsExemptionClause:
|
|
568
|
+
"Oproščena dobava blaga znotraj Unije – člen 138(1) in člen 226(11) Direktive 2006/112/ES (46. člen ZDDV-1) / Intra-Community exempt supply of goods",
|
|
569
|
+
}),
|
|
570
|
+
SK: Object.freeze({
|
|
571
|
+
memberState: "SK",
|
|
572
|
+
countryNameEn: "Slovakia",
|
|
573
|
+
nativeCountryName: "Slovensko",
|
|
574
|
+
taxIdAcronym: "IČ DPH",
|
|
575
|
+
nativeTaxIdName: "Identifikačné číslo pre daň z pridanej hodnoty",
|
|
576
|
+
directiveArticle: "Art. 196 & Art. 226(11a) Council Directive 2006/112/EC",
|
|
577
|
+
directiveGoodsArticle: "Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
578
|
+
statutoryReverseChargeClause:
|
|
579
|
+
"Prenesenie daňovej povinnosti – čl. 196 a čl. 226 bod 11a smernice 2006/112/ES / Reverse charge (B2B services)",
|
|
580
|
+
statutoryGoodsExemptionClause:
|
|
581
|
+
"Oslobodené dodanie tovaru do iného členského štátu – čl. 138 ods. 1 a čl. 226 bod 11 smernice 2006/112/ES (§ 43 zákona o DPH) / Intra-Community exempt supply of goods",
|
|
582
|
+
}),
|
|
583
|
+
XI: Object.freeze({
|
|
584
|
+
memberState: "XI",
|
|
585
|
+
countryNameEn: "Northern Ireland (Windsor Framework)",
|
|
586
|
+
nativeCountryName: "Northern Ireland (Windsor Framework)",
|
|
587
|
+
taxIdAcronym: "XI VAT No",
|
|
588
|
+
nativeTaxIdName: "Northern Ireland Protocol / Windsor Framework VAT Number (Goods Only)",
|
|
589
|
+
goodsOnlyProtocol: true,
|
|
590
|
+
directiveArticle:
|
|
591
|
+
"Windsor Framework (Goods Only — Services Not Covered by XI VIES) / Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
592
|
+
directiveGoodsArticle:
|
|
593
|
+
"Windsor Framework (Goods Only) / Art. 138(1) & Art. 226(11) Council Directive 2006/112/EC",
|
|
594
|
+
statutoryReverseChargeClause:
|
|
595
|
+
"N/A for B2B services under XI VIES (Windsor Framework applies to goods only under Art. 138(1) & Art. 226(11) Directive 2006/112/EC; UK/GB place-of-supply rules govern services)",
|
|
596
|
+
statutoryGoodsExemptionClause:
|
|
597
|
+
"Zero-rated intra-community supply of goods under Windsor Framework (Northern Ireland Protocol) – Art. 138(1) & Art. 226(11) Directive 2006/112/EC",
|
|
598
|
+
}),
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
export function getEuViesStatutoryTerminology(rawCode) {
|
|
602
|
+
const code = normalizeCountryCode(rawCode || "");
|
|
603
|
+
if (!code || !Object.prototype.hasOwnProperty.call(EU_VIES_STATUTORY_TERMINOLOGY_MAP, code)) {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
return EU_VIES_STATUTORY_TERMINOLOGY_MAP[code];
|
|
607
|
+
}
|
|
608
|
+
|
|
213
609
|
const REVCLAMP_START_MARKER = "--- BEGIN REVCLAMP CE3 EVIDENCE ---";
|
|
214
610
|
const REVCLAMP_END_MARKER = "--- END REVCLAMP CE3 EVIDENCE ---";
|
|
215
611
|
const REVCLAMP_BRACKET_START_MARKER = "[RevClamp Verified Product Usage Log]";
|
|
@@ -357,6 +753,13 @@ export const LOCAL_MCP_TOOLS = Object.freeze([
|
|
|
357
753
|
properties: {
|
|
358
754
|
sellerCountry: { type: "string", default: "DE" },
|
|
359
755
|
buyerVatId: { type: "string" },
|
|
756
|
+
supplyType: {
|
|
757
|
+
type: "string",
|
|
758
|
+
enum: ["GOODS", "SERVICES"],
|
|
759
|
+
default: "GOODS",
|
|
760
|
+
description:
|
|
761
|
+
"Cross-border transaction supply category: 'GOODS' (Directive 2006/112/EC Art. 138(1) intra-Community supply, default; permitted for Northern Ireland XI under Windsor Framework) or 'SERVICES' (Directive 2006/112/EC Art. 196 B2B reverse charge; excluded from EU VIES for Northern Ireland XI).",
|
|
762
|
+
},
|
|
360
763
|
viesMode: {
|
|
361
764
|
type: "string",
|
|
362
765
|
enum: [
|
|
@@ -655,14 +1058,20 @@ export function validateArgsAgainstSchema(schema, args) {
|
|
|
655
1058
|
function normalizeCountryCode(raw) {
|
|
656
1059
|
const clean = String(raw || "")
|
|
657
1060
|
.trim()
|
|
658
|
-
.toUpperCase()
|
|
659
|
-
|
|
1061
|
+
.toUpperCase()
|
|
1062
|
+
.replace(/[\s.\-/:_]+/g, "");
|
|
1063
|
+
if (clean === "GR") return "EL";
|
|
1064
|
+
if (clean === "GBNIR") return "XI";
|
|
1065
|
+
return clean;
|
|
660
1066
|
}
|
|
661
1067
|
|
|
662
1068
|
function normalizeVatId(rawVat) {
|
|
663
|
-
|
|
1069
|
+
let compact = String(rawVat || "")
|
|
664
1070
|
.toUpperCase()
|
|
665
|
-
.replace(/[\s.\-/:]+/g, "");
|
|
1071
|
+
.replace(/[\s.\-/:_]+/g, "");
|
|
1072
|
+
if (compact.startsWith("GBNIR")) {
|
|
1073
|
+
compact = `XI${compact.slice(5)}`;
|
|
1074
|
+
}
|
|
666
1075
|
if (compact.length < 4) {
|
|
667
1076
|
return { validFormat: false, memberState: "", vatNumber: "", fullVatId: compact };
|
|
668
1077
|
}
|
|
@@ -1008,14 +1417,37 @@ function evaluateLocalGhostUsage(subscriptionsEnv, usageEvent, dunningGracePerio
|
|
|
1008
1417
|
reason: "UNMATCHED_CUSTOMER_ID",
|
|
1009
1418
|
};
|
|
1010
1419
|
}
|
|
1420
|
+
const hasPositiveCustomerIdMatch = Boolean(evCustomerId && subCus && subCus === evCustomerId);
|
|
1421
|
+
const hasPositiveEmailMatch = Boolean(evEmail && subEmail && subEmail === evEmail);
|
|
1422
|
+
if (!hasPositiveCustomerIdMatch && !hasPositiveEmailMatch) {
|
|
1423
|
+
return {
|
|
1424
|
+
ok: true,
|
|
1425
|
+
executionMode: "local_open_source_engine",
|
|
1426
|
+
isGhostUsage: false,
|
|
1427
|
+
decision: "HOLD_CUSTOMER_MISMATCH",
|
|
1428
|
+
reason: subCus ? "UNMATCHED_CUSTOMER_ID" : "UNMATCHED_CUSTOMER_EMAIL",
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1011
1431
|
const st = sub.status.trim();
|
|
1012
1432
|
if (ENTITLED_SUB_STATUSES.has(st)) {
|
|
1433
|
+
const collectionPaused = Boolean(
|
|
1434
|
+
sub.pause_collection && typeof sub.pause_collection === "object"
|
|
1435
|
+
);
|
|
1013
1436
|
return {
|
|
1014
1437
|
ok: true,
|
|
1015
1438
|
executionMode: "local_open_source_engine",
|
|
1016
1439
|
isGhostUsage: false,
|
|
1017
1440
|
decision: "ALLOW_ENTITLED",
|
|
1018
1441
|
reason: "ACTIVE_SUBSCRIPTION_PRESENT",
|
|
1442
|
+
...(collectionPaused
|
|
1443
|
+
? {
|
|
1444
|
+
collectionPaused: true,
|
|
1445
|
+
pauseCollectionBehavior:
|
|
1446
|
+
typeof sub.pause_collection.behavior === "string"
|
|
1447
|
+
? sub.pause_collection.behavior
|
|
1448
|
+
: "void",
|
|
1449
|
+
}
|
|
1450
|
+
: {}),
|
|
1019
1451
|
};
|
|
1020
1452
|
}
|
|
1021
1453
|
if (sub.items?.has_more === true) {
|
|
@@ -1152,7 +1584,36 @@ function parseStrictIpv4Octets(str) {
|
|
|
1152
1584
|
|
|
1153
1585
|
function normalizeIpForCe3Correlation(ip) {
|
|
1154
1586
|
if (typeof ip !== "string") return null;
|
|
1155
|
-
|
|
1587
|
+
let raw = ip.trim().toLowerCase();
|
|
1588
|
+
if (!raw || raw.includes(",")) return null;
|
|
1589
|
+
if (raw.startsWith("ipv4:")) {
|
|
1590
|
+
raw = raw.slice(5).trim();
|
|
1591
|
+
} else if (raw.startsWith("ipv6_64:")) {
|
|
1592
|
+
const v6Match = raw.match(
|
|
1593
|
+
/^ipv6_64:([0-9a-f]{1,4}):([0-9a-f]{1,4}):([0-9a-f]{1,4}):([0-9a-f]{1,4})$/
|
|
1594
|
+
);
|
|
1595
|
+
if (!v6Match) return null;
|
|
1596
|
+
return `ipv6_64:${v6Match
|
|
1597
|
+
.slice(1, 5)
|
|
1598
|
+
.map((w) => Number.parseInt(w, 16).toString(16).padStart(4, "0"))
|
|
1599
|
+
.join(":")}`;
|
|
1600
|
+
}
|
|
1601
|
+
const bracketPortMatch = raw.match(/^\[([^\]]+)\](?::(\d{1,5}))?$/);
|
|
1602
|
+
if (bracketPortMatch) {
|
|
1603
|
+
if (bracketPortMatch[2] !== undefined) {
|
|
1604
|
+
const portNum = Number(bracketPortMatch[2]);
|
|
1605
|
+
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) return null;
|
|
1606
|
+
}
|
|
1607
|
+
raw = bracketPortMatch[1];
|
|
1608
|
+
} else {
|
|
1609
|
+
const v4PortMatch = raw.match(/^(\d{1,3}(?:\.\d{1,3}){3}):(\d{1,5})$/);
|
|
1610
|
+
if (v4PortMatch) {
|
|
1611
|
+
const portNum = Number(v4PortMatch[2]);
|
|
1612
|
+
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) return null;
|
|
1613
|
+
raw = v4PortMatch[1];
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
const clean = raw.replace(/^\[|\]$/g, "").replace(/%[^\s%\]]+$/, "").trim();
|
|
1156
1617
|
if (!clean) return null;
|
|
1157
1618
|
const directV4 = parseStrictIpv4Octets(clean);
|
|
1158
1619
|
if (directV4) return `ipv4:${directV4.join(".")}`;
|
|
@@ -1283,14 +1744,30 @@ function extractNormalizedCe3Identifiers(tx) {
|
|
|
1283
1744
|
|
|
1284
1745
|
function extractPaymentCredential(tx) {
|
|
1285
1746
|
if (!tx || typeof tx !== "object") return "";
|
|
1286
|
-
const
|
|
1287
|
-
tx.card_fingerprint
|
|
1288
|
-
tx.payment_method_fingerprint
|
|
1289
|
-
tx.
|
|
1290
|
-
tx.
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1747
|
+
const fpCandidates = [
|
|
1748
|
+
tx.card_fingerprint,
|
|
1749
|
+
tx.payment_method_fingerprint,
|
|
1750
|
+
tx.payment_method_details?.card?.fingerprint,
|
|
1751
|
+
tx.payment_method && typeof tx.payment_method === "object"
|
|
1752
|
+
? tx.payment_method.card?.fingerprint
|
|
1753
|
+
: "",
|
|
1754
|
+
tx.card?.fingerprint,
|
|
1755
|
+
tx.source?.card?.fingerprint,
|
|
1756
|
+
];
|
|
1757
|
+
for (const cand of fpCandidates) {
|
|
1758
|
+
if (typeof cand === "string" && cand.trim()) {
|
|
1759
|
+
return sanitizeLogToken(cand.trim(), 96);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
const pmId =
|
|
1763
|
+
typeof tx.payment_method === "string"
|
|
1764
|
+
? tx.payment_method
|
|
1765
|
+
: tx.payment_method &&
|
|
1766
|
+
typeof tx.payment_method === "object" &&
|
|
1767
|
+
typeof tx.payment_method.id === "string"
|
|
1768
|
+
? tx.payment_method.id
|
|
1769
|
+
: "";
|
|
1770
|
+
return sanitizeLogToken(pmId, 96);
|
|
1294
1771
|
}
|
|
1295
1772
|
|
|
1296
1773
|
function evaluateLocalVisaCe3Qualification(disputeReason, disputedTransaction, priorTransactions) {
|
|
@@ -1436,7 +1913,7 @@ export const LOCAL_STATELESS_CLOUD_UPGRADE_HINT = Object.freeze({
|
|
|
1436
1913
|
message:
|
|
1437
1914
|
"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
1915
|
command: "npx --yes revclamp-mcp --init-workspace <work_email>",
|
|
1439
|
-
cliActivateCommand: "npx -y revclamp-mcp@1.20.
|
|
1916
|
+
cliActivateCommand: "npx -y revclamp-mcp@1.20.12 --init-workspace you@company.com",
|
|
1440
1917
|
upgradeUrl: "https://revclamp.com/pricing?source=mcp_cli",
|
|
1441
1918
|
});
|
|
1442
1919
|
|
|
@@ -2447,11 +2924,10 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2447
2924
|
if (
|
|
2448
2925
|
args.consultationNumber !== undefined &&
|
|
2449
2926
|
(typeof args.consultationNumber !== "string" ||
|
|
2450
|
-
args.consultationNumber.trim()
|
|
2451
|
-
args.consultationNumber.trim().length > 64)
|
|
2927
|
+
!/^[A-Za-z0-9_-]{1,64}$/.test(args.consultationNumber.trim()))
|
|
2452
2928
|
) {
|
|
2453
2929
|
const err = new Error(
|
|
2454
|
-
"Invalid params: consultationNumber must be
|
|
2930
|
+
"Invalid params: consultationNumber must be 1..64 alphanumeric, underscore, or hyphen characters [A-Za-z0-9_-]"
|
|
2455
2931
|
);
|
|
2456
2932
|
err.code = -32602;
|
|
2457
2933
|
throw err;
|
|
@@ -2464,10 +2940,58 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2464
2940
|
err.code = -32602;
|
|
2465
2941
|
throw err;
|
|
2466
2942
|
}
|
|
2943
|
+
if (
|
|
2944
|
+
args.supplyType !== undefined &&
|
|
2945
|
+
(typeof args.supplyType !== "string" ||
|
|
2946
|
+
!["GOODS", "SERVICES"].includes(args.supplyType.trim().toUpperCase()))
|
|
2947
|
+
) {
|
|
2948
|
+
const err = new Error("Invalid params: supplyType must be 'GOODS' or 'SERVICES'");
|
|
2949
|
+
err.code = -32602;
|
|
2950
|
+
throw err;
|
|
2951
|
+
}
|
|
2952
|
+
const supplyType =
|
|
2953
|
+
args.supplyType === undefined ? "GOODS" : args.supplyType.trim().toUpperCase();
|
|
2467
2954
|
const norm = normalizeVatId(args.buyerVatId || "");
|
|
2468
2955
|
const viesMode = String(args.viesMode || "FORMAT_ONLY").toUpperCase();
|
|
2469
2956
|
const isDemo = args.demo === true;
|
|
2470
2957
|
|
|
2958
|
+
if (
|
|
2959
|
+
norm.validFormat &&
|
|
2960
|
+
sellerCountry !== norm.memberState &&
|
|
2961
|
+
supplyType === "SERVICES" &&
|
|
2962
|
+
(sellerCountry === "XI" || norm.memberState === "XI")
|
|
2963
|
+
) {
|
|
2964
|
+
const statutoryTerminology = getEuViesStatutoryTerminology(norm.memberState);
|
|
2965
|
+
const sellerStatutoryTerminology = getEuViesStatutoryTerminology(sellerCountry);
|
|
2966
|
+
return {
|
|
2967
|
+
ok: true,
|
|
2968
|
+
executionMode: "local_open_source_engine",
|
|
2969
|
+
...(isDemo ? { sample: true, simulatedViesLookup: true } : {}),
|
|
2970
|
+
valid: null,
|
|
2971
|
+
formatValid: true,
|
|
2972
|
+
supplyType,
|
|
2973
|
+
status: "HOLD_XI_SERVICES_OUTSIDE_EU_VIES",
|
|
2974
|
+
action: "APPLY_UK_OR_NON_EU_SERVICES_VAT_RULES",
|
|
2975
|
+
reason: "WINDSOR_FRAMEWORK_XI_B2B_SERVICES_EXCLUDED_FROM_VIES",
|
|
2976
|
+
sellerCountry,
|
|
2977
|
+
sellerStatutoryTerminology,
|
|
2978
|
+
normalizedVatId: norm.fullVatId,
|
|
2979
|
+
memberState: norm.memberState,
|
|
2980
|
+
statutoryTerminology,
|
|
2981
|
+
crossBorderSupply: true,
|
|
2982
|
+
domesticSameMemberState: false,
|
|
2983
|
+
reverseChargeEligible: false,
|
|
2984
|
+
zeroRateAllowed: false,
|
|
2985
|
+
statutoryReverseChargeClause: null,
|
|
2986
|
+
sellerStatutoryReverseChargeClause: null,
|
|
2987
|
+
statutoryGoodsExemptionClause: null,
|
|
2988
|
+
sellerStatutoryGoodsExemptionClause: null,
|
|
2989
|
+
applicableStatutoryClause: null,
|
|
2990
|
+
sellerApplicableStatutoryClause: null,
|
|
2991
|
+
consultationId: null,
|
|
2992
|
+
};
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2471
2995
|
if (viesMode === "LIVE") {
|
|
2472
2996
|
const err = new Error(
|
|
2473
2997
|
"LIVE_VIES_REQUIRES_CLOUD_ENDPOINT: Live European Commission VIES consultation requires cloud mode (https://api.revclamp.com/api/mcp with REVCLAMP_API_KEY)."
|
|
@@ -2488,9 +3012,10 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2488
3012
|
return {
|
|
2489
3013
|
ok: true,
|
|
2490
3014
|
executionMode: "local_open_source_engine",
|
|
2491
|
-
...(isDemo ? { sample: true } : {}),
|
|
3015
|
+
...(isDemo ? { sample: true, simulatedViesLookup: true } : {}),
|
|
2492
3016
|
valid: false,
|
|
2493
3017
|
formatValid: false,
|
|
3018
|
+
supplyType,
|
|
2494
3019
|
status: "HOLD_INVALID_VAT",
|
|
2495
3020
|
reason: "INVALID_EU_VAT_FORMAT",
|
|
2496
3021
|
sellerCountry,
|
|
@@ -2502,6 +3027,12 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2502
3027
|
}
|
|
2503
3028
|
|
|
2504
3029
|
const crossBorder = sellerCountry !== norm.memberState;
|
|
3030
|
+
const statutoryTerminology = getEuViesStatutoryTerminology(norm.memberState);
|
|
3031
|
+
const sellerStatutoryTerminology = getEuViesStatutoryTerminology(sellerCountry);
|
|
3032
|
+
const callerConsultationId =
|
|
3033
|
+
typeof args.consultationNumber === "string" && args.consultationNumber.trim().length > 0
|
|
3034
|
+
? args.consultationNumber.trim().slice(0, 64)
|
|
3035
|
+
: null;
|
|
2505
3036
|
|
|
2506
3037
|
if (!isDemo || viesMode === "FORMAT_ONLY") {
|
|
2507
3038
|
return {
|
|
@@ -2509,14 +3040,25 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2509
3040
|
executionMode: "local_open_source_engine",
|
|
2510
3041
|
valid: null,
|
|
2511
3042
|
formatValid: true,
|
|
3043
|
+
supplyType,
|
|
2512
3044
|
status: "FORMAT_VALID_UNVERIFIED",
|
|
3045
|
+
action: crossBorder ? "FORMAT_VALID_UNVERIFIED" : "APPLY_DOMESTIC_STANDARD_VAT",
|
|
2513
3046
|
reason: "LOCAL_FORMAT_CHECK_ONLY_NO_LIVE_VIES_CONSULTATION",
|
|
2514
3047
|
sellerCountry,
|
|
3048
|
+
sellerStatutoryTerminology,
|
|
2515
3049
|
normalizedVatId: norm.fullVatId,
|
|
2516
3050
|
memberState: norm.memberState,
|
|
3051
|
+
statutoryTerminology,
|
|
2517
3052
|
crossBorderSupply: crossBorder,
|
|
3053
|
+
domesticSameMemberState: !crossBorder,
|
|
2518
3054
|
reverseChargeEligible: false,
|
|
2519
3055
|
zeroRateAllowed: false,
|
|
3056
|
+
statutoryReverseChargeClause: null,
|
|
3057
|
+
sellerStatutoryReverseChargeClause: null,
|
|
3058
|
+
statutoryGoodsExemptionClause: null,
|
|
3059
|
+
sellerStatutoryGoodsExemptionClause: null,
|
|
3060
|
+
applicableStatutoryClause: null,
|
|
3061
|
+
sellerApplicableStatutoryClause: null,
|
|
2520
3062
|
consultationId: null,
|
|
2521
3063
|
limitations: ["NO_LIVE_VIES_CONSULTATION_NUMBER"],
|
|
2522
3064
|
upgrade: {
|
|
@@ -2527,56 +3069,157 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2527
3069
|
};
|
|
2528
3070
|
}
|
|
2529
3071
|
|
|
2530
|
-
|
|
3072
|
+
const TRANSIENT_SIM_MODES = new Set([
|
|
3073
|
+
"MS_UNAVAILABLE",
|
|
3074
|
+
"GLOBAL_MAX_CONCURRENT_REQ",
|
|
3075
|
+
"MS_MAX_CONCURRENT_REQ",
|
|
3076
|
+
"MS_MAX_CONCURRENT_REQ_TIME",
|
|
3077
|
+
"GLOBAL_MAX_CONCURRENT_REQ_TIME",
|
|
3078
|
+
"SERVICE_UNAVAILABLE",
|
|
3079
|
+
"TIMEOUT",
|
|
3080
|
+
"SERVER_BUSY",
|
|
3081
|
+
"NETWORK_ERROR",
|
|
3082
|
+
]);
|
|
3083
|
+
if (TRANSIENT_SIM_MODES.has(viesMode)) {
|
|
2531
3084
|
return {
|
|
2532
3085
|
ok: true,
|
|
2533
3086
|
executionMode: "local_open_source_engine",
|
|
2534
3087
|
sample: true,
|
|
3088
|
+
simulatedViesLookup: true,
|
|
2535
3089
|
valid: null,
|
|
2536
3090
|
formatValid: true,
|
|
3091
|
+
supplyType,
|
|
2537
3092
|
status: "PENDING_ASYNC_RETRY",
|
|
2538
3093
|
reason: `VIES_SOFT_FAULT_${viesMode}`,
|
|
2539
3094
|
sellerCountry,
|
|
3095
|
+
sellerStatutoryTerminology,
|
|
3096
|
+
normalizedVatId: norm.fullVatId,
|
|
3097
|
+
memberState: norm.memberState,
|
|
3098
|
+
statutoryTerminology,
|
|
3099
|
+
domesticSameMemberState: !crossBorder,
|
|
3100
|
+
reverseChargeEligible: false,
|
|
3101
|
+
zeroRateAllowed: false,
|
|
3102
|
+
consultationId: null,
|
|
3103
|
+
};
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
if (viesMode === "INVALID_REQUESTER_INFO" || viesMode === "IP_BLOCKED") {
|
|
3107
|
+
return {
|
|
3108
|
+
ok: true,
|
|
3109
|
+
executionMode: "local_open_source_engine",
|
|
3110
|
+
sample: true,
|
|
3111
|
+
simulatedViesLookup: true,
|
|
3112
|
+
valid: null,
|
|
3113
|
+
formatValid: true,
|
|
3114
|
+
supplyType,
|
|
3115
|
+
status: "HOLD_UNVERIFIED_VIES_FAULT",
|
|
3116
|
+
reason: `VIES_GATEWAY_FAULT_${viesMode}`,
|
|
3117
|
+
sellerCountry,
|
|
3118
|
+
sellerStatutoryTerminology,
|
|
2540
3119
|
normalizedVatId: norm.fullVatId,
|
|
2541
3120
|
memberState: norm.memberState,
|
|
3121
|
+
statutoryTerminology,
|
|
3122
|
+
domesticSameMemberState: !crossBorder,
|
|
2542
3123
|
reverseChargeEligible: false,
|
|
2543
3124
|
zeroRateAllowed: false,
|
|
2544
3125
|
consultationId: null,
|
|
2545
3126
|
};
|
|
2546
3127
|
}
|
|
2547
3128
|
|
|
2548
|
-
if (viesMode === "INVALID") {
|
|
3129
|
+
if (viesMode === "INVALID" || viesMode === "VAT_BLOCKED" || viesMode === "INVALID_INPUT") {
|
|
2549
3130
|
return {
|
|
2550
3131
|
ok: true,
|
|
2551
3132
|
executionMode: "local_open_source_engine",
|
|
2552
3133
|
sample: true,
|
|
3134
|
+
simulatedViesLookup: true,
|
|
2553
3135
|
valid: false,
|
|
2554
3136
|
formatValid: true,
|
|
3137
|
+
supplyType,
|
|
2555
3138
|
status: "HOLD_INVALID_VAT",
|
|
2556
|
-
reason: "VIES_DEFINITE_INVALID"
|
|
3139
|
+
reason: viesMode === "INVALID" ? "VIES_DEFINITE_INVALID" : `VIES_${viesMode}`,
|
|
3140
|
+
sellerCountry,
|
|
3141
|
+
sellerStatutoryTerminology,
|
|
3142
|
+
normalizedVatId: norm.fullVatId,
|
|
3143
|
+
memberState: norm.memberState,
|
|
3144
|
+
statutoryTerminology,
|
|
3145
|
+
domesticSameMemberState: !crossBorder,
|
|
3146
|
+
reverseChargeEligible: false,
|
|
3147
|
+
zeroRateAllowed: false,
|
|
3148
|
+
consultationId: null,
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
if (viesMode !== "VALID" && viesMode !== "VERIFIED") {
|
|
3153
|
+
return {
|
|
3154
|
+
ok: true,
|
|
3155
|
+
executionMode: "local_open_source_engine",
|
|
3156
|
+
sample: true,
|
|
3157
|
+
simulatedViesLookup: true,
|
|
3158
|
+
valid: null,
|
|
3159
|
+
formatValid: true,
|
|
3160
|
+
supplyType,
|
|
3161
|
+
status: "HOLD_UNVERIFIED_VIES_FAULT",
|
|
3162
|
+
reason: "UNRECOGNIZED_VIES_SIMULATION_MODE",
|
|
2557
3163
|
sellerCountry,
|
|
3164
|
+
sellerStatutoryTerminology,
|
|
2558
3165
|
normalizedVatId: norm.fullVatId,
|
|
2559
3166
|
memberState: norm.memberState,
|
|
3167
|
+
statutoryTerminology,
|
|
3168
|
+
domesticSameMemberState: !crossBorder,
|
|
2560
3169
|
reverseChargeEligible: false,
|
|
2561
3170
|
zeroRateAllowed: false,
|
|
2562
3171
|
consultationId: null,
|
|
2563
3172
|
};
|
|
2564
3173
|
}
|
|
2565
3174
|
|
|
3175
|
+
const applicableStatutoryClause = crossBorder
|
|
3176
|
+
? supplyType === "GOODS"
|
|
3177
|
+
? statutoryTerminology?.statutoryGoodsExemptionClause || null
|
|
3178
|
+
: statutoryTerminology?.statutoryReverseChargeClause || null
|
|
3179
|
+
: null;
|
|
3180
|
+
const sellerApplicableStatutoryClause = crossBorder
|
|
3181
|
+
? supplyType === "GOODS"
|
|
3182
|
+
? sellerStatutoryTerminology?.statutoryGoodsExemptionClause || null
|
|
3183
|
+
: sellerStatutoryTerminology?.statutoryReverseChargeClause || null
|
|
3184
|
+
: null;
|
|
3185
|
+
|
|
2566
3186
|
return {
|
|
2567
3187
|
ok: true,
|
|
2568
3188
|
executionMode: "local_open_source_engine",
|
|
2569
3189
|
sample: true,
|
|
3190
|
+
simulatedViesLookup: true,
|
|
2570
3191
|
valid: true,
|
|
2571
3192
|
formatValid: true,
|
|
3193
|
+
supplyType,
|
|
2572
3194
|
status: crossBorder ? "VERIFIED_ZERO_RATED" : "DOMESTIC_TAXABLE_SUPPLY",
|
|
3195
|
+
action: crossBorder ? "ALLOW_ZERO_RATED_REVERSE_CHARGE" : "APPLY_DOMESTIC_STANDARD_VAT",
|
|
2573
3196
|
reason: crossBorder ? "VALID_CROSS_BORDER_REVERSE_CHARGE" : "SAME_MEMBER_STATE_DOMESTIC",
|
|
2574
3197
|
sellerCountry,
|
|
3198
|
+
sellerStatutoryTerminology,
|
|
2575
3199
|
normalizedVatId: norm.fullVatId,
|
|
2576
3200
|
memberState: norm.memberState,
|
|
3201
|
+
statutoryTerminology,
|
|
3202
|
+
domesticSameMemberState: !crossBorder,
|
|
2577
3203
|
reverseChargeEligible: crossBorder,
|
|
2578
3204
|
zeroRateAllowed: crossBorder,
|
|
2579
|
-
|
|
3205
|
+
statutoryReverseChargeClause: crossBorder
|
|
3206
|
+
? statutoryTerminology?.statutoryReverseChargeClause || null
|
|
3207
|
+
: null,
|
|
3208
|
+
sellerStatutoryReverseChargeClause: crossBorder
|
|
3209
|
+
? sellerStatutoryTerminology?.statutoryReverseChargeClause || null
|
|
3210
|
+
: null,
|
|
3211
|
+
statutoryGoodsExemptionClause: crossBorder
|
|
3212
|
+
? statutoryTerminology?.statutoryGoodsExemptionClause || null
|
|
3213
|
+
: null,
|
|
3214
|
+
sellerStatutoryGoodsExemptionClause: crossBorder
|
|
3215
|
+
? sellerStatutoryTerminology?.statutoryGoodsExemptionClause || null
|
|
3216
|
+
: null,
|
|
3217
|
+
applicableStatutoryClause,
|
|
3218
|
+
sellerApplicableStatutoryClause,
|
|
3219
|
+
consultationId: callerConsultationId || "DEMO_SAMPLE_NOT_FOR_TAX_AUDIT",
|
|
3220
|
+
consultationIdSource: callerConsultationId
|
|
3221
|
+
? "CALLER_SUPPLIED_UNVERIFIED"
|
|
3222
|
+
: "DEMO_SAMPLE_DEFAULT",
|
|
2580
3223
|
};
|
|
2581
3224
|
}
|
|
2582
3225
|
|
|
@@ -2670,20 +3313,21 @@ function executeLocalMcpToolCore(toolName, rawArgs = {}) {
|
|
|
2670
3313
|
|
|
2671
3314
|
const effectiveTotalCents = Math.max(0, orderTotalCents - creditNotesCents);
|
|
2672
3315
|
const hasExplicitDepositCents = args.requiredDepositCents !== undefined;
|
|
2673
|
-
const
|
|
3316
|
+
const rawRequiredDepositCents = hasExplicitDepositCents
|
|
2674
3317
|
? args.requiredDepositCents
|
|
2675
3318
|
: Math.ceil((effectiveTotalCents * requiredDepositPercent) / 100);
|
|
2676
3319
|
if (
|
|
2677
|
-
!Number.isSafeInteger(
|
|
2678
|
-
|
|
2679
|
-
|
|
3320
|
+
!Number.isSafeInteger(rawRequiredDepositCents) ||
|
|
3321
|
+
rawRequiredDepositCents < 0 ||
|
|
3322
|
+
rawRequiredDepositCents > orderTotalCents
|
|
2680
3323
|
) {
|
|
2681
3324
|
const err = new Error(
|
|
2682
|
-
"INVALID_REQUIRED_DEPOSIT_CENTS: requiredDepositCents must be an integer between 0 and
|
|
3325
|
+
"INVALID_REQUIRED_DEPOSIT_CENTS: requiredDepositCents must be an integer between 0 and totalOrderCents."
|
|
2683
3326
|
);
|
|
2684
3327
|
err.code = -32602;
|
|
2685
3328
|
throw err;
|
|
2686
3329
|
}
|
|
3330
|
+
const requiredDepositCents = Math.min(rawRequiredDepositCents, effectiveTotalCents);
|
|
2687
3331
|
|
|
2688
3332
|
const shortfallRawCents = Math.max(0, effectiveTotalCents - paidAmountCents);
|
|
2689
3333
|
const overpaidCents = Math.max(0, paidAmountCents - effectiveTotalCents);
|
|
@@ -3341,7 +3985,7 @@ function toSafeLocalRpcId(rawId) {
|
|
|
3341
3985
|
|
|
3342
3986
|
export function executeLocalMcpJsonRpc(
|
|
3343
3987
|
rpcRequest,
|
|
3344
|
-
packageVersion = "1.20.
|
|
3988
|
+
packageVersion = "1.20.12",
|
|
3345
3989
|
options = {}
|
|
3346
3990
|
) {
|
|
3347
3991
|
if (!rpcRequest || typeof rpcRequest !== "object" || Array.isArray(rpcRequest)) {
|
|
@@ -3457,7 +4101,7 @@ export function executeLocalMcpJsonRpc(
|
|
|
3457
4101
|
version: packageVersion,
|
|
3458
4102
|
localExecution: "9 deterministic tools in local_engine.mjs (0 network calls by default)",
|
|
3459
4103
|
cloudCapabilities: [
|
|
3460
|
-
"90-day
|
|
4104
|
+
"90-day durable transactional usage & audit ledger",
|
|
3461
4105
|
"24/7 autonomous Stripe dispute & entitlement webhook outbox",
|
|
3462
4106
|
"Live EU Commission VIES SOAP consultation numbers (viesMode: 'LIVE')",
|
|
3463
4107
|
],
|
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.12",
|
|
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": "c67f214211284a479fbe10857dfef984b45e3c3403c37d5d834dcd5a5b326b60"
|
|
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.12",
|
|
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.12",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|