@samanhappy/mcphub 1.0.5 → 1.0.6

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.
Files changed (89) hide show
  1. package/dist/betterAuth.js +2 -2
  2. package/dist/betterAuth.js.map +1 -1
  3. package/dist/clients/openapi.js +98 -5
  4. package/dist/clients/openapi.js.map +1 -1
  5. package/dist/controllers/hostedInternalController.js +55 -0
  6. package/dist/controllers/hostedInternalController.js.map +1 -0
  7. package/dist/controllers/serverController.js +1 -1
  8. package/dist/controllers/serverController.js.map +1 -1
  9. package/dist/dao/ServerDao.js +24 -0
  10. package/dist/dao/ServerDao.js.map +1 -1
  11. package/dist/dao/ServerDaoDbImpl.js +11 -0
  12. package/dist/dao/ServerDaoDbImpl.js.map +1 -1
  13. package/dist/db/repositories/ServerRepository.js +16 -0
  14. package/dist/db/repositories/ServerRepository.js.map +1 -1
  15. package/dist/index.js +8 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/routes/index.js +5 -1
  18. package/dist/routes/index.js.map +1 -1
  19. package/dist/services/betterAuthConfig.js +144 -33
  20. package/dist/services/betterAuthConfig.js.map +1 -1
  21. package/dist/services/hostedAuthService.js +314 -0
  22. package/dist/services/hostedAuthService.js.map +1 -0
  23. package/dist/services/hostedControlPlaneClient.js +90 -0
  24. package/dist/services/hostedControlPlaneClient.js.map +1 -0
  25. package/dist/services/hostedEventSubscriber.js +206 -0
  26. package/dist/services/hostedEventSubscriber.js.map +1 -0
  27. package/dist/services/hostedInternalAuth.js +108 -0
  28. package/dist/services/hostedInternalAuth.js.map +1 -0
  29. package/dist/services/hostedMode.js +4 -0
  30. package/dist/services/hostedMode.js.map +1 -0
  31. package/dist/services/hostedNodeIdentity.js +8 -0
  32. package/dist/services/hostedNodeIdentity.js.map +1 -0
  33. package/dist/services/hostedRuntimeCatalogNames.js +7 -0
  34. package/dist/services/hostedRuntimeCatalogNames.js.map +1 -0
  35. package/dist/services/hostedRuntimeCatalogService.js +31 -0
  36. package/dist/services/hostedRuntimeCatalogService.js.map +1 -0
  37. package/dist/services/mcpService.js +84 -10
  38. package/dist/services/mcpService.js.map +1 -1
  39. package/dist/services/requestContextService.js +12 -0
  40. package/dist/services/requestContextService.js.map +1 -1
  41. package/dist/services/sseService.js +61 -10
  42. package/dist/services/sseService.js.map +1 -1
  43. package/dist/utils/rateLimit.js +4 -0
  44. package/dist/utils/rateLimit.js.map +1 -1
  45. package/frontend/dist/assets/{ActivityPage-Ccbl6DLW.js → ActivityPage-CLXufyzU.js} +2 -2
  46. package/frontend/dist/assets/{ActivityPage-Ccbl6DLW.js.map → ActivityPage-CLXufyzU.js.map} +1 -1
  47. package/frontend/dist/assets/{Dashboard-CPkAALtS.js → Dashboard-YMaaIlIZ.js} +2 -2
  48. package/frontend/dist/assets/{Dashboard-CPkAALtS.js.map → Dashboard-YMaaIlIZ.js.map} +1 -1
  49. package/frontend/dist/assets/{EndpointCopy-BYHUhlpW.js → EndpointCopy-Cpc2WqQz.js} +2 -2
  50. package/frontend/dist/assets/{EndpointCopy-BYHUhlpW.js.map → EndpointCopy-Cpc2WqQz.js.map} +1 -1
  51. package/frontend/dist/assets/{GroupsPage-CJI35G25.js → GroupsPage-DqK5U5rY.js} +2 -2
  52. package/frontend/dist/assets/{GroupsPage-CJI35G25.js.map → GroupsPage-DqK5U5rY.js.map} +1 -1
  53. package/frontend/dist/assets/{LoginPage-BZ0WR09v.js → LoginPage-ByV35kun.js} +2 -2
  54. package/frontend/dist/assets/{LoginPage-BZ0WR09v.js.map → LoginPage-ByV35kun.js.map} +1 -1
  55. package/frontend/dist/assets/{LogsPage-C_U-xXX0.js → LogsPage-BygFVcaV.js} +2 -2
  56. package/frontend/dist/assets/{LogsPage-C_U-xXX0.js.map → LogsPage-BygFVcaV.js.map} +1 -1
  57. package/frontend/dist/assets/{MarketPage-dyC4ocP6.js → MarketPage-Cc7QeqSw.js} +2 -2
  58. package/frontend/dist/assets/{MarketPage-dyC4ocP6.js.map → MarketPage-Cc7QeqSw.js.map} +1 -1
  59. package/frontend/dist/assets/{PromptsPage-gNHl5xn5.js → PromptsPage-DvLm5TW4.js} +2 -2
  60. package/frontend/dist/assets/{PromptsPage-gNHl5xn5.js.map → PromptsPage-DvLm5TW4.js.map} +1 -1
  61. package/frontend/dist/assets/{ResourcesPage-DvgjlTqh.js → ResourcesPage-Dnn1u2fr.js} +2 -2
  62. package/frontend/dist/assets/{ResourcesPage-DvgjlTqh.js.map → ResourcesPage-Dnn1u2fr.js.map} +1 -1
  63. package/frontend/dist/assets/ServersPage-RQCARDfE.js +37 -0
  64. package/frontend/dist/assets/ServersPage-RQCARDfE.js.map +1 -0
  65. package/frontend/dist/assets/{SettingsPage-D66oC6py.js → SettingsPage-CF40R-50.js} +2 -2
  66. package/frontend/dist/assets/{SettingsPage-D66oC6py.js.map → SettingsPage-CF40R-50.js.map} +1 -1
  67. package/frontend/dist/assets/{StatusDot-C7XhRfMO.js → StatusDot-CkF9WMhU.js} +2 -2
  68. package/frontend/dist/assets/{StatusDot-C7XhRfMO.js.map → StatusDot-CkF9WMhU.js.map} +1 -1
  69. package/frontend/dist/assets/{ToggleGroup-_MiJO3n_.js → ToggleGroup-vRqJ9DIB.js} +2 -2
  70. package/frontend/dist/assets/{ToggleGroup-_MiJO3n_.js.map → ToggleGroup-vRqJ9DIB.js.map} +1 -1
  71. package/frontend/dist/assets/{UsersPage-COmrRpdL.js → UsersPage-DBN5qCeO.js} +2 -2
  72. package/frontend/dist/assets/{UsersPage-COmrRpdL.js.map → UsersPage-DBN5qCeO.js.map} +1 -1
  73. package/frontend/dist/assets/{index-D82vzW6B.js → index-C7dQApMG.js} +3 -3
  74. package/frontend/dist/assets/{index-D82vzW6B.js.map → index-C7dQApMG.js.map} +1 -1
  75. package/frontend/dist/assets/{resourceService-D-fKBZtF.js → resourceService-BgjWoJFK.js} +2 -2
  76. package/frontend/dist/assets/{resourceService-D-fKBZtF.js.map → resourceService-BgjWoJFK.js.map} +1 -1
  77. package/frontend/dist/assets/{useServerData-DgGTUuZ8.js → useServerData-CEGj5OU1.js} +2 -2
  78. package/frontend/dist/assets/{useServerData-DgGTUuZ8.js.map → useServerData-CEGj5OU1.js.map} +1 -1
  79. package/frontend/dist/assets/useSettingsData-C2-q9Okf.js +2 -0
  80. package/frontend/dist/assets/{useSettingsData-B3CTLIUT.js.map → useSettingsData-C2-q9Okf.js.map} +1 -1
  81. package/frontend/dist/assets/variableDetection-GTKqOf1F.js +16 -0
  82. package/frontend/dist/assets/variableDetection-GTKqOf1F.js.map +1 -0
  83. package/frontend/dist/index.html +1 -1
  84. package/package.json +2 -1
  85. package/frontend/dist/assets/ServersPage-CKuVFL3O.js +0 -37
  86. package/frontend/dist/assets/ServersPage-CKuVFL3O.js.map +0 -1
  87. package/frontend/dist/assets/useSettingsData-B3CTLIUT.js +0 -2
  88. package/frontend/dist/assets/variableDetection-DsYuiOB_.js +0 -16
  89. package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +0 -1
