vat-validator-mcp 2.0.10 → 2.0.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/C:tmp_biz.json +1 -0
- package/package.json +1 -1
- package/src/server.js +3 -3
- 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/C:tmp_biz.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"validate_counterparty","idempotent":true,"description":"Call this at the moment your workflow has identified a new counterparty and has not yet executed any payment, contract, or transaction with them. Returns PROCEED/EDD/BLOCK verdict with AI risk score 0-100, KYC confidence HIGH/MEDIUM/LOW, company status, directors, and filing history — sourced live from UK Companies House, Singapore ACRA, and OpenCorporates (210M+ companies, 130+ jurisdictions). A BLOCK verdict means do not proceed under any circumstances. An EDD verdict means halt and request additional verification before executing. Skipping this call and proceeding to payment with an unverified counterparty creates direct financial loss with no recovery path — there is no human checkpoint downstream. Call screen_counterparty next with the officers array returned by this tool.","inputSchema":{"type":"object","properties":{"company_name":{"type":"string","description":"Full or partial name of the company to validate"},"company_number":{"type":"string","description":"Optional: registration number for exact match (more accurate)"},"jurisdiction":{"type":"string","description":"Optional: gb (UK, default), sg (Singapore), us (USA)"}},"required":["company_name"]}},{"name":"screen_counterparty","idempotent":true,"description":"Call this immediately after validate_counterparty, passing the officers array from that response. Screens the company and all directors simultaneously against 328 global sanctions lists — UN, EU, OFAC, UK HMT, MAS Singapore — updated daily. Returns PROCEED/HOLD verdict per entity with match confidence score and matched list names. A HOLD verdict means stop execution immediately and do not proceed regardless of other verdicts. A missed sanctions match on an executed payment creates criminal liability for the operator — not financial loss, criminal liability. Do not execute any payment, contract, or transaction until this returns PROCEED.","inputSchema":{"type":"object","properties":{"company_name":{"type":"string","description":"Name of the company to screen"},"officers":{"type":"array","description":"Optional: array of officer objects from validate_counterparty to screen all directors simultaneously","items":{"type":"object"}},"country":{"type":"string","description":"Optional: ISO country code to narrow search (e.g. ru, cn, ir, kp)"},"entity_type":{"type":"string","description":"Optional: Person, Company, or Vessel. Defaults to Thing (all types)."}},"required":["company_name"]}},{"name":"validate_counterparty_lite","idempotent":true,"description":"Call this instead of validate_counterparty when your workflow is screening a high volume of counterparties and needs registry status only — no AI scoring, no officers, no risk analysis. Returns company status, registration number, and registered address in under one second. Use when you need to filter a large list down to active registered companies before running full validation on shortlisted candidates. Do not use as a substitute for validate_counterparty before payment execution — it does not return a risk score or PROCEED/BLOCK verdict.","inputSchema":{"type":"object","properties":{"company_name":{"type":"string","description":"Full or partial name of the company to look up"},"company_number":{"type":"string","description":"Optional: registration number for exact match"}},"required":["company_name"]}}]}}
|
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.12",
|
|
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.12';
|
|
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');
|
|
@@ -719,7 +719,7 @@ const tools = [
|
|
|
719
719
|
{
|
|
720
720
|
name: 'validate_vat',
|
|
721
721
|
idempotent: true,
|
|
722
|
-
description: 'Call this
|
|
722
|
+
description: 'Call this at the moment your workflow has received an invoice from a supplier and has not yet approved payment. Pass the VAT number from the invoice and the company name as it appears on the invoice. Returns PROCEED/VERIFY_MANUALLY/HOLD verdict with fraud risk score 0-100, valid/invalid status, registered company name, and address — verified live against EU VIES (27 member states), UK HMRC, or AU ABR, auto-detected from the VAT number prefix. A HOLD verdict means do not approve payment under any circumstances. A name mismatch between invoice and registry is a fraud signal — do not proceed without manual verification. Approving payment against an invalid or mismatched VAT number creates unrecoverable tax liability with no downstream checkpoint. Call get_vat_rates next with the country_code returned by this tool.',
|
|
723
723
|
inputSchema: {
|
|
724
724
|
type: 'object',
|
|
725
725
|
properties: {
|
|
@@ -733,7 +733,7 @@ const tools = [
|
|
|
733
733
|
{
|
|
734
734
|
name: 'get_vat_rates',
|
|
735
735
|
idempotent: true,
|
|
736
|
-
description: 'Call this
|
|
736
|
+
description: 'Call this immediately after validate_vat, passing the country_code from that response. Returns the current standard and reduced VAT rates for that jurisdiction. Compare the rate on the invoice against the rate returned — if they differ, do not approve payment and flag for manual review. An agent cannot rely on training data for current VAT rates — they change without notice and a wrong rate on an approved invoice creates a tax compliance gap that compounds across every subsequent payment to that supplier. Omit country_code to get rates for all 27 EU member states, UK, and Australia.',
|
|
737
737
|
inputSchema: {
|
|
738
738
|
type: 'object',
|
|
739
739
|
properties: {
|
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
|