@mcp-guardian/server 0.4.0 → 0.7.0

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.
Files changed (58) hide show
  1. package/README.md +119 -8
  2. package/dist/auth/auth-types.d.ts +40 -0
  3. package/dist/auth/auth-types.d.ts.map +1 -0
  4. package/dist/auth/auth-types.js +5 -0
  5. package/dist/auth/auth-types.js.map +1 -0
  6. package/dist/auth/oauth.d.ts +25 -0
  7. package/dist/auth/oauth.d.ts.map +1 -0
  8. package/dist/auth/oauth.js +96 -0
  9. package/dist/auth/oauth.js.map +1 -0
  10. package/dist/auth/redis-session-cache.d.ts +21 -0
  11. package/dist/auth/redis-session-cache.d.ts.map +1 -0
  12. package/dist/auth/redis-session-cache.js +74 -0
  13. package/dist/auth/redis-session-cache.js.map +1 -0
  14. package/dist/auth/session-cache.d.ts +47 -0
  15. package/dist/auth/session-cache.d.ts.map +1 -0
  16. package/dist/auth/session-cache.js +91 -0
  17. package/dist/auth/session-cache.js.map +1 -0
  18. package/dist/cli.js +27 -5
  19. package/dist/cli.js.map +1 -1
  20. package/dist/database/database-interface.d.ts +17 -0
  21. package/dist/database/database-interface.d.ts.map +1 -0
  22. package/dist/database/database-interface.js +2 -0
  23. package/dist/database/database-interface.js.map +1 -0
  24. package/dist/database/history-db.d.ts.map +1 -1
  25. package/dist/database/history-db.js.map +1 -1
  26. package/dist/database/postgres-db.d.ts +18 -0
  27. package/dist/database/postgres-db.d.ts.map +1 -0
  28. package/dist/database/postgres-db.js +118 -0
  29. package/dist/database/postgres-db.js.map +1 -0
  30. package/dist/index.js +1 -1
  31. package/dist/policy/policy-engine.d.ts.map +1 -1
  32. package/dist/policy/policy-engine.js +21 -0
  33. package/dist/policy/policy-engine.js.map +1 -1
  34. package/dist/policy/policy-types.d.ts +9 -0
  35. package/dist/policy/policy-types.d.ts.map +1 -1
  36. package/dist/policy/policy-watcher.d.ts +24 -0
  37. package/dist/policy/policy-watcher.d.ts.map +1 -0
  38. package/dist/policy/policy-watcher.js +68 -0
  39. package/dist/policy/policy-watcher.js.map +1 -0
  40. package/dist/proxy/proxy-manager.d.ts +3 -1
  41. package/dist/proxy/proxy-manager.d.ts.map +1 -1
  42. package/dist/proxy/proxy-manager.js +10 -3
  43. package/dist/proxy/proxy-manager.js.map +1 -1
  44. package/dist/proxy/proxy-server.d.ts +20 -8
  45. package/dist/proxy/proxy-server.d.ts.map +1 -1
  46. package/dist/proxy/proxy-server.js +209 -37
  47. package/dist/proxy/proxy-server.js.map +1 -1
  48. package/dist/utils/circuit-breaker.d.ts +29 -0
  49. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  50. package/dist/utils/circuit-breaker.js +81 -0
  51. package/dist/utils/circuit-breaker.js.map +1 -0
  52. package/dist/utils/metrics.d.ts +10 -0
  53. package/dist/utils/metrics.d.ts.map +1 -0
  54. package/dist/utils/metrics.js +77 -0
  55. package/dist/utils/metrics.js.map +1 -0
  56. package/dist/utils/structured-logger.d.ts +1 -1
  57. package/dist/utils/structured-logger.d.ts.map +1 -1
  58. package/package.json +9 -1