@@ -0,0 +1,108 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ const SIGNATURE_HEADER = 'x-internal-signature';
3
+ const TIMESTAMP_HEADER = 'x-internal-timestamp';
4
+ const REPLAY_WINDOW_MS = 5 * 60 * 1000;
5
+ const REDACTED_SIGNATURE_VALUE = '[REDACTED]';
6
+ const REDACTED_SIGNATURE_FIELDS = new Set(['apiKey', 'apiKeyId']);
7
+ export { SIGNATURE_HEADER, TIMESTAMP_HEADER, REPLAY_WINDOW_MS, REDACTED_SIGNATURE_VALUE };
8
+ function isPlainObject(value) {
9
+ return Object.prototype.toString.call(value) === '[object Object]';
10
+ }
11
+ function normalizeSignatureObject(value) {
12
+ const normalized = {};
13
+ for (const key of Object.keys(value).sort((left, right) => left.localeCompare(right))) {
14
+ if (REDACTED_SIGNATURE_FIELDS.has(key)) {
15
+ // Sensitive credential values must never be read during signature canonicalization.
16
+ normalized[key] = REDACTED_SIGNATURE_VALUE;
17
+ continue;
18
+ }
19
+ normalized[key] = normalizeSignatureBody(value[key]);
20
+ }
21
+ return normalized;
22
+ }
23
+ function normalizeSignatureBody(value) {
24
+ if (Buffer.isBuffer(value)) {
25
+ return normalizeSignatureBody(value.toString('utf8'));
26
+ }
27
+ if (typeof value === 'string') {
28
+ if (!value)
29
+ return '';
30
+ try {
31
+ return normalizeSignatureBody(JSON.parse(value));
32
+ }
33
+ catch {
34
+ return value;
35
+ }
36
+ }
37
+ if (Array.isArray(value)) {
38
+ return value.map((item) => normalizeSignatureBody(item));
39
+ }
40
+ if (isPlainObject(value)) {
41
+ return normalizeSignatureObject(value);
42
+ }
43
+ return value;
44
+ }
45
+ export function serializeInternalRequestBodyForSignature(body) {
46
+ if (body === undefined || body === null || body === '') {
47
+ return '';
48
+ }
49
+ return JSON.stringify(normalizeSignatureBody(body));
50
+ }
51
+ function getSecret() {
52
+ const secret = process.env.INTERNAL_API_SECRET;
53
+ if (!secret || secret.length < 32) {
54
+ throw new Error('INTERNAL_API_SECRET is not configured or is shorter than 32 chars');
55
+ }
56
+ return secret;
57
+ }
58
+ function payload(timestamp, method, path, body) {
59
+ return `${timestamp}.${method.toUpperCase()}.${path}.${body}`;
60
+ }
61
+ export function signInternalRequest(method, path, body) {
62
+ const timestamp = Date.now().toString();
63
+ const serializedBody = serializeInternalRequestBodyForSignature(body);
64
+ const signature = createHmac('sha256', getSecret())
65
+ .update(payload(timestamp, method, path, serializedBody))
66
+ .digest('hex');
67
+ return { timestamp, signature: `sha256=${signature}` };
68
+ }
69
+ export function verifyInternalSignature(opts) {
70
+ if (!opts.timestamp || !opts.signature) {
71
+ return { ok: false, reason: 'missing_signature_headers' };
72
+ }
73
+ const ts = Number(opts.timestamp);
74
+ if (!Number.isFinite(ts)) {
75
+ return { ok: false, reason: 'bad_timestamp' };
76
+ }
77
+ if (Math.abs(Date.now() - ts) > REPLAY_WINDOW_MS) {
78
+ return { ok: false, reason: 'stale_timestamp' };
79
+ }
80
+ let secret;
81
+ try {
82
+ secret = getSecret();
83
+ }
84
+ catch {
85
+ return { ok: false, reason: 'secret_not_configured' };
86
+ }
87
+ const expected = 'sha256=' +
88
+ createHmac('sha256', secret)
89
+ .update(payload(opts.timestamp, opts.method, opts.path, serializeInternalRequestBodyForSignature(opts.body)))
90
+ .digest('hex');
91
+ const actualBuffer = Buffer.from(opts.signature);
92
+ const expectedBuffer = Buffer.from(expected);
93
+ if (actualBuffer.length !== expectedBuffer.length ||
94
+ !timingSafeEqual(actualBuffer, expectedBuffer)) {
95
+ return { ok: false, reason: 'bad_signature' };
96
+ }
97
+ return { ok: true };
98
+ }
99
+ export function verifyInternalExpressRequest(req, body) {
100
+ return verifyInternalSignature({
101
+ method: req.method,
102
+ path: req.path,
103
+ body,
104
+ timestamp: req.header(TIMESTAMP_HEADER),
105
+ signature: req.header(SIGNATURE_HEADER),
106
+ });
107
+ }
108
+ //# sourceMappingURL=hostedInternalAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedInternalAuth.js","sourceRoot":"","sources":["../../src/services/hostedInternalAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export function isHostedModeEnabled() {
2
+ return process.env.HUB_MODE === 'hosted';
3
+ }
4
+ //# sourceMappingURL=hostedMode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedMode.js","sourceRoot":"","sources":["../../src/services/hostedMode.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,8 @@
1
+ import os from 'node:os';
2
+ export function getHostedNodeIdentity() {
3
+ return {
4
+ clusterId: process.env.HUB_CLUSTER_ID || undefined,
5
+ nodeId: process.env.HUB_NODE_ID || os.hostname(),
6
+ };
7
+ }
8
+ //# sourceMappingURL=hostedNodeIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedNodeIdentity.js","sourceRoot":"","sources":["../../src/services/hostedNodeIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAOzB,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,SAAS;QAClD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,QAAQ,EAAE;KACjD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export function stripRuntimeToolName(serverSlug, publicToolName, nameSeparator) {
2
+ const prefix = `${serverSlug}${nameSeparator}`;
3
+ return publicToolName.startsWith(prefix)
4
+ ? publicToolName.slice(prefix.length)
5
+ : publicToolName;
6
+ }
7
+ //# sourceMappingURL=hostedRuntimeCatalogNames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedRuntimeCatalogNames.js","sourceRoot":"","sources":["../../src/services/hostedRuntimeCatalogNames.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAClC,UAAkB,EAClB,cAAsB,EACtB,aAAqB;IAErB,MAAM,MAAM,GAAG,GAAG,UAAU,GAAG,aAAa,EAAE,CAAC;IAC/C,OAAO,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC;QACtC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;QACrC,CAAC,CAAC,cAAc,CAAC;AACrB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { getNameSeparator } from '../config/index.js';
2
+ import { getServersInfo } from './mcpService.js';
3
+ import { getHostedNodeIdentity } from './hostedNodeIdentity.js';
4
+ import { stripRuntimeToolName } from './hostedRuntimeCatalogNames.js';
5
+ export async function getHostedRuntimeCatalog() {
6
+ const identity = getHostedNodeIdentity();
7
+ const nameSeparator = getNameSeparator();
8
+ const servers = await getServersInfo();
9
+ return {
10
+ clusterId: identity.clusterId ?? 'default',
11
+ nodeId: identity.nodeId,
12
+ nameSeparator,
13
+ servers: servers.map((server) => ({
14
+ slug: server.name,
15
+ status: server.status,
16
+ enabled: server.enabled !== false,
17
+ description: server.config?.description ?? '',
18
+ version: server.version,
19
+ instructions: server.instructions,
20
+ error: server.error,
21
+ tools: server.tools.map((tool) => ({
22
+ name: stripRuntimeToolName(server.name, tool.name, nameSeparator),
23
+ publicName: tool.name,
24
+ description: tool.description ?? '',
25
+ inputSchema: tool.inputSchema ?? {},
26
+ enabled: tool.enabled !== false,
27
+ })),
28
+ })),
29
+ };
30
+ }
31
+ //# sourceMappingURL=hostedRuntimeCatalogService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedRuntimeCatalogService.js","sourceRoot":"","sources":["../../src/services/hostedRuntimeCatalogService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AA4BtE,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;IAEvC,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,SAAS;QAC1C,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,aAAa;QACb,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,KAAK;YACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE;YAC7C,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACjC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;gBACjE,UAAU,EAAE,IAAI,CAAC,IAAI;gBACrB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,KAAK;aAChC,CAAC,CAAC;SACJ,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -22,6 +22,7 @@ import { initializeAllOAuthClients } from './oauthService.js';
22
22
  import { createOAuthProvider } from './mcpOAuthProvider.js';
