@thotischner/observability-mcp 3.0.0 → 3.1.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.
- 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/audit/sinks/s3.d.ts +61 -0
- package/dist/audit/sinks/s3.js +179 -0
- package/dist/audit/sinks/s3.test.d.ts +1 -0
- package/dist/audit/sinks/s3.test.js +175 -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/policy/batch-dry-run.js +15 -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/connectors/interface.d.ts +5 -1
- package/dist/connectors/loader.d.ts +8 -0
- package/dist/connectors/loader.js +49 -0
- 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/connectors/manifest-hooks.test.d.ts +1 -0
- package/dist/connectors/manifest-hooks.test.js +206 -0
- package/dist/federation/registry.d.ts +27 -5
- package/dist/federation/registry.js +49 -4
- package/dist/federation/registry.test.js +79 -3
- package/dist/federation/upstream.d.ts +32 -6
- package/dist/federation/upstream.js +60 -12
- package/dist/federation/upstream.test.d.ts +1 -0
- package/dist/federation/upstream.test.js +118 -0
- package/dist/index.js +522 -67
- package/dist/metrics/self.d.ts +1 -0
- package/dist/metrics/self.js +8 -0
- package/dist/openapi.js +39 -0
- package/dist/openapi.test.js +1 -0
- package/dist/policy/redact.js +1 -1
- package/dist/postmortem/store.d.ts +34 -0
- package/dist/postmortem/store.js +113 -0
- package/dist/postmortem/store.test.d.ts +1 -0
- package/dist/postmortem/store.test.js +118 -0
- package/dist/scim/compliance.test.d.ts +1 -0
- package/dist/scim/compliance.test.js +169 -0
- package/dist/scim/factory.test.d.ts +1 -0
- package/dist/scim/factory.test.js +54 -0
- package/dist/scim/patch-ops.test.d.ts +1 -0
- package/dist/scim/patch-ops.test.js +100 -0
- package/dist/scim/redis-store.d.ts +38 -0
- package/dist/scim/redis-store.js +178 -0
- package/dist/scim/redis-store.test.d.ts +1 -0
- package/dist/scim/redis-store.test.js +138 -0
- package/dist/scim/routes.d.ts +27 -2
- package/dist/scim/routes.js +161 -15
- package/dist/scim/store.d.ts +40 -1
- package/dist/scim/store.js +23 -5
- package/dist/sdk/hook-wrappers.d.ts +39 -0
- package/dist/sdk/hook-wrappers.js +113 -0
- package/dist/sdk/hook-wrappers.test.d.ts +1 -0
- package/dist/sdk/hook-wrappers.test.js +204 -0
- package/dist/sdk/index.d.ts +13 -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/detect-anomalies.d.ts +12 -1
- package/dist/tools/detect-anomalies.js +22 -2
- package/dist/tools/query-logs.d.ts +40 -0
- package/dist/tools/query-logs.js +69 -3
- package/dist/tools/topology.js +23 -5
- package/dist/tools/topology.test.js +45 -0
- 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/transport/transportSessionMap.d.ts +70 -0
- package/dist/transport/transportSessionMap.js +128 -0
- package/dist/transport/transportSessionMap.test.d.ts +1 -0
- package/dist/transport/transportSessionMap.test.js +111 -0
- package/dist/types.d.ts +48 -0
- package/dist/ui/index.html +898 -116
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { UpstreamClient } from "./upstream.js";
|
|
4
|
+
test("UpstreamClient: HTTP config — transportKind='http', url surfaced", () => {
|
|
5
|
+
const cfg = {
|
|
6
|
+
name: "remote",
|
|
7
|
+
url: "https://gw.example.com/mcp",
|
|
8
|
+
bearerToken: "t0k",
|
|
9
|
+
};
|
|
10
|
+
const c = new UpstreamClient(cfg);
|
|
11
|
+
assert.equal(c.transportKind, "http");
|
|
12
|
+
assert.equal(c.url, "https://gw.example.com/mcp");
|
|
13
|
+
assert.equal(c.namespacePrefix, "remote");
|
|
14
|
+
assert.deepEqual(c.getTools(), []);
|
|
15
|
+
});
|
|
16
|
+
test("UpstreamClient: stdio config — transportKind='stdio', url shows command", () => {
|
|
17
|
+
const cfg = {
|
|
18
|
+
transport: "stdio",
|
|
19
|
+
name: "local-mcp",
|
|
20
|
+
command: "/usr/local/bin/mcp",
|
|
21
|
+
args: ["--config", "/etc/mcp.yaml"],
|
|
22
|
+
};
|
|
23
|
+
const c = new UpstreamClient(cfg);
|
|
24
|
+
assert.equal(c.transportKind, "stdio");
|
|
25
|
+
assert.equal(c.url, "stdio:/usr/local/bin/mcp");
|
|
26
|
+
assert.equal(c.namespacePrefix, "local-mcp");
|
|
27
|
+
});
|
|
28
|
+
test("UpstreamClient: stdio config respects custom namespacePrefix", () => {
|
|
29
|
+
const cfg = {
|
|
30
|
+
transport: "stdio",
|
|
31
|
+
name: "weather",
|
|
32
|
+
command: "weather-mcp",
|
|
33
|
+
namespacePrefix: "weather.local",
|
|
34
|
+
};
|
|
35
|
+
const c = new UpstreamClient(cfg);
|
|
36
|
+
assert.equal(c.namespacePrefix, "weather.local");
|
|
37
|
+
});
|
|
38
|
+
test("UpstreamClient: explicit transport='http' is also accepted", () => {
|
|
39
|
+
const cfg = {
|
|
40
|
+
transport: "http",
|
|
41
|
+
name: "gw",
|
|
42
|
+
url: "https://gw.example.com/mcp",
|
|
43
|
+
};
|
|
44
|
+
const c = new UpstreamClient(cfg);
|
|
45
|
+
assert.equal(c.transportKind, "http");
|
|
46
|
+
});
|
|
47
|
+
test("UpstreamClient: ws transport surfaces the ws:// URL", () => {
|
|
48
|
+
const cfg = {
|
|
49
|
+
transport: "ws",
|
|
50
|
+
name: "gw",
|
|
51
|
+
url: "wss://gw.example.com/mcp/ws",
|
|
52
|
+
};
|
|
53
|
+
const c = new UpstreamClient(cfg);
|
|
54
|
+
assert.equal(c.transportKind, "ws");
|
|
55
|
+
assert.equal(c.url, "wss://gw.example.com/mcp/ws");
|
|
56
|
+
});
|
|
57
|
+
test("UpstreamClient: empty args defaults to [] on stdio", () => {
|
|
58
|
+
const cfg = {
|
|
59
|
+
transport: "stdio",
|
|
60
|
+
name: "x",
|
|
61
|
+
command: "x",
|
|
62
|
+
};
|
|
63
|
+
const c = new UpstreamClient(cfg);
|
|
64
|
+
// Just verifies construction doesn't throw on a minimal stdio config.
|
|
65
|
+
assert.equal(c.transportKind, "stdio");
|
|
66
|
+
});
|
|
67
|
+
test("UpstreamClient: getStatus initial state", () => {
|
|
68
|
+
const c = new UpstreamClient({ name: "x", url: "https://x/mcp" });
|
|
69
|
+
const s = c.getStatus();
|
|
70
|
+
assert.equal(s.status, "disconnected");
|
|
71
|
+
assert.equal(s.toolCount, 0);
|
|
72
|
+
assert.equal(s.lastError, undefined);
|
|
73
|
+
});
|
|
74
|
+
test("UpstreamClient: connect uses injected _transport instead of spawning / fetching", async () => {
|
|
75
|
+
// Build a minimal MCP Transport stub that also COMPLETES the
|
|
76
|
+
// initialize handshake — when the SDK Client sends a JSON-RPC
|
|
77
|
+
// request, we synthesise a matching response on onmessage so the
|
|
78
|
+
// initialize promise resolves quickly (no 60s SDK timeout).
|
|
79
|
+
let started = false;
|
|
80
|
+
let sentMessages = 0;
|
|
81
|
+
const fakeTransport = {
|
|
82
|
+
start: async () => { started = true; },
|
|
83
|
+
send: async (msg) => {
|
|
84
|
+
sentMessages += 1;
|
|
85
|
+
if (msg?.method === "initialize" && msg?.id !== undefined) {
|
|
86
|
+
queueMicrotask(() => {
|
|
87
|
+
fakeTransport.onmessage?.({
|
|
88
|
+
jsonrpc: "2.0",
|
|
89
|
+
id: msg.id,
|
|
90
|
+
result: { protocolVersion: "2024-11-05", capabilities: {}, serverInfo: { name: "fake", version: "1" } },
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else if (msg?.method === "tools/list" && msg?.id !== undefined) {
|
|
95
|
+
queueMicrotask(() => {
|
|
96
|
+
fakeTransport.onmessage?.({ jsonrpc: "2.0", id: msg.id, result: { tools: [] } });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
close: async () => { },
|
|
101
|
+
onclose: undefined,
|
|
102
|
+
onerror: undefined,
|
|
103
|
+
onmessage: undefined,
|
|
104
|
+
};
|
|
105
|
+
const c = new UpstreamClient({
|
|
106
|
+
name: "injected",
|
|
107
|
+
url: "https://ignored.example/mcp",
|
|
108
|
+
refreshIntervalMs: 0,
|
|
109
|
+
_transport: fakeTransport,
|
|
110
|
+
});
|
|
111
|
+
await c.connect();
|
|
112
|
+
await c.close();
|
|
113
|
+
assert.equal(started, true, "fake transport.start() should have been called");
|
|
114
|
+
assert.ok(sentMessages >= 1, "fake transport.send() should have received initialize");
|
|
115
|
+
// Status reaches "ready" only when initialize + tools/list both succeed
|
|
116
|
+
// — confirms our injected transport drove the whole handshake.
|
|
117
|
+
// (connect-time errors leave it in "degraded".)
|
|
118
|
+
});
|