@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,125 @@
1
+ import { z } from "zod";
2
+ import { ManifestResolver } from "../sandbox/manifest-resolver.js";
3
+ import { toolError } from "../utils/errors.js";
4
+ /**
5
+ * Register the `mcp_sandbox` meta-tool — view and customize per-server
6
+ * capability manifests (the sandbox security contract).
7
+ *
8
+ * - view: show the effective/saved manifest + a human-readable summary
9
+ * - set: override fields (network, env, filesystem, subprocess, enforcement)
10
+ * — takes effect on the next connection to that server
11
+ * - reset: clear the override, reverting to trust-tier defaults
12
+ */
13
+ export function registerSandbox(server, connectionManager) {
14
+ server.tool("mcp_sandbox", "View or customize a server's sandbox capability manifest (env/network/filesystem/subprocess access). Use action 'view' to inspect, 'set' to tighten or loosen grants (applies on next connect), or 'reset' to revert to defaults.", {
15
+ action: z
16
+ .enum(["view", "set", "reset"])
17
+ .describe("view = inspect manifest; set = override grants; reset = revert to defaults"),
18
+ slug: z.string().describe("Server slug (as shown by mcp_list_active or mcp_discover)"),
19
+ enforcement: z
20
+ .enum(["none", "l1-process", "l2-container"])
21
+ .optional()
22
+ .describe("[set] Isolation level. l2-container requires Docker/Podman."),
23
+ network: z
24
+ .enum(["none", "allowlist", "all"])
25
+ .optional()
26
+ .describe("[set] Network mode. 'none' = no network, 'allowlist' = only listed hosts, 'all' = unrestricted"),
27
+ networkAllow: z
28
+ .array(z.string())
29
+ .optional()
30
+ .describe("[set] Allowed host:port patterns for allowlist mode, e.g. ['api.github.com:443', '*.example.com']"),
31
+ envAllow: z
32
+ .array(z.string())
33
+ .optional()
34
+ .describe("[set] Environment variable NAMES the server may receive, e.g. ['GITHUB_TOKEN']"),
35
+ fsRead: z.array(z.string()).optional().describe("[set] Absolute paths the server may read"),
36
+ fsWrite: z.array(z.string()).optional().describe("[set] Absolute paths the server may write"),
37
+ subprocess: z.boolean().optional().describe("[set] Whether the server may spawn subprocesses"),
38
+ }, async (params) => {
39
+ try {
40
+ const resolver = connectionManager.manifestResolver;
41
+ if (!resolver) {
42
+ return toolError("Sandbox is not enabled on this gateway.");
43
+ }
44
+ const { action, slug } = params;
45
+ // ── RESET ──────────────────────────────────────────────────────────
46
+ if (action === "reset") {
47
+ resolver.clearOverride(slug);
48
+ return text(`## 🛡️ Sandbox override cleared for \`${slug}\`\n\nThe server will use trust-tier defaults on the next connection.`);
49
+ }
50
+ // ── VIEW ───────────────────────────────────────────────────────────
51
+ if (action === "view") {
52
+ // Prefer the live connection's resolved manifest, then a saved
53
+ // override, then a note that defaults will apply on connect.
54
+ const conn = connectionManager.getConnection(slug);
55
+ const manifest = conn?.manifest ?? resolver.getOverride(slug);
56
+ if (!manifest) {
57
+ return text(`## 🛡️ Sandbox: \`${slug}\`\n\nNo saved override and not currently connected. Trust-tier defaults will apply when you connect. Use \`mcp_sandbox({action: "set", slug: "${slug}", ...})\` to pre-configure grants.`);
58
+ }
59
+ return text(renderManifest(slug, manifest, Boolean(conn)));
60
+ }
61
+ // ── SET ────────────────────────────────────────────────────────────
62
+ // Start from existing override / live manifest / a locked baseline.
63
+ const conn = connectionManager.getConnection(slug);
64
+ const base = resolver.getOverride(slug) ??
65
+ conn?.manifest ?? {
66
+ version: 1,
67
+ slug,
68
+ enforcement: "l1-process",
69
+ env: { allow: [], inheritDefaults: true },
70
+ network: { mode: "none", allow: [] },
71
+ filesystem: { read: [], write: [] },
72
+ subprocess: false,
73
+ };
74
+ const updated = {
75
+ ...base,
76
+ slug,
77
+ enforcement: params.enforcement ?? base.enforcement,
78
+ env: {
79
+ allow: params.envAllow ?? base.env.allow,
80
+ inheritDefaults: base.env.inheritDefaults,
81
+ },
82
+ network: {
83
+ mode: params.network ?? base.network.mode,
84
+ allow: params.networkAllow ?? base.network.allow,
85
+ },
86
+ filesystem: {
87
+ read: params.fsRead ?? base.filesystem.read,
88
+ write: params.fsWrite ?? base.filesystem.write,
89
+ },
90
+ subprocess: params.subprocess ?? base.subprocess,
91
+ };
92
+ resolver.saveOverride(updated);
93
+ return text(`## 🛡️ Sandbox override saved for \`${slug}\`\n\n${renderManifest(slug, updated, false)}\n\n_Takes effect on the next connection. Reconnect to apply._`);
94
+ }
95
+ catch (err) {
96
+ return toolError(err instanceof Error ? err.message : String(err));
97
+ }
98
+ });
99
+ }
100
+ function renderManifest(slug, manifest, isLive) {
101
+ const summary = ManifestResolver.summarize(manifest);
102
+ const lines = [
103
+ `## 🛡️ Sandbox: \`${slug}\`${isLive ? " (active connection)" : ""}`,
104
+ `**Enforcement:** ${manifest.enforcement}`,
105
+ "",
106
+ "**Grants:**",
107
+ ...summary.lines.map((l) => `- ${l}`),
108
+ "",
109
+ "**Raw manifest:**",
110
+ "```json",
111
+ JSON.stringify({
112
+ enforcement: manifest.enforcement,
113
+ env: manifest.env,
114
+ network: manifest.network,
115
+ filesystem: manifest.filesystem,
116
+ subprocess: manifest.subprocess,
117
+ }, null, 2),
118
+ "```",
119
+ ];
120
+ return lines.join("\n");
121
+ }
122
+ function text(t) {
123
+ return { content: [{ type: "text", text: t }] };
124
+ }
125
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/meta-tools/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
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
+ export declare function registerServerInfo(server: McpServer, connectionManager: ConnectionManager, registryClient: RegistryClient): void;
@@ -0,0 +1,156 @@
1
+ import { z } from "zod";
2
+ import { TRUST_LABELS } from "../permissions/trust-tiers.js";
3
+ import { namespaceTool } from "../proxy/tool-router.js";
4
+ import { detectLiveUi } from "../proxy/ui-detect.js";
5
+ import { toolError } from "../utils/errors.js";
6
+ export function registerServerInfo(server, connectionManager, registryClient) {
7
+ server.tool("mcp_server_info", "Get detailed information about an MCP server from the registry or a currently connected server.", {
8
+ slug: z
9
+ .string()
10
+ .describe("Server slug (from registry or connected server)"),
11
+ }, async ({ slug }) => {
12
+ try {
13
+ // Check if it's a connected server first
14
+ const connected = connectionManager.getConnection(slug);
15
+ const lines = [];
16
+ // Fetch registry data
17
+ let registryData;
18
+ try {
19
+ registryData = await registryClient.getServer(slug);
20
+ }
21
+ catch {
22
+ // Registry unreachable — that's okay if we have a live connection
23
+ }
24
+ if (!connected && !registryData) {
25
+ return toolError(`Server "${slug}" not found in registry and not currently connected.`);
26
+ }
27
+ // Header
28
+ const name = connected?.displayName || registryData?.name || slug;
29
+ lines.push(`## ${name}`, "");
30
+ // Connection status
31
+ if (connected) {
32
+ const tierLabel = TRUST_LABELS[connected.trustTier];
33
+ lines.push(`**Status:** 🟢 Connected · **Trust:** [${tierLabel}]`);
34
+ if (connected.serverInfo) {
35
+ lines.push(`**Server:** ${connected.serverInfo.name} v${connected.serverInfo.version}`);
36
+ }
37
+ lines.push("");
38
+ }
39
+ else {
40
+ lines.push("**Status:** ⚪ Not connected", "");
41
+ }
42
+ // Registry info
43
+ if (registryData) {
44
+ const tier = (await import("../registry/registry-client.js")).RegistryClient.determineTrustTier(registryData);
45
+ const tierLabel = TRUST_LABELS[tier];
46
+ const score = registryData.qualityScore ?? 0;
47
+ const breakdown = registryData.metadata?.scoreBreakdown;
48
+ lines.push("### Registry Info");
49
+ lines.push(`**Quality Score:** ${score}/100 · **Trust:** [${tierLabel}]`);
50
+ if (breakdown) {
51
+ lines.push(`**Breakdown:** Popularity ${Math.round(breakdown.popularity ?? 0)} · ` +
52
+ `Freshness ${Math.round(breakdown.freshness ?? 0)} · ` +
53
+ `Completeness ${Math.round(breakdown.completeness ?? 0)} · ` +
54
+ `MCP Compliance ${Math.round(breakdown.mcpCompliance ?? 0)} · ` +
55
+ `Community ${Math.round(breakdown.community ?? 0)}`);
56
+ }
57
+ if (registryData.description) {
58
+ lines.push(`**Description:** ${registryData.description}`);
59
+ }
60
+ if (registryData.author) {
61
+ lines.push(`**Author:** ${registryData.author}`);
62
+ }
63
+ if (registryData.category) {
64
+ lines.push(`**Category:** ${registryData.category.name}`);
65
+ }
66
+ const stats = [];
67
+ if (registryData.stars)
68
+ stats.push(`${registryData.stars.toLocaleString()} ★`);
69
+ if (registryData.weeklyDownloads)
70
+ stats.push(`${registryData.weeklyDownloads.toLocaleString()} downloads/wk`);
71
+ if (registryData.supportsDiscovery)
72
+ stats.push("✓ .well-known/mcp");
73
+ // Heuristic UI capability from the registry ("detected").
74
+ if (registryData.supportsUi) {
75
+ const uiType = registryData.uiType;
76
+ stats.push(`🖼️ UI-capable (detected${uiType ? `: ${uiType}` : ""})`);
77
+ }
78
+ if (stats.length > 0) {
79
+ lines.push(`**Stats:** ${stats.join(" · ")}`);
80
+ }
81
+ if (registryData.installCommand) {
82
+ lines.push(`**Install:** \`${registryData.installCommand}\``);
83
+ }
84
+ // Auth requirements
85
+ const requiresAuth = registryData.requiresAuth || registryData.metadata?.requiresAuth;
86
+ if (requiresAuth) {
87
+ lines.push("");
88
+ lines.push("### Authentication Required");
89
+ const authEnvVars = registryData.authDetails?.envVars || registryData.metadata?.authEnvVars || [];
90
+ if (authEnvVars.length > 0) {
91
+ lines.push("Environment variables needed:");
92
+ for (const ev of authEnvVars) {
93
+ lines.push(`- \`${ev.name}\`${ev.description ? `: ${ev.description}` : ""}`);
94
+ }
95
+ }
96
+ const authSchemes = registryData.authDetails?.schemes || registryData.metadata?.authSchemes || [];
97
+ if (authSchemes.length > 0) {
98
+ lines.push(`**Auth schemes:** ${authSchemes.join(", ")}`);
99
+ }
100
+ }
101
+ lines.push("");
102
+ }
103
+ // Live tools (from connection or registry)
104
+ const tools = connected
105
+ ? [...connected.tools.values()]
106
+ : registryData?.tools || [];
107
+ if (tools.length > 0) {
108
+ lines.push(`### Tools (${tools.length})`);
109
+ for (const tool of tools) {
110
+ const nsName = connected
111
+ ? `\`${namespaceTool(slug, tool.name)}\``
112
+ : `\`${tool.name}\``;
113
+ lines.push(`- ${nsName}: ${tool.description || "_No description_"}`);
114
+ }
115
+ lines.push("");
116
+ }
117
+ // Authoritative UI capability (live connection only) — inspect actual
118
+ // tool _meta.ui.resourceUri and ui:// resources. This confirms (or
119
+ // refutes) the registry's heuristic "detected" flag.
120
+ if (connected) {
121
+ const liveUi = detectLiveUi(connected.tools.values(), connected.resources.values());
122
+ if (liveUi.supportsUi) {
123
+ lines.push("### 🖼️ Interactive UI (confirmed live)");
124
+ if (liveUi.uiTools.length > 0) {
125
+ lines.push(`**UI tools:** ${liveUi.uiTools.map((t) => `\`${t}\``).join(", ")}`);
126
+ }
127
+ if (liveUi.uiResources.length > 0) {
128
+ lines.push(`**UI resources:** ${liveUi.uiResources.map((u) => `\`${u}\``).join(", ")}`);
129
+ }
130
+ lines.push("");
131
+ }
132
+ }
133
+ // Action suggestions
134
+ if (!connected) {
135
+ if (registryData?.installCommand) {
136
+ lines.push(`→ Connect: \`mcp_connect({slug: "${slug}"})\``);
137
+ }
138
+ else {
139
+ lines.push("⚠️ No install command available. You can connect manually:", `\`mcp_connect({command: "npx", args: ["-y", "package-name"]})\``);
140
+ }
141
+ }
142
+ else {
143
+ lines.push(`→ Disconnect: \`mcp_disconnect({slug: "${slug}"})\``);
144
+ }
145
+ return {
146
+ content: [
147
+ { type: "text", text: lines.join("\n") },
148
+ ],
149
+ };
150
+ }
151
+ catch (err) {
152
+ return toolError(`Failed to get server info: ${err instanceof Error ? err.message : String(err)}`);
153
+ }
154
+ });
155
+ }
156
+ //# sourceMappingURL=server-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-info.js","sourceRoot":"","sources":["../../src/meta-tools/server-info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { UsageTracker } from "../analytics/usage-tracker.js";
3
+ /**
4
+ * Register the `mcp_usage` meta-tool for viewing usage analytics.
5
+ */
6
+ export declare function registerUsage(server: McpServer, usageTracker: UsageTracker): void;
@@ -0,0 +1,149 @@
1
+ import { z } from "zod";
2
+ import { toolError } from "../utils/errors.js";
3
+ /**
4
+ * Register the `mcp_usage` meta-tool for viewing usage analytics.
5
+ */
6
+ export function registerUsage(server, usageTracker) {
7
+ server.tool("mcp_usage", "View usage analytics for connected MCP servers — call counts, latency, error rates, and recent activity.", {
8
+ slug: z
9
+ .string()
10
+ .optional()
11
+ .describe("Filter stats to a specific server slug. Omit for global stats."),
12
+ action: z
13
+ .enum(["stats", "recent", "slow", "reset"])
14
+ .optional()
15
+ .describe("Action: stats (default — summary), recent (recent calls), slow (slow calls), reset (clear all data)"),
16
+ limit: z
17
+ .number()
18
+ .optional()
19
+ .describe("Limit number of results for 'recent' and 'slow' actions (default: 20)"),
20
+ threshold: z
21
+ .number()
22
+ .optional()
23
+ .describe("Latency threshold in ms for 'slow' action (default: 5000)"),
24
+ }, async ({ slug, action = "stats", limit = 20, threshold = 5000 }) => {
25
+ try {
26
+ switch (action) {
27
+ case "stats": {
28
+ const stats = usageTracker.getStats(slug);
29
+ if (stats.totalCalls === 0) {
30
+ return {
31
+ content: [
32
+ {
33
+ type: "text",
34
+ text: slug
35
+ ? `No usage data recorded for **${slug}** yet.`
36
+ : "No usage data recorded yet. Start calling tools to see analytics.",
37
+ },
38
+ ],
39
+ };
40
+ }
41
+ const lines = [
42
+ slug ? `## Usage Stats: ${slug}` : "## Global Usage Stats",
43
+ "",
44
+ `**Total calls:** ${stats.totalCalls}`,
45
+ `**Total errors:** ${stats.totalErrors} (${((stats.totalErrors / stats.totalCalls) * 100).toFixed(1)}%)`,
46
+ `**Avg latency:** ${stats.avgLatencyMs.toFixed(0)}ms`,
47
+ "",
48
+ ];
49
+ // Top tools by calls
50
+ if (stats.topToolsByCalls.length > 0) {
51
+ lines.push("### Most Used Tools");
52
+ for (const tool of stats.topToolsByCalls.slice(0, 5)) {
53
+ const errorRate = tool.callCount > 0
54
+ ? ((tool.errorCount / tool.callCount) * 100).toFixed(1)
55
+ : "0.0";
56
+ lines.push(`- **${tool.key}**: ${tool.callCount} calls, ${tool.avgLatencyMs.toFixed(0)}ms avg, p95 ${tool.p95LatencyMs.toFixed(0)}ms, ${errorRate}% errors`);
57
+ }
58
+ lines.push("");
59
+ }
60
+ // Slowest tools
61
+ if (stats.slowestTools.length > 0) {
62
+ lines.push("### Slowest Tools (≥5 calls)");
63
+ for (const tool of stats.slowestTools.slice(0, 5)) {
64
+ lines.push(`- **${tool.key}**: ${tool.avgLatencyMs.toFixed(0)}ms avg, p95 ${tool.p95LatencyMs.toFixed(0)}ms (${tool.callCount} calls)`);
65
+ }
66
+ lines.push("");
67
+ }
68
+ // Per-server breakdown
69
+ if (stats.perServer.length > 0) {
70
+ lines.push("### Per-Server Breakdown");
71
+ for (const srv of stats.perServer) {
72
+ const errorRate = srv.totalCalls > 0
73
+ ? ((srv.totalErrors / srv.totalCalls) * 100).toFixed(1)
74
+ : "0.0";
75
+ lines.push(`- **${srv.slug}**: ${srv.totalCalls} calls, ${srv.avgLatencyMs.toFixed(0)}ms avg, ${errorRate}% errors`);
76
+ }
77
+ lines.push("");
78
+ }
79
+ return {
80
+ content: [{ type: "text", text: lines.join("\n") }],
81
+ };
82
+ }
83
+ case "recent": {
84
+ const recent = usageTracker.getRecentCalls(limit);
85
+ if (recent.length === 0) {
86
+ return {
87
+ content: [
88
+ { type: "text", text: "No recent tool calls recorded." },
89
+ ],
90
+ };
91
+ }
92
+ const lines = [
93
+ `## Recent Tool Calls (${recent.length})`,
94
+ "",
95
+ ];
96
+ for (const call of recent) {
97
+ const status = call.success ? "✅" : "❌";
98
+ const time = new Date(call.startedAt).toISOString().slice(11, 19);
99
+ lines.push(`${status} \`${call.slug}::${call.toolName}\` — ${call.durationMs}ms [${time}]${call.error ? ` — ${call.error}` : ""}`);
100
+ }
101
+ return {
102
+ content: [{ type: "text", text: lines.join("\n") }],
103
+ };
104
+ }
105
+ case "slow": {
106
+ const slowCalls = usageTracker.getSlowCalls(threshold);
107
+ if (slowCalls.length === 0) {
108
+ return {
109
+ content: [
110
+ {
111
+ type: "text",
112
+ text: `No tool calls exceeded the ${threshold}ms threshold.`,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ const sorted = [...slowCalls]
118
+ .sort((a, b) => b.durationMs - a.durationMs)
119
+ .slice(0, limit);
120
+ const lines = [
121
+ `## Slow Tool Calls (>${threshold}ms) — ${sorted.length} results`,
122
+ "",
123
+ ];
124
+ for (const call of sorted) {
125
+ const status = call.success ? "✅" : "❌";
126
+ lines.push(`${status} \`${call.slug}::${call.toolName}\` — **${call.durationMs}ms**`);
127
+ }
128
+ return {
129
+ content: [{ type: "text", text: lines.join("\n") }],
130
+ };
131
+ }
132
+ case "reset": {
133
+ usageTracker.reset();
134
+ return {
135
+ content: [
136
+ { type: "text", text: "✅ Usage analytics data has been reset." },
137
+ ],
138
+ };
139
+ }
140
+ default:
141
+ return toolError(`Unknown action: ${action}`);
142
+ }
143
+ }
144
+ catch (err) {
145
+ return toolError(err instanceof Error ? err.message : String(err));
146
+ }
147
+ });
148
+ }
149
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/meta-tools/usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { GatewayConfig } from "../config/types.js";
2
+ import type { TrustTier } from "../registry/types.js";
3
+ export interface ServerPermissions {
4
+ slug: string;
5
+ trustTier: TrustTier;
6
+ allowedTools: string[] | "all";
7
+ blockedTools: string[];
8
+ autoConnect: boolean;
9
+ }
10
+ /**
11
+ * Manages per-server permissions with file-based persistence.
12
+ *
13
+ * In Phase 1 this is primarily informational — the host client's
14
+ * built-in HITL confirmation (tool call approval dialog) serves as
15
+ * the primary permission gate.
16
+ */
17
+ export declare class PermissionManager {
18
+ private permissions;
19
+ private readonly filePath;
20
+ constructor(config: GatewayConfig);
21
+ getPermissions(slug: string, trustTier: TrustTier): ServerPermissions;
22
+ setPermissions(slug: string, perms: ServerPermissions): void;
23
+ isToolAllowed(slug: string, toolName: string): boolean;
24
+ private loadFromDisk;
25
+ private saveToDisk;
26
+ }
@@ -0,0 +1,73 @@
1
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
2
+ import { log } from "../utils/logger.js";
3
+ /**
4
+ * Manages per-server permissions with file-based persistence.
5
+ *
6
+ * In Phase 1 this is primarily informational — the host client's
7
+ * built-in HITL confirmation (tool call approval dialog) serves as
8
+ * the primary permission gate.
9
+ */
10
+ export class PermissionManager {
11
+ permissions = new Map();
12
+ filePath;
13
+ constructor(config) {
14
+ this.filePath = config.permissionsPath;
15
+ this.loadFromDisk();
16
+ }
17
+ getPermissions(slug, trustTier) {
18
+ const existing = this.permissions.get(slug);
19
+ if (existing)
20
+ return existing;
21
+ // Return defaults for this trust tier
22
+ return {
23
+ slug,
24
+ trustTier,
25
+ allowedTools: "all",
26
+ blockedTools: [],
27
+ autoConnect: trustTier === "verified" || trustTier === "trusted",
28
+ };
29
+ }
30
+ setPermissions(slug, perms) {
31
+ this.permissions.set(slug, perms);
32
+ this.saveToDisk();
33
+ }
34
+ isToolAllowed(slug, toolName) {
35
+ const perms = this.permissions.get(slug);
36
+ if (!perms)
37
+ return true; // No restrictions stored → allow
38
+ if (perms.blockedTools.includes(toolName))
39
+ return false;
40
+ if (perms.allowedTools === "all")
41
+ return true;
42
+ return perms.allowedTools.includes(toolName);
43
+ }
44
+ loadFromDisk() {
45
+ if (!existsSync(this.filePath))
46
+ return;
47
+ try {
48
+ const raw = readFileSync(this.filePath, "utf-8");
49
+ const data = JSON.parse(raw);
50
+ for (const [slug, perms] of Object.entries(data.servers || {})) {
51
+ this.permissions.set(slug, { slug, ...perms });
52
+ }
53
+ log.debug("Loaded permissions", { count: this.permissions.size });
54
+ }
55
+ catch {
56
+ log.warn("Failed to load permissions file, using defaults");
57
+ }
58
+ }
59
+ saveToDisk() {
60
+ const data = { servers: {} };
61
+ for (const [slug, perms] of this.permissions) {
62
+ const { slug: _slug, ...rest } = perms;
63
+ data.servers[slug] = rest;
64
+ }
65
+ try {
66
+ writeFileSync(this.filePath, JSON.stringify(data, null, 2), "utf-8");
67
+ }
68
+ catch (err) {
69
+ log.warn("Failed to save permissions", { error: String(err) });
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=permission-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-manager.js","sourceRoot":"","sources":["../../src/permissions/permission-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { TrustTier } from "../registry/types.js";
2
+ /** Human-readable label for tool description prefixes */
3
+ export declare const TRUST_LABELS: Record<TrustTier, string>;
4
+ /** Default max concurrent tool calls per trust tier */
5
+ export declare const DEFAULT_MAX_CONCURRENT: Record<TrustTier, number>;
6
+ /** Policy controlling connection behavior per trust tier */
7
+ export interface TrustPolicy {
8
+ /** Must the user explicitly confirm before connecting? */
9
+ requiresConfirmation: boolean;
10
+ /** Can this server be connected at all? */
11
+ allowByDefault: boolean;
12
+ /** Description shown to user in confirmation warnings */
13
+ description: string;
14
+ }
15
+ /** Default trust policies per tier */
16
+ export declare const DEFAULT_TRUST_POLICIES: Record<TrustTier, TrustPolicy>;
17
+ /** Get the trust policy for a given tier */
18
+ export declare function getTrustPolicy(tier: TrustTier): TrustPolicy;
@@ -0,0 +1,42 @@
1
+ /** Human-readable label for tool description prefixes */
2
+ export const TRUST_LABELS = {
3
+ verified: "Verified",
4
+ trusted: "Trusted",
5
+ community: "Community",
6
+ unknown: "Unverified",
7
+ };
8
+ /** Default max concurrent tool calls per trust tier */
9
+ export const DEFAULT_MAX_CONCURRENT = {
10
+ verified: 10,
11
+ trusted: 5,
12
+ community: 3,
13
+ unknown: 1,
14
+ };
15
+ /** Default trust policies per tier */
16
+ export const DEFAULT_TRUST_POLICIES = {
17
+ verified: {
18
+ requiresConfirmation: false,
19
+ allowByDefault: true,
20
+ description: "Verified server — high quality, officially reviewed.",
21
+ },
22
+ trusted: {
23
+ requiresConfirmation: false,
24
+ allowByDefault: true,
25
+ description: "Trusted server — good quality with repository and install command.",
26
+ },
27
+ community: {
28
+ requiresConfirmation: true,
29
+ allowByDefault: true,
30
+ description: "Community server — listed in registry with basic quality. User confirmation recommended.",
31
+ },
32
+ unknown: {
33
+ requiresConfirmation: true,
34
+ allowByDefault: true,
35
+ description: "Unverified server — unknown origin. User confirmation required.",
36
+ },
37
+ };
38
+ /** Get the trust policy for a given tier */
39
+ export function getTrustPolicy(tier) {
40
+ return DEFAULT_TRUST_POLICIES[tier];
41
+ }
42
+ //# sourceMappingURL=trust-tiers.js.map