23
23
  import { initSmartRoutingService, getSmartRoutingTools, handleSearchToolsRequest, handleDescribeToolRequest, isSmartRoutingGroup, } from './smartRoutingService.js';
24
24
  import { getActivityLoggingService } from './activityLoggingService.js';
25
+ import { assertHostedToolAllowed, filterHostedTools, reserveHostedToolCall, settleHostedToolCall, } from './hostedAuthService.js';
25
26
  import { formatErrorForLogging, sanitizeStringForLogging, summarizeErrorForLogging, } from '../utils/serialization.js';
26
27
  const servers = {};
27
28
  import { setupClientKeepAlive } from './keepAliveService.js';
@@ -797,7 +798,26 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
797
798
  nextServerInfos.push(serverInfo);
798
799
  try {
799
800
  // Create OpenAPI client instance
800
- openApiClient = new OpenAPIClient(expandedConf);
801
+ openApiClient = new OpenAPIClient(expandedConf, {
802
+ persistOAuth2Token: async (oauth2) => {
803
+ const openapiConfig = {
804
+ ...(expandedConf.openapi || {}),
805
+ security: {
806
+ ...(expandedConf.openapi?.security || { type: 'oauth2' }),
807
+ type: 'oauth2',
808
+ oauth2: { ...oauth2 },
809
+ },
810
+ };
811
+ expandedConf.openapi = openapiConfig;
812
+ serverInfo.config = {
813
+ ...expandedConf,
814
+ openapi: openapiConfig,
815
+ };
816
+ await getServerDao().update(name, {
817
+ openapi: openapiConfig,
818
+ });
819
+ },
820
+ });
801
821
  console.log(`Initializing OpenAPI server: ${name}...`);
802
822
  // Perform async initialization
803
823
  await openApiClient.initialize();
@@ -847,8 +867,9 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
847
867
  });
