@ivotoby/openapi-mcp-server 1.9.3 → 1.10.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/README.md +42 -0
- package/dist/bundle.js +37 -3
- package/dist/cli.js +37 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -297,6 +297,48 @@ The HTTP transport allows the MCP server to be accessed over HTTP, enabling web
|
|
|
297
297
|
|
|
298
298
|
**When to use**: When you need to expose the MCP server to web clients or systems that communicate over HTTP rather than stdio.
|
|
299
299
|
|
|
300
|
+
### Health Check Endpoint
|
|
301
|
+
|
|
302
|
+
When using HTTP transport, a health check endpoint is available at `/health` for monitoring and service discovery:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Check server health
|
|
306
|
+
curl http://localhost:3000/health
|
|
307
|
+
|
|
308
|
+
# Response:
|
|
309
|
+
# {
|
|
310
|
+
# "status": "healthy",
|
|
311
|
+
# "activeSessions": 2,
|
|
312
|
+
# "uptime": 3600
|
|
313
|
+
# }
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Health Response Fields:**
|
|
317
|
+
- `status`: Always returns "healthy" when server is running
|
|
318
|
+
- `activeSessions`: Number of active MCP sessions
|
|
319
|
+
- `uptime`: Server uptime in seconds
|
|
320
|
+
|
|
321
|
+
**Key Features:**
|
|
322
|
+
- No authentication required
|
|
323
|
+
- Works with any HTTP method (GET, POST, etc.)
|
|
324
|
+
- Ideal for load balancers, Kubernetes probes, and monitoring systems
|
|
325
|
+
|
|
326
|
+
**Integration Examples:**
|
|
327
|
+
|
|
328
|
+
```yaml
|
|
329
|
+
# Kubernetes liveness probe
|
|
330
|
+
livenessProbe:
|
|
331
|
+
httpGet:
|
|
332
|
+
path: /health
|
|
333
|
+
port: 3000
|
|
334
|
+
initialDelaySeconds: 3
|
|
335
|
+
periodSeconds: 10
|
|
336
|
+
|
|
337
|
+
# Docker healthcheck
|
|
338
|
+
HEALTHCHECK --interval=30s --timeout=3s \
|
|
339
|
+
CMD curl -f http://localhost:3000/health || exit 1
|
|
340
|
+
```
|
|
341
|
+
|
|
300
342
|
## Security Considerations
|
|
301
343
|
|
|
302
344
|
- The HTTP transport validates Origin headers to prevent DNS rebinding attacks
|
package/dist/bundle.js
CHANGED
|
@@ -18606,6 +18606,7 @@ var ApiClient = class {
|
|
|
18606
18606
|
return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18607
18607
|
};
|
|
18608
18608
|
const headerParams = {};
|
|
18609
|
+
const queryParams = {};
|
|
18609
18610
|
if (toolDef?.inputSchema?.properties) {
|
|
18610
18611
|
for (const [key, value] of Object.entries(paramsCopy)) {
|
|
18611
18612
|
const paramDef = toolDef.inputSchema.properties[key];
|
|
@@ -18626,6 +18627,9 @@ var ApiClient = class {
|
|
|
18626
18627
|
resolvedPath = resolvedPath.replace(`/${key}`, `/${encodeURIComponent(value)}`);
|
|
18627
18628
|
}
|
|
18628
18629
|
delete paramsCopy[key];
|
|
18630
|
+
} else if (paramLocation === "query") {
|
|
18631
|
+
queryParams[key] = value;
|
|
18632
|
+
delete paramsCopy[key];
|
|
18629
18633
|
} else if (paramLocation === "header") {
|
|
18630
18634
|
headerParams[key] = String(value);
|
|
18631
18635
|
delete paramsCopy[key];
|
|
@@ -18657,10 +18661,20 @@ var ApiClient = class {
|
|
|
18657
18661
|
url: resolvedPath,
|
|
18658
18662
|
headers: { ...authHeaders, ...headerParams }
|
|
18659
18663
|
};
|
|
18664
|
+
if (Object.keys(queryParams).length > 0) {
|
|
18665
|
+
config.params = this.processQueryParams(queryParams);
|
|
18666
|
+
}
|
|
18660
18667
|
if (isGetLikeMethod(method)) {
|
|
18661
|
-
|
|
18668
|
+
if (Object.keys(paramsCopy).length > 0) {
|
|
18669
|
+
config.params = {
|
|
18670
|
+
...config.params,
|
|
18671
|
+
...this.processQueryParams(paramsCopy)
|
|
18672
|
+
};
|
|
18673
|
+
}
|
|
18662
18674
|
} else {
|
|
18663
|
-
|
|
18675
|
+
if (Object.keys(paramsCopy).length > 0) {
|
|
18676
|
+
config.data = paramsCopy;
|
|
18677
|
+
}
|
|
18664
18678
|
}
|
|
18665
18679
|
const response = await this.axiosInstance(config);
|
|
18666
18680
|
return response.data;
|
|
@@ -24000,7 +24014,6 @@ import {
|
|
|
24000
24014
|
import * as http2 from "http";
|
|
24001
24015
|
import { randomUUID } from "crypto";
|
|
24002
24016
|
var StreamableHttpServerTransport = class {
|
|
24003
|
-
// Maps request IDs to session IDs
|
|
24004
24017
|
/**
|
|
24005
24018
|
* Initialize a new StreamableHttpServerTransport
|
|
24006
24019
|
*
|
|
@@ -24017,9 +24030,12 @@ var StreamableHttpServerTransport = class {
|
|
|
24017
24030
|
server;
|
|
24018
24031
|
sessions = /* @__PURE__ */ new Map();
|
|
24019
24032
|
started = false;
|
|
24033
|
+
startTime = Date.now();
|
|
24020
24034
|
maxBodySize = 4 * 1024 * 1024;
|
|
24021
24035
|
// 4MB max request size
|
|
24022
24036
|
requestSessionMap = /* @__PURE__ */ new Map();
|
|
24037
|
+
// Maps request IDs to session IDs
|
|
24038
|
+
healthCheckPath = "/health";
|
|
24023
24039
|
/**
|
|
24024
24040
|
* Callback when message is received
|
|
24025
24041
|
*/
|
|
@@ -24163,10 +24179,28 @@ var StreamableHttpServerTransport = class {
|
|
|
24163
24179
|
}
|
|
24164
24180
|
}
|
|
24165
24181
|
}
|
|
24182
|
+
/**
|
|
24183
|
+
* Handle health check request
|
|
24184
|
+
*/
|
|
24185
|
+
handleHealthCheck(_req, res) {
|
|
24186
|
+
const uptime = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
24187
|
+
const healthResponse = {
|
|
24188
|
+
status: "healthy",
|
|
24189
|
+
activeSessions: this.sessions.size,
|
|
24190
|
+
uptime
|
|
24191
|
+
};
|
|
24192
|
+
res.setHeader("Content-Type", "application/json");
|
|
24193
|
+
res.writeHead(200);
|
|
24194
|
+
res.end(JSON.stringify(healthResponse));
|
|
24195
|
+
}
|
|
24166
24196
|
/**
|
|
24167
24197
|
* Handle HTTP request
|
|
24168
24198
|
*/
|
|
24169
24199
|
handleRequest(req, res) {
|
|
24200
|
+
if (req.url === this.healthCheckPath) {
|
|
24201
|
+
this.handleHealthCheck(req, res);
|
|
24202
|
+
return;
|
|
24203
|
+
}
|
|
24170
24204
|
if (req.url !== this.endpointPath) {
|
|
24171
24205
|
res.writeHead(404);
|
|
24172
24206
|
res.end();
|
package/dist/cli.js
CHANGED
|
@@ -18606,6 +18606,7 @@ var ApiClient = class {
|
|
|
18606
18606
|
return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18607
18607
|
};
|
|
18608
18608
|
const headerParams = {};
|
|
18609
|
+
const queryParams = {};
|
|
18609
18610
|
if (toolDef?.inputSchema?.properties) {
|
|
18610
18611
|
for (const [key, value] of Object.entries(paramsCopy)) {
|
|
18611
18612
|
const paramDef = toolDef.inputSchema.properties[key];
|
|
@@ -18626,6 +18627,9 @@ var ApiClient = class {
|
|
|
18626
18627
|
resolvedPath = resolvedPath.replace(`/${key}`, `/${encodeURIComponent(value)}`);
|
|
18627
18628
|
}
|
|
18628
18629
|
delete paramsCopy[key];
|
|
18630
|
+
} else if (paramLocation === "query") {
|
|
18631
|
+
queryParams[key] = value;
|
|
18632
|
+
delete paramsCopy[key];
|
|
18629
18633
|
} else if (paramLocation === "header") {
|
|
18630
18634
|
headerParams[key] = String(value);
|
|
18631
18635
|
delete paramsCopy[key];
|
|
@@ -18657,10 +18661,20 @@ var ApiClient = class {
|
|
|
18657
18661
|
url: resolvedPath,
|
|
18658
18662
|
headers: { ...authHeaders, ...headerParams }
|
|
18659
18663
|
};
|
|
18664
|
+
if (Object.keys(queryParams).length > 0) {
|
|
18665
|
+
config.params = this.processQueryParams(queryParams);
|
|
18666
|
+
}
|
|
18660
18667
|
if (isGetLikeMethod(method)) {
|
|
18661
|
-
|
|
18668
|
+
if (Object.keys(paramsCopy).length > 0) {
|
|
18669
|
+
config.params = {
|
|
18670
|
+
...config.params,
|
|
18671
|
+
...this.processQueryParams(paramsCopy)
|
|
18672
|
+
};
|
|
18673
|
+
}
|
|
18662
18674
|
} else {
|
|
18663
|
-
|
|
18675
|
+
if (Object.keys(paramsCopy).length > 0) {
|
|
18676
|
+
config.data = paramsCopy;
|
|
18677
|
+
}
|
|
18664
18678
|
}
|
|
18665
18679
|
const response = await this.axiosInstance(config);
|
|
18666
18680
|
return response.data;
|
|
@@ -24000,7 +24014,6 @@ import {
|
|
|
24000
24014
|
import * as http2 from "http";
|
|
24001
24015
|
import { randomUUID } from "crypto";
|
|
24002
24016
|
var StreamableHttpServerTransport = class {
|
|
24003
|
-
// Maps request IDs to session IDs
|
|
24004
24017
|
/**
|
|
24005
24018
|
* Initialize a new StreamableHttpServerTransport
|
|
24006
24019
|
*
|
|
@@ -24017,9 +24030,12 @@ var StreamableHttpServerTransport = class {
|
|
|
24017
24030
|
server;
|
|
24018
24031
|
sessions = /* @__PURE__ */ new Map();
|
|
24019
24032
|
started = false;
|
|
24033
|
+
startTime = Date.now();
|
|
24020
24034
|
maxBodySize = 4 * 1024 * 1024;
|
|
24021
24035
|
// 4MB max request size
|
|
24022
24036
|
requestSessionMap = /* @__PURE__ */ new Map();
|
|
24037
|
+
// Maps request IDs to session IDs
|
|
24038
|
+
healthCheckPath = "/health";
|
|
24023
24039
|
/**
|
|
24024
24040
|
* Callback when message is received
|
|
24025
24041
|
*/
|
|
@@ -24163,10 +24179,28 @@ var StreamableHttpServerTransport = class {
|
|
|
24163
24179
|
}
|
|
24164
24180
|
}
|
|
24165
24181
|
}
|
|
24182
|
+
/**
|
|
24183
|
+
* Handle health check request
|
|
24184
|
+
*/
|
|
24185
|
+
handleHealthCheck(_req, res) {
|
|
24186
|
+
const uptime = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
24187
|
+
const healthResponse = {
|
|
24188
|
+
status: "healthy",
|
|
24189
|
+
activeSessions: this.sessions.size,
|
|
24190
|
+
uptime
|
|
24191
|
+
};
|
|
24192
|
+
res.setHeader("Content-Type", "application/json");
|
|
24193
|
+
res.writeHead(200);
|
|
24194
|
+
res.end(JSON.stringify(healthResponse));
|
|
24195
|
+
}
|
|
24166
24196
|
/**
|
|
24167
24197
|
* Handle HTTP request
|
|
24168
24198
|
*/
|
|
24169
24199
|
handleRequest(req, res) {
|
|
24200
|
+
if (req.url === this.healthCheckPath) {
|
|
24201
|
+
this.handleHealthCheck(req, res);
|
|
24202
|
+
return;
|
|
24203
|
+
}
|
|
24170
24204
|
if (req.url !== this.endpointPath) {
|
|
24171
24205
|
res.writeHead(404);
|
|
24172
24206
|
res.end();
|