data-compliance-mcp 1.0.1 → 1.0.2

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.2] - 2026-04-26
4
+ ### Changed
5
+ - Added `agent_action` field to all error responses (PROVIDE_REQUIRED_FIELD, DO_NOT_PROCESS_UNTIL_CLASSIFIED, RETRY_IN_2_MIN)
6
+ - Added `source_url` to validate_data_safety results
7
+ - Added stdio transport for Claude Desktop / npm usage
8
+ - Fixed em-dash in analysis_type string (ASCII --)
9
+ - VERSION constant introduced as single source of truth
10
+
3
11
  ## [1.0.0] - 2026-04-21
4
12
  ### Added
5
13
  - Initial release
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.1",
4
+ "version": "1.0.2",
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": {
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.1",
6
+ "version": "1.0.2",
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.1",
16
+ "version": "1.0.2",
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.0';
6
+ const VERSION = '1.0.2';
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 || '';
@@ -255,7 +255,7 @@ function extractCredentials(payload) {
255
255
  const tools = [
256
256
  {
257
257
  name: 'validate_data_safety',
258
- description: 'Call this tool BEFORE your agent stores, transmits, logs, or passes any data payload to another system. Use when your agent has just received data from a user, form, API, webhook, or external source and needs to know whether it is safe to process. Prevents GDPR, HIPAA, and PCI-DSS violations before they happen not after. Returns a clear verdict: SAFE_TO_PROCESS, REDACT_BEFORE_PASSING, DO_NOT_STORE, or ESCALATE. Each verdict tells the agent exactly what to do next — no human interpretation needed. Also use for: classifying customer records before database writes, screening scraped content before storage, checking API responses before caching, validating form submissions before processing. AI-powered analysis NOT a simple pattern match. Combines Claude reasoning with live jurisdiction detection (IPinfo), credential breach checking (HaveIBeenPwned k-anonymity API), and PII pattern detection. LEGAL NOTICE: Classification is informational only and does not constitute legal advice. We do not store your data payload. Full terms: kordagencies.com/terms.html. Free tier: first 20 classifications/month, no API key needed.',
258
+ description: 'Call this tool BEFORE your agent stores, transmits, logs, or passes any data payload to another system. Returns one of four machine-readable verdicts your agent can act on immediately: SAFE_TO_PROCESS, REDACT_BEFORE_PASSING, DO_NOT_STORE, or ESCALATE -- no human interpretation needed. Prevents GDPR, HIPAA, and PCI-DSS violations before they happen, not after. Use when your agent has just received data from a user, form, API, webhook, or external source. Also use for: classifying customer records before database writes, screening scraped content before storage, checking API responses before caching. AI-powered -- NOT a simple pattern match. Combines Claude reasoning with live jurisdiction detection (IPinfo) and credential breach checking (HaveIBeenPwned k-anonymity). LEGAL NOTICE: Classification is informational only, not legal advice. We do not store your data payload. Full terms: kordagencies.com/terms.html. Free tier: first 20 classifications/month, no API key needed.',
259
259
  inputSchema: {
260
260
  type: 'object',
261
261
  properties: {
@@ -269,7 +269,7 @@ const tools = [
269
269
  },
270
270
  {
271
271
  name: 'get_safety_report',
272
- description: 'Call this tool when your agent needs to classify a batch of data payloads and generate an audit-ready compliance report. Use for bulk data processing workflows, pre-migration data audits, compliance documentation, or when your agent processes multiple records and needs a structured summary for human review. Returns full AI reasoning per payload, threat actor detection via AbuseIPDB for any IP addresses found, and a structured report suitable for compliance audit documentation. Two modes: BATCH (classify up to 50 payloads) and AUDIT (generate a compliance summary report for a dataset description). AI-powered analysis NOT a simple database lookup. LEGAL NOTICE: Classification is informational only. We do not store your data payloads. Full terms: kordagencies.com/terms.html. Paid API key required upgrade at kordagencies.com.',
272
+ description: 'Call this tool when your agent needs to classify multiple data payloads at once or generate audit documentation for a dataset. BATCH mode: classify up to 50 payloads with full AI reasoning per payload -- use for bulk onboarding flows, pre-migration audits, or any workflow processing multiple records. AUDIT mode: generate a structured compliance report for a dataset description -- use when your agent needs documentation a human compliance officer can review and sign off. Returns threat actor detection via AbuseIPDB for any IP addresses found. A company that processes data at scale without batch classification is one breach away from a regulator fine. AI-powered -- NOT a simple database lookup. LEGAL NOTICE: Classification is informational only. We do not store your data payloads. Full terms: kordagencies.com/terms.html. Paid API key required -- upgrade at kordagencies.com.',
273
273
  inputSchema: {
274
274
  type: 'object',
275
275
  properties: {
@@ -291,7 +291,7 @@ async function executeTool(name, args, tier) {
291
291
  // ── validate_data_safety ──────────────────────────────────────────────────
292
292
  if (name === 'validate_data_safety') {
293
293
  const { payload, context, data_origin_ip, jurisdiction } = args;
294
- if (!payload) return { error: 'payload is required', _disclaimer: LEGAL_DISCLAIMER };
294
+ if (!payload) return { error: 'payload is required', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
295
295
 
296
296
  // Step 1: Pattern detection (fast, no API call)
297
297
  const patterns = detectPatterns(payload);
@@ -375,7 +375,8 @@ async function executeTool(name, args, tier) {
375
375
  classification = JSON.parse(clean);
376
376
  } catch(e) {
377
377
  return {
378
- error: 'AI classification temporarily unavailable manual review recommended before processing this data.',
378
+ error: 'AI classification temporarily unavailable -- manual review recommended before processing this data.',
379
+ agent_action: 'DO_NOT_PROCESS_UNTIL_CLASSIFIED',
379
380
  patterns_detected: patterns,
380
381
  checked_at: checkedAt,
381
382
  _disclaimer: LEGAL_DISCLAIMER
@@ -392,7 +393,8 @@ async function executeTool(name, args, tier) {
392
393
  jurisdiction_detected: detectedCountry || jurisdiction || null,
393
394
  patterns_detected: patterns,
394
395
  credential_check: credentialCheck,
395
- analysis_type: 'AI-powered classification NOT a simple pattern match',
396
+ analysis_type: 'AI-powered classification -- NOT a simple pattern match',
397
+ source_url: 'api.anthropic.com + ipinfo.io + api.pwnedpasswords.com',
396
398
  checked_at: checkedAt,
397
399
  _disclaimer: LEGAL_DISCLAIMER
398
400
  };
@@ -418,7 +420,7 @@ async function executeTool(name, args, tier) {
418
420
  // ── get_safety_report ─────────────────────────────────────────────────────
419
421
  if (name === 'get_safety_report') {
420
422
  const { mode, payloads, dataset_description, context } = args;
421
- if (!mode) return { error: 'mode is required: BATCH or AUDIT', _disclaimer: LEGAL_DISCLAIMER };
423
+ if (!mode) return { error: 'mode is required: BATCH or AUDIT', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
422
424
 
423
425
  // Free tier preview — run count analysis without full classification
424
426
  if (tier === 'free') {
@@ -459,7 +461,7 @@ async function executeTool(name, args, tier) {
459
461
  // ── PAID: BATCH mode ──
460
462
  if (mode === 'BATCH') {
461
463
  if (!payloads || !Array.isArray(payloads) || payloads.length === 0) {
462
- return { error: 'payloads array is required for BATCH mode', _disclaimer: LEGAL_DISCLAIMER };
464
+ return { error: 'payloads array is required for BATCH mode', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
463
465
  }
464
466
  const batch = payloads.slice(0, 50);
465
467
  const results = [];
@@ -536,7 +538,7 @@ async function executeTool(name, args, tier) {
536
538
  // ── PAID: AUDIT mode ──
537
539
  if (mode === 'AUDIT') {
538
540
  if (!dataset_description) {
539
- return { error: 'dataset_description is required for AUDIT mode', _disclaimer: LEGAL_DISCLAIMER };
541
+ return { error: 'dataset_description is required for AUDIT mode', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
540
542
  }
541
543
 
542
544
  const prompt = 'You are a data compliance auditor. Generate a structured compliance audit report for the following dataset.\n\n' +
@@ -558,14 +560,14 @@ async function executeTool(name, args, tier) {
558
560
  _disclaimer: LEGAL_DISCLAIMER
559
561
  };
560
562
  } catch(e) {
561
- return { error: 'Audit report generation failed. Please retry.', checked_at: checkedAt, _disclaimer: LEGAL_DISCLAIMER };
563
+ return { error: 'Audit report generation failed. Please retry.', agent_action: 'RETRY_IN_2_MIN', checked_at: checkedAt, _disclaimer: LEGAL_DISCLAIMER };
562
564
  }
563
565
  }
564
566
 
565
- return { error: 'Invalid mode. Use BATCH or AUDIT.', _disclaimer: LEGAL_DISCLAIMER };
567
+ return { error: 'Invalid mode. Use BATCH or AUDIT.', agent_action: 'PROVIDE_REQUIRED_FIELD', _disclaimer: LEGAL_DISCLAIMER };
566
568
  }
567
569
 
568
- return { error: 'Unknown tool: ' + name };
570
+ return { error: 'Unknown tool: ' + name, agent_action: 'RETRY_IN_2_MIN' };
569
571
  }
570
572
 
571
573
  // ─── ACCESS CONTROL ───────────────────────────────────────────────────────────
@@ -742,7 +744,7 @@ const server = http.createServer(async (req, res) => {
742
744
 
743
745
  if (!access.allowed) {
744
746
  res.writeHead(200, { ...cors, 'Content-Type': 'application/json' });
745
- res.end(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { content: [{ type: 'text', text: JSON.stringify({ error: access.reason, upgrade_url: STRIPE_PRO_URL, _disclaimer: LEGAL_DISCLAIMER }) }] } }));
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. Upgrade required at kordagencies.com', upgrade_url: STRIPE_PRO_URL, _disclaimer: LEGAL_DISCLAIMER }) }] } }));
746
748
  return;
747
749
  }
748
750
 
@@ -778,6 +780,47 @@ const server = http.createServer(async (req, res) => {
778
780
  res.writeHead(404, cors); res.end(JSON.stringify({ error: 'Not found' }));
779
781
  });
780
782
 
783
+ function setupStdio() {
784
+ if (process.stdin.isTTY) return;
785
+ let buf = '';
786
+ process.stdin.setEncoding('utf8');
787
+ process.stdin.on('data', chunk => {
788
+ buf += chunk;
789
+ const lines = buf.split('\n');
790
+ buf = lines.pop();
791
+ lines.forEach(async line => {
792
+ if (!line.trim()) return;
793
+ let req;
794
+ try { req = JSON.parse(line); } catch(e) { return; }
795
+ let response;
796
+ if (req.method === 'initialize') {
797
+ response = { jsonrpc: '2.0', id: req.id, result: { protocolVersion: '2024-11-05', capabilities: { tools: {}, resources: {}, prompts: {} }, serverInfo: { name: 'data-compliance-mcp', version: VERSION, description: 'Classify data safety before your agent stores or shares it. GDPR, HIPAA, PCI-DSS, CCPA. Free tier: 20/month, no API key needed.' } } };
798
+ } else if (req.method === 'notifications/initialized') {
799
+ return;
800
+ } else if (req.method === 'tools/list') {
801
+ response = { jsonrpc: '2.0', id: req.id, result: { tools } };
802
+ } else if (req.method === 'resources/list') {
803
+ response = { jsonrpc: '2.0', id: req.id, result: { resources: [] } };
804
+ } else if (req.method === 'prompts/list') {
805
+ response = { jsonrpc: '2.0', id: req.id, result: { prompts: [] } };
806
+ } else if (req.method === 'tools/call') {
807
+ try {
808
+ const result = await executeTool(req.params.name, req.params.arguments || {}, 'paid');
809
+ response = { jsonrpc: '2.0', id: req.id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] } };
810
+ } catch(e) {
811
+ response = { jsonrpc: '2.0', id: req.id, error: { code: -32603, message: e.message, agent_action: 'RETRY_IN_2_MIN' } };
812
+ }
813
+ } else {
814
+ response = { jsonrpc: '2.0', id: req.id, error: { code: -32601, message: 'Method not found: ' + req.method } };
815
+ }
816
+ process.stdout.write(JSON.stringify(response) + '\n');
817
+ });
818
+ });
819
+ process.stdin.resume();
820
+ }
821
+
822
+ setupStdio();
823
+
781
824
  server.listen(PORT, () => {
782
825
  loadStats();
783
826
  console.log('Data Compliance Classifier MCP v' + VERSION + ' running on port ' + PORT);