848
868
  // Get request options from server configuration, with fallbacks
849
869
  const serverRequestOptions = expandedConf.options || {};
870
+ const defaultRequestTimeout = Number(process.env.DEFAULT_REQUEST_TIMEOUT) || 60000;
850
871
  const requestOptions = {
851
- timeout: serverRequestOptions.timeout || 60000,
872
+ timeout: serverRequestOptions.timeout || defaultRequestTimeout,
852
873
  resetTimeoutOnProgress: serverRequestOptions.resetTimeoutOnProgress ?? true,
853
874
  maxTotalTimeout: serverRequestOptions.maxTotalTimeout,
854
875
  };
@@ -1020,11 +1041,12 @@ export const registerAllTools = async (isInit, serverName, options) => {
1020
1041
  // Get all server information
1021
1042
  export const getServersInfo = async (page, limit, user) => {
1022
1043
  const dataService = getDataService();
1023
- // Get paginated or all server configurations from DAO
1024
- // If pagination is used with a non-admin user, filtering is already done at DAO level
1044
+ const isNonAdminUser = Boolean(user && !user.isAdmin);
1025
1045
  const isPaginated = limit !== undefined && page !== undefined;
1026
1046
  const allServers = isPaginated
1027
- ? (await getServerDao().findAllPaginated(page, limit)).data
1047
+ ? (isNonAdminUser
1048
+ ? await getServerDao().findVisibleToUserPaginated(user.username, page, limit)
1049
+ : await getServerDao().findAllPaginated(page, limit)).data
1028
1050
  : await getServerDao().findAll();
1029
1051
  // Ensure that servers recently added via DAO but not yet initialized in serverInfos
1030
1052
  // are still visible in the servers list. This avoids a race condition where
@@ -1059,15 +1081,16 @@ export const getServersInfo = async (page, limit, user) => {
1059
1081
  });
1060
1082
  }
