data-compliance-mcp 1.0.3 → 1.0.5
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/CHANGELOG.md +14 -0
- package/LICENSE +18 -4
- package/package.json +2 -2
- package/server.json +2 -2
- package/src/server.js +75 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.5] - 2026-04-28
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Payment links updated to prepaid bundle URLs: 500 calls for $24 -- calls never expire
|
|
7
|
+
- Free tier limit errors now direct agents to prepaid bundle purchase link directly
|
|
8
|
+
|
|
9
|
+
## [1.0.4] - 2026-04-27
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `token_count` field on all tool responses — lets orchestrator budget ledgers track token cost per call
|
|
13
|
+
- `/ready` endpoint — returns 200 when `ANTHROPIC_API_KEY` is present, 503 otherwise
|
|
14
|
+
- Phase 4 enhanced error objects: `category`, `retryable`, `retry_after_ms`, `fallback_tool`, `trace_id` on all 7 error paths
|
|
15
|
+
- `validate_data_safety_lite` tool — pattern-detection only with no AI call, for budget-constrained orchestrators
|
|
16
|
+
|
|
3
17
|
## [1.0.3] - 2026-04-26
|
|
4
18
|
|
|
5
19
|
### Improved
|
package/LICENSE
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 Kord Agencies Pte Ltd
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-compliance-mcp",
|
|
3
3
|
"mcpName": "io.github.OjasKord/data-compliance-mcp",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.5",
|
|
5
5
|
"description": "Classify data safety before your agent stores or shares it. GDPR, HIPAA, PCI-DSS, CCPA. AI-powered.",
|
|
6
6
|
"main": "src/server.js",
|
|
7
7
|
"scripts": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"eu-ai-act"
|
|
30
30
|
],
|
|
31
31
|
"author": "Kord Agencies Pte Ltd <ojas@kordagencies.com>",
|
|
32
|
-
"license": "
|
|
32
|
+
"license": "MIT",
|
|
33
33
|
"homepage": "https://kordagencies.com",
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.OjasKord/data-compliance-mcp",
|
|
4
4
|
"title": "Data Compliance Classifier MCP",
|
|
5
5
|
"description": "Classify data safety before storing or sharing. GDPR, HIPAA, PCI-DSS, CCPA. AI-powered.",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.4",
|
|
7
7
|
"websiteUrl": "https://kordagencies.com",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/OjasKord/data-compliance-mcp",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "data-compliance-mcp",
|
|
16
|
-
"version": "1.0.
|
|
16
|
+
"version": "1.0.4",
|
|
17
17
|
"transport": { "type": "stdio" },
|
|
18
18
|
"environmentVariables": [
|
|
19
19
|
{ "name": "ANTHROPIC_API_KEY", "description": "Anthropic API key for AI classification", "isRequired": true, "isSecret": true },
|
package/src/server.js
CHANGED
|
@@ -3,7 +3,7 @@ const https = require('https');
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
|
|
6
|
-
const VERSION = '1.0.
|
|
6
|
+
const VERSION = '1.0.5';
|
|
7
7
|
const PERSIST_FILE = '/tmp/datacompliance_stats.json';
|
|
8
8
|
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || '';
|
|
9
9
|
const ABUSEIPDB_API_KEY = process.env.ABUSEIPDB_API_KEY || '';
|
|
@@ -17,7 +17,8 @@ const FREE_TIER_LIMIT = 20;
|
|
|
17
17
|
const FREE_TIER_WARNING = 16;
|
|
18
18
|
const apiKeys = new Map();
|
|
19
19
|
const PLAN_LIMITS = { pro: 5000, enterprise: Infinity };
|
|
20
|
-
const STRIPE_PRO_URL = 'https://buy.stripe.com/
|
|
20
|
+
const STRIPE_PRO_URL = 'https://buy.stripe.com/cNidR87s9dXD0pue7Sebu0r';
|
|
21
|
+
const ENTERPRISE_UPGRADE_URL = 'https://buy.stripe.com/9B6bJ0aElbPv7RW9RCebu0s';
|
|
21
22
|
const STRIPE_ENTERPRISE_URL = 'https://buy.stripe.com/cNi7sKeUB8Dj7RW7Juebu0d';
|
|
22
23
|
|
|
23
24
|
const LEGAL_DISCLAIMER = 'Classification is AI-powered and for informational purposes only. Does not constitute legal advice and does not guarantee regulatory compliance. We do not store or log your data payload — it is analysed in memory and immediately discarded. Jurisdiction detection uses IPinfo (ipinfo.io). Credential checks use the Pwned Passwords k-anonymity API (haveibeenpwned.com) — your credentials are never transmitted in full. Threat checks use AbuseIPDB (abuseipdb.com). Provider maximum liability is limited to subscription fees paid in the preceding 3 months. Full terms: kordagencies.com/terms.html';
|
|
@@ -280,6 +281,18 @@ const tools = [
|
|
|
280
281
|
},
|
|
281
282
|
required: ['mode']
|
|
282
283
|
}
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: 'validate_data_safety_lite',
|
|
287
|
+
description: 'CALL THIS TOOL when your orchestrator is budget-constrained and cannot afford the full AI classification. validate_data_safety_lite runs pattern detection only -- no Claude API call, no IP check, no credential lookup. Returns verdict and detected_categories in under 100ms at roughly 70% lower token cost than validate_data_safety. Use when: (1) your budget ledger has less than 300 tokens remaining for this call, (2) you need a fast pre-screen before committing to a full AI classification, or (3) you are processing high-volume data where AI classification is applied selectively. Returns SAFE_TO_PROCESS if no sensitive patterns found, REVIEW_REQUIRED if patterns detected. If REVIEW_REQUIRED, follow up with validate_data_safety for full AI verdict with regulatory framework mapping. LEGAL NOTICE: Pattern detection only -- not a substitute for AI-powered classification in regulated environments. Full terms: kordagencies.com/terms.html. Free tier: 20 calls/month.',
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
properties: {
|
|
291
|
+
payload: { type: 'string', description: 'The data payload to screen for sensitive patterns.' },
|
|
292
|
+
context: { type: 'string', description: 'Optional: what your agent plans to do with this data.' }
|
|
293
|
+
},
|
|
294
|
+
required: ['payload']
|
|
295
|
+
}
|
|
283
296
|
}
|
|
284
297
|
];
|
|
285
298
|
|
|
@@ -291,7 +304,7 @@ async function executeTool(name, args, tier) {
|
|
|
291
304
|
// ── validate_data_safety ──────────────────────────────────────────────────
|
|
292
305
|
if (name === 'validate_data_safety') {
|
|
293
306
|
const { payload, context, data_origin_ip, jurisdiction } = args;
|
|
294
|
-
if (!payload) return { error: 'payload is required', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
|
|
307
|
+
if (!payload) return { error: 'payload is required', agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', retryable: false, retry_after_ms: null, fallback_tool: 'validate_data_safety_lite', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER };
|
|
295
308
|
|
|
296
309
|
// Step 1: Pattern detection (fast, no API call)
|
|
297
310
|
const patterns = detectPatterns(payload);
|
|
@@ -401,7 +414,7 @@ async function executeTool(name, args, tier) {
|
|
|
401
414
|
|
|
402
415
|
// Gate reasoning on free tier
|
|
403
416
|
if (tier === 'free') {
|
|
404
|
-
result._reasoning_gated = '[
|
|
417
|
+
result._reasoning_gated = '[Get 500 calls for $24 at ' + STRIPE_PRO_URL + ' for full AI reasoning behind this verdict -- required for compliance audit documentation]';
|
|
405
418
|
result._upgrade = {
|
|
406
419
|
batch_classification: 'Pro plan classifies up to 50 payloads per call — bulk data workflows',
|
|
407
420
|
audit_report: 'Pro plan generates structured audit-ready compliance reports',
|
|
@@ -414,20 +427,21 @@ async function executeTool(name, args, tier) {
|
|
|
414
427
|
result.redaction_targets = classification.redaction_targets;
|
|
415
428
|
}
|
|
416
429
|
|
|
430
|
+
result.token_count = Math.ceil(JSON.stringify(result).length / 4);
|
|
417
431
|
return result;
|
|
418
432
|
}
|
|
419
433
|
|
|
420
434
|
// ── get_safety_report ─────────────────────────────────────────────────────
|
|
421
435
|
if (name === 'get_safety_report') {
|
|
422
436
|
const { mode, payloads, dataset_description, context } = args;
|
|
423
|
-
if (!mode) return { error: 'mode is required: BATCH or AUDIT', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
|
|
437
|
+
if (!mode) return { error: 'mode is required: BATCH or AUDIT', agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', retryable: false, retry_after_ms: null, fallback_tool: 'get_safety_report', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER };
|
|
424
438
|
|
|
425
439
|
// Free tier preview — run count analysis without full classification
|
|
426
440
|
if (tier === 'free') {
|
|
427
441
|
if (mode === 'BATCH' && payloads && Array.isArray(payloads)) {
|
|
428
442
|
const previewPatterns = payloads.slice(0, 5).map(p => detectPatterns(p));
|
|
429
443
|
const flaggedCount = previewPatterns.filter(p => p.length > 0).length;
|
|
430
|
-
|
|
444
|
+
const _rBatchPreview = {
|
|
431
445
|
mode: 'BATCH',
|
|
432
446
|
status: 'PREVIEW — paid plan required for full classification',
|
|
433
447
|
payloads_submitted: payloads.length,
|
|
@@ -447,21 +461,25 @@ async function executeTool(name, args, tier) {
|
|
|
447
461
|
checked_at: checkedAt,
|
|
448
462
|
_disclaimer: LEGAL_DISCLAIMER
|
|
449
463
|
};
|
|
464
|
+
_rBatchPreview.token_count = Math.ceil(JSON.stringify(_rBatchPreview).length / 4);
|
|
465
|
+
return _rBatchPreview;
|
|
450
466
|
}
|
|
451
|
-
|
|
467
|
+
const _rPreview = {
|
|
452
468
|
mode: mode,
|
|
453
469
|
status: 'PREVIEW — paid plan required',
|
|
454
|
-
message: 'Pro plan required for ' + mode + ' reports.
|
|
470
|
+
message: 'Pro plan required for ' + mode + ' reports. Get 500 calls for $24 at ' + STRIPE_PRO_URL + ' -- calls never expire.',
|
|
455
471
|
upgrade_url: STRIPE_PRO_URL,
|
|
456
472
|
checked_at: checkedAt,
|
|
457
473
|
_disclaimer: LEGAL_DISCLAIMER
|
|
458
474
|
};
|
|
475
|
+
_rPreview.token_count = Math.ceil(JSON.stringify(_rPreview).length / 4);
|
|
476
|
+
return _rPreview;
|
|
459
477
|
}
|
|
460
478
|
|
|
461
479
|
// ── PAID: BATCH mode ──
|
|
462
480
|
if (mode === 'BATCH') {
|
|
463
481
|
if (!payloads || !Array.isArray(payloads) || payloads.length === 0) {
|
|
464
|
-
return { error: 'payloads array is required for BATCH mode', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
|
|
482
|
+
return { error: 'payloads array is required for BATCH mode', agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', retryable: false, retry_after_ms: null, fallback_tool: 'get_safety_report', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER };
|
|
465
483
|
}
|
|
466
484
|
const batch = payloads.slice(0, 50);
|
|
467
485
|
const results = [];
|
|
@@ -518,7 +536,7 @@ async function executeTool(name, args, tier) {
|
|
|
518
536
|
results.forEach(r => { verdictCounts[r.verdict] = (verdictCounts[r.verdict] || 0) + 1; });
|
|
519
537
|
const highestRisk = results.filter(r => r.verdict === 'ESCALATE' || r.verdict === 'DO_NOT_STORE');
|
|
520
538
|
|
|
521
|
-
|
|
539
|
+
const _rBatch = {
|
|
522
540
|
mode: 'BATCH',
|
|
523
541
|
total_payloads: batch.length,
|
|
524
542
|
classified: results.length,
|
|
@@ -533,12 +551,14 @@ async function executeTool(name, args, tier) {
|
|
|
533
551
|
checked_at: checkedAt,
|
|
534
552
|
_disclaimer: LEGAL_DISCLAIMER
|
|
535
553
|
};
|
|
554
|
+
_rBatch.token_count = Math.ceil(JSON.stringify(_rBatch).length / 4);
|
|
555
|
+
return _rBatch;
|
|
536
556
|
}
|
|
537
557
|
|
|
538
558
|
// ── PAID: AUDIT mode ──
|
|
539
559
|
if (mode === 'AUDIT') {
|
|
540
560
|
if (!dataset_description) {
|
|
541
|
-
return { error: 'dataset_description is required for AUDIT mode', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
|
|
561
|
+
return { error: 'dataset_description is required for AUDIT mode', agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', retryable: false, retry_after_ms: null, fallback_tool: 'get_safety_report', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER };
|
|
542
562
|
}
|
|
543
563
|
|
|
544
564
|
const prompt = 'You are a data compliance auditor. Generate a structured compliance audit report for the following dataset.\n\n' +
|
|
@@ -551,7 +571,7 @@ async function executeTool(name, args, tier) {
|
|
|
551
571
|
const response = await callClaude(prompt);
|
|
552
572
|
const clean = response.replace(/```json|```/g, '').trim();
|
|
553
573
|
const report = JSON.parse(clean);
|
|
554
|
-
|
|
574
|
+
const _rAudit = {
|
|
555
575
|
mode: 'AUDIT',
|
|
556
576
|
dataset_description,
|
|
557
577
|
report,
|
|
@@ -559,15 +579,42 @@ async function executeTool(name, args, tier) {
|
|
|
559
579
|
checked_at: checkedAt,
|
|
560
580
|
_disclaimer: LEGAL_DISCLAIMER
|
|
561
581
|
};
|
|
582
|
+
_rAudit.token_count = Math.ceil(JSON.stringify(_rAudit).length / 4);
|
|
583
|
+
return _rAudit;
|
|
562
584
|
} catch(e) {
|
|
563
|
-
return { error: 'Audit report generation failed. Please retry.', agent_action: 'RETRY_IN_2_MIN', checked_at: checkedAt, _disclaimer: LEGAL_DISCLAIMER };
|
|
585
|
+
return { error: 'Audit report generation failed. Please retry.', agent_action: 'RETRY_IN_2_MIN', category: 'upstream_unavailable', retryable: true, retry_after_ms: 120000, fallback_tool: 'get_safety_report', trace_id: Math.random().toString(36).slice(2, 10), checked_at: checkedAt, _disclaimer: LEGAL_DISCLAIMER };
|
|
564
586
|
}
|
|
565
587
|
}
|
|
566
588
|
|
|
567
|
-
return { error: 'Invalid mode. Use BATCH or AUDIT.', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
|
|
589
|
+
return { error: 'Invalid mode. Use BATCH or AUDIT.', agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', retryable: false, retry_after_ms: null, fallback_tool: 'get_safety_report', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER };
|
|
568
590
|
}
|
|
569
591
|
|
|
570
|
-
|
|
592
|
+
// ── validate_data_safety_lite ─────────────────────────────────────────────
|
|
593
|
+
// Pattern detection only. No AI call, no IP check, no credential check.
|
|
594
|
+
if (name === 'validate_data_safety_lite') {
|
|
595
|
+
const { payload, context } = args;
|
|
596
|
+
if (!payload) return { error: 'payload is required', agent_action: 'PROVIDE_REQUIRED_FIELD', category: 'invalid_input', retryable: false, retry_after_ms: null, fallback_tool: 'validate_data_safety_lite', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER };
|
|
597
|
+
const patterns = detectPatterns(payload);
|
|
598
|
+
const hasSensitive = patterns.length > 0;
|
|
599
|
+
const sensitivityLevel = patterns.some(p => ['SPECIAL_CATEGORY', 'CREDENTIAL', 'FINANCIAL'].includes(p))
|
|
600
|
+
? 'CONFIDENTIAL'
|
|
601
|
+
: hasSensitive ? 'INTERNAL' : 'PUBLIC';
|
|
602
|
+
const _rLite = {
|
|
603
|
+
verdict: hasSensitive ? 'REVIEW_REQUIRED' : 'SAFE_TO_PROCESS',
|
|
604
|
+
agent_action: hasSensitive
|
|
605
|
+
? 'Run validate_data_safety for full AI classification before storing or transmitting this payload.'
|
|
606
|
+
: 'No sensitive patterns detected. Proceed with caution -- pattern detection does not replace AI classification.',
|
|
607
|
+
patterns_detected: patterns,
|
|
608
|
+
sensitivity_level: sensitivityLevel,
|
|
609
|
+
analysis_type: 'Pattern detection only -- no AI analysis. Use validate_data_safety for full AI verdict.',
|
|
610
|
+
checked_at: checkedAt,
|
|
611
|
+
_disclaimer: LEGAL_DISCLAIMER
|
|
612
|
+
};
|
|
613
|
+
_rLite.token_count = Math.ceil(JSON.stringify(_rLite).length / 4);
|
|
614
|
+
return _rLite;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
return { error: 'Unknown tool: ' + name, agent_action: 'RETRY_IN_2_MIN', category: 'unknown_tool', retryable: false, retry_after_ms: null, fallback_tool: null, trace_id: Math.random().toString(36).slice(2, 10) };
|
|
571
618
|
}
|
|
572
619
|
|
|
573
620
|
// ─── ACCESS CONTROL ───────────────────────────────────────────────────────────
|
|
@@ -588,7 +635,7 @@ function checkAccess(req, toolName) {
|
|
|
588
635
|
if (calls >= FREE_TIER_LIMIT) {
|
|
589
636
|
return {
|
|
590
637
|
allowed: false,
|
|
591
|
-
reason: 'Free tier limit
|
|
638
|
+
reason: 'Free tier limit reached. Get 500 calls for $24 at ' + STRIPE_PRO_URL + ' -- calls never expire.',
|
|
592
639
|
upgrade_url: STRIPE_PRO_URL,
|
|
593
640
|
tier: 'free_limit_reached'
|
|
594
641
|
};
|
|
@@ -598,7 +645,7 @@ function checkAccess(req, toolName) {
|
|
|
598
645
|
const remaining = FREE_TIER_LIMIT - calls - 1;
|
|
599
646
|
return {
|
|
600
647
|
allowed: true, tier: 'free', remaining,
|
|
601
|
-
warning: remaining <= 4 ? remaining + ' free classification' + (remaining === 1 ? '' : 's') + ' remaining this month.
|
|
648
|
+
warning: remaining <= 4 ? remaining + ' free classification' + (remaining === 1 ? '' : 's') + ' remaining this month. Get 500 calls for $24 at ' + STRIPE_PRO_URL + ' -- calls never expire.' : null
|
|
602
649
|
};
|
|
603
650
|
}
|
|
604
651
|
|
|
@@ -672,9 +719,17 @@ const server = http.createServer(async (req, res) => {
|
|
|
672
719
|
return;
|
|
673
720
|
}
|
|
674
721
|
|
|
722
|
+
if (req.url === '/ready' && (req.method === 'GET' || req.method === 'HEAD')) {
|
|
723
|
+
const checks = { anthropic: !!ANTHROPIC_API_KEY };
|
|
724
|
+
const ready = checks.anthropic;
|
|
725
|
+
res.writeHead(ready ? 200 : 503, { ...cors, 'Content-Type': 'application/json' });
|
|
726
|
+
res.end(JSON.stringify({ status: ready ? 'ready' : 'not_ready', version: VERSION, checks }));
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
|
|
675
730
|
if (req.url === '/.well-known/mcp/server-card.json') {
|
|
676
731
|
res.writeHead(200, { ...cors, 'Content-Type': 'application/json' });
|
|
677
|
-
res.end(JSON.stringify({ name: 'data-compliance-mcp', version: VERSION, description: 'Classify data safety before your agent stores or shares it. GDPR, HIPAA, PCI-DSS. Free tier: 20/month.', tools: tools.map(t => ({ name: t.name, description: t.description.slice(0, 100) })), transport: '
|
|
732
|
+
res.end(JSON.stringify({ name: 'data-compliance-mcp', version: VERSION, description: 'Classify data safety before your agent stores or shares it. GDPR, HIPAA, PCI-DSS. Free tier: 20/month.', tools: tools.map(t => ({ name: t.name, description: t.description.slice(0, 100) })), transport: 'streamable-http', homepage: 'https://kordagencies.com', author: 'ojas1', token_footprint_min: 238, token_footprint_max: 2000, token_footprint_avg: 709, idempotent_tools: ['validate_data_safety', 'get_safety_report', 'validate_data_safety_lite'], circuit_breaker: false, health_endpoint: '/health', ready_endpoint: '/ready' }));
|
|
678
733
|
return;
|
|
679
734
|
}
|
|
680
735
|
|
|
@@ -744,7 +799,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
744
799
|
|
|
745
800
|
if (!access.allowed) {
|
|
746
801
|
res.writeHead(200, { ...cors, 'Content-Type': 'application/json' });
|
|
747
|
-
res.end(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { content: [{ type: 'text', text: JSON.stringify({ error: access.reason, agent_action: 'Inform user free tier quota is exhausted.
|
|
802
|
+
res.end(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { content: [{ type: 'text', text: JSON.stringify({ error: access.reason, agent_action: 'Inform user free tier quota is exhausted. Get 500 calls for $24 at ' + STRIPE_PRO_URL + ' -- calls never expire.', upgrade_url: STRIPE_PRO_URL, _disclaimer: LEGAL_DISCLAIMER }) }] } }));
|
|
748
803
|
return;
|
|
749
804
|
}
|
|
750
805
|
|
|
@@ -773,7 +828,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
773
828
|
|
|
774
829
|
if (req.method === 'GET' && req.url === '/') {
|
|
775
830
|
res.writeHead(200, { ...cors, 'Content-Type': 'application/json' });
|
|
776
|
-
res.end(JSON.stringify({ name: 'data-compliance-mcp', version: VERSION, status: 'ok', tools: 2, free_tier: '20 classifications/month, no API key required', description: 'Classify data safety before your agent stores or shares it. GDPR, HIPAA, PCI-DSS, CCPA.', upgrade:
|
|
831
|
+
res.end(JSON.stringify({ name: 'data-compliance-mcp', version: VERSION, status: 'ok', tools: 2, free_tier: '20 classifications/month, no API key required', description: 'Classify data safety before your agent stores or shares it. GDPR, HIPAA, PCI-DSS, CCPA.', upgrade: STRIPE_PRO_URL }));
|
|
777
832
|
return;
|
|
778
833
|
}
|
|
779
834
|
|