vat-validator-mcp 2.0.10 → 2.0.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vat-validator-mcp",
3
3
  "mcpName": "io.github.OjasKord/vat-validator-mcp",
4
- "version": "2.0.10",
4
+ "version": "2.0.11",
5
5
  "description": "VAT number validator for AI agents. EU VIES, UK HMRC, AU ABR — auto-detects jurisdiction. Fraud risk scoring and invoice name cross-check in one call.",
6
6
  "main": "src/server.js",
7
7
  "scripts": {
package/src/server.js CHANGED
@@ -7,7 +7,7 @@ const Stripe = require('stripe');
7
7
  const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
8
8
 
9
9
  const PERSIST_FILE = '/tmp/vat_stats.json';
10
- const VERSION = '2.0.10';
10
+ const VERSION = '2.0.11';
11
11
 
12
12
  // Persistent device ID for HMRC fraud prevention headers (BATCH_PROCESS_DIRECT)
13
13
  const DEVICE_ID_FILE = path.join(__dirname, '..', 'device-id.txt');
package/cd DELETED
File without changes
package/del DELETED
File without changes
package/git DELETED
File without changes
package/main DELETED
File without changes
package/node DELETED
File without changes
package/patch_vat_v134.js DELETED
@@ -1,84 +0,0 @@
1
- const fs = require('fs');
2
- let c = fs.readFileSync('C:/vat-validator-mcp/src/server.js', 'utf8');
3
-
4
- console.log('File size:', c.length);
5
- console.log('Has vat_stats:', c.includes('vat_stats'));
6
- console.log('Version 1.3.2:', c.includes('1.3.2'));
7
- console.log('Has validate_vat:', c.includes('validate_vat'));
8
-
9
- if (!c.includes('vat_stats')) {
10
- console.error('ERROR: Wrong file');
11
- process.exit(1);
12
- }
13
-
14
- // 1. Add FREE_TIER_WARNING constant
15
- c = c.replace(
16
- 'const FREE_TIER_LIMIT = 20;',
17
- 'const FREE_TIER_LIMIT = 20;\nconst FREE_TIER_WARNING = 16; // warn at 80% usage'
18
- );
19
-
20
- // 2. Bump version to 1.4.0
21
- c = c.replace(/1\.3\.2/g, '1.4.0');
22
-
23
- // 3. Add partial response logic in tools/call handler
24
- // Find the existing tools/call result handling
25
- const oldResult = ` const result = await executeTool(name, toolArgs || {});
26
- if (req._accessWarning) result._notice = req._accessWarning;
27
- response = { jsonrpc: '2.0', id: request.id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] } };`;
28
-
29
- const newResult = ` const result = await executeTool(name, toolArgs || {});
30
- if (req._accessWarning) result._notice = req._accessWarning;
31
-
32
- // Partial response for free tier
33
- if (req._tier === 'free' && !result.error) {
34
- const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress || 'unknown';
35
- const used = freeTierUsage.get(ip) || 0;
36
- const remaining = FREE_TIER_LIMIT - used;
37
- const isWarning = used >= FREE_TIER_WARNING;
38
-
39
- if (name === 'validate_vat' || name === 'validate_uk_vat') {
40
- // Gate address on free tier — company name + valid status visible
41
- const gated = ['registered_address', 'address', 'consultation_number'];
42
- gated.forEach(f => delete result[f]);
43
- result._upgrade_note = 'Free tier: ' + remaining + ' of ' + FREE_TIER_LIMIT + ' calls remaining. Upgrade to Pro ($39/month) at kordagencies.com for full registered address and HMRC consultation number.';
44
- result._gated_fields = gated;
45
- }
46
-
47
- if (name === 'analyse_vat_risk') {
48
- // Gate full reasoning — verdict visible, details gated
49
- const gated = ['fraud_signals', 'positive_indicators', 'recommended_action', 'summary'];
50
- gated.forEach(f => delete result[f]);
51
- result._upgrade_note = 'Free tier: ' + remaining + ' of ' + FREE_TIER_LIMIT + ' calls remaining. Upgrade to Pro ($39/month) at kordagencies.com for full fraud signal breakdown, positive indicators, and recommended action.';
52
- result._gated_fields = gated;
53
- }
54
-
55
- if (name === 'compare_invoice_details') {
56
- // Gate detail fields — match_status visible, discrepancies gated
57
- const gated = ['discrepancies', 'name_match', 'address_match', 'recommended_action', 'summary'];
58
- gated.forEach(f => delete result[f]);
59
- result._upgrade_note = 'Free tier: ' + remaining + ' of ' + FREE_TIER_LIMIT + ' calls remaining. Upgrade to Pro ($39/month) at kordagencies.com for full discrepancy analysis and recommended action.';
60
- result._gated_fields = gated;
61
- }
62
-
63
- if (isWarning) result._notice = 'Warning: only ' + remaining + ' free call' + (remaining === 1 ? '' : 's') + ' left this month. Upgrade to Pro at kordagencies.com to avoid interruption.';
64
- }
65
-
66
- response = { jsonrpc: '2.0', id: request.id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] } };`;
67
-
68
- if (!c.includes(oldResult)) {
69
- console.error('ERROR: Could not find tool call handler');
70
- const idx = c.indexOf('executeTool(name');
71
- console.log('executeTool at:', idx);
72
- console.log('Context:', c.substring(idx - 20, idx + 150));
73
- process.exit(1);
74
- }
75
-
76
- c = c.replace(oldResult, newResult);
77
-
78
- console.log('FREE_TIER_WARNING:', c.includes('FREE_TIER_WARNING'));
79
- console.log('Version 1.4.0:', c.includes('1.4.0'));
80
- console.log('Partial response:', c.includes('_upgrade_note'));
81
- console.log('New size:', c.length);
82
-
83
- fs.writeFileSync('C:/vat-validator-mcp/src/server.js', c);
84
- console.log('Done');
package/privacy.html DELETED
@@ -1,501 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Privacy Policy — Kord Agencies</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com">
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
- <link href="https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400&display=swap" rel="stylesheet">
10
- <style>
11
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
12
-
13
- :root {
14
- --bg: #070910;
15
- --bg-2: #0C1018;
16
- --bg-3: #111722;
17
- --teal: #00E5C3;
18
- --amber: #F0A030;
19
- --text: #E2E8F2;
20
- --text-2: #8895AA;
21
- --text-3: #505A6A;
22
- --border: rgba(255,255,255,0.06);
23
- --border-2: rgba(255,255,255,0.12);
24
- --teal-dim: rgba(0,229,195,0.08);
25
- --teal-border: rgba(0,229,195,0.25);
26
- }
27
-
28
- html { font-size: 14px; }
29
-
30
- body {
31
- background: var(--bg);
32
- color: var(--text);
33
- font-family: 'DM Mono', monospace;
34
- line-height: 1.7;
35
- min-height: 100vh;
36
- }
37
-
38
- /* ── Nav ── */
39
- nav {
40
- height: 44px;
41
- border-bottom: 1px solid var(--border);
42
- display: flex;
43
- align-items: center;
44
- padding: 0 1.5rem;
45
- position: sticky;
46
- top: 0;
47
- background: var(--bg);
48
- z-index: 10;
49
- }
50
- nav a {
51
- color: var(--teal);
52
- text-decoration: none;
53
- font-size: 11px;
54
- letter-spacing: 0.1em;
55
- text-transform: uppercase;
56
- }
57
- nav .sep {
58
- color: var(--text-3);
59
- margin: 0 0.6rem;
60
- font-size: 11px;
61
- }
62
- nav .current {
63
- color: var(--text-2);
64
- font-size: 11px;
65
- letter-spacing: 0.05em;
66
- }
67
-
68
- /* ── Layout ── */
69
- .wrap {
70
- max-width: 780px;
71
- margin: 0 auto;
72
- padding: 3rem 1.5rem 5rem;
73
- }
74
-
75
- /* ── Header ── */
76
- .page-header {
77
- border-bottom: 1px solid var(--border);
78
- padding-bottom: 2rem;
79
- margin-bottom: 2.5rem;
80
- }
81
- .label {
82
- font-size: 10px;
83
- letter-spacing: 0.15em;
84
- text-transform: uppercase;
85
- color: var(--teal);
86
- margin-bottom: 0.75rem;
87
- }
88
- h1 {
89
- font-size: 1.4rem;
90
- font-weight: 400;
91
- color: var(--text);
92
- letter-spacing: -0.01em;
93
- margin-bottom: 0.75rem;
94
- }
95
- .meta {
96
- font-size: 11px;
97
- color: var(--text-3);
98
- letter-spacing: 0.05em;
99
- }
100
- .meta span { color: var(--text-2); }
101
-
102
- /* ── Sections ── */
103
- section {
104
- margin-bottom: 2.5rem;
105
- padding-bottom: 2.5rem;
106
- border-bottom: 1px solid var(--border);
107
- }
108
- section:last-of-type {
109
- border-bottom: none;
110
- }
111
- h2 {
112
- font-size: 11px;
113
- font-weight: 500;
114
- letter-spacing: 0.12em;
115
- text-transform: uppercase;
116
- color: var(--teal);
117
- margin-bottom: 1rem;
118
- }
119
- p {
120
- font-size: 13px;
121
- color: var(--text-2);
122
- margin-bottom: 0.9rem;
123
- line-height: 1.75;
124
- }
125
- p:last-child { margin-bottom: 0; }
126
-
127
- /* ── Callout box ── */
128
- .callout {
129
- background: var(--teal-dim);
130
- border: 1px solid var(--teal-border);
131
- border-radius: 4px;
132
- padding: 1rem 1.25rem;
133
- margin: 1.25rem 0;
134
- font-size: 12px;
135
- color: var(--text);
136
- line-height: 1.7;
137
- }
138
- .callout strong {
139
- color: var(--teal);
140
- font-weight: 500;
141
- }
142
-
143
- /* ── Data table ── */
144
- .data-table {
145
- width: 100%;
146
- border-collapse: collapse;
147
- font-size: 12px;
148
- margin: 1rem 0;
149
- }
150
- .data-table th {
151
- text-align: left;
152
- font-size: 10px;
153
- letter-spacing: 0.1em;
154
- text-transform: uppercase;
155
- color: var(--text-3);
156
- padding: 0.5rem 0.75rem;
157
- border-bottom: 1px solid var(--border-2);
158
- font-weight: 400;
159
- }
160
- .data-table td {
161
- padding: 0.65rem 0.75rem;
162
- border-bottom: 1px solid var(--border);
163
- color: var(--text-2);
164
- vertical-align: top;
165
- }
166
- .data-table tr:last-child td { border-bottom: none; }
167
- .data-table td:first-child { color: var(--text); }
168
- .tag {
169
- display: inline-block;
170
- font-size: 9px;
171
- letter-spacing: 0.1em;
172
- text-transform: uppercase;
173
- padding: 2px 6px;
174
- border-radius: 3px;
175
- font-weight: 500;
176
- }
177
- .tag-no { background: rgba(248,113,113,0.1); color: #F87171; border: 1px solid rgba(248,113,113,0.2); }
178
- .tag-yes { background: rgba(0,229,195,0.1); color: var(--teal); border: 1px solid var(--teal-border); }
179
- .tag-ltd { background: rgba(240,160,48,0.1); color: var(--amber); border: 1px solid rgba(240,160,48,0.2); }
180
-
181
- /* ── Inline list ── */
182
- ul.plain {
183
- list-style: none;
184
- margin: 0.5rem 0 0.9rem;
185
- padding: 0;
186
- }
187
- ul.plain li {
188
- font-size: 13px;
189
- color: var(--text-2);
190
- padding: 0.3rem 0;
191
- padding-left: 1rem;
192
- position: relative;
193
- }
194
- ul.plain li::before {
195
- content: '—';
196
- position: absolute;
197
- left: 0;
198
- color: var(--text-3);
199
- }
200
-
201
- /* ── Contact block ── */
202
- .contact-block {
203
- background: var(--bg-2);
204
- border: 1px solid var(--border-2);
205
- border-radius: 4px;
206
- padding: 1.25rem;
207
- font-size: 12px;
208
- color: var(--text-2);
209
- line-height: 1.9;
210
- }
211
- .contact-block a {
212
- color: var(--teal);
213
- text-decoration: none;
214
- }
215
- .contact-block a:hover { text-decoration: underline; }
216
- .contact-block .field {
217
- display: flex;
218
- gap: 1rem;
219
- }
220
- .contact-block .field-label {
221
- color: var(--text-3);
222
- font-size: 10px;
223
- letter-spacing: 0.1em;
224
- text-transform: uppercase;
225
- min-width: 80px;
226
- padding-top: 1px;
227
- }
228
-
229
- /* ── Footer ── */
230
- footer {
231
- border-top: 1px solid var(--border);
232
- padding: 1.5rem;
233
- text-align: center;
234
- font-size: 11px;
235
- color: var(--text-3);
236
- letter-spacing: 0.05em;
237
- }
238
- footer a { color: var(--text-3); text-decoration: none; }
239
- footer a:hover { color: var(--text-2); }
240
- </style>
241
- </head>
242
- <body>
243
-
244
- <nav>
245
- <a href="https://kordagencies.com">kordagencies.com</a>
246
- <span class="sep">/</span>
247
- <span class="current">Privacy Policy</span>
248
- </nav>
249
-
250
- <div class="wrap">
251
-
252
- <div class="page-header">
253
- <div class="label">Legal</div>
254
- <h1>Privacy Policy</h1>
255
- <div class="meta">
256
- Kord Agencies &nbsp;·&nbsp; <span>Last updated May 2026</span>
257
- </div>
258
- </div>
259
-
260
- <!-- 1 -->
261
- <section>
262
- <h2>Who we are</h2>
263
- <p>
264
- This policy applies to VAT Validator MCP and all services operated by
265
- <strong style="color:var(--text)">Kord Agencies</strong>, a company incorporated in Singapore.
266
- </p>
267
- <div class="contact-block">
268
- <div class="field"><span class="field-label">Company</span> Kord Agencies, Singapore</div>
269
- <div class="field"><span class="field-label">Contact</span> <a href="mailto:ojas@kordagencies.com">ojas@kordagencies.com</a></div>
270
- <div class="field"><span class="field-label">Service</span> VAT Validator MCP — <a href="https://kordagencies.com">kordagencies.com</a></div>
271
- </div>
272
- </section>
273
-
274
- <!-- 2 -->
275
- <section>
276
- <h2>What we collect</h2>
277
-
278
- <div class="callout">
279
- <strong>VAT numbers you submit are never logged or stored.</strong> Query content — the VAT numbers, company names, and invoice amounts passed to our tools — is transmitted to the relevant government API and immediately discarded. It does not touch our database.
280
- </div>
281
-
282
- <table class="data-table">
283
- <thead>
284
- <tr>
285
- <th>Data</th>
286
- <th>Why</th>
287
- <th>Stored</th>
288
- </tr>
289
- </thead>
290
- <tbody>
291
- <tr>
292
- <td>Email address</td>
293
- <td>Paid subscribers only — to deliver your API key</td>
294
- <td><span class="tag tag-yes">Yes</span></td>
295
- </tr>
296
- <tr>
297
- <td>Payment information</td>
298
- <td>Processed by Stripe — we never see raw card data</td>
299
- <td><span class="tag tag-no">Stripe only</span></td>
300
- </tr>
301
- <tr>
302
- <td>API key</td>
303
- <td>Authentication and usage tracking for paid plans</td>
304
- <td><span class="tag tag-yes">Yes</span></td>
305
- </tr>
306
- <tr>
307
- <td>IP address</td>
308
- <td>Free tier rate limiting (50 calls/month/IP). Stored as truncated hash, not full address.</td>
309
- <td><span class="tag tag-ltd">Truncated</span></td>
310
- </tr>
311
- <tr>
312
- <td>Tool name + timestamp</td>
313
- <td>Aggregate usage statistics (e.g. "validate_vat called at 14:22"). No query content.</td>
314
- <td><span class="tag tag-ltd">Aggregate</span></td>
315
- </tr>
316
- <tr>
317
- <td>VAT numbers / query content</td>
318
- <td>Not applicable — not collected</td>
319
- <td><span class="tag tag-no">Never</span></td>
320
- </tr>
321
- </tbody>
322
- </table>
323
- </section>
324
-
325
- <!-- 3 -->
326
- <section>
327
- <h2>Where data is stored</h2>
328
- <p>
329
- Subscriber API keys and rate-limiting counters are stored in
330
- <strong style="color:var(--text)">Upstash Redis</strong> (hosted in the United States).
331
- The application itself runs on <strong style="color:var(--text)">Railway</strong>
332
- (hosted in the United States). Both providers maintain industry-standard
333
- encryption at rest and in transit.
334
- </p>
335
- <p>
336
- We do not operate our own database servers. No data is stored in Singapore.
337
- </p>
338
- </section>
339
-
340
- <!-- 4 -->
341
- <section>
342
- <h2>Third-party services</h2>
343
- <p>
344
- When you call our tools, your VAT number is forwarded to the relevant official
345
- government registry to perform the lookup. These are read-only API calls — no
346
- personal data about you is sent to them.
347
- </p>
348
- <table class="data-table">
349
- <thead>
350
- <tr>
351
- <th>Third party</th>
352
- <th>Purpose</th>
353
- <th>Data sent</th>
354
- </tr>
355
- </thead>
356
- <tbody>
357
- <tr>
358
- <td>Stripe</td>
359
- <td>Payment processing and subscription management</td>
360
- <td>Name, email, card details (handled entirely by Stripe)</td>
361
- </tr>
362
- <tr>
363
- <td>UK HMRC VAT API v2</td>
364
- <td>UK VAT number validation</td>
365
- <td>VAT number only</td>
366
- </tr>
367
- <tr>
368
- <td>EU VIES (ec.europa.eu)</td>
369
- <td>EU VAT number validation (all 27 member states)</td>
370
- <td>VAT number only</td>
371
- </tr>
372
- <tr>
373
- <td>Australian ABR (abr.business.gov.au)</td>
374
- <td>Australian ABN validation</td>
375
- <td>ABN only</td>
376
- </tr>
377
- <tr>
378
- <td>Anthropic (Claude API)</td>
379
- <td>AI-powered fraud risk analysis</td>
380
- <td>Validation result metadata — no raw VAT numbers or personal data</td>
381
- </tr>
382
- <tr>
383
- <td>Upstash Redis</td>
384
- <td>API key storage and rate limiting</td>
385
- <td>API keys and truncated IP counters</td>
386
- </tr>
387
- <tr>
388
- <td>Railway</td>
389
- <td>Application hosting</td>
390
- <td>Application logs (no query content)</td>
391
- </tr>
392
- </tbody>
393
- </table>
394
- </section>
395
-
396
- <!-- 5 -->
397
- <section>
398
- <h2>Legal basis and UK GDPR</h2>
399
- <p>
400
- Where we process personal data relating to individuals in the UK or EEA, we do so
401
- under the following legal bases:
402
- </p>
403
- <ul class="plain">
404
- <li><strong style="color:var(--text)">Contract performance</strong> — processing your email and API key to deliver the service you subscribed to.</li>
405
- <li><strong style="color:var(--text)">Legitimate interests</strong> — rate limiting by truncated IP address to prevent abuse of the free tier.</li>
406
- <li><strong style="color:var(--text)">Legal obligation</strong> — retaining transaction records as required for tax compliance.</li>
407
- </ul>
408
- <p>
409
- We comply with the UK General Data Protection Regulation (UK GDPR) and the
410
- Data Protection Act 2018. For EEA residents, we comply with EU GDPR (Regulation
411
- 2016/679). Transfers of personal data to the United States (Upstash, Railway,
412
- Anthropic) are made under Standard Contractual Clauses or equivalent adequacy
413
- mechanisms.
414
- </p>
415
- </section>
416
-
417
- <!-- 6 -->
418
- <section>
419
- <h2>Data retention</h2>
420
- <ul class="plain">
421
- <li>API keys and associated email addresses are retained for the lifetime of the subscription plus 90 days, then deleted.</li>
422
- <li>Truncated IP rate-limit counters reset automatically each calendar month.</li>
423
- <li>Aggregate tool usage statistics (tool name + timestamp, no content) are retained for up to 12 months for service improvement.</li>
424
- <li>Stripe retains payment records in accordance with their own privacy policy and applicable financial regulations.</li>
425
- </ul>
426
- </section>
427
-
428
- <!-- 7 -->
429
- <section>
430
- <h2>Your rights</h2>
431
- <p>
432
- Under UK GDPR and EU GDPR, you have the right to access, rectify, or erase
433
- personal data we hold about you. You also have the right to restrict or object
434
- to processing, and to data portability where applicable.
435
- </p>
436
- <p>
437
- To exercise any of these rights — including requesting deletion of your API key
438
- and associated email — contact us at:
439
- </p>
440
- <div class="contact-block" style="margin-top:0.75rem">
441
- <div class="field">
442
- <span class="field-label">Email</span>
443
- <a href="mailto:ojas@kordagencies.com">ojas@kordagencies.com</a>
444
- </div>
445
- <div class="field">
446
- <span class="field-label">Response</span>
447
- Within 30 days of receipt
448
- </div>
449
- </div>
450
- <p style="margin-top:1rem">
451
- If you are located in the UK, you have the right to lodge a complaint with the
452
- Information Commissioner's Office (ICO) at
453
- <a href="https://ico.org.uk" style="color:var(--teal)">ico.org.uk</a>.
454
- If you are in the EEA, you may contact your local supervisory authority.
455
- </p>
456
- </section>
457
-
458
- <!-- 8 -->
459
- <section>
460
- <h2>Cookies and tracking</h2>
461
- <p>
462
- The VAT Validator MCP API does not use cookies, browser tracking, analytics
463
- scripts, or fingerprinting of any kind. This privacy policy page itself does not
464
- set any cookies.
465
- </p>
466
- </section>
467
-
468
- <!-- 9 -->
469
- <section>
470
- <h2>Changes to this policy</h2>
471
- <p>
472
- We may update this policy from time to time. The date at the top of this page
473
- reflects when it was last revised. Material changes will be communicated to
474
- active subscribers by email.
475
- </p>
476
- </section>
477
-
478
- <!-- 10 -->
479
- <section>
480
- <h2>Contact</h2>
481
- <div class="contact-block">
482
- <div class="field"><span class="field-label">Company</span> Kord Agencies, Singapore</div>
483
- <div class="field"><span class="field-label">Email</span> <a href="mailto:ojas@kordagencies.com">ojas@kordagencies.com</a></div>
484
- <div class="field"><span class="field-label">Website</span> <a href="https://kordagencies.com">kordagencies.com</a></div>
485
- </div>
486
- </section>
487
-
488
- </div><!-- /wrap -->
489
-
490
- <footer>
491
- <a href="https://kordagencies.com">kordagencies.com</a>
492
- &nbsp;·&nbsp;
493
- <a href="https://kordagencies.com/terms.html">Terms</a>
494
- &nbsp;·&nbsp;
495
- Privacy Policy
496
- &nbsp;·&nbsp;
497
- &copy; 2026 Kord Agencies
498
- </footer>
499
-
500
- </body>
501
- </html>
package/railway DELETED
File without changes