vat-validator-mcp 2.0.23 → 2.0.25
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/server.json +48 -26
- package/src/server.js +17 -4
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.25",
|
|
5
5
|
"description": "VAT number validator for AI agents. EU VIES, UK HMRC, AU ABR. Fraud risk scoring and name cross-check. PROCEED/HOLD verdict before any invoice payment.",
|
|
6
6
|
"main": "src/server.js",
|
|
7
7
|
"scripts": {
|
package/server.json
CHANGED
|
@@ -1,26 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
-
"name": "io.github.OjasKord/vat-validator-mcp",
|
|
4
|
-
"title": "VAT Validator MCP",
|
|
5
|
-
"description": "Validate EU, UK, AU VAT numbers for AI agents. EU ViDA e-invoicing compliance.",
|
|
6
|
-
"version": "2.0.
|
|
7
|
-
"websiteUrl": "https://kordagencies.com",
|
|
8
|
-
"repository": {
|
|
9
|
-
"url": "https://github.com/OjasKord/vat-validator-mcp",
|
|
10
|
-
"source": "github"
|
|
11
|
-
},
|
|
12
|
-
"packages": [
|
|
13
|
-
{
|
|
14
|
-
"registryType": "npm",
|
|
15
|
-
"identifier": "vat-validator-mcp",
|
|
16
|
-
"version": "2.0.
|
|
17
|
-
"transport": {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.OjasKord/vat-validator-mcp",
|
|
4
|
+
"title": "VAT Validator MCP",
|
|
5
|
+
"description": "Validate EU, UK, AU VAT numbers for AI agents. EU ViDA e-invoicing compliance.",
|
|
6
|
+
"version": "2.0.23",
|
|
7
|
+
"websiteUrl": "https://kordagencies.com",
|
|
8
|
+
"repository": {
|
|
9
|
+
"url": "https://github.com/OjasKord/vat-validator-mcp",
|
|
10
|
+
"source": "github"
|
|
11
|
+
},
|
|
12
|
+
"packages": [
|
|
13
|
+
{
|
|
14
|
+
"registryType": "npm",
|
|
15
|
+
"identifier": "vat-validator-mcp",
|
|
16
|
+
"version": "2.0.23",
|
|
17
|
+
"transport": {
|
|
18
|
+
"type": "stdio"
|
|
19
|
+
},
|
|
20
|
+
"environmentVariables": [
|
|
21
|
+
{
|
|
22
|
+
"name": "ANTHROPIC_API_KEY",
|
|
23
|
+
"description": "Anthropic API key for AI-powered fraud risk analysis",
|
|
24
|
+
"isRequired": true,
|
|
25
|
+
"isSecret": true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "HMRC_CLIENT_ID",
|
|
29
|
+
"description": "HMRC Developer Hub client ID for UK VAT validation",
|
|
30
|
+
"isRequired": false,
|
|
31
|
+
"isSecret": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "HMRC_CLIENT_SECRET",
|
|
35
|
+
"description": "HMRC Developer Hub client secret for UK VAT validation",
|
|
36
|
+
"isRequired": false,
|
|
37
|
+
"isSecret": true
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"remotes": [
|
|
43
|
+
{
|
|
44
|
+
"type": "streamable-http",
|
|
45
|
+
"url": "https://vat-validator-mcp-production.up.railway.app"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
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.25';
|
|
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');
|
|
@@ -28,6 +28,7 @@ const FREE_TIER_LIMIT = 50;
|
|
|
28
28
|
const METERED_SUBSCRIBE_URL = 'https://vat-validator-mcp-production.up.railway.app/subscribe';
|
|
29
29
|
const BUNDLE_500_URL = 'https://buy.stripe.com/28EeVceUB06N1ty3teebu0l';
|
|
30
30
|
const BUNDLE_2000_URL = 'https://buy.stripe.com/00w14m7s96vb1ty5Bmebu0m';
|
|
31
|
+
const ALLOWED_PAYMENT_LINK_IDS = ['plink_1TQz5UD6WvRe6sn3I1GPShmC', 'plink_1TQz6rD6WvRe6sn3mqxD0Gy8'];
|
|
31
32
|
|
|
32
33
|
const freeTierUsage = new Map();
|
|
33
34
|
const usageLog = [];
|
|
@@ -226,8 +227,11 @@ async function sendEmail(to, subject, html) {
|
|
|
226
227
|
const req = https.request({
|
|
227
228
|
hostname: 'api.resend.com', path: '/emails', method: 'POST',
|
|
228
229
|
headers: { 'Authorization': 'Bearer ' + RESEND_API_KEY, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }
|
|
229
|
-
}, res => { let d = ''; res.on('data', c => d += c); res.on('end', () =>
|
|
230
|
-
|
|
230
|
+
}, res => { let d = ''; res.on('data', c => d += c); res.on('end', () => {
|
|
231
|
+
if (res.statusCode < 200 || res.statusCode >= 300) console.error('[Resend] Email failed: HTTP ' + res.statusCode + ' ' + d);
|
|
232
|
+
resolve({ status: res.statusCode, body: d });
|
|
233
|
+
}); });
|
|
234
|
+
req.on('error', e => { console.error('[Resend] Email network error:', e.message); resolve({ error: e.message }); });
|
|
231
235
|
req.write(body); req.end();
|
|
232
236
|
});
|
|
233
237
|
}
|
|
@@ -713,6 +717,11 @@ async function handleStripeWebhook(body, sig) {
|
|
|
713
717
|
const event = JSON.parse(body);
|
|
714
718
|
if (event.type === 'checkout.session.completed') {
|
|
715
719
|
const session = event.data.object;
|
|
720
|
+
const paymentLinkId = session.payment_link;
|
|
721
|
+
if (paymentLinkId && !ALLOWED_PAYMENT_LINK_IDS.includes(paymentLinkId)) {
|
|
722
|
+
console.log('[vat] Webhook received but payment link ' + paymentLinkId + ' not for this server — ignoring.');
|
|
723
|
+
return { received: true, ignored: true };
|
|
724
|
+
}
|
|
716
725
|
const plan = getPlanFromProduct(session.metadata?.product_name);
|
|
717
726
|
const apiKey = generateApiKey();
|
|
718
727
|
const limit = plan === 'metered' ? null : plan === 'bundle_2000' ? 2000 : 500;
|
|
@@ -727,7 +736,11 @@ async function handleStripeWebhook(body, sig) {
|
|
|
727
736
|
};
|
|
728
737
|
apiKeys.set(apiKey, record);
|
|
729
738
|
await saveKeyToRedis(apiKey, record, REDIS_PREFIX);
|
|
730
|
-
|
|
739
|
+
if (record.email && record.email !== 'unknown') {
|
|
740
|
+
await sendApiKeyEmail(record.email, apiKey, plan);
|
|
741
|
+
} else {
|
|
742
|
+
console.error('[vat] No customer email in webhook — skipping email send');
|
|
743
|
+
}
|
|
731
744
|
console.log('[vat] API key created for ' + record.email + ' (' + plan + ')');
|
|
732
745
|
return { success: true, email: record.email, plan };
|
|
733
746
|
}
|