1061
1083
  }
1062
- // Apply user filtering only when NOT using pagination (pagination already filtered at DAO level)
1063
- // Or when no pagination parameters provided (backward compatibility)
1084
+ // Apply user filtering only when NOT using pagination.
1085
+ // Paginated non-admin requests are filtered at DAO level; paginated admin requests
1086
+ // should remain unfiltered as well.
1064
1087
  const shouldApplyUserFilter = !isPaginated;
1065
1088
  const filterServerInfos = shouldApplyUserFilter && dataService.filterData
1066
1089
  ? dataService.filterData(filteredServerInfos, user)
1067
1090
  : filteredServerInfos;
1068
1091
  const infos = filterServerInfos
1069
1092
  .filter((info) => requestedServerNames.has(info.name)) // Only include requested servers
1070
- .map(({ name, status, tools, prompts, resources, createTime, error, oauth }) => {
1093
+ .map(({ name, version, instructions, owner, visibility, status, tools, prompts, resources, createTime, error, oauth, }) => {
1071
1094
  const serverConfig = allServers.find((server) => server.name === name);
1072
1095
  const enabled = serverConfig ? serverConfig.enabled !== false : true;
1073
1096
  const resolvedType = inferServerType(serverConfig);
@@ -1090,6 +1113,10 @@ export const getServersInfo = async (page, limit, user) => {
1090
1113
  });
1091
1114
  return {
1092
1115
  name,
1116
+ version,
1117
+ instructions,
1118
+ owner,
1119
+ visibility,
1093
1120
  status,
1094
1121
  error,
1095
1122
  tools: toolsWithEnabled,
@@ -1364,6 +1391,22 @@ export const handleCallToolRequest = async (request, extra) => {
1364
1391
  const keyId = bearerKeyContext.keyId || extra?.keyId || undefined;
1365
1392
  const keyName = bearerKeyContext.keyName || extra?.keyName || undefined;
1366
1393
  const sourceIp = requestContextService.getRequestContext()?.remoteAddress || undefined;
1394
+ let hostedReservation = null;
1395
+ const reserveHostedIfNeeded = async (serverName, toolName) => {
1396
+ const hostedAuth = requestContextService.getHostedAuthContext();
1397
+ assertHostedToolAllowed(hostedAuth, serverName, toolName);
1398
+ hostedReservation = await reserveHostedToolCall(hostedAuth, serverName, toolName);
1399
+ };
1400
+ const settleHostedIfNeeded = async (input) => {
1401
+ const reservation = hostedReservation;
1402
+ hostedReservation = null;
1403
+ await settleHostedToolCall(reservation, {
1404
+ success: input.success,
1405
+ latencyMs: Date.now() - startTime,
1406
+ requestContent: input.requestContent,
1407
+ responseContent: input.responseContent,
1408
+ });
1409
+ };
1367
1410
  try {
1368
1411
  // Special handling for smart routing tools
1369
1412
  if (request.params.name === 'search_tools') {
@@ -1441,7 +1484,13 @@ export const handleCallToolRequest = async (request, extra) => {
1441
1484
  }
1442
1485
  }
1443
1486
  }
1487
+ await reserveHostedIfNeeded(targetServerInfo.name, cleanToolName);
1444
1488
  const result = await openApiClient.callTool(cleanToolName, finalArgs, passthroughHeaders);
1489
+ await settleHostedIfNeeded({
1490
+ success: true,
1491
+ requestContent: finalArgs,
1492
+ responseContent: result,
1493
+ });
1445
1494
  console.log('OpenAPI tool invocation result', {
1446
1495
  serverName: targetServerInfo.name,
1447
1496
  toolName: cleanToolName,
@@ -1487,10 +1536,16 @@ export const handleCallToolRequest = async (request, extra) => {
1487
1536
  const cleanToolName = toolName.startsWith(prefix)
1488
1537
  ? toolName.substring(prefix.length)
1489
1538
  : toolName;
1539
+ await reserveHostedIfNeeded(targetServerInfo.name, cleanToolName);
1490
1540
  const result = await callToolWithReconnect(targetServerInfo, {
1491
1541
  name: cleanToolName,
1492
1542
  arguments: finalArgs,
1493
1543
  }, targetServerInfo.options || {});
1544
+ await settleHostedIfNeeded({
1545
+ success: !result.isError,
1546
+ requestContent: finalArgs,
1547
+ responseContent: result,
1548
+ });
1494
1549
  console.log('Tool invocation result', {
1495
1550
  serverName: targetServerInfo.name,
1496
1551
  toolName: cleanToolName,
@@ -1557,7 +1612,14 @@ export const handleCallToolRequest = async (request, extra) => {
1557
1612
  }
1558
1613
  }
1559
1614
  }
1560
- const result = await openApiClient.callTool(cleanToolName, request.params.arguments || {}, passthroughHeaders);
1615
+ const finalArgs = request.params.arguments || {};
1616
+ await reserveHostedIfNeeded(serverInfo.name, cleanToolName);
1617
+ const result = await openApiClient.callTool(cleanToolName, finalArgs, passthroughHeaders);
1618
+ await settleHostedIfNeeded({
1619
+ success: true,
1620
+ requestContent: finalArgs,
1621
+ responseContent: result,
1622
+ });
1561
1623
  console.log('OpenAPI tool invocation result', {
1562
1624
  serverName: serverInfo.name,
1563
1625
  toolName: cleanToolName,
@@ -1596,7 +1658,13 @@ export const handleCallToolRequest = async (request, extra) => {
1596
1658
  const cleanToolName = request.params.name.startsWith(prefix)
1597
1659
  ? request.params.name.substring(prefix.length)
1598
1660
  : request.params.name;
1661
+ await reserveHostedIfNeeded(serverInfo.name, cleanToolName);
1599
1662
  const result = await callToolWithReconnect(serverInfo, { ...request.params, name: cleanToolName }, serverInfo.options || {});
1663
+ await settleHostedIfNeeded({
1664
+ success: !result.isError,
1665
+ requestContent: request.params.arguments,
1666
+ responseContent: result,
1667
+ });
1600
1668
  console.log('Tool call result', {
1601
1669
  serverName: serverInfo.name,
1602
1670
  toolName: cleanToolName,
@@ -1623,6 +1691,11 @@ export const handleCallToolRequest = async (request, extra) => {
1623
1691
  console.error('Error handling CallToolRequest', summarizeErrorForLogging(error));
1624
1692
  // Log error activity
1625
1693
  const duration = Date.now() - startTime;
1694
+ await settleHostedIfNeeded({
1695
+ success: false,
1696
+ requestContent: getActivityInputFromToolRequest(request),
1697
+ responseContent: { error: formatErrorForLogging(error) },
1698
+ });
1626
1699
  const activityToolName = getActivityToolNameFromRequest(request);
1627
1700
  const serverInfo = (typeof extra?.server === 'string' ? getServerByName(extra.server) : undefined) ||
1628
1701
  getServerByTool(activityToolName);
@@ -1931,7 +2004,8 @@ async function filterToolsByGroup(group, serverName, tools, serverConfig) {
1931
2004
  tools = tools.filter((tool) => allowedToolNames.includes(tool.name));
1932
2005
  }
1933
2006
  }
1934
- return tools;
2007
+ const hostedAuth = RequestContextService.getInstance().getHostedAuthContext();
2008
+ return filterHostedTools(hostedAuth, serverName, tools, getNameSeparator());
1935
2009
  }
1936
2010
  const normalizePromptNameForGroup = (serverName, promptName) => {
1937
2011
  const prefix = `${serverName}${getNameSeparator()}`;