@@ -0,0 +1,77 @@
1
+ import { Registry, Counter, Gauge, Histogram, collectDefaultMetrics } from 'prom-client';
2
+ import { Logger } from './logger.js';
3
+ /**
4
+ * Prometheus metrics for MCP Guardian.
5
+ * Exposed at /metrics for scraping by Prometheus/Grafana.
6
+ *
7
+ * Enable with: METRICS_ENABLED=true METRICS_PORT=9090
8
+ */
9
+ const registry = new Registry();
10
+ collectDefaultMetrics({ register: registry, prefix: 'mcp_guardian_' });
11
+ // ── Counters ─────────────────────────────────────────────────────
12
+ export const requestsTotal = new Counter({
13
+ name: 'mcp_guardian_requests_total',
14
+ help: 'Total number of tools/call requests processed',
15
+ labelNames: ['server_name', 'decision', 'authn_success'],
16
+ registers: [registry],
17
+ });
18
+ export const blockedRequestsTotal = new Counter({
19
+ name: 'mcp_guardian_blocked_requests_total',
20
+ help: 'Total number of blocked tools/call requests',
21
+ labelNames: ['server_name', 'block_reason', 'rule'],
22
+ registers: [registry],
23
+ });
24
+ export const authFailuresTotal = new Counter({
25
+ name: 'mcp_guardian_auth_failures_total',
26
+ help: 'Total number of authentication failures',
27
+ labelNames: ['server_name', 'reason'],
28
+ registers: [registry],
29
+ });
30
+ // ── Gauges ────────────────────────────────────────────────────────
31
+ export const circuitBreakerState = new Gauge({
32
+ name: 'mcp_guardian_circuit_breaker_state',
33
+ help: 'Circuit breaker state: 0=CLOSED, 1=OPEN, 2=HALF_OPEN',
34
+ labelNames: ['server_name'],
35
+ registers: [registry],
36
+ });
37
+ export const activeSessions = new Gauge({
38
+ name: 'mcp_guardian_active_sessions',
39
+ help: 'Number of active session tokens',
40
+ registers: [registry],
41
+ });
42
+ // ── Histograms ────────────────────────────────────────────────────
43
+ export const proxyLatencyMs = new Histogram({
44
+ name: 'mcp_guardian_proxy_latency_ms',
45
+ help: 'Proxy processing latency in milliseconds',
46
+ labelNames: ['server_name'],
47
+ buckets: [1, 5, 10, 25, 50, 100, 250, 500, 1000],
48
+ registers: [registry],
49
+ });
50
+ export const authLatencyMs = new Histogram({
51
+ name: 'mcp_guardian_auth_latency_ms',
52
+ help: 'Authentication/JWT validation latency in milliseconds',
53
+ labelNames: ['server_name'],
54
+ buckets: [1, 5, 10, 25, 50, 100, 250, 500],
55
+ registers: [registry],
56
+ });
57
+ // ── Metrics server ────────────────────────────────────────────────
58
+ export async function startMetricsServer(port = 9090) {
59
+ if (process.env['METRICS_ENABLED'] !== 'true') {
60
+ Logger.debug('[metrics] Metrics server not enabled (set METRICS_ENABLED=true)');
61
+ return;
62
+ }
63
+ try {
64
+ const { createServer } = await import('http');
65
+ const server = createServer(async (_req, res) => {
66
+ res.writeHead(200, { 'Content-Type': registry.contentType });
67
+ res.end(await registry.metrics());
68
+ });
69
+ server.listen(port, () => {
70
+ Logger.info(`[metrics] Prometheus metrics available at http://0.0.0.0:${port}/metrics`);
71
+ });
72
+ }
73
+ catch (err) {
74
+ Logger.error(`[metrics] Failed to start metrics server: ${err?.message}`);
75
+ }
76
+ }
77
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/utils/metrics.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ export interface BlockLogEntry {
16
16
  rule: string;
17
17
  }
18
18
  export interface ErrorLogEntry {
19
- event: 'proxy_error';
19
+ event: 'proxy_error' | 'oidc_discovery_error' | 'oidc_auth_error';
20
20
  requestId?: string | number;
21
21
  serverName: string;
22
22
  error: string;
@@ -1 +1 @@
1
- {"version":3,"file":"structured-logger.d.ts","sourceRoot":"","sources":["../../src/utils/structured-logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAkBxE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAgB;IAC3B;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIpD;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAI7C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAI3C;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAGzC"}
1
+ {"version":3,"file":"structured-logger.d.ts","sourceRoot":"","sources":["../../src/utils/structured-logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAkBxE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,aAAa,GAAG,sBAAsB,GAAG,iBAAiB,CAAC;IAClE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAgB;IAC3B;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIpD;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAI7C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAI3C;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAGzC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-guardian/server",
3
- "version": "0.4.0",
3
+ "version": "0.7.0",
4
4
  "description": "Security, cost, and health audit for MCP infrastructure",
5
5
  "type": "module",
6
6
  "files": [
@@ -40,16 +40,24 @@
40
40
  "@modelcontextprotocol/sdk": "^1.0.0",
41
41
  "axios": "^1.7.0",
42
42
  "chalk": "^5.3.0",
43
+ "chokidar": "^5.0.0",
43
44
  "commander": "^12.0.0",
45
+ "ioredis": "^5.10.1",
46
+ "jose": "^6.2.3",
44
47
  "js-yaml": "^4.1.1",
48
+ "pg": "^8.20.0",
45
49
  "pino": "^10.3.1",
50
+ "prom-client": "^15.1.3",
46
51
  "sql.js": "^1.11.0",
47
52
  "tiktoken": "^1.0.15",
48
53
  "zod": "^3.23.0"
49
54
  },
50
55
  "devDependencies": {
56
+ "@types/chokidar": "^1.7.5",
57
+ "@types/ioredis": "^4.28.10",
51
58
  "@types/js-yaml": "^4.0.9",
52
59
  "@types/node": "^20.0.0",
60
+ "@types/pg": "^8.20.0",
53
61
  "tsx": "^4.7.0",
54
62
  "typescript": "^5.4.0",
55
63
  "vitest": "^1.6.0"