nvidia-nim-mcp 2.1.0 → 2.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/client.js +63 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -1,8 +1,52 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import axiosRetry from "axios-retry";
|
|
3
|
+
import http from "http";
|
|
4
|
+
import https from "https";
|
|
3
5
|
import { getConfig } from "./config.js";
|
|
4
6
|
import { logger } from "./logger.js";
|
|
5
7
|
const config = getConfig();
|
|
8
|
+
// Create HTTP/HTTPS agents with keep-alive for connection reuse
|
|
9
|
+
const httpAgent = new http.Agent({
|
|
10
|
+
keepAlive: true,
|
|
11
|
+
keepAliveMsecs: 30_000,
|
|
12
|
+
maxSockets: 50,
|
|
13
|
+
maxFreeSockets: 10,
|
|
14
|
+
timeout: 60_000,
|
|
15
|
+
scheduling: "lifo",
|
|
16
|
+
});
|
|
17
|
+
const httpsAgent = new https.Agent({
|
|
18
|
+
keepAlive: true,
|
|
19
|
+
keepAliveMsecs: 30_000,
|
|
20
|
+
maxSockets: 50,
|
|
21
|
+
maxFreeSockets: 10,
|
|
22
|
+
timeout: 60_000,
|
|
23
|
+
scheduling: "lifo",
|
|
24
|
+
});
|
|
25
|
+
// Network error codes that should trigger a retry
|
|
26
|
+
const RETRYABLE_NETWORK_CODES = new Set([
|
|
27
|
+
"ECONNRESET",
|
|
28
|
+
"ETIMEDOUT",
|
|
29
|
+
"ENOTFOUND",
|
|
30
|
+
"ECONNREFUSED",
|
|
31
|
+
"EPIPE",
|
|
32
|
+
"ECONNABORTED",
|
|
33
|
+
"EAI_AGAIN",
|
|
34
|
+
"EHOSTUNREACH",
|
|
35
|
+
"ENETUNREACH",
|
|
36
|
+
]);
|
|
37
|
+
function isRetryableNetworkError(error) {
|
|
38
|
+
if (axiosRetry.isNetworkError(error))
|
|
39
|
+
return true;
|
|
40
|
+
if (error.code && RETRYABLE_NETWORK_CODES.has(error.code))
|
|
41
|
+
return true;
|
|
42
|
+
// Check for timeout error message
|
|
43
|
+
if (error.message?.includes("timeout") || error.message?.includes("ECONNABORTED"))
|
|
44
|
+
return true;
|
|
45
|
+
// Check for connection closed/reset in error message
|
|
46
|
+
if (error.message?.includes("Connection closed") || error.message?.includes("socket hang up"))
|
|
47
|
+
return true;
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
6
50
|
class RateLimiter {
|
|
7
51
|
requests = [];
|
|
8
52
|
maxRequests;
|
|
@@ -36,10 +80,13 @@ export class NIMClient {
|
|
|
36
80
|
const http = axios.create({
|
|
37
81
|
baseURL: config.NVIDIA_NIM_BASE_URL,
|
|
38
82
|
timeout: config.REQUEST_TIMEOUT_MS,
|
|
83
|
+
httpAgent,
|
|
84
|
+
httpsAgent,
|
|
39
85
|
headers: {
|
|
40
86
|
Authorization: `Bearer ${config.NVIDIA_API_KEY}`,
|
|
41
87
|
"Content-Type": "application/json",
|
|
42
88
|
"User-Agent": `${config.MCP_SERVER_NAME}/${config.MCP_SERVER_VERSION}`,
|
|
89
|
+
"Connection": "keep-alive",
|
|
43
90
|
},
|
|
44
91
|
});
|
|
45
92
|
axiosRetry(http, {
|
|
@@ -51,13 +98,14 @@ export class NIMClient {
|
|
|
51
98
|
},
|
|
52
99
|
retryCondition: (error) => {
|
|
53
100
|
const status = error.response?.status;
|
|
54
|
-
return (
|
|
101
|
+
return (isRetryableNetworkError(error) ||
|
|
55
102
|
status === 429 ||
|
|
56
103
|
(status !== undefined && status >= 500));
|
|
57
104
|
},
|
|
58
105
|
onRetry: (retryCount, error) => {
|
|
59
106
|
logger.warn(`Retrying request (${retryCount}/${config.MAX_RETRIES})`, {
|
|
60
107
|
status: error.response?.status,
|
|
108
|
+
code: error.code,
|
|
61
109
|
message: error.message,
|
|
62
110
|
});
|
|
63
111
|
},
|
|
@@ -92,6 +140,20 @@ export class NIMClient {
|
|
|
92
140
|
const apiMsg = data?.detail ||
|
|
93
141
|
data?.message ||
|
|
94
142
|
error.message;
|
|
143
|
+
// Handle connection-level errors (no HTTP response)
|
|
144
|
+
if (!error.response) {
|
|
145
|
+
if (error.code && RETRYABLE_NETWORK_CODES.has(error.code)) {
|
|
146
|
+
return new Error(`Connection error (${error.code}): ${error.message}. ` +
|
|
147
|
+
`The connection to NVIDIA NIM was closed unexpectedly. ` +
|
|
148
|
+
`This may be due to network instability, server overload, or firewall rules. ` +
|
|
149
|
+
`The request will be retried automatically (attempt ${error.config?.headers?.["Retry-Count"] ?? "1"}/${config.MAX_RETRIES}).`);
|
|
150
|
+
}
|
|
151
|
+
if (error.message?.includes("timeout") || error.code === "ECONNABORTED") {
|
|
152
|
+
return new Error(`Request timeout after ${config.REQUEST_TIMEOUT_MS}ms: ${error.message}. ` +
|
|
153
|
+
`Consider increasing REQUEST_TIMEOUT_MS for long-running operations like image generation.`);
|
|
154
|
+
}
|
|
155
|
+
return new Error(`Network error: ${error.message}`);
|
|
156
|
+
}
|
|
95
157
|
if (status === 401)
|
|
96
158
|
return new Error(`Authentication failed: ${apiMsg}`);
|
|
97
159
|
if (status === 403)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nvidia-nim-mcp",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Production-ready MCP server for NVIDIA NIM models - 50+ LLMs, multimodal, image generation, embeddings, reranking with rich metadata for agent selection",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|