@mcp-rating/gateway 0.2.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.
Files changed (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -0
  3. package/dist/ads/ad-tracker.d.ts +63 -0
  4. package/dist/ads/ad-tracker.js +144 -0
  5. package/dist/ads/ad-tracker.js.map +1 -0
  6. package/dist/analytics/usage-tracker.d.ts +67 -0
  7. package/dist/analytics/usage-tracker.js +148 -0
  8. package/dist/analytics/usage-tracker.js.map +1 -0
  9. package/dist/audit/audit-log.d.ts +71 -0
  10. package/dist/audit/audit-log.js +72 -0
  11. package/dist/audit/audit-log.js.map +1 -0
  12. package/dist/config/gateway-config.d.ts +6 -0
  13. package/dist/config/gateway-config.js +135 -0
  14. package/dist/config/gateway-config.js.map +1 -0
  15. package/dist/config/groups.d.ts +29 -0
  16. package/dist/config/groups.js +102 -0
  17. package/dist/config/groups.js.map +1 -0
  18. package/dist/config/profiles.d.ts +42 -0
  19. package/dist/config/profiles.js +167 -0
  20. package/dist/config/profiles.js.map +1 -0
  21. package/dist/config/types.d.ts +76 -0
  22. package/dist/config/types.js +2 -0
  23. package/dist/config/types.js.map +1 -0
  24. package/dist/connection/auto-installer.d.ts +13 -0
  25. package/dist/connection/auto-installer.js +61 -0
  26. package/dist/connection/auto-installer.js.map +1 -0
  27. package/dist/connection/connection-manager.d.ts +106 -0
  28. package/dist/connection/connection-manager.js +845 -0
  29. package/dist/connection/connection-manager.js.map +1 -0
  30. package/dist/connection/downstream-client.d.ts +50 -0
  31. package/dist/connection/downstream-client.js +170 -0
  32. package/dist/connection/downstream-client.js.map +1 -0
  33. package/dist/connection/http-client.d.ts +12 -0
  34. package/dist/connection/http-client.js +26 -0
  35. package/dist/connection/http-client.js.map +1 -0
  36. package/dist/connection/sse-client.d.ts +12 -0
  37. package/dist/connection/sse-client.js +26 -0
  38. package/dist/connection/sse-client.js.map +1 -0
  39. package/dist/connection/transport-factory.d.ts +31 -0
  40. package/dist/connection/transport-factory.js +67 -0
  41. package/dist/connection/transport-factory.js.map +1 -0
  42. package/dist/connection/types.d.ts +134 -0
  43. package/dist/connection/types.js +5 -0
  44. package/dist/connection/types.js.map +1 -0
  45. package/dist/connection/ws-client.d.ts +12 -0
  46. package/dist/connection/ws-client.js +26 -0
  47. package/dist/connection/ws-client.js.map +1 -0
  48. package/dist/discovery/auto-recommender.d.ts +51 -0
  49. package/dist/discovery/auto-recommender.js +176 -0
  50. package/dist/discovery/auto-recommender.js.map +1 -0
  51. package/dist/gateway-server.d.ts +42 -0
  52. package/dist/gateway-server.js +135 -0
  53. package/dist/gateway-server.js.map +1 -0
  54. package/dist/http-daemon.d.ts +26 -0
  55. package/dist/http-daemon.js +302 -0
  56. package/dist/http-daemon.js.map +1 -0
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.js +83 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/meta-tools/ad-status.d.ts +8 -0
  61. package/dist/meta-tools/ad-status.js +41 -0
  62. package/dist/meta-tools/ad-status.js.map +1 -0
  63. package/dist/meta-tools/audit.d.ts +12 -0
  64. package/dist/meta-tools/audit.js +98 -0
  65. package/dist/meta-tools/audit.js.map +1 -0
  66. package/dist/meta-tools/call-tool.d.ts +11 -0
  67. package/dist/meta-tools/call-tool.js +65 -0
  68. package/dist/meta-tools/call-tool.js.map +1 -0
  69. package/dist/meta-tools/connect.d.ts +3 -0
  70. package/dist/meta-tools/connect.js +105 -0
  71. package/dist/meta-tools/connect.js.map +1 -0
  72. package/dist/meta-tools/disconnect.d.ts +3 -0
  73. package/dist/meta-tools/disconnect.js +30 -0
  74. package/dist/meta-tools/disconnect.js.map +1 -0
  75. package/dist/meta-tools/discover.d.ts +3 -0
  76. package/dist/meta-tools/discover.js +97 -0
  77. package/dist/meta-tools/discover.js.map +1 -0
  78. package/dist/meta-tools/groups.d.ts +7 -0
  79. package/dist/meta-tools/groups.js +237 -0
  80. package/dist/meta-tools/groups.js.map +1 -0
  81. package/dist/meta-tools/health.d.ts +4 -0
  82. package/dist/meta-tools/health.js +76 -0
  83. package/dist/meta-tools/health.js.map +1 -0
  84. package/dist/meta-tools/index.d.ts +28 -0
  85. package/dist/meta-tools/index.js +56 -0
  86. package/dist/meta-tools/index.js.map +1 -0
  87. package/dist/meta-tools/list-active.d.ts +3 -0
  88. package/dist/meta-tools/list-active.js +50 -0
  89. package/dist/meta-tools/list-active.js.map +1 -0
  90. package/dist/meta-tools/profiles.d.ts +6 -0
  91. package/dist/meta-tools/profiles.js +197 -0
  92. package/dist/meta-tools/profiles.js.map +1 -0
  93. package/dist/meta-tools/recommend.d.ts +14 -0
  94. package/dist/meta-tools/recommend.js +74 -0
  95. package/dist/meta-tools/recommend.js.map +1 -0
  96. package/dist/meta-tools/sandbox.d.ts +12 -0
  97. package/dist/meta-tools/sandbox.js +125 -0
  98. package/dist/meta-tools/sandbox.js.map +1 -0
  99. package/dist/meta-tools/server-info.d.ts +4 -0
  100. package/dist/meta-tools/server-info.js +156 -0
  101. package/dist/meta-tools/server-info.js.map +1 -0
  102. package/dist/meta-tools/usage.d.ts +6 -0
  103. package/dist/meta-tools/usage.js +149 -0
  104. package/dist/meta-tools/usage.js.map +1 -0
  105. package/dist/permissions/permission-manager.d.ts +26 -0
  106. package/dist/permissions/permission-manager.js +73 -0
  107. package/dist/permissions/permission-manager.js.map +1 -0
  108. package/dist/permissions/trust-tiers.d.ts +18 -0
  109. package/dist/permissions/trust-tiers.js +42 -0
  110. package/dist/permissions/trust-tiers.js.map +1 -0
  111. package/dist/plugins/builtin/logging-plugin.d.ts +6 -0
  112. package/dist/plugins/builtin/logging-plugin.js +41 -0
  113. package/dist/plugins/builtin/logging-plugin.js.map +1 -0
  114. package/dist/plugins/plugin-manager.d.ts +65 -0
  115. package/dist/plugins/plugin-manager.js +137 -0
  116. package/dist/plugins/plugin-manager.js.map +1 -0
  117. package/dist/proxy/prime-handlers.d.ts +27 -0
  118. package/dist/proxy/prime-handlers.js +47 -0
  119. package/dist/proxy/prime-handlers.js.map +1 -0
  120. package/dist/proxy/progress-forwarder.d.ts +44 -0
  121. package/dist/proxy/progress-forwarder.js +40 -0
  122. package/dist/proxy/progress-forwarder.js.map +1 -0
  123. package/dist/proxy/prompt-router.d.ts +25 -0
  124. package/dist/proxy/prompt-router.js +110 -0
  125. package/dist/proxy/prompt-router.js.map +1 -0
  126. package/dist/proxy/resource-router.d.ts +25 -0
  127. package/dist/proxy/resource-router.js +91 -0
  128. package/dist/proxy/resource-router.js.map +1 -0
  129. package/dist/proxy/schema-adapter.d.ts +11 -0
  130. package/dist/proxy/schema-adapter.js +36 -0
  131. package/dist/proxy/schema-adapter.js.map +1 -0
  132. package/dist/proxy/task-proxy.d.ts +28 -0
  133. package/dist/proxy/task-proxy.js +186 -0
  134. package/dist/proxy/task-proxy.js.map +1 -0
  135. package/dist/proxy/tool-router.d.ts +38 -0
  136. package/dist/proxy/tool-router.js +229 -0
  137. package/dist/proxy/tool-router.js.map +1 -0
  138. package/dist/proxy/ui-detect.d.ts +22 -0
  139. package/dist/proxy/ui-detect.js +30 -0
  140. package/dist/proxy/ui-detect.js.map +1 -0
  141. package/dist/registry/registry-client.d.ts +55 -0
  142. package/dist/registry/registry-client.js +211 -0
  143. package/dist/registry/registry-client.js.map +1 -0
  144. package/dist/registry/types.d.ts +69 -0
  145. package/dist/registry/types.js +2 -0
  146. package/dist/registry/types.js.map +1 -0
  147. package/dist/sandbox/container-runtime.d.ts +91 -0
  148. package/dist/sandbox/container-runtime.js +178 -0
  149. package/dist/sandbox/container-runtime.js.map +1 -0
  150. package/dist/sandbox/egress-proxy.d.ts +51 -0
  151. package/dist/sandbox/egress-proxy.js +146 -0
  152. package/dist/sandbox/egress-proxy.js.map +1 -0
  153. package/dist/sandbox/env-scoper.d.ts +29 -0
  154. package/dist/sandbox/env-scoper.js +60 -0
  155. package/dist/sandbox/env-scoper.js.map +1 -0
  156. package/dist/sandbox/manifest-resolver.d.ts +40 -0
  157. package/dist/sandbox/manifest-resolver.js +185 -0
  158. package/dist/sandbox/manifest-resolver.js.map +1 -0
  159. package/dist/sandbox/types.d.ts +88 -0
  160. package/dist/sandbox/types.js +21 -0
  161. package/dist/sandbox/types.js.map +1 -0
  162. package/dist/utils/errors.d.ts +39 -0
  163. package/dist/utils/errors.js +67 -0
  164. package/dist/utils/errors.js.map +1 -0
  165. package/dist/utils/logger.d.ts +16 -0
  166. package/dist/utils/logger.js +51 -0
  167. package/dist/utils/logger.js.map +1 -0
  168. package/package.json +72 -0
@@ -0,0 +1,76 @@
1
+ import { TRUST_LABELS } from "../permissions/trust-tiers.js";
2
+ const GATEWAY_VERSION = "0.1.0";
3
+ export function registerHealth(server, connectionManager, registryClient) {
4
+ server.tool("mcp_gateway_health", "Get gateway diagnostics: version, uptime, connection status, registry reachability, and per-server health.", {}, async () => {
5
+ const connections = connectionManager.listConnections();
6
+ const registryStatus = registryClient.getStatus();
7
+ const uptimeMs = Date.now() - connectionManager.startedAt.getTime();
8
+ const lines = [
9
+ `## MCP Gateway Health`,
10
+ "",
11
+ `**Version:** ${GATEWAY_VERSION}`,
12
+ `**Uptime:** ${formatDuration(uptimeMs)}`,
13
+ `**Connections:** ${connections.length}`,
14
+ "",
15
+ ];
16
+ // Registry status
17
+ lines.push("### Registry");
18
+ if (registryStatus.lastSuccessfulCall) {
19
+ const ago = formatDuration(Date.now() - registryStatus.lastSuccessfulCall.getTime());
20
+ lines.push(`**Status:** Reachable (last success ${ago} ago)`);
21
+ }
22
+ else if (registryStatus.lastError) {
23
+ lines.push(`**Status:** Unreachable`);
24
+ lines.push(`**Last Error:** ${registryStatus.lastError}`);
25
+ }
26
+ else {
27
+ lines.push(`**Status:** No calls made yet`);
28
+ }
29
+ lines.push(`**Cache Entries:** ${registryStatus.cacheSize}`, "");
30
+ // Per-connection details
31
+ if (connections.length > 0) {
32
+ lines.push("### Connections", "");
33
+ for (const conn of connections) {
34
+ const tierLabel = TRUST_LABELS[conn.trustTier];
35
+ const duration = formatDuration(Date.now() - conn.connectedAt.getTime());
36
+ const serverVer = conn.serverInfo
37
+ ? `${conn.serverInfo.name} v${conn.serverInfo.version}`
38
+ : "unknown";
39
+ lines.push(`**${conn.displayName}** (\`${conn.slug}\`)`);
40
+ lines.push(` State: ${conn.state} · Trust: [${tierLabel}] · Tools: ${conn.toolCount}`);
41
+ lines.push(` Server: ${serverVer} · Connected: ${duration}`);
42
+ if (conn.reconnectAttempts && conn.reconnectAttempts > 0) {
43
+ lines.push(` Reconnect attempts: ${conn.reconnectAttempts}`);
44
+ }
45
+ if (conn.failedPings && conn.failedPings > 0) {
46
+ lines.push(` Failed pings: ${conn.failedPings}`);
47
+ }
48
+ if (conn.lastPingAt) {
49
+ const pingAgo = formatDuration(Date.now() - conn.lastPingAt.getTime());
50
+ lines.push(` Last ping: ${pingAgo} ago`);
51
+ }
52
+ lines.push("");
53
+ }
54
+ }
55
+ else {
56
+ lines.push("### Connections", "", "No servers connected.", "");
57
+ }
58
+ return {
59
+ content: [{ type: "text", text: lines.join("\n") }],
60
+ };
61
+ });
62
+ }
63
+ function formatDuration(ms) {
64
+ const seconds = Math.floor(ms / 1000);
65
+ if (seconds < 60)
66
+ return `${seconds}s`;
67
+ const minutes = Math.floor(seconds / 60);
68
+ if (minutes < 60)
69
+ return `${minutes}m ${seconds % 60}s`;
70
+ const hours = Math.floor(minutes / 60);
71
+ if (hours < 24)
72
+ return `${hours}h ${minutes % 60}m`;
73
+ const days = Math.floor(hours / 24);
74
+ return `${days}d ${hours % 24}h`;
75
+ }
76
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/meta-tools/health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ConnectionManager } from "../connection/connection-manager.js";
3
+ import type { RegistryClient } from "../registry/registry-client.js";
4
+ import type { AdTracker } from "../ads/ad-tracker.js";
5
+ import type { UsageTracker } from "../analytics/usage-tracker.js";
6
+ import type { AutoRecommender } from "../discovery/auto-recommender.js";
7
+ import type { AuditLog } from "../audit/audit-log.js";
8
+ export interface MetaToolOptions {
9
+ /** Ad tracker for ad-related meta-tool */
10
+ adTracker?: AdTracker | null;
11
+ /** Usage tracker for analytics meta-tool */
12
+ usageTracker?: UsageTracker | null;
13
+ /** Auto-recommender for recommendation meta-tool */
14
+ autoRecommender?: AutoRecommender | null;
15
+ /** Path to profiles file (for profiles meta-tool) */
16
+ profilesPath?: string;
17
+ /** Path to groups file (for groups meta-tool) */
18
+ groupsPath?: string;
19
+ /** Safety audit log (for the audit forensics meta-tool) */
20
+ auditLog?: AuditLog | null;
21
+ }
22
+ /**
23
+ * Register all gateway meta-tools on the MCP server.
24
+ *
25
+ * These are the tools users interact with to discover, connect,
26
+ * and manage downstream MCP servers.
27
+ */
28
+ export declare function registerMetaTools(server: McpServer, connectionManager: ConnectionManager, registryClient: RegistryClient, options?: MetaToolOptions): void;
@@ -0,0 +1,56 @@
1
+ import { registerDiscover } from "./discover.js";
2
+ import { registerConnect } from "./connect.js";
3
+ import { registerDisconnect } from "./disconnect.js";
4
+ import { registerListActive } from "./list-active.js";
5
+ import { registerServerInfo } from "./server-info.js";
6
+ import { registerCallTool } from "./call-tool.js";
7
+ import { registerHealth } from "./health.js";
8
+ import { registerAdStatus } from "./ad-status.js";
9
+ import { registerProfiles } from "./profiles.js";
10
+ import { registerGroups } from "./groups.js";
11
+ import { registerUsage } from "./usage.js";
12
+ import { registerRecommend } from "./recommend.js";
13
+ import { registerSandbox } from "./sandbox.js";
14
+ import { registerAudit } from "./audit.js";
15
+ /**
16
+ * Register all gateway meta-tools on the MCP server.
17
+ *
18
+ * These are the tools users interact with to discover, connect,
19
+ * and manage downstream MCP servers.
20
+ */
21
+ export function registerMetaTools(server, connectionManager, registryClient, options = {}) {
22
+ // Core meta-tools
23
+ registerDiscover(server, registryClient);
24
+ registerConnect(server, connectionManager);
25
+ registerDisconnect(server, connectionManager);
26
+ registerListActive(server, connectionManager);
27
+ registerServerInfo(server, connectionManager, registryClient);
28
+ registerCallTool(server, connectionManager);
29
+ registerHealth(server, connectionManager, registryClient);
30
+ registerSandbox(server, connectionManager);
31
+ // Safety audit forensics meta-tool
32
+ if (options.auditLog) {
33
+ registerAudit(server, options.auditLog);
34
+ }
35
+ // Ad tracking meta-tool (if partner key configured)
36
+ if (options.adTracker) {
37
+ registerAdStatus(server, connectionManager, options.adTracker);
38
+ }
39
+ // Profile management meta-tool
40
+ if (options.profilesPath) {
41
+ registerProfiles(server, connectionManager, options.profilesPath);
42
+ }
43
+ // Group management meta-tool
44
+ if (options.groupsPath) {
45
+ registerGroups(server, connectionManager, options.groupsPath);
46
+ }
47
+ // Usage analytics meta-tool
48
+ if (options.usageTracker) {
49
+ registerUsage(server, options.usageTracker);
50
+ }
51
+ // Auto-recommendation meta-tool
52
+ if (options.usageTracker && options.autoRecommender) {
53
+ registerRecommend(server, options.autoRecommender, options.usageTracker);
54
+ }
55
+ }
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/meta-tools/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkB3C;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,iBAAoC,EACpC,cAA8B,EAC9B,UAA2B,EAAE;IAE7B,kBAAkB;IAClB,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzC,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC3C,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC9C,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC9C,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAC9D,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5C,cAAc,CAAC,MAAM,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAC1D,eAAe,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAE3C,mCAAmC;IACnC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,oDAAoD;IACpD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACjE,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,CAAC;IAED,6BAA6B;IAC7B,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,cAAc,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAChE,CAAC;IAED,4BAA4B;IAC5B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,gCAAgC;IAChC,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QACpD,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ConnectionManager } from "../connection/connection-manager.js";
3
+ export declare function registerListActive(server: McpServer, connectionManager: ConnectionManager): void;
@@ -0,0 +1,50 @@
1
+ import { TRUST_LABELS } from "../permissions/trust-tiers.js";
2
+ export function registerListActive(server, connectionManager) {
3
+ server.tool("mcp_list_active", "List all currently connected MCP servers and their tools.", {}, async () => {
4
+ const connections = connectionManager.listConnections();
5
+ if (connections.length === 0) {
6
+ return {
7
+ content: [
8
+ {
9
+ type: "text",
10
+ text: "No MCP servers are currently connected.\n\nUse `mcp_discover` to find servers, then `mcp_connect` to connect.",
11
+ },
12
+ ],
13
+ };
14
+ }
15
+ const lines = [
16
+ `## Active MCP Connections (${connections.length})`,
17
+ "",
18
+ ];
19
+ for (const conn of connections) {
20
+ const tierLabel = TRUST_LABELS[conn.trustTier];
21
+ const duration = formatDuration(Date.now() - conn.connectedAt.getTime());
22
+ const serverVer = conn.serverInfo
23
+ ? `${conn.serverInfo.name} v${conn.serverInfo.version}`
24
+ : "unknown";
25
+ lines.push(`### ${conn.displayName}`, `**Slug:** \`${conn.slug}\` · **Trust:** [${tierLabel}] · **State:** ${conn.state}`, `**Server:** ${serverVer} · **Tools:** ${conn.toolCount} · **Connected:** ${duration}`);
26
+ if (conn.state === "reconnecting" && conn.reconnectAttempts) {
27
+ lines.push(`⚠️ Reconnecting (attempt ${conn.reconnectAttempts})...`);
28
+ }
29
+ if (conn.state === "failed") {
30
+ lines.push(`❌ Connection failed — use \`mcp_connect\` to retry manually.`);
31
+ }
32
+ lines.push("");
33
+ }
34
+ lines.push("---", `Use \`mcp_disconnect({slug: "..."})\` to disconnect a server.`);
35
+ return {
36
+ content: [{ type: "text", text: lines.join("\n") }],
37
+ };
38
+ });
39
+ }
40
+ function formatDuration(ms) {
41
+ const seconds = Math.floor(ms / 1000);
42
+ if (seconds < 60)
43
+ return `${seconds}s`;
44
+ const minutes = Math.floor(seconds / 60);
45
+ if (minutes < 60)
46
+ return `${minutes}m ${seconds % 60}s`;
47
+ const hours = Math.floor(minutes / 60);
48
+ return `${hours}h ${minutes % 60}m`;
49
+ }
50
+ //# sourceMappingURL=list-active.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-active.js","sourceRoot":"","sources":["../../src/meta-tools/list-active.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,iBAAoC;IAEpC,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,2DAA2D,EAC3D,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,WAAW,GAAG,iBAAiB,CAAC,eAAe,EAAE,CAAC;QAExD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,+GAA+G;qBACtH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAa;YACtB,8BAA8B,WAAW,CAAC,MAAM,GAAG;YACnD,EAAE;SACH,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,cAAc,CAC7B,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CACxC,CAAC;YACF,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU;gBAC/B,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;gBACvD,CAAC,CAAC,SAAS,CAAC;YAEd,KAAK,CAAC,IAAI,CACR,OAAO,IAAI,CAAC,WAAW,EAAE,EACzB,eAAe,IAAI,CAAC,IAAI,oBAAoB,SAAS,kBAAkB,IAAI,CAAC,KAAK,EAAE,EACnF,eAAe,SAAS,iBAAiB,IAAI,CAAC,SAAS,qBAAqB,QAAQ,EAAE,CACvF,CAAC;YACF,IAAI,IAAI,CAAC,KAAK,KAAK,cAAc,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5D,KAAK,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,iBAAiB,MAAM,CAAC,CAAC;YACvE,CAAC;YACD,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;YAC7E,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,IAAI,CACR,KAAK,EACL,+DAA+D,CAChE,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SAC7D,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,EAAU;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,OAAO,GAAG,KAAK,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;AACtC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ConnectionManager } from "../connection/connection-manager.js";
3
+ /**
4
+ * Register the `mcp_profiles` meta-tool for managing named connection profiles.
5
+ */
6
+ export declare function registerProfiles(server: McpServer, connectionManager: ConnectionManager, profilesPath: string): void;
@@ -0,0 +1,197 @@
1
+ import { z } from "zod";
2
+ import { listNamedProfiles, createNamedProfile, deleteNamedProfile, addToNamedProfile, removeFromNamedProfile, getActiveProfileName, setActiveProfile, getProfileConnections, } from "../config/profiles.js";
3
+ import { toolError } from "../utils/errors.js";
4
+ /**
5
+ * Register the `mcp_profiles` meta-tool for managing named connection profiles.
6
+ */
7
+ export function registerProfiles(server, connectionManager, profilesPath) {
8
+ server.tool("mcp_profiles", "Manage named connection profiles. Profiles are presets of server connections that can be switched between (e.g., 'work', 'personal').", {
9
+ action: z
10
+ .enum(["list", "create", "delete", "add_server", "remove_server", "switch", "show"])
11
+ .describe("Action: list (all profiles), create (new profile), delete, add_server (add a server to profile), remove_server, switch (activate profile), show (details of a profile)"),
12
+ name: z
13
+ .string()
14
+ .optional()
15
+ .describe("Profile name (required for create, delete, add_server, remove_server, switch, show)"),
16
+ description: z
17
+ .string()
18
+ .optional()
19
+ .describe("Profile description (optional, for create)"),
20
+ slug: z
21
+ .string()
22
+ .optional()
23
+ .describe("Server slug to add/remove from a profile"),
24
+ command: z
25
+ .string()
26
+ .optional()
27
+ .describe("Explicit command for the server (for add_server with stdio)"),
28
+ args: z
29
+ .array(z.string())
30
+ .optional()
31
+ .describe("Command arguments (for add_server with stdio)"),
32
+ url: z
33
+ .string()
34
+ .optional()
35
+ .describe("Server URL (for add_server with SSE/WS/HTTP)"),
36
+ transportType: z
37
+ .enum(["stdio", "sse", "websocket", "streamable-http"])
38
+ .optional()
39
+ .describe("Transport type (for add_server)"),
40
+ }, async ({ action, name, description, slug, command, args, url, transportType }) => {
41
+ try {
42
+ switch (action) {
43
+ case "list": {
44
+ const profiles = listNamedProfiles(profilesPath);
45
+ const active = getActiveProfileName(profilesPath);
46
+ if (profiles.length === 0) {
47
+ return {
48
+ content: [
49
+ {
50
+ type: "text",
51
+ text: "No named profiles exist yet.\n\nUse `mcp_profiles({action: \"create\", name: \"work\"})` to create one.",
52
+ },
53
+ ],
54
+ };
55
+ }
56
+ const lines = [
57
+ `## Connection Profiles (${profiles.length})`,
58
+ "",
59
+ ];
60
+ for (const p of profiles) {
61
+ const isActive = p.name === active ? " ⭐ **active**" : "";
62
+ lines.push(`### ${p.name}${isActive}`, p.description ? `_${p.description}_` : "", `**Servers:** ${p.connections.length}`, "");
63
+ }
64
+ return {
65
+ content: [{ type: "text", text: lines.filter(Boolean).join("\n") }],
66
+ };
67
+ }
68
+ case "create": {
69
+ if (!name)
70
+ return toolError("Profile name is required for 'create'.");
71
+ createNamedProfile(profilesPath, name, description);
72
+ return {
73
+ content: [
74
+ {
75
+ type: "text",
76
+ text: `✅ Profile **"${name}"** created.${description ? ` (${description})` : ""}\n\nAdd servers with \`mcp_profiles({action: "add_server", name: "${name}", slug: "..."})\``,
77
+ },
78
+ ],
79
+ };
80
+ }
81
+ case "delete": {
82
+ if (!name)
83
+ return toolError("Profile name is required for 'delete'.");
84
+ const deleted = deleteNamedProfile(profilesPath, name);
85
+ if (!deleted)
86
+ return toolError(`Profile "${name}" not found.`);
87
+ return {
88
+ content: [
89
+ { type: "text", text: `✅ Profile **"${name}"** deleted.` },
90
+ ],
91
+ };
92
+ }
93
+ case "add_server": {
94
+ if (!name)
95
+ return toolError("Profile name is required for 'add_server'.");
96
+ if (!slug && !command && !url) {
97
+ return toolError("Either 'slug', 'command', or 'url' is required to add a server.");
98
+ }
99
+ addToNamedProfile(profilesPath, name, {
100
+ slug,
101
+ command,
102
+ args,
103
+ url,
104
+ transportType: transportType,
105
+ confirmed: true,
106
+ });
107
+ const identifier = slug || command || url;
108
+ return {
109
+ content: [
110
+ {
111
+ type: "text",
112
+ text: `✅ Server **${identifier}** added to profile **"${name}"**.`,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ case "remove_server": {
118
+ if (!name)
119
+ return toolError("Profile name is required for 'remove_server'.");
120
+ if (!slug)
121
+ return toolError("Server slug is required to remove a server.");
122
+ removeFromNamedProfile(profilesPath, name, slug);
123
+ return {
124
+ content: [
125
+ {
126
+ type: "text",
127
+ text: `✅ Server **${slug}** removed from profile **"${name}"**.`,
128
+ },
129
+ ],
130
+ };
131
+ }
132
+ case "switch": {
133
+ if (!name)
134
+ return toolError("Profile name is required for 'switch'.");
135
+ // Disconnect all current connections
136
+ await connectionManager.disconnectAll();
137
+ // Set the active profile
138
+ setActiveProfile(profilesPath, name);
139
+ // Connect all servers in the profile
140
+ const connections = getProfileConnections(profilesPath, name);
141
+ const results = [];
142
+ for (const profile of connections) {
143
+ try {
144
+ await connectionManager.connect({ ...profile, confirmed: true });
145
+ results.push(`✅ ${profile.slug || profile.command || profile.url}`);
146
+ }
147
+ catch (err) {
148
+ results.push(`❌ ${profile.slug || profile.command || profile.url}: ${err instanceof Error ? err.message : String(err)}`);
149
+ }
150
+ }
151
+ const lines = [
152
+ `## Switched to profile **"${name}"**`,
153
+ "",
154
+ `**Servers:** ${connections.length}`,
155
+ "",
156
+ ...results,
157
+ "",
158
+ `**Active connections:** ${connectionManager.connectionCount}`,
159
+ ];
160
+ return {
161
+ content: [{ type: "text", text: lines.join("\n") }],
162
+ };
163
+ }
164
+ case "show": {
165
+ if (!name)
166
+ return toolError("Profile name is required for 'show'.");
167
+ const conns = getProfileConnections(profilesPath, name);
168
+ const active = getActiveProfileName(profilesPath);
169
+ const isActive = name === active;
170
+ const lines = [
171
+ `## Profile: ${name}${isActive ? " ⭐ active" : ""}`,
172
+ "",
173
+ `**Servers:** ${conns.length}`,
174
+ "",
175
+ ];
176
+ for (const c of conns) {
177
+ const transport = c.transportType || "stdio";
178
+ const target = c.slug || c.command || c.url || "unknown";
179
+ lines.push(`- \`${target}\` (${transport})`);
180
+ }
181
+ if (conns.length === 0) {
182
+ lines.push("_No servers in this profile yet._");
183
+ }
184
+ return {
185
+ content: [{ type: "text", text: lines.join("\n") }],
186
+ };
187
+ }
188
+ default:
189
+ return toolError(`Unknown action: ${action}`);
190
+ }
191
+ }
192
+ catch (err) {
193
+ return toolError(err instanceof Error ? err.message : String(err));
194
+ }
195
+ });
196
+ }
197
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/meta-tools/profiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { AutoRecommender } from "../discovery/auto-recommender.js";
3
+ import type { UsageTracker } from "../analytics/usage-tracker.js";
4
+ /**
5
+ * Register the `mcp_recommend` meta-tool.
6
+ *
7
+ * Two modes:
8
+ * - **Intent mode** (`query` provided): searches the registry for servers
9
+ * matching the goal, with server-side intent expansion (cloud storage →
10
+ * dropbox/gdrive/onedrive/...).
11
+ * - **Usage mode** (no `query`): analyzes recent tool-call patterns and
12
+ * suggests servers that complement the workflow.
13
+ */
14
+ export declare function registerRecommend(server: McpServer, autoRecommender: AutoRecommender, usageTracker: UsageTracker): void;
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ import { toolError } from "../utils/errors.js";
3
+ /**
4
+ * Register the `mcp_recommend` meta-tool.
5
+ *
6
+ * Two modes:
7
+ * - **Intent mode** (`query` provided): searches the registry for servers
8
+ * matching the goal, with server-side intent expansion (cloud storage →
9
+ * dropbox/gdrive/onedrive/...).
10
+ * - **Usage mode** (no `query`): analyzes recent tool-call patterns and
11
+ * suggests servers that complement the workflow.
12
+ */
13
+ export function registerRecommend(server, autoRecommender, usageTracker) {
14
+ server.tool("mcp_recommend", "Get MCP server recommendations. Pass `query` to describe a goal or task (e.g. \"file sync with cloud storage\", \"manage GitHub issues\"). Omit `query` to get suggestions based on your recent tool-call patterns.", {
15
+ query: z
16
+ .string()
17
+ .optional()
18
+ .describe("Free-text goal or task. When provided, recommends servers that match this intent using semantic/keyword/expansion search. When omitted, recommends based on usage history."),
19
+ category: z
20
+ .string()
21
+ .optional()
22
+ .describe("Optional category slug to filter (e.g. 'developer-tools', 'data-databases'). Only used with `query`."),
23
+ limit: z
24
+ .number()
25
+ .min(1)
26
+ .max(20)
27
+ .optional()
28
+ .describe("Maximum number of recommendations (default 5, max 20)"),
29
+ }, async ({ query, category, limit = 5 }) => {
30
+ try {
31
+ const isIntentMode = typeof query === "string" && query.trim().length > 0;
32
+ const recommendations = isIntentMode
33
+ ? await autoRecommender.recommendByQuery(query.trim(), {
34
+ limit,
35
+ category,
36
+ })
37
+ : await autoRecommender.recommend(usageTracker.getRecentCalls(50), usageTracker);
38
+ const limited = recommendations.slice(0, limit);
39
+ if (limited.length === 0) {
40
+ return {
41
+ content: [
42
+ {
43
+ type: "text",
44
+ text: isIntentMode
45
+ ? `No MCP servers found for "${query}". Try a broader description, or use \`mcp_discover\` to search by keyword.`
46
+ : "No recommendations available right now. Use more tools to build usage patterns, pass a `query` to describe a goal, or try `mcp_discover` to search the registry directly.",
47
+ },
48
+ ],
49
+ };
50
+ }
51
+ const header = isIntentMode
52
+ ? `## Recommended for "${query}" (${limited.length})`
53
+ : `## Recommended Servers (${limited.length})`;
54
+ const subHeader = isIntentMode
55
+ ? `_Best matches in the registry for your goal:_`
56
+ : `_Based on your recent tool usage patterns:_`;
57
+ const lines = [header, "", subHeader, ""];
58
+ for (const rec of limited) {
59
+ // qualityScore is 0-100 from the registry; display as /100.
60
+ const quality = rec.qualityScore > 0
61
+ ? ` · Quality: ${rec.qualityScore.toFixed(0)}/100`
62
+ : "";
63
+ lines.push(`### ${rec.name}`, `**Slug:** \`${rec.slug}\`${quality}`, `**Why:** ${rec.reason}`, `→ Connect: \`mcp_connect({slug: "${rec.slug}"})\``, "");
64
+ }
65
+ return {
66
+ content: [{ type: "text", text: lines.join("\n") }],
67
+ };
68
+ }
69
+ catch (err) {
70
+ return toolError(err instanceof Error ? err.message : String(err));
71
+ }
72
+ });
73
+ }
74
+ //# sourceMappingURL=recommend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../src/meta-tools/recommend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ConnectionManager } from "../connection/connection-manager.js";
3
+ /**
4
+ * Register the `mcp_sandbox` meta-tool — view and customize per-server
5
+ * capability manifests (the sandbox security contract).
6
+ *
7
+ * - view: show the effective/saved manifest + a human-readable summary
8
+ * - set: override fields (network, env, filesystem, subprocess, enforcement)
9
+ * — takes effect on the next connection to that server
10
+ * - reset: clear the override, reverting to trust-tier defaults
11
+ */
12
+ export declare function registerSandbox(server: McpServer, connectionManager: ConnectionManager): void;