mcp-server-kubernetes 3.7.0 → 3.8.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/utils/streamable-http.js +47 -14
- package/package.json +1 -1
|
@@ -1,22 +1,63 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
3
3
|
import { createAuthMiddleware, isAuthEnabled } from "./auth.js";
|
|
4
|
+
/**
|
|
5
|
+
* Build the default allowedHosts list for DNS rebinding protection.
|
|
6
|
+
* Includes localhost variants with and without port.
|
|
7
|
+
*/
|
|
8
|
+
function buildDefaultAllowedHosts(host, port) {
|
|
9
|
+
// Always allow the bare host and host:port for common localhost addresses
|
|
10
|
+
const localhostAliases = ["127.0.0.1", "localhost", "::1"];
|
|
11
|
+
const hosts = [];
|
|
12
|
+
for (const alias of localhostAliases) {
|
|
13
|
+
hosts.push(alias);
|
|
14
|
+
// HTTP Host header uses bracket notation for IPv6: [::1]:3000
|
|
15
|
+
if (alias.includes(":")) {
|
|
16
|
+
hosts.push(`[${alias}]`);
|
|
17
|
+
hosts.push(`[${alias}]:${port}`);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
hosts.push(`${alias}:${port}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Also add the configured host if it's not already covered
|
|
24
|
+
if (!localhostAliases.includes(host)) {
|
|
25
|
+
hosts.push(host);
|
|
26
|
+
if (host.includes(":") && !host.startsWith("[")) {
|
|
27
|
+
hosts.push(`[${host}]`);
|
|
28
|
+
hosts.push(`[${host}]:${port}`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
hosts.push(`${host}:${port}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return hosts;
|
|
35
|
+
}
|
|
4
36
|
export function startStreamableHTTPServer(server) {
|
|
5
37
|
const app = express();
|
|
6
38
|
app.use(express.json());
|
|
7
39
|
// Create auth middleware - when MCP_AUTH_TOKEN is set, requires X-MCP-AUTH header
|
|
8
40
|
const authMiddleware = createAuthMiddleware();
|
|
41
|
+
// DNS rebinding protection is enabled by default. Set DNS_REBINDING_PROTECTION=false to disable.
|
|
42
|
+
const enableDnsRebindingProtection = process.env.DNS_REBINDING_PROTECTION !== "false";
|
|
43
|
+
const host = process.env.HOST || "localhost";
|
|
44
|
+
const parsed = parseInt(process.env.PORT || "3000", 10);
|
|
45
|
+
const port = Number.isNaN(parsed) ? 3000 : parsed;
|
|
46
|
+
const allowedHosts = process.env.DNS_REBINDING_ALLOWED_HOST
|
|
47
|
+
? [process.env.DNS_REBINDING_ALLOWED_HOST]
|
|
48
|
+
: buildDefaultAllowedHosts(host, port);
|
|
49
|
+
// Warn when binding to all interfaces with DNS rebinding protection disabled
|
|
50
|
+
if (!enableDnsRebindingProtection && (host === "0.0.0.0" || host === "::")) {
|
|
51
|
+
console.warn("WARNING: DNS rebinding protection is disabled while HOST is set to " +
|
|
52
|
+
`'${host}'. This exposes the MCP server to DNS rebinding attacks ` +
|
|
53
|
+
"from any browser on the network. Set DNS_REBINDING_PROTECTION=true " +
|
|
54
|
+
"(the default) or restrict HOST to 'localhost' / '127.0.0.1'.");
|
|
55
|
+
}
|
|
9
56
|
app.post("/mcp", authMiddleware, async (req, res) => {
|
|
10
57
|
// In stateless mode, create a new instance of transport and server for each request
|
|
11
58
|
// to ensure complete isolation. A single instance would cause request ID collisions
|
|
12
59
|
// when multiple clients connect concurrently.
|
|
13
60
|
try {
|
|
14
|
-
// DNS rebinding protection is disabled by default for backwards compatibility. If you are running this server
|
|
15
|
-
// locally, make sure to set DNS_REBINDING_PROTECTION=true
|
|
16
|
-
const enableDnsRebindingProtection = process.env.DNS_REBINDING_PROTECTION === "true";
|
|
17
|
-
const allowedHosts = process.env.DNS_REBINDING_ALLOWED_HOST
|
|
18
|
-
? [process.env.DNS_REBINDING_ALLOWED_HOST]
|
|
19
|
-
: ["127.0.0.1"];
|
|
20
61
|
const transport = new StreamableHTTPServerTransport({
|
|
21
62
|
sessionIdGenerator: undefined,
|
|
22
63
|
enableDnsRebindingProtection,
|
|
@@ -91,14 +132,6 @@ export function startStreamableHTTPServer(server) {
|
|
|
91
132
|
});
|
|
92
133
|
}
|
|
93
134
|
});
|
|
94
|
-
let port = 3000;
|
|
95
|
-
try {
|
|
96
|
-
port = parseInt(process.env.PORT || "3000", 10);
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
console.error("Invalid PORT environment variable, using default port 3000.");
|
|
100
|
-
}
|
|
101
|
-
const host = process.env.HOST || "localhost";
|
|
102
135
|
const httpServer = app.listen(port, host, () => {
|
|
103
136
|
console.log(`mcp-kubernetes-server is listening on port ${port}\nUse the following url to connect to the server:\nhttp://${host}:${port}/mcp`);
|
|
104
137
|
if (isAuthEnabled()) {
|