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 +1 -1
- package/src/server.js +1 -1
- package/cd +0 -0
- package/del +0 -0
- package/git +0 -0
- package/main +0 -0
- package/node +0 -0
- package/patch_vat_v134.js +0 -84
- package/privacy.html +0 -501
- package/railway +0 -0
- package/src/server.js.bak +0 -437
- package/src/vat_server_v130_clean.js +0 -401
- package/vat_server_v2_fixed.js +0 -586
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.
|
|
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
|
+
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 · <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
|
-
·
|
|
493
|
-
<a href="https://kordagencies.com/terms.html">Terms</a>
|
|
494
|
-
·
|
|
495
|
-
Privacy Policy
|
|
496
|
-
·
|
|
497
|
-
© 2026 Kord Agencies
|
|
498
|
-
</footer>
|
|
499
|
-
|
|
500
|
-
</body>
|
|
501
|
-
</html>
|
package/railway
DELETED
|
File without changes
|