@samanhappy/mcphub 1.0.37 → 1.0.39
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/constants/oauthServerDefaults.js +1 -0
- package/dist/constants/oauthServerDefaults.js.map +1 -1
- package/dist/controllers/oauthDynamicRegistrationController.js +6 -32
- package/dist/controllers/oauthDynamicRegistrationController.js.map +1 -1
- package/dist/controllers/serverController.js +28 -3
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/dao/OAuthClientDaoDbImpl.js +3 -0
- package/dist/dao/OAuthClientDaoDbImpl.js.map +1 -1
- package/dist/db/entities/OAuthClient.js +4 -0
- package/dist/db/entities/OAuthClient.js.map +1 -1
- package/dist/db/repositories/VectorEmbeddingRepository.js +35 -3
- package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
- package/dist/models/OAuth.js +98 -1
- package/dist/models/OAuth.js.map +1 -1
- package/dist/services/mcpService.js +213 -7
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/vectorSearchService.js +12 -3
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/cacheUtils.js +477 -5
- package/dist/utils/cacheUtils.js.map +1 -1
- package/dist/utils/migration.js +1 -0
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/packageUpdate.js +242 -0
- package/dist/utils/packageUpdate.js.map +1 -0
- package/dist/utils/serverConfigPersistence.js +6 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/dist/utils/smartRouting.js +1 -1
- package/dist/utils/smartRouting.js.map +1 -1
- package/frontend/dist/assets/{ActivityPage-Bx5-Jrxq.js → ActivityPage-CDKSVr2I.js} +2 -2
- package/frontend/dist/assets/{ActivityPage-Bx5-Jrxq.js.map → ActivityPage-CDKSVr2I.js.map} +1 -1
- package/frontend/dist/assets/CopyClientConfigDialog-DYiucK0d.js +4 -0
- package/frontend/dist/assets/CopyClientConfigDialog-DYiucK0d.js.map +1 -0
- package/frontend/dist/assets/{CredentialsPage-BGbk_kBx.js → CredentialsPage-DMJE4uT2.js} +2 -2
- package/frontend/dist/assets/{CredentialsPage-BGbk_kBx.js.map → CredentialsPage-DMJE4uT2.js.map} +1 -1
- package/frontend/dist/assets/Dashboard-Dh_39img.js +2 -0
- package/frontend/dist/assets/{Dashboard-gHeXLPEn.js.map → Dashboard-Dh_39img.js.map} +1 -1
- package/frontend/dist/assets/EndpointCopy-CQmwGXbD.js +2 -0
- package/frontend/dist/assets/EndpointCopy-CQmwGXbD.js.map +1 -0
- package/frontend/dist/assets/GroupsPage-BqscWSfR.js +33 -0
- package/frontend/dist/assets/GroupsPage-BqscWSfR.js.map +1 -0
- package/frontend/dist/assets/{LoginPage-C7-m2jmB.js → LoginPage-DcrwvgS6.js} +2 -2
- package/frontend/dist/assets/{LoginPage-C7-m2jmB.js.map → LoginPage-DcrwvgS6.js.map} +1 -1
- package/frontend/dist/assets/{LogsPage-B00XTokA.js → LogsPage--Blkr-Ni.js} +2 -2
- package/frontend/dist/assets/{LogsPage-B00XTokA.js.map → LogsPage--Blkr-Ni.js.map} +1 -1
- package/frontend/dist/assets/{MarketPage-CVJMdSDD.js → MarketPage-DWv18j4V.js} +2 -2
- package/frontend/dist/assets/{MarketPage-CVJMdSDD.js.map → MarketPage-DWv18j4V.js.map} +1 -1
- package/frontend/dist/assets/{OAuthConsentPage-znW3HtpR.js → OAuthConsentPage-DCKZIMzE.js} +2 -2
- package/frontend/dist/assets/{OAuthConsentPage-znW3HtpR.js.map → OAuthConsentPage-DCKZIMzE.js.map} +1 -1
- package/frontend/dist/assets/{PromptsPage-DGcNS3fO.js → PromptsPage-DoVmnVnp.js} +2 -2
- package/frontend/dist/assets/{PromptsPage-DGcNS3fO.js.map → PromptsPage-DoVmnVnp.js.map} +1 -1
- package/frontend/dist/assets/{ResourcesPage-CfyZoadu.js → ResourcesPage-B8udCQQR.js} +2 -2
- package/frontend/dist/assets/{ResourcesPage-CfyZoadu.js.map → ResourcesPage-B8udCQQR.js.map} +1 -1
- package/frontend/dist/assets/ServersPage-OLpH1K1I.js +39 -0
- package/frontend/dist/assets/ServersPage-OLpH1K1I.js.map +1 -0
- package/frontend/dist/assets/SettingsPage-DlK0Jcta.js +12 -0
- package/frontend/dist/assets/SettingsPage-DlK0Jcta.js.map +1 -0
- package/frontend/dist/assets/{StatusDot-DYO56shE.js → StatusDot-DgDU3plH.js} +2 -2
- package/frontend/dist/assets/{StatusDot-DYO56shE.js.map → StatusDot-DgDU3plH.js.map} +1 -1
- package/frontend/dist/assets/{ToggleGroup-r8yGt_Fq.js → ToggleGroup-11yhmcwY.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-r8yGt_Fq.js.map → ToggleGroup-11yhmcwY.js.map} +1 -1
- package/frontend/dist/assets/{UsersPage-B3muXE90.js → UsersPage-BqPEkoIX.js} +2 -2
- package/frontend/dist/assets/{UsersPage-B3muXE90.js.map → UsersPage-BqPEkoIX.js.map} +1 -1
- package/frontend/dist/assets/clipboard-BukcCPLt.js +2 -0
- package/frontend/dist/assets/clipboard-BukcCPLt.js.map +1 -0
- package/frontend/dist/assets/{icons-vendor-VW-UwEhw.js → icons-vendor-Bk5sng-h.js} +66 -61
- package/frontend/dist/assets/icons-vendor-Bk5sng-h.js.map +1 -0
- package/frontend/dist/assets/index-D4Vy78bV.css +1 -0
- package/frontend/dist/assets/index-DhzWX9nb.js +3 -0
- package/frontend/dist/assets/index-DhzWX9nb.js.map +1 -0
- package/frontend/dist/assets/{resourceService-CSXOSi7M.js → resourceService-D-PRt7tB.js} +2 -2
- package/frontend/dist/assets/{resourceService-CSXOSi7M.js.map → resourceService-D-PRt7tB.js.map} +1 -1
- package/frontend/dist/assets/{useCostData-BOxUFQAH.js → useCostData-B-uSfiuA.js} +2 -2
- package/frontend/dist/assets/{useCostData-BOxUFQAH.js.map → useCostData-B-uSfiuA.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-Bk1AwN5F.js +2 -0
- package/frontend/dist/assets/{useSettingsData-DmpLlRI6.js.map → useSettingsData-Bk1AwN5F.js.map} +1 -1
- package/frontend/dist/assets/variableDetection-B7Ko56CL.js +16 -0
- package/frontend/dist/assets/variableDetection-B7Ko56CL.js.map +1 -0
- package/frontend/dist/index.html +3 -3
- package/mcp_settings.json +2 -1
- package/package.json +2 -1
- package/frontend/dist/assets/Dashboard-gHeXLPEn.js +0 -2
- package/frontend/dist/assets/EndpointCopy-BRwX7Dpv.js +0 -2
- package/frontend/dist/assets/EndpointCopy-BRwX7Dpv.js.map +0 -1
- package/frontend/dist/assets/GroupsPage-grCAx55k.js +0 -33
- package/frontend/dist/assets/GroupsPage-grCAx55k.js.map +0 -1
- package/frontend/dist/assets/ServersPage-BlC0RdIu.js +0 -39
- package/frontend/dist/assets/ServersPage-BlC0RdIu.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-CiVNDyr_.js +0 -12
- package/frontend/dist/assets/SettingsPage-CiVNDyr_.js.map +0 -1
- package/frontend/dist/assets/icons-vendor-VW-UwEhw.js.map +0 -1
- package/frontend/dist/assets/index-B-aT0HW5.js +0 -3
- package/frontend/dist/assets/index-B-aT0HW5.js.map +0 -1
- package/frontend/dist/assets/index-B3OqAhGz.css +0 -1
- package/frontend/dist/assets/toolDescription-Dw3sa28K.js +0 -2
- package/frontend/dist/assets/toolDescription-Dw3sa28K.js.map +0 -1
- package/frontend/dist/assets/useSettingsData-DmpLlRI6.js +0 -2
- package/frontend/dist/assets/variableDetection-cmwwuSWB.js +0 -16
- package/frontend/dist/assets/variableDetection-cmwwuSWB.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthClient.js","sourceRoot":"","sources":["../../../src/db/entities/OAuthClient.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,MAAM,EACN,MAAM,EACN,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAW;
|
|
1
|
+
{"version":3,"file":"OAuthClient.js","sourceRoot":"","sources":["../../../src/db/entities/OAuthClient.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,MAAM,EACN,MAAM,EACN,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAW;CA+CvB,CAAA;AA7CC;IADC,sBAAsB,CAAC,MAAM,CAAC;;uCACpB;AAGX;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;;6CACzD;AAGjB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;iDAC1D;AAGtB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;yCAC5B;AAGb;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;;iDAChC;AAGvB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;;2CACf;AAGjB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2CAC9B;AAGlB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;0CAC1C;AAGf;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;qDAC3C;AAG1B;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;6CAY9C;AAGF;IADC,gBAAgB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;8BACjD,IAAI;8CAAC;AAGhB;IADC,gBAAgB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;8BACjD,IAAI;8CAAC;AA9CL,WAAW;IADvB,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;GACrB,WAAW,CA+CvB;;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -92,14 +92,37 @@ export class VectorEmbeddingRepository extends BaseRepository {
|
|
|
92
92
|
result.model = model;
|
|
93
93
|
return result;
|
|
94
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Build the `content_id` predicate that restricts a search to a set of
|
|
97
|
+
* servers. Embeddings are keyed by server: tools as `<serverName>:<toolName>`
|
|
98
|
+
* and the server-level row as `<serverName>`, so one predicate covers both
|
|
99
|
+
* content types. Returns undefined when no restriction applies.
|
|
100
|
+
*/
|
|
101
|
+
buildServerScopeFilter(serverNames) {
|
|
102
|
+
const names = serverNames.filter((name) => typeof name === 'string' && name.length > 0);
|
|
103
|
+
if (names.length === 0) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const parameters = { scopedServerNames: names };
|
|
107
|
+
const clauses = ['vector_embedding.content_id IN (:...scopedServerNames)'];
|
|
108
|
+
names.forEach((name, index) => {
|
|
109
|
+
const key = `scopedServerPrefix${index}`;
|
|
110
|
+
parameters[key] = `${escapeLikePattern(name)}:%`;
|
|
111
|
+
clauses.push(`vector_embedding.content_id LIKE :${key} ESCAPE '\\'`);
|
|
112
|
+
});
|
|
113
|
+
return { clause: `(${clauses.join(' OR ')})`, parameters };
|
|
114
|
+
}
|
|
95
115
|
/**
|
|
96
116
|
* Search for similar embeddings using cosine similarity
|
|
97
117
|
* @param embedding Vector embedding to search against
|
|
98
118
|
* @param limit Maximum number of results (default: 10)
|
|
99
119
|
* @param threshold Similarity threshold (default: 0.7)
|
|
100
120
|
* @param contentTypes Optional content types to filter by
|
|
121
|
+
* @param serverNames Optional server names to restrict the search to. Applied
|
|
122
|
+
* in SQL so that `limit` counts rows the caller can actually use.
|
|
101
123
|
*/
|
|
102
|
-
async searchSimilar(embedding, limit = 10, threshold = 0.7, contentTypes) {
|
|
124
|
+
async searchSimilar(embedding, limit = 10, threshold = 0.7, contentTypes, serverNames) {
|
|
125
|
+
const serverScope = serverNames ? this.buildServerScopeFilter(serverNames) : undefined;
|
|
103
126
|
try {
|
|
104
127
|
// Try using vector similarity operator first
|
|
105
128
|
try {
|
|
@@ -120,6 +143,10 @@ export class VectorEmbeddingRepository extends BaseRepository {
|
|
|
120
143
|
.andWhere('vector_embedding.content_type IN (:...contentTypes)')
|
|
121
144
|
.setParameter('contentTypes', contentTypes);
|
|
122
145
|
}
|
|
146
|
+
// Restrict to the requested servers before the limit is applied
|
|
147
|
+
if (serverScope) {
|
|
148
|
+
query = query.andWhere(serverScope.clause, serverScope.parameters);
|
|
149
|
+
}
|
|
123
150
|
// Execute query
|
|
124
151
|
const results = await query.getRawMany();
|
|
125
152
|
// Return results if successful
|
|
@@ -138,6 +165,10 @@ export class VectorEmbeddingRepository extends BaseRepository {
|
|
|
138
165
|
.where('vector_embedding.content_type IN (:...contentTypes)')
|
|
139
166
|
.setParameter('contentTypes', contentTypes);
|
|
140
167
|
}
|
|
168
|
+
// Restrict to the requested servers before the limit is applied
|
|
169
|
+
if (serverScope) {
|
|
170
|
+
query = query.andWhere(serverScope.clause, serverScope.parameters);
|
|
171
|
+
}
|
|
141
172
|
// Limit results
|
|
142
173
|
query = query.take(limit);
|
|
143
174
|
// Execute query
|
|
@@ -161,13 +192,14 @@ export class VectorEmbeddingRepository extends BaseRepository {
|
|
|
161
192
|
* @param limit Maximum number of results
|
|
162
193
|
* @param threshold Similarity threshold
|
|
163
194
|
* @param contentTypes Optional content types to filter by
|
|
195
|
+
* @param serverNames Optional server names to restrict the search to
|
|
164
196
|
*/
|
|
165
|
-
async searchByText(text, getEmbeddingFunc, limit = 10, threshold = 0.7, contentTypes) {
|
|
197
|
+
async searchByText(text, getEmbeddingFunc, limit = 10, threshold = 0.7, contentTypes, serverNames) {
|
|
166
198
|
try {
|
|
167
199
|
// Get embedding for the search text
|
|
168
200
|
const embedding = await getEmbeddingFunc(text);
|
|
169
201
|
// Search by embedding
|
|
170
|
-
return this.searchSimilar(embedding, limit, threshold, contentTypes);
|
|
202
|
+
return this.searchSimilar(embedding, limit, threshold, contentTypes, serverNames);
|
|
171
203
|
}
|
|
172
204
|
catch (error) {
|
|
173
205
|
logger.error('Error searching by text:', error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VectorEmbeddingRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/VectorEmbeddingRepository.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"VectorEmbeddingRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/VectorEmbeddingRepository.ts"],"names":[],"mappings":"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"}
|
package/dist/models/OAuth.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
|
-
import { getOAuthClientDao, getOAuthTokenDao } from '../dao/index.js';
|
|
2
|
+
import { getOAuthClientDao, getOAuthTokenDao, getSystemConfigDao } from '../dao/index.js';
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
// In-memory storage for authorization codes (short-lived, no persistence needed)
|
|
5
5
|
const authorizationCodes = new Map();
|
|
6
6
|
// In-memory cache for tokens (also persisted via DAO)
|
|
7
7
|
const tokensCache = new Map();
|
|
8
|
+
// In-memory registration access tokens (RFC 7591 §3.2). Expiry is enforced
|
|
9
|
+
// lazily on verification; cleanupExpired() sweeps entries that are never used
|
|
10
|
+
// again so expired tokens do not accumulate for the lifetime of the process.
|
|
11
|
+
const registrationTokens = new Map();
|
|
12
|
+
const REGISTRATION_TOKEN_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
13
|
+
// Default idle TTL for dynamically-registered clients (see oauthServerDefaults).
|
|
14
|
+
const DEFAULT_DYNAMIC_CLIENT_TTL_SECONDS = 30 * 24 * 60 * 60; // 30 days
|
|
8
15
|
// Flag to track if we've initialized from DAO
|
|
9
16
|
let initialized = false;
|
|
10
17
|
/**
|
|
@@ -71,6 +78,43 @@ export const deleteOAuthClient = async (clientId) => {
|
|
|
71
78
|
const clientDao = getOAuthClientDao();
|
|
72
79
|
return clientDao.delete(clientId);
|
|
73
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Generate a registration access token for a dynamically-registered client
|
|
83
|
+
* (RFC 7591 §3.2). The token is stored in memory and expires after `ttlMs`.
|
|
84
|
+
*/
|
|
85
|
+
export const createRegistrationToken = (clientId, ttlMs = REGISTRATION_TOKEN_TTL_MS) => {
|
|
86
|
+
const token = crypto.randomBytes(32).toString('hex');
|
|
87
|
+
registrationTokens.set(token, {
|
|
88
|
+
clientId,
|
|
89
|
+
expiresAt: new Date(Date.now() + ttlMs),
|
|
90
|
+
});
|
|
91
|
+
return token;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Verify a registration access token. Returns the client ID it was issued to,
|
|
95
|
+
* or null if the token is unknown or expired (expired tokens are removed).
|
|
96
|
+
*/
|
|
97
|
+
export const verifyRegistrationToken = (token) => {
|
|
98
|
+
const data = registrationTokens.get(token);
|
|
99
|
+
if (!data) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
if (new Date() > data.expiresAt) {
|
|
103
|
+
registrationTokens.delete(token);
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return data.clientId;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Delete a registration access token (e.g. when the client registration is deleted)
|
|
110
|
+
*/
|
|
111
|
+
export const deleteRegistrationToken = (token) => {
|
|
112
|
+
registrationTokens.delete(token);
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Number of registration access tokens currently held in memory (for diagnostics/tests)
|
|
116
|
+
*/
|
|
117
|
+
export const countRegistrationTokens = () => registrationTokens.size;
|
|
74
118
|
/**
|
|
75
119
|
* Generate a secure random token
|
|
76
120
|
*/
|
|
@@ -238,6 +282,59 @@ export const cleanupExpired = async () => {
|
|
|
238
282
|
catch (error) {
|
|
239
283
|
logger.error('Failed to cleanup persisted OAuth tokens:', error);
|
|
240
284
|
}
|
|
285
|
+
// Sweep expired registration access tokens that were never verified again
|
|
286
|
+
for (const [token, data] of registrationTokens.entries()) {
|
|
287
|
+
if (data.expiresAt < now) {
|
|
288
|
+
registrationTokens.delete(token);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
await cleanupIdleDynamicClients(now);
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Reap dynamically-registered OAuth clients that are idle: older than the
|
|
295
|
+
* configured `oauthServer.dynamicRegistration.clientTtl` with no live token and
|
|
296
|
+
* no in-progress authorization flow. Reclaimed clients must register again.
|
|
297
|
+
* Legacy records without `clientIdIssuedAt` are never treated as expired.
|
|
298
|
+
* A `clientTtl` of 0 disables cleanup entirely.
|
|
299
|
+
*/
|
|
300
|
+
const cleanupIdleDynamicClients = async (now) => {
|
|
301
|
+
try {
|
|
302
|
+
// Client IDs that are still in use: they have a live token or an unexpired
|
|
303
|
+
// authorization code (an in-progress authorization flow).
|
|
304
|
+
const liveClientIds = new Set();
|
|
305
|
+
for (const [, authCode] of authorizationCodes.entries()) {
|
|
306
|
+
liveClientIds.add(authCode.clientId);
|
|
307
|
+
}
|
|
308
|
+
for (const [, token] of tokensCache.entries()) {
|
|
309
|
+
liveClientIds.add(token.clientId);
|
|
310
|
+
}
|
|
311
|
+
const persistedTokens = await getOAuthTokenDao().findAll();
|
|
312
|
+
for (const token of persistedTokens) {
|
|
313
|
+
liveClientIds.add(token.clientId);
|
|
314
|
+
}
|
|
315
|
+
// Read the configured idle-client TTL. 0 disables cleanup entirely.
|
|
316
|
+
const systemConfig = await getSystemConfigDao().get();
|
|
317
|
+
const clientTtl = systemConfig?.oauthServer?.dynamicRegistration?.clientTtl;
|
|
318
|
+
if (clientTtl !== undefined && clientTtl <= 0) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const ttlSeconds = clientTtl ?? DEFAULT_DYNAMIC_CLIENT_TTL_SECONDS;
|
|
322
|
+
const clientDao = getOAuthClientDao();
|
|
323
|
+
const dynamicClients = await clientDao.findByOwner('dynamic-registration');
|
|
324
|
+
const cutoff = Math.floor(now.getTime() / 1000) - ttlSeconds;
|
|
325
|
+
const stale = dynamicClients.filter((client) => typeof client.clientIdIssuedAt === 'number' &&
|
|
326
|
+
client.clientIdIssuedAt < cutoff &&
|
|
327
|
+
!liveClientIds.has(client.clientId));
|
|
328
|
+
for (const client of stale) {
|
|
329
|
+
await clientDao.delete(client.clientId);
|
|
330
|
+
}
|
|
331
|
+
if (stale.length > 0) {
|
|
332
|
+
logger.log(`Reaped ${stale.length} idle dynamically-registered OAuth client(s)`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
logger.error('Failed to cleanup idle dynamically-registered OAuth clients:', error);
|
|
337
|
+
}
|
|
241
338
|
};
|
|
242
339
|
// Run cleanup every 5 minutes in production
|
|
243
340
|
let cleanupIntervalId = null;
|
package/dist/models/OAuth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuth.js","sourceRoot":"","sources":["../../src/models/OAuth.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OAuth.js","sourceRoot":"","sources":["../../src/models/OAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,7 +40,8 @@ import { assertHostedToolAllowed, filterHostedTools, reserveHostedToolCall, sett
|
|
|
40
40
|
import { formatErrorForLogging, sanitizeStringForLogging, summarizeErrorForLogging, } from '../utils/serialization.js';
|
|
41
41
|
import { addStdioErrorContext, observeStdioStderr } from '../utils/stdioDiagnostics.js';
|
|
42
42
|
import { MCP_APPS_CAPABILITIES, filterModelVisibleTools, hasMcpAppsCapability, isAppOnlyTool, stripMcpAppsMetadata, } from '../utils/mcpApps.js';
|
|
43
|
-
import { supportsCacheRefresh, injectRefreshFlag, clearRunnerCache } from '../utils/cacheUtils.js';
|
|
43
|
+
import { supportsCacheRefresh, injectRefreshFlag, clearRunnerCache, resolveRunnerPackageVersion } from '../utils/cacheUtils.js';
|
|
44
|
+
import { checkPackageUpdate } from '../utils/packageUpdate.js';
|
|
44
45
|
const servers = {};
|
|
45
46
|
import { setupClientKeepAlive } from './keepAliveService.js';
|
|
46
47
|
import { logger } from '../utils/logger.js';
|
|
@@ -525,6 +526,82 @@ const normalizeResourceForCache = (resource) => {
|
|
|
525
526
|
};
|
|
526
527
|
// Store all server information
|
|
527
528
|
let serverInfos = [];
|
|
529
|
+
/**
|
|
530
|
+
* How many upstream connections an initialization pass may open at once.
|
|
531
|
+
* Unset, empty or `0` keeps the previous behaviour of connecting every enabled
|
|
532
|
+
* server in parallel. Read per pass so a restart is enough to change it.
|
|
533
|
+
*/
|
|
534
|
+
const resolveStartupConcurrency = () => {
|
|
535
|
+
const raw = process.env.STARTUP_CONNECT_CONCURRENCY?.trim();
|
|
536
|
+
if (!raw) {
|
|
537
|
+
return 0;
|
|
538
|
+
}
|
|
539
|
+
const parsed = Number(raw);
|
|
540
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
541
|
+
logger.warn(`Ignoring invalid STARTUP_CONNECT_CONCURRENCY="${raw}"; expected a non-negative integer. Connecting without a limit.`);
|
|
542
|
+
return 0;
|
|
543
|
+
}
|
|
544
|
+
return parsed;
|
|
545
|
+
};
|
|
546
|
+
/**
|
|
547
|
+
* Rejection reason for a queued connection that was dropped before it started,
|
|
548
|
+
* because the server it belonged to was disabled, removed or superseded while
|
|
549
|
+
* it waited for a slot. Not a connection failure: nothing was spawned and there
|
|
550
|
+
* is nothing wrong with the server, so callers report it as a cancellation
|
|
551
|
+
* rather than marking the server as failed.
|
|
552
|
+
*/
|
|
553
|
+
class QueuedConnectCancelledError extends Error {
|
|
554
|
+
constructor() {
|
|
555
|
+
super('Queued connection was cancelled before it started');
|
|
556
|
+
this.name = 'QueuedConnectCancelledError';
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Defers the *invocation* of a connect rather than wrapping its promise, so a
|
|
561
|
+
* server waiting for a slot has not started its request yet and its timeout
|
|
562
|
+
* budget is not spent queueing. A limit of 0 runs everything immediately.
|
|
563
|
+
*
|
|
564
|
+
* Because work waits here, what the operator wants can change while it waits -
|
|
565
|
+
* a queued server may be disabled, removed or replaced by a later pass. The
|
|
566
|
+
* `isStillWanted` guard is therefore evaluated when the slot is granted, not
|
|
567
|
+
* when the work is queued; a queued entry that is no longer wanted is cancelled
|
|
568
|
+
* and its slot handed straight to the next in line.
|
|
569
|
+
*/
|
|
570
|
+
const createConnectGate = (limit) => {
|
|
571
|
+
if (limit <= 0) {
|
|
572
|
+
// Nothing queues, so nothing can go stale while it waits.
|
|
573
|
+
return { run: (start) => start() };
|
|
574
|
+
}
|
|
575
|
+
let active = 0;
|
|
576
|
+
const waiting = [];
|
|
577
|
+
const startNextWaiting = () => {
|
|
578
|
+
waiting.shift()?.();
|
|
579
|
+
};
|
|
580
|
+
const release = () => {
|
|
581
|
+
active -= 1;
|
|
582
|
+
startNextWaiting();
|
|
583
|
+
};
|
|
584
|
+
return {
|
|
585
|
+
run: (start, isStillWanted) => new Promise((resolve, reject) => {
|
|
586
|
+
const begin = () => {
|
|
587
|
+
if (isStillWanted && !isStillWanted()) {
|
|
588
|
+
// The slot was never taken, so pass it on rather than release it.
|
|
589
|
+
reject(new QueuedConnectCancelledError());
|
|
590
|
+
startNextWaiting();
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
active += 1;
|
|
594
|
+
start().then(resolve, reject).finally(release);
|
|
595
|
+
};
|
|
596
|
+
if (active < limit) {
|
|
597
|
+
begin();
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
waiting.push(begin);
|
|
601
|
+
}
|
|
602
|
+
}),
|
|
603
|
+
};
|
|
604
|
+
};
|
|
528
605
|
// Bumped by every initializeClientsFromSettings pass. Connections are started
|
|
529
606
|
// fire-and-forget and settle long after the pass that started them returned, so
|
|
530
607
|
// a callback needs to know whether a later pass has run before it writes its
|
|
@@ -678,6 +755,7 @@ export const connected = () => {
|
|
|
678
755
|
};
|
|
679
756
|
// Global cleanup function to close all connections
|
|
680
757
|
export const cleanupAllServers = () => {
|
|
758
|
+
stopPackageUpdateSweep();
|
|
681
759
|
principalRuntimes.invalidate();
|
|
682
760
|
for (const serverInfo of serverInfos) {
|
|
683
761
|
try {
|
|
@@ -1206,6 +1284,15 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
|
|
|
1206
1284
|
const existingServerInfos = serverInfos;
|
|
1207
1285
|
const nextServerInfos = [];
|
|
1208
1286
|
const generation = ++initGeneration;
|
|
1287
|
+
const concurrency = resolveStartupConcurrency();
|
|
1288
|
+
const connectGate = createConnectGate(concurrency);
|
|
1289
|
+
// Set once this pass swaps its entries into `serverInfos`. Until then a
|
|
1290
|
+
// queued server cannot have been retired by anyone, because the entry that
|
|
1291
|
+
// `closeServer`/`toggleServerStatus` would act on is not published yet.
|
|
1292
|
+
let entriesPublished = false;
|
|
1293
|
+
if (isInit && concurrency > 0) {
|
|
1294
|
+
logger.log(`Connecting upstream servers with a concurrency limit of ${concurrency}`);
|
|
1295
|
+
}
|
|
1209
1296
|
try {
|
|
1210
1297
|
for (const conf of allServers) {
|
|
1211
1298
|
const { name } = conf;
|
|
@@ -1500,7 +1587,33 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
|
|
|
1500
1587
|
const current = serverInfos.find((si) => si.name === name);
|
|
1501
1588
|
return current && current.client === client ? current : undefined;
|
|
1502
1589
|
};
|
|
1503
|
-
|
|
1590
|
+
// A queued connection has not spawned anything yet, so cancelling it is
|
|
1591
|
+
// free - and necessary: `closeServerRuntime` clears the client/transport
|
|
1592
|
+
// references that would later own the child process, so connecting after
|
|
1593
|
+
// a disable strands a process nothing can clean up.
|
|
1594
|
+
const connectStillWanted = () => {
|
|
1595
|
+
// Until this pass publishes its entries, nothing else can have retired
|
|
1596
|
+
// this server: the entry a disable would act on does not exist yet.
|
|
1597
|
+
if (!entriesPublished)
|
|
1598
|
+
return true;
|
|
1599
|
+
const current = serverInfos.find((si) => si.name === name);
|
|
1600
|
+
// Gone from the configuration while it waited.
|
|
1601
|
+
if (!current)
|
|
1602
|
+
return false;
|
|
1603
|
+
// Client identity, not the generation, decides whether anyone is still
|
|
1604
|
+
// waiting on this connect - the same rule liveServerInfo() applies to
|
|
1605
|
+
// the result. A later pass that *preserved* this server spreads our
|
|
1606
|
+
// client into its entry and relies on this very connect to complete it
|
|
1607
|
+
// (a scoped reload preserves every other server whatever its status,
|
|
1608
|
+
// see #921), so cancelling on generation alone would strand it on
|
|
1609
|
+
// 'connecting' for good - the failure #1150 was about. A later pass
|
|
1610
|
+
// that rebuilt the server carries a client of its own, and disabling
|
|
1611
|
+
// closes the runtime before replacing the entry, so in both of those
|
|
1612
|
+
// cases the published entry no longer carries our client.
|
|
1613
|
+
return current.client === client && current.enabled !== false;
|
|
1614
|
+
};
|
|
1615
|
+
connectGate
|
|
1616
|
+
.run(() => connectClientWithDiagnostics(client, transport, initRequestOptions || requestOptions), connectStillWanted)
|
|
1504
1617
|
.then(() => {
|
|
1505
1618
|
const info = liveServerInfo();
|
|
1506
1619
|
if (!info) {
|
|
@@ -1514,6 +1627,8 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
|
|
|
1514
1627
|
const serverVersion = client.getServerVersion?.();
|
|
1515
1628
|
info.version = serverVersion?.version;
|
|
1516
1629
|
info.instructions = client.getInstructions?.();
|
|
1630
|
+
// Record the resolved npx/uvx package version backing this server.
|
|
1631
|
+
applyResolvedPackageVersion(info, expandedConf);
|
|
1517
1632
|
const capabilities = client.getServerCapabilities();
|
|
1518
1633
|
logger.log('Server capabilities', JSON.stringify(capabilities));
|
|
1519
1634
|
let dataError = null;
|
|
@@ -1593,6 +1708,11 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
|
|
|
1593
1708
|
}
|
|
1594
1709
|
})
|
|
1595
1710
|
.catch(async (error) => {
|
|
1711
|
+
if (error instanceof QueuedConnectCancelledError) {
|
|
1712
|
+
logger.log(`Cancelled queued connection for server: ${name} (disabled, removed or superseded while queued)`);
|
|
1713
|
+
closeServerRuntime(serverInfo);
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1596
1716
|
const info = liveServerInfo();
|
|
1597
1717
|
if (!info) {
|
|
1598
1718
|
logger.log(`Discarding superseded connection failure for server: ${name}`);
|
|
@@ -1632,10 +1752,11 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
|
|
|
1632
1752
|
throw error;
|
|
1633
1753
|
}
|
|
1634
1754
|
serverInfos = nextServerInfos;
|
|
1755
|
+
entriesPublished = true;
|
|
1635
1756
|
// Populate the tool cache for on-demand stdio servers so their tools are
|
|
1636
1757
|
// visible to agents, then put them back to sleep. Running here (rather than
|
|
1637
1758
|
// only at startup) also covers servers added/enabled/reloaded after startup.
|
|
1638
|
-
const primePromise = primeOnDemandServers();
|
|
1759
|
+
const primePromise = primeOnDemandServers(connectGate);
|
|
1639
1760
|
// At full startup (no serverName) keep prime fire-and-forget so a slow or
|
|
1640
1761
|
// broken on-demand server does not block init. For a targeted reload/edit
|
|
1641
1762
|
// (serverName set), await it so the caller - and the dashboard refresh that
|
|
@@ -1730,7 +1851,7 @@ export const getServersInfo = async (page, limit, user) => {
|
|
|
1730
1851
|
}));
|
|
1731
1852
|
const infos = presentedInfos
|
|
1732
1853
|
.filter((info) => requestedServerNames.has(info.name)) // Only include requested servers
|
|
1733
|
-
.map(({ name, version, instructions, owner, visibility, status, tools, prompts, resources, createTime, error, oauth, }) => {
|
|
1854
|
+
.map(({ name, version, packageVersion, latestVersion, updateAvailable, instructions, owner, visibility, status, tools, prompts, resources, createTime, error, oauth, }) => {
|
|
1734
1855
|
const serverConfig = allServers.find((server) => server.name === name);
|
|
1735
1856
|
const enabled = serverConfig ? serverConfig.enabled !== false : true;
|
|
1736
1857
|
const resolvedType = inferServerType(serverConfig);
|
|
@@ -1774,6 +1895,12 @@ export const getServersInfo = async (page, limit, user) => {
|
|
|
1774
1895
|
resources: resourcesWithEnabled,
|
|
1775
1896
|
createTime,
|
|
1776
1897
|
enabled,
|
|
1898
|
+
// Resolved npx/uvx package version + registry update hint (#1166).
|
|
1899
|
+
// Runtime state, kept at the top level like `version` so it can never
|
|
1900
|
+
// be round-tripped into a persisted ServerConfig.
|
|
1901
|
+
...(packageVersion ? { packageVersion } : {}),
|
|
1902
|
+
...(latestVersion ? { latestVersion } : {}),
|
|
1903
|
+
...(updateAvailable !== undefined ? { updateAvailable } : {}),
|
|
1777
1904
|
oauth: oauth || oauthConnected
|
|
1778
1905
|
? {
|
|
1779
1906
|
...(oauth
|
|
@@ -1852,6 +1979,75 @@ export const reconnectServer = async (serverName) => {
|
|
|
1852
1979
|
await initializeClientsFromSettings(false, serverName);
|
|
1853
1980
|
logger.log(`Successfully reconnected server: ${serverName}`);
|
|
1854
1981
|
};
|
|
1982
|
+
/**
|
|
1983
|
+
* Resolve the installed package version for an npx/uvx stdio server and record
|
|
1984
|
+
* it on the live ServerInfo, so the dashboard can answer "what version is
|
|
1985
|
+
* actually running" (see #1166). Also checks the configured registry for a
|
|
1986
|
+
* newer version and marks updateAvailable. Fire-and-forget: best-effort
|
|
1987
|
+
* display data — a resolution failure must never break or delay a connection.
|
|
1988
|
+
*
|
|
1989
|
+
* On any failure the runtime fields are cleared so the UI never shows a stale
|
|
1990
|
+
* version or a stale "update available" hint from an earlier, healthier check.
|
|
1991
|
+
*/
|
|
1992
|
+
const applyResolvedPackageVersion = (info, config) => {
|
|
1993
|
+
const command = config?.command;
|
|
1994
|
+
if (!command || !supportsCacheRefresh(command))
|
|
1995
|
+
return;
|
|
1996
|
+
void (async () => {
|
|
1997
|
+
try {
|
|
1998
|
+
const args = config.args ?? [];
|
|
1999
|
+
const version = await resolveRunnerPackageVersion(command, args);
|
|
2000
|
+
if (!version) {
|
|
2001
|
+
info.packageVersion = undefined;
|
|
2002
|
+
info.latestVersion = undefined;
|
|
2003
|
+
info.updateAvailable = undefined;
|
|
2004
|
+
return;
|
|
2005
|
+
}
|
|
2006
|
+
info.packageVersion = version;
|
|
2007
|
+
const systemConfig = await getSystemConfigDao().get();
|
|
2008
|
+
const update = await checkPackageUpdate(command, args, version, {
|
|
2009
|
+
npmRegistry: systemConfig?.install?.npmRegistry,
|
|
2010
|
+
pythonIndexUrl: systemConfig?.install?.pythonIndexUrl,
|
|
2011
|
+
});
|
|
2012
|
+
if (update?.latestVersion) {
|
|
2013
|
+
info.latestVersion = update.latestVersion;
|
|
2014
|
+
info.updateAvailable = update.updateAvailable;
|
|
2015
|
+
}
|
|
2016
|
+
else {
|
|
2017
|
+
// Registry unreachable or no metadata: hide the hint rather than keep
|
|
2018
|
+
// a stale "update available" from a previous successful check.
|
|
2019
|
+
info.latestVersion = undefined;
|
|
2020
|
+
info.updateAvailable = undefined;
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
catch (error) {
|
|
2024
|
+
logger.warn(`Failed to resolve package update for ${info.name}`, { error });
|
|
2025
|
+
info.latestVersion = undefined;
|
|
2026
|
+
info.updateAvailable = undefined;
|
|
2027
|
+
}
|
|
2028
|
+
})();
|
|
2029
|
+
};
|
|
2030
|
+
// Periodically refresh the "update available" flag for npx/uvx servers (#1166).
|
|
2031
|
+
// Each check respects the TTL cache inside checkPackageUpdate, so this only
|
|
2032
|
+
// re-queries packages whose last registry lookup has gone stale. The timer is
|
|
2033
|
+
// unref'd so it never keeps the process alive by itself.
|
|
2034
|
+
//
|
|
2035
|
+
// Note: personal-runtime servers (credential-template bindings) are not part of
|
|
2036
|
+
// `serverInfos` and are therefore not swept here — their flags refresh when a
|
|
2037
|
+
// new per-user connection is created in createPrincipalRuntime instead.
|
|
2038
|
+
const PACKAGE_UPDATE_SWEEP_MS = 6 * 60 * 60 * 1000;
|
|
2039
|
+
const packageUpdateSweepTimer = setInterval(() => {
|
|
2040
|
+
for (const info of serverInfos) {
|
|
2041
|
+
if (!info.config?.command)
|
|
2042
|
+
continue;
|
|
2043
|
+
applyResolvedPackageVersion(info, info.config);
|
|
2044
|
+
}
|
|
2045
|
+
}, PACKAGE_UPDATE_SWEEP_MS);
|
|
2046
|
+
packageUpdateSweepTimer.unref?.();
|
|
2047
|
+
/** Stop the periodic package-update sweep (called on shutdown). */
|
|
2048
|
+
export const stopPackageUpdateSweep = () => {
|
|
2049
|
+
clearInterval(packageUpdateSweepTimer);
|
|
2050
|
+
};
|
|
1855
2051
|
// Reinstall server: clear package cache and reconnect.
|
|
1856
2052
|
// For npx: deletes ~/.npm/_npx before reconnect (--ignore-existing removed in npm 7+).
|
|
1857
2053
|
// For uvx: schedules --refresh flag injection on next spawn via pendingReinstalls Set.
|
|
@@ -1877,7 +2073,9 @@ export const reinstallServer = async (serverName) => {
|
|
|
1877
2073
|
try {
|
|
1878
2074
|
// For npx, clear cache directory synchronously before reconnect.
|
|
1879
2075
|
// For uvx, this is a no-op — refresh is handled via --refresh flag injection.
|
|
1880
|
-
|
|
2076
|
+
// Pass the server's own arguments so the npx clear can be scoped to this
|
|
2077
|
+
// server's package instead of discarding every npx server's install.
|
|
2078
|
+
await clearRunnerCache(command, serverConfig.args || []);
|
|
1881
2079
|
// Close and reconnect (will pick up pendingReinstalls flag for uvx)
|
|
1882
2080
|
await reconnectServer(serverName);
|
|
1883
2081
|
logger.log(`Successfully initiated reinstall for server: ${serverName}`);
|
|
@@ -2184,6 +2382,8 @@ const ensureServerReady = async (serverInfo) => {
|
|
|
2184
2382
|
serverInfo.version = client.getServerVersion?.()?.version;
|
|
2185
2383
|
serverInfo.instructions = client.getInstructions?.();
|
|
2186
2384
|
serverInfo.config = expandedConf;
|
|
2385
|
+
// Record the resolved npx/uvx package version backing this server.
|
|
2386
|
+
applyResolvedPackageVersion(serverInfo, expandedConf);
|
|
2187
2387
|
serverInfo.status = 'connected';
|
|
2188
2388
|
serverInfo.error = null;
|
|
2189
2389
|
let toolCount = 0;
|
|
@@ -2261,7 +2461,7 @@ const isStdioServer = (conf) => !!conf && (conf.type === 'stdio' || (!conf.type
|
|
|
2261
2461
|
* does not block init. Each server is isolated so one failure does not affect
|
|
2262
2462
|
* the others. See #1029 / #1032.
|
|
2263
2463
|
*/
|
|
2264
|
-
const primeOnDemandServers = () => {
|
|
2464
|
+
const primeOnDemandServers = (gate) => {
|
|
2265
2465
|
const targets = serverInfos.filter((si) => si.config?.startOnDemand === true &&
|
|
2266
2466
|
!hasCredentialTemplate(si.config) &&
|
|
2267
2467
|
isStdioServer(si.config) &&
|
|
@@ -2270,9 +2470,13 @@ const primeOnDemandServers = () => {
|
|
|
2270
2470
|
if (targets.length === 0)
|
|
2271
2471
|
return Promise.resolve();
|
|
2272
2472
|
logger.log(`Priming ${targets.length} on-demand server(s) for tool discovery…`);
|
|
2473
|
+
// Priming happens right after init, so it competes for the same machine.
|
|
2474
|
+
// Share the pass's concurrency limit rather than waking every sleeping server
|
|
2475
|
+
// at once and undoing the pacing above.
|
|
2476
|
+
const run = gate ? gate.run : (start) => start();
|
|
2273
2477
|
return Promise.allSettled(targets.map(async (si) => {
|
|
2274
2478
|
try {
|
|
2275
|
-
await ensureServerReady(si);
|
|
2479
|
+
await run(() => ensureServerReady(si));
|
|
2276
2480
|
// Sleep the child unless a tool call is using it; keep the cached tool list.
|
|
2277
2481
|
shutdownOnDemandServer(si);
|
|
2278
2482
|
logger.log('On-demand server tool cache primed');
|
|
@@ -3483,6 +3687,8 @@ const createPrincipalRuntime = async (name, resolvedConfig) => {
|
|
|
3483
3687
|
if (capabilities?.resources)
|
|
3484
3688
|
info.resources = (await client.listResources({}, resolvedConfig.options)).resources.map(normalizeResourceForCache);
|
|
3485
3689
|
info.version = client.getServerVersion()?.version;
|
|
3690
|
+
// Record the resolved npx/uvx package version backing this server.
|
|
3691
|
+
applyResolvedPackageVersion(info, resolvedConfig);
|
|
3486
3692
|
client.onclose = () => {
|
|
3487
3693
|
info.status = 'disconnected';
|
|
3488
3694
|
};
|