data-compliance-mcp 1.0.24 → 1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.25] - 2026-06-25
4
+ - feat: calls_remaining field added to every successful tool response -- "unlimited" for paid keys, numeric free-tier headroom otherwise
5
+ - feat: verdict_ttl field added to validate_data_safety, validate_data_safety_lite, get_safety_report responses (86400s/24h each)
6
+ - feat: data_source_status field added (full/degraded/partial) -- get_safety_report BATCH mode reports "degraded" when AI classification fails for any individual payload in the batch (AI is the critical source for this server); validate_data_safety_lite is always "full" (pattern-only, no AI dependency)
7
+
3
8
  ## [1.0.24] - 2026-06-24
4
9
  - feat: unauthenticated /public-stats endpoint -- first_deployed, lifetime tool calls, uptime %, version, for agent orchestrators evaluating server trustworthiness
5
10
  - feat: /process-trial-followups endpoint + 24h follow-up record on trial-extension grant
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.24",
4
+ "version": "1.0.25",
5
5
  "description": "Data safety classifier for AI agents. GDPR, HIPAA, PCI-DSS compliance before your agent stores or shares any payload. SAFE/ESCALATE verdict in one call.",
6
6
  "main": "src/server.js",
7
7
  "scripts": {
package/server.json CHANGED
@@ -1,42 +1,42 @@
1
- {
2
- "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
- "name": "io.github.OjasKord/data-compliance-mcp",
4
- "title": "Data Compliance Classifier MCP",
5
- "description": "Classify data safety before storing or sharing. GDPR, HIPAA, PCI-DSS, CCPA. AI-powered.",
6
- "version": "1.0.19",
7
- "websiteUrl": "https://kordagencies.com",
8
- "repository": {
9
- "url": "https://github.com/OjasKord/data-compliance-mcp",
10
- "source": "github"
11
- },
12
- "packages": [
13
- {
14
- "registryType": "npm",
15
- "identifier": "data-compliance-mcp",
16
- "version": "1.0.19",
17
- "transport": {
18
- "type": "stdio"
19
- },
20
- "environmentVariables": [
21
- {
22
- "name": "ANTHROPIC_API_KEY",
23
- "description": "Anthropic API key for AI classification",
24
- "isRequired": true,
25
- "isSecret": true
26
- },
27
- {
28
- "name": "ABUSEIPDB_API_KEY",
29
- "description": "AbuseIPDB API key for threat intelligence (optional)",
30
- "isRequired": false,
31
- "isSecret": true
32
- }
33
- ]
34
- }
35
- ],
36
- "remotes": [
37
- {
38
- "type": "streamable-http",
39
- "url": "https://data-compliance-mcp-production.up.railway.app"
40
- }
41
- ]
42
- }
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.OjasKord/data-compliance-mcp",
4
+ "title": "Data Compliance Classifier MCP",
5
+ "description": "Classify data safety before storing or sharing. GDPR, HIPAA, PCI-DSS, CCPA. AI-powered.",
6
+ "version": "1.0.25",
7
+ "websiteUrl": "https://kordagencies.com",
8
+ "repository": {
9
+ "url": "https://github.com/OjasKord/data-compliance-mcp",
10
+ "source": "github"
11
+ },
12
+ "packages": [
13
+ {
14
+ "registryType": "npm",
15
+ "identifier": "data-compliance-mcp",
16
+ "version": "1.0.25",
17
+ "transport": {
18
+ "type": "stdio"
19
+ },
20
+ "environmentVariables": [
21
+ {
22
+ "name": "ANTHROPIC_API_KEY",
23
+ "description": "Anthropic API key for AI classification",
24
+ "isRequired": true,
25
+ "isSecret": true
26
+ },
27
+ {
28
+ "name": "ABUSEIPDB_API_KEY",
29
+ "description": "AbuseIPDB API key for threat intelligence (optional)",
30
+ "isRequired": false,
31
+ "isSecret": true
32
+ }
33
+ ]
34
+ }
35
+ ],
36
+ "remotes": [
37
+ {
38
+ "type": "streamable-http",
39
+ "url": "https://data-compliance-mcp-production.up.railway.app"
40
+ }
41
+ ]
42
+ }
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.24';
6
+ const VERSION = '1.0.25';
7
7
  const FIRST_DEPLOYED = '2026-04-21T09:53:12Z';
8
8
  const LIFETIME_CALLS_REDIS_KEY = 'dcc:lifetime_calls';
