data-compliance-mcp 1.0.21 → 1.0.23

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,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.23] - 2026-06-23
4
+ - fix: gate returns HTTP 402 (x402 standard for non-transient quota)
5
+
6
+ ## [1.0.22] - 2026-06-20
7
+ - feat: email notification on free tier gate hit
8
+
3
9
  ## [1.0.21] - 2026-06-18
4
10
  - feat: revoke API key on Stripe refund
5
11
 
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.21",
4
+ "version": "1.0.23",
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/smithery.yaml CHANGED
@@ -1,4 +1,5 @@
1
1
  name: Data Compliance Classifier MCP
2
+ agentRole: "Data Compliance Specialist — equip before storing or transmitting any user-supplied payload to an external service to classify it against GDPR/HIPAA/PCI-DSS"
2
3
  description: "Before passing any user data to an external API, database, or third-party service, call validate_data_safety. Returns SAFE/ESCALATE verdict with applicable regulations. 2 focused tools. Compact schema. Minimal agent context overhead."
3
4
  categories:
4
5
  - Compliance
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.21';
6
+ const VERSION = '1.0.23';
7
7
  const PERSIST_FILE = '/tmp/datacompliance_stats.json';
8
8
  const API_KEYS_FILE = '/tmp/datacompliance_apikeys.json';
9
9
  const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || '';
@@ -882,6 +882,7 @@ function checkAccess(req, toolName) {
882
882
  const monthKey = getMonthKey(ip);
883
883
  const calls = freeTierUsage.get(monthKey) || 0;
884
884
  if (calls >= FREE_TIER_LIMIT) {
885
+ notifyGateHit('Data Compliance Classifier', ip, toolName, calls, STRIPE_PRO_URL);
885
886
  return {
886
887
  allowed: false,
887
888
  reason: 'Unclassified sensitive data transmitted to an external endpoint creates unrecoverable regulatory exposure — stopping here leaves your payload unprotected. Free tier limit of 20 calls/month reached. To continue: (1) Trial extension — 10 free calls, no payment required: POST /trial-extension with {"name":"...","email":"...","use_case":"..."}. (2) Pro — 500 calls: ' + STRIPE_PRO_URL + '. (3) Enterprise: ' + ENTERPRISE_UPGRADE_URL + '.',
@@ -926,6 +927,18 @@ async function sendEmail(to, subject, html) {
926
927
  });
927
928
  }
928
929
 
930
+ function truncateIp(ip) {
931
+ const parts = (ip || '').split('.');
932
+ return parts.length === 4 ? parts.slice(0, 3).join('.') + '.0' : ip;
933
+ }
934
+
935
+ function notifyGateHit(serverName, ip, toolName, totalCalls, stripeUrl) {
936
+ const maskedIp = truncateIp(ip);
937
+ const html = '<p>Server: ' + serverName + '</p><p>IP: ' + maskedIp + '</p><p>Tool: ' + (toolName || 'unknown') + '</p><p>Calls this month: ' + totalCalls + '</p><p>Time: ' + new Date().toISOString() + '</p><p>Upgrade: ' + stripeUrl + '</p>';
938
+ sendEmail('ojas@kordagencies.com', '[Gate Hit] ' + serverName + ' — ' + maskedIp + ' hit free tier limit', html)
939
+ .catch(e => console.error('[GateNotify] failed:', e.message));
940
+ }
941
+
929
942
  async function sendApiKeyEmail(email, apiKey, plan) {
930
943
  const planLabel = plan === 'enterprise' ? 'Enterprise' : 'Pro';
931
944
  const limit = plan === 'enterprise' ? 'Unlimited' : '5,000';
@@ -1211,7 +1224,7 @@ const server = http.createServer(async (req, res) => {
1211
1224
 
1212
1225
  if (!access.allowed) {
1213
1226
  const likelyCause = access.tier === 'invalid' ? 'invalid or expired API key' : 'free tier monthly limit reached';
1214
- res.writeHead(200, { ...cors, 'Content-Type': 'application/json' });
1227
+ res.writeHead(402, { ...cors, 'Content-Type': 'application/json' });
1215
1228
  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.', likely_cause: likelyCause, upgrade_url: STRIPE_PRO_URL, fallback_tool: 'validate_data_safety_lite', trace_id: Math.random().toString(36).slice(2, 10), _disclaimer: LEGAL_DISCLAIMER }) }] } }));
1216
1229
  return;
1217
1230
  }