@thotischner/observability-mcp 3.0.1 → 3.1.1
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/dist/analysis/history.d.ts +36 -2
- package/dist/analysis/history.js +60 -2
- package/dist/analysis/history.test.js +46 -0
- package/dist/auth/csrf.d.ts +6 -0
- package/dist/auth/csrf.js +4 -0
- package/dist/auth/csrf.test.js +22 -0
- package/dist/auth/lockout.d.ts +72 -0
- package/dist/auth/lockout.js +134 -0
- package/dist/auth/lockout.test.d.ts +1 -0
- package/dist/auth/lockout.test.js +133 -0
- package/dist/auth/middleware.d.ts +5 -0
- package/dist/auth/middleware.js +6 -1
- package/dist/auth/middleware.test.js +31 -0
- package/dist/auth/password-policy.d.ts +52 -0
- package/dist/auth/password-policy.js +125 -0
- package/dist/auth/password-policy.test.d.ts +1 -0
- package/dist/auth/password-policy.test.js +111 -0
- package/dist/auth/revocation.d.ts +93 -0
- package/dist/auth/revocation.js +193 -0
- package/dist/auth/revocation.test.d.ts +1 -0
- package/dist/auth/revocation.test.js +136 -0
- package/dist/auth/session.d.ts +7 -0
- package/dist/auth/session.js +6 -0
- package/dist/auth/session.test.js +21 -0
- package/dist/conformance/mcp-2025-11-25.test.js +14 -0
- package/dist/connectors/interface.d.ts +5 -1
- package/dist/connectors/loki.d.ts +45 -1
- package/dist/connectors/loki.js +141 -8
- package/dist/connectors/loki.test.js +171 -1
- package/dist/index.js +244 -4
- package/dist/openapi.js +39 -0
- package/dist/openapi.test.js +1 -0
- package/dist/security/csp.d.ts +64 -0
- package/dist/security/csp.js +135 -0
- package/dist/security/csp.test.d.ts +1 -0
- package/dist/security/csp.test.js +97 -0
- package/dist/tools/query-logs-schema.test.d.ts +1 -0
- package/dist/tools/query-logs-schema.test.js +38 -0
- package/dist/tools/query-logs.d.ts +40 -0
- package/dist/tools/query-logs.js +69 -3
- package/dist/tools/validation.d.ts +13 -0
- package/dist/tools/validation.js +74 -0
- package/dist/tools/validation.test.js +54 -1
- package/dist/types.d.ts +48 -0
- package/dist/ui/index.html +42 -15
- package/package.json +1 -1
package/dist/ui/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Observability MCP Gateway</title>
|
|
7
|
-
<script>
|
|
7
|
+
<script nonce="__CSP_NONCE__">
|
|
8
8
|
// Resolve the theme + density BEFORE first paint to avoid a flash.
|
|
9
9
|
// Explicit user choice (localStorage) wins; otherwise follow the OS
|
|
10
10
|
// setting for theme and default to comfortable density.
|
|
@@ -2656,7 +2656,7 @@ curl -s http://localhost:3000/api/enterprise/status</pre>
|
|
|
2656
2656
|
<div class="drawer-bd" id="drawer-body"></div>
|
|
2657
2657
|
</aside>
|
|
2658
2658
|
|
|
2659
|
-
<script>
|
|
2659
|
+
<script nonce="__CSP_NONCE__">
|
|
2660
2660
|
let sourcesData=[], servicesData=[], supportedTypes=[], settings={}, healthThresholds={}, defaults={};
|
|
2661
2661
|
let deleteTarget=null, deleteType=null;
|
|
2662
2662
|
// Per-source metrics state
|
|
@@ -6251,9 +6251,8 @@ function saveMetric() {
|
|
|
6251
6251
|
// --- Health Dashboard ---
|
|
6252
6252
|
let healthData={};
|
|
6253
6253
|
let healthInterval=null;
|
|
6254
|
-
//
|
|
6255
|
-
//
|
|
6256
|
-
// for the last ~7.5 minutes (30 points × 15s refresh).
|
|
6254
|
+
// Client-side live-score trend, kept as a fallback for when the server's
|
|
6255
|
+
// anomaly-history sink isn't active. ~7.5 minutes (30 points × 15s refresh).
|
|
6257
6256
|
const SPARK_MAX = 30;
|
|
6258
6257
|
const scoreHistory = {};
|
|
6259
6258
|
function pushScore(name, score) {
|
|
@@ -6262,31 +6261,59 @@ function pushScore(name, score) {
|
|
|
6262
6261
|
arr.push(score);
|
|
6263
6262
|
if (arr.length > SPARK_MAX) arr.shift();
|
|
6264
6263
|
}
|
|
6265
|
-
|
|
6266
|
-
|
|
6264
|
+
// Server-side anomaly-score history (Q21). Populated from
|
|
6265
|
+
// /api/health/anomaly-sparklines — the last hour of omcp_anomaly_score
|
|
6266
|
+
// from the anomaly-history sink. Survives reloads; preferred over the
|
|
6267
|
+
// client-side trend when present.
|
|
6268
|
+
let anomalySpark = { enabled:false, windowMs:0, series:{} };
|
|
6269
|
+
|
|
6270
|
+
function drawSpark(values, status, domainMax, title){
|
|
6267
6271
|
const w = 100, h = 36, pad = 2;
|
|
6268
|
-
if (
|
|
6269
|
-
// Placeholder dashed midline until we have ≥2 samples.
|
|
6272
|
+
if (!values || values.length < 2) {
|
|
6270
6273
|
return `<svg class="hc-spark ${status}" viewBox="0 0 ${w} ${h}" preserveAspectRatio="none" aria-hidden="true">`
|
|
6271
6274
|
+ `<line class="spark-empty" x1="0" y1="${h/2}" x2="${w}" y2="${h/2}"/></svg>`;
|
|
6272
6275
|
}
|
|
6273
|
-
const min = 0, max =
|
|
6274
|
-
const step = (w - pad*2) / (
|
|
6275
|
-
const y = v => h - pad - ((v - min) / (max - min)) * (h - pad*2);
|
|
6276
|
-
const coords =
|
|
6276
|
+
const min = 0, max = domainMax;
|
|
6277
|
+
const step = (w - pad*2) / (values.length - 1);
|
|
6278
|
+
const y = v => h - pad - ((Math.max(min, Math.min(max, v)) - min) / (max - min || 1)) * (h - pad*2);
|
|
6279
|
+
const coords = values.map((v, i) => `${pad + i*step},${y(v)}`);
|
|
6277
6280
|
const line = coords.join(' ');
|
|
6278
|
-
const area = `M${coords[0]} L${line.split(' ').join(' L')} L${pad + (
|
|
6281
|
+
const area = `M${coords[0]} L${line.split(' ').join(' L')} L${pad + (values.length-1)*step},${h-pad} L${pad},${h-pad} Z`;
|
|
6279
6282
|
const last = coords[coords.length - 1].split(',');
|
|
6280
6283
|
return `<svg class="hc-spark ${status}" viewBox="0 0 ${w} ${h}" preserveAspectRatio="none" aria-hidden="true">`
|
|
6284
|
+
+ (title?`<title>${esc(title)}</title>`:'')
|
|
6281
6285
|
+ `<path class="spark-fill" d="${area}"/>`
|
|
6282
6286
|
+ `<polyline class="spark-line" points="${line}"/>`
|
|
6283
6287
|
+ `<circle class="spark-dot" cx="${last[0]}" cy="${last[1]}" r="1.8"/>`
|
|
6284
6288
|
+ `</svg>`;
|
|
6285
6289
|
}
|
|
6286
6290
|
|
|
6291
|
+
function sparkSvg(name, status) {
|
|
6292
|
+
// Prefer the server anomaly-score series (real omcp_anomaly_score, last
|
|
6293
|
+
// hour, survives reload). Anomaly scores are 0..1; widen the domain if a
|
|
6294
|
+
// score ever exceeds 1 so spikes aren't clipped.
|
|
6295
|
+
const series = (anomalySpark.series && anomalySpark.series[name]) || [];
|
|
6296
|
+
if (series.length >= 2) {
|
|
6297
|
+
const scores = series.map(p => p.score);
|
|
6298
|
+
const domainMax = Math.max(1, ...scores);
|
|
6299
|
+
const mins = anomalySpark.windowMs ? Math.round(anomalySpark.windowMs/60000) : 60;
|
|
6300
|
+
return drawSpark(scores, status, domainMax, `anomaly score · ${series.length} pts · last ${mins}m`);
|
|
6301
|
+
}
|
|
6302
|
+
// Fallback: client-side live health-score trend (0..100).
|
|
6303
|
+
return drawSpark(scoreHistory[name] || [], status, 100, 'live score trend');
|
|
6304
|
+
}
|
|
6305
|
+
|
|
6287
6306
|
async function loadHealthData() {
|
|
6288
6307
|
try {
|
|
6289
|
-
|
|
6308
|
+
// Fetch health + the server-side anomaly-score sparkline data in
|
|
6309
|
+
// parallel. The sparkline endpoint is best-effort: if it fails we
|
|
6310
|
+
// simply fall back to the client-side live-score trend.
|
|
6311
|
+
const [h, spark] = await Promise.all([
|
|
6312
|
+
fetch('/api/health').then(r=>r.json()),
|
|
6313
|
+
fetch('/api/health/anomaly-sparklines').then(r=>r.ok?r.json():null).catch(()=>null),
|
|
6314
|
+
]);
|
|
6315
|
+
healthData=h;
|
|
6316
|
+
if (spark && spark.series) anomalySpark = spark;
|
|
6290
6317
|
renderHealthCards();
|
|
6291
6318
|
} catch(e){ document.getElementById('health-cards').innerHTML='<div class="empty">Failed to load health data.</div>'; }
|
|
6292
6319
|
if(!healthInterval) healthInterval=setInterval(()=>{ if(document.getElementById('page-health').classList.contains('active')) loadHealthData(); },15000);
|
package/package.json
CHANGED