9
9
  const UPTIME_HEARTBEAT_KEY = 'dcc:uptime:heartbeat_count';
@@ -23,6 +23,8 @@ const freeTierUsage = new Map();
23
23
  const usageLog = [];
24
24
  const FREE_TIER_LIMIT = 20;
25
25
  const FREE_TIER_WARNING = 16;
26
+ // Caching/staleness policy per tool, in seconds.
27
+ const VERDICT_TTL = { validate_data_safety: 86400, validate_data_safety_lite: 86400, get_safety_report: 86400 };
26
28
  const apiKeys = new Map();
27
29
  const PLAN_LIMITS = { pro: 5000, enterprise: Infinity };
28
30
  const toolUsageCounts = {};
@@ -698,6 +700,8 @@ async function executeTool(name, args, tier) {
698
700
  patterns_detected: patterns,
699
701
  credential_check: credentialCheck,
700
702
  analysis_type: 'AI-powered classification -- NOT a simple pattern match',
703
+ verdict_ttl: VERDICT_TTL.validate_data_safety,
704
+ data_source_status: 'full',
701
705
  source_url: 'api.anthropic.com + ipinfo.io + api.pwnedpasswords.com',
702
706
  checked_at: checkedAt,
703
707
  _disclaimer: LEGAL_DISCLAIMER
@@ -781,6 +785,8 @@ async function executeTool(name, args, tier) {
781
785
  confidence: report.confidence,
782
786
  patterns_detected: patterns,
783
787
  analysis_type: 'AI-powered compliance remediation -- NOT a simple pattern match',
788
+ verdict_ttl: VERDICT_TTL.get_safety_report,
789
+ data_source_status: 'full',
784
790
  checked_at: checkedAt,
785
791
  _disclaimer: LEGAL_DISCLAIMER
786
792
  };
@@ -903,6 +909,8 @@ async function executeTool(name, args, tier) {
903
909
  },
904
910
  results,
905
911
  analysis_type: 'AI-powered batch classification with threat intelligence',
912
+ verdict_ttl: VERDICT_TTL.get_safety_report,
913
+ data_source_status: errors.length > 0 ? 'degraded' : 'full',
906
914
  checked_at: checkedAt,
907
915
  _disclaimer: LEGAL_DISCLAIMER
908
916
  };
@@ -931,6 +939,8 @@ async function executeTool(name, args, tier) {
931
939
  dataset_description,
932
940
  report,
933
941
  analysis_type: 'AI-powered compliance audit — NOT legal advice',
942
+ verdict_ttl: VERDICT_TTL.get_safety_report,
943
+ data_source_status: 'full',
934
944
  checked_at: checkedAt,
935
945
  _disclaimer: LEGAL_DISCLAIMER
936
946
  };
@@ -962,6 +972,8 @@ async function executeTool(name, args, tier) {
962
972
  patterns_detected: patterns,
963
973
  sensitivity_level: sensitivityLevel,
964
974
  analysis_type: 'Pattern detection only -- no AI analysis. Use validate_data_safety for full AI verdict.',
975
+ verdict_ttl: VERDICT_TTL.validate_data_safety_lite,
976
+ data_source_status: 'full',
965
977
  checked_at: checkedAt,
966
978
  _disclaimer: LEGAL_DISCLAIMER
967
979
  };
@@ -1417,6 +1429,7 @@ const server = http.createServer(async (req, res) => {
1417
1429
 
1418
1430
  const result = await executeTool(name, toolArgs || {}, access.tier);
1419
1431
  if (access.warning) result._notice = access.warning;
1432
+ result.calls_remaining = access.tier === 'free' ? Math.max(0, access.remaining || 0) : 'unlimited';
1420
1433
 
1421
1434
  response = { jsonrpc: '2.0', id: request.id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] } };
1422
1435
  } else {
@@ -1473,6 +1486,7 @@ function setupStdio() {
1473
1486
  response = { jsonrpc: '2.0', id: req.id, result: { content: [{ type: 'text', text: JSON.stringify({ error: 'This tool is temporarily unavailable for maintenance.', agent_action: 'RETRY_IN_30_MIN', retryable: true, retry_after_ms: 1800000 }) }] } };
1474
1487
  } else {
1475
1488
  const result = await executeTool(_name, req.params.arguments || {}, 'paid');
1489
+ result.calls_remaining = 'unlimited';
1476
1490
  response = { jsonrpc: '2.0', id: req.id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] } };
1477
1491
  }
1478
1492
  } catch(e) {