ssh-mcp-pro 1.0.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 (267) hide show
  1. package/AGENTS.md +127 -0
  2. package/ARCHITECTURE.md +145 -0
  3. package/LICENSE +21 -0
  4. package/LICENSES/MIT.txt +21 -0
  5. package/MIGRATION.md +14 -0
  6. package/README.md +175 -0
  7. package/REGISTRY_SUBMISSION.md +38 -0
  8. package/SECURITY.md +40 -0
  9. package/SECURITY_DECISIONS.md +59 -0
  10. package/dist/agent-bin.d.ts +3 -0
  11. package/dist/agent-bin.d.ts.map +1 -0
  12. package/dist/agent-bin.js +8 -0
  13. package/dist/agent-bin.js.map +1 -0
  14. package/dist/audit.d.ts +25 -0
  15. package/dist/audit.d.ts.map +1 -0
  16. package/dist/audit.js +50 -0
  17. package/dist/audit.js.map +1 -0
  18. package/dist/auth.d.ts +4 -0
  19. package/dist/auth.d.ts.map +1 -0
  20. package/dist/auth.js +33 -0
  21. package/dist/auth.js.map +1 -0
  22. package/dist/cli.d.ts +16 -0
  23. package/dist/cli.d.ts.map +1 -0
  24. package/dist/cli.js +99 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/config.d.ts +103 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +490 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/connector-credentials.d.ts +8 -0
  31. package/dist/connector-credentials.d.ts.map +1 -0
  32. package/dist/connector-credentials.js +132 -0
  33. package/dist/connector-credentials.js.map +1 -0
  34. package/dist/connector-profile.d.ts +17 -0
  35. package/dist/connector-profile.d.ts.map +1 -0
  36. package/dist/connector-profile.js +81 -0
  37. package/dist/connector-profile.js.map +1 -0
  38. package/dist/container.d.ts +18 -0
  39. package/dist/container.d.ts.map +1 -0
  40. package/dist/container.js +52 -0
  41. package/dist/container.js.map +1 -0
  42. package/dist/detect.d.ts +7 -0
  43. package/dist/detect.d.ts.map +1 -0
  44. package/dist/detect.js +271 -0
  45. package/dist/detect.js.map +1 -0
  46. package/dist/ensure.d.ts +17 -0
  47. package/dist/ensure.d.ts.map +1 -0
  48. package/dist/ensure.js +531 -0
  49. package/dist/ensure.js.map +1 -0
  50. package/dist/errors.d.ts +54 -0
  51. package/dist/errors.d.ts.map +1 -0
  52. package/dist/errors.js +84 -0
  53. package/dist/errors.js.map +1 -0
  54. package/dist/fs-tools.d.ts +26 -0
  55. package/dist/fs-tools.d.ts.map +1 -0
  56. package/dist/fs-tools.js +599 -0
  57. package/dist/fs-tools.js.map +1 -0
  58. package/dist/http-rate-limit.d.ts +9 -0
  59. package/dist/http-rate-limit.d.ts.map +1 -0
  60. package/dist/http-rate-limit.js +41 -0
  61. package/dist/http-rate-limit.js.map +1 -0
  62. package/dist/http-security.d.ts +22 -0
  63. package/dist/http-security.d.ts.map +1 -0
  64. package/dist/http-security.js +88 -0
  65. package/dist/http-security.js.map +1 -0
  66. package/dist/index.d.ts +10 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +201 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/logging.d.ts +52 -0
  71. package/dist/logging.d.ts.map +1 -0
  72. package/dist/logging.js +180 -0
  73. package/dist/logging.js.map +1 -0
  74. package/dist/mcp.d.ts +16 -0
  75. package/dist/mcp.d.ts.map +1 -0
  76. package/dist/mcp.js +159 -0
  77. package/dist/mcp.js.map +1 -0
  78. package/dist/metrics.d.ts +95 -0
  79. package/dist/metrics.d.ts.map +1 -0
  80. package/dist/metrics.js +204 -0
  81. package/dist/metrics.js.map +1 -0
  82. package/dist/oauth.d.ts +14 -0
  83. package/dist/oauth.d.ts.map +1 -0
  84. package/dist/oauth.js +105 -0
  85. package/dist/oauth.js.map +1 -0
  86. package/dist/policy.d.ts +64 -0
  87. package/dist/policy.d.ts.map +1 -0
  88. package/dist/policy.js +368 -0
  89. package/dist/policy.js.map +1 -0
  90. package/dist/process.d.ts +24 -0
  91. package/dist/process.d.ts.map +1 -0
  92. package/dist/process.js +212 -0
  93. package/dist/process.js.map +1 -0
  94. package/dist/prompts.d.ts +49 -0
  95. package/dist/prompts.d.ts.map +1 -0
  96. package/dist/prompts.js +191 -0
  97. package/dist/prompts.js.map +1 -0
  98. package/dist/rate-limiter.d.ts +57 -0
  99. package/dist/rate-limiter.d.ts.map +1 -0
  100. package/dist/rate-limiter.js +141 -0
  101. package/dist/rate-limiter.js.map +1 -0
  102. package/dist/remote/agent-cli.d.ts +2 -0
  103. package/dist/remote/agent-cli.d.ts.map +1 -0
  104. package/dist/remote/agent-cli.js +270 -0
  105. package/dist/remote/agent-cli.js.map +1 -0
  106. package/dist/remote/agent-executor.d.ts +26 -0
  107. package/dist/remote/agent-executor.d.ts.map +1 -0
  108. package/dist/remote/agent-executor.js +400 -0
  109. package/dist/remote/agent-executor.js.map +1 -0
  110. package/dist/remote/config.d.ts +3 -0
  111. package/dist/remote/config.d.ts.map +1 -0
  112. package/dist/remote/config.js +52 -0
  113. package/dist/remote/config.js.map +1 -0
  114. package/dist/remote/control-plane.d.ts +57 -0
  115. package/dist/remote/control-plane.d.ts.map +1 -0
  116. package/dist/remote/control-plane.js +1248 -0
  117. package/dist/remote/control-plane.js.map +1 -0
  118. package/dist/remote/crypto.d.ts +38 -0
  119. package/dist/remote/crypto.d.ts.map +1 -0
  120. package/dist/remote/crypto.js +143 -0
  121. package/dist/remote/crypto.js.map +1 -0
  122. package/dist/remote/mcp-tools.d.ts +10 -0
  123. package/dist/remote/mcp-tools.d.ts.map +1 -0
  124. package/dist/remote/mcp-tools.js +201 -0
  125. package/dist/remote/mcp-tools.js.map +1 -0
  126. package/dist/remote/policy.d.ts +11 -0
  127. package/dist/remote/policy.d.ts.map +1 -0
  128. package/dist/remote/policy.js +94 -0
  129. package/dist/remote/policy.js.map +1 -0
  130. package/dist/remote/schemas.d.ts +298 -0
  131. package/dist/remote/schemas.d.ts.map +1 -0
  132. package/dist/remote/schemas.js +111 -0
  133. package/dist/remote/schemas.js.map +1 -0
  134. package/dist/remote/scopes.d.ts +6 -0
  135. package/dist/remote/scopes.d.ts.map +1 -0
  136. package/dist/remote/scopes.js +24 -0
  137. package/dist/remote/scopes.js.map +1 -0
  138. package/dist/remote/store.d.ts +45 -0
  139. package/dist/remote/store.d.ts.map +1 -0
  140. package/dist/remote/store.js +355 -0
  141. package/dist/remote/store.js.map +1 -0
  142. package/dist/remote/types.d.ts +183 -0
  143. package/dist/remote/types.d.ts.map +1 -0
  144. package/dist/remote/types.js +103 -0
  145. package/dist/remote/types.js.map +1 -0
  146. package/dist/remote/util.d.ts +6 -0
  147. package/dist/remote/util.d.ts.map +1 -0
  148. package/dist/remote/util.js +45 -0
  149. package/dist/remote/util.js.map +1 -0
  150. package/dist/remote/websocket.d.ts +26 -0
  151. package/dist/remote/websocket.d.ts.map +1 -0
  152. package/dist/remote/websocket.js +167 -0
  153. package/dist/remote/websocket.js.map +1 -0
  154. package/dist/render-http.d.ts +2 -0
  155. package/dist/render-http.d.ts.map +1 -0
  156. package/dist/render-http.js +14 -0
  157. package/dist/render-http.js.map +1 -0
  158. package/dist/resources.d.ts +19 -0
  159. package/dist/resources.d.ts.map +1 -0
  160. package/dist/resources.js +96 -0
  161. package/dist/resources.js.map +1 -0
  162. package/dist/retry.d.ts +45 -0
  163. package/dist/retry.d.ts.map +1 -0
  164. package/dist/retry.js +120 -0
  165. package/dist/retry.js.map +1 -0
  166. package/dist/safety.d.ts +31 -0
  167. package/dist/safety.d.ts.map +1 -0
  168. package/dist/safety.js +174 -0
  169. package/dist/safety.js.map +1 -0
  170. package/dist/server-http.d.ts +2 -0
  171. package/dist/server-http.d.ts.map +1 -0
  172. package/dist/server-http.js +432 -0
  173. package/dist/server-http.js.map +1 -0
  174. package/dist/session.d.ts +116 -0
  175. package/dist/session.d.ts.map +1 -0
  176. package/dist/session.js +666 -0
  177. package/dist/session.js.map +1 -0
  178. package/dist/shell.d.ts +10 -0
  179. package/dist/shell.d.ts.map +1 -0
  180. package/dist/shell.js +83 -0
  181. package/dist/shell.js.map +1 -0
  182. package/dist/ssh-config.d.ts +94 -0
  183. package/dist/ssh-config.d.ts.map +1 -0
  184. package/dist/ssh-config.js +234 -0
  185. package/dist/ssh-config.js.map +1 -0
  186. package/dist/streaming.d.ts +36 -0
  187. package/dist/streaming.d.ts.map +1 -0
  188. package/dist/streaming.js +140 -0
  189. package/dist/streaming.js.map +1 -0
  190. package/dist/telemetry.d.ts +17 -0
  191. package/dist/telemetry.d.ts.map +1 -0
  192. package/dist/telemetry.js +101 -0
  193. package/dist/telemetry.js.map +1 -0
  194. package/dist/tools/connector.provider.d.ts +28 -0
  195. package/dist/tools/connector.provider.d.ts.map +1 -0
  196. package/dist/tools/connector.provider.js +360 -0
  197. package/dist/tools/connector.provider.js.map +1 -0
  198. package/dist/tools/ensure.provider.d.ts +18 -0
  199. package/dist/tools/ensure.provider.d.ts.map +1 -0
  200. package/dist/tools/ensure.provider.js +173 -0
  201. package/dist/tools/ensure.provider.js.map +1 -0
  202. package/dist/tools/fs.provider.d.ts +21 -0
  203. package/dist/tools/fs.provider.d.ts.map +1 -0
  204. package/dist/tools/fs.provider.js +259 -0
  205. package/dist/tools/fs.provider.js.map +1 -0
  206. package/dist/tools/index.d.ts +4 -0
  207. package/dist/tools/index.d.ts.map +1 -0
  208. package/dist/tools/index.js +68 -0
  209. package/dist/tools/index.js.map +1 -0
  210. package/dist/tools/metadata.d.ts +11 -0
  211. package/dist/tools/metadata.d.ts.map +1 -0
  212. package/dist/tools/metadata.js +10 -0
  213. package/dist/tools/metadata.js.map +1 -0
  214. package/dist/tools/output-schemas.d.ts +217 -0
  215. package/dist/tools/output-schemas.d.ts.map +1 -0
  216. package/dist/tools/output-schemas.js +300 -0
  217. package/dist/tools/output-schemas.js.map +1 -0
  218. package/dist/tools/process.provider.d.ts +22 -0
  219. package/dist/tools/process.provider.d.ts.map +1 -0
  220. package/dist/tools/process.provider.js +146 -0
  221. package/dist/tools/process.provider.js.map +1 -0
  222. package/dist/tools/registry.d.ts +12 -0
  223. package/dist/tools/registry.d.ts.map +1 -0
  224. package/dist/tools/registry.js +163 -0
  225. package/dist/tools/registry.js.map +1 -0
  226. package/dist/tools/results.d.ts +4 -0
  227. package/dist/tools/results.d.ts.map +1 -0
  228. package/dist/tools/results.js +5 -0
  229. package/dist/tools/results.js.map +1 -0
  230. package/dist/tools/session.provider.d.ts +23 -0
  231. package/dist/tools/session.provider.d.ts.map +1 -0
  232. package/dist/tools/session.provider.js +299 -0
  233. package/dist/tools/session.provider.js.map +1 -0
  234. package/dist/tools/system.provider.d.ts +18 -0
  235. package/dist/tools/system.provider.d.ts.map +1 -0
  236. package/dist/tools/system.provider.js +81 -0
  237. package/dist/tools/system.provider.js.map +1 -0
  238. package/dist/tools/transfer.provider.d.ts +16 -0
  239. package/dist/tools/transfer.provider.d.ts.map +1 -0
  240. package/dist/tools/transfer.provider.js +85 -0
  241. package/dist/tools/transfer.provider.js.map +1 -0
  242. package/dist/tools/tunnel.provider.d.ts +18 -0
  243. package/dist/tools/tunnel.provider.d.ts.map +1 -0
  244. package/dist/tools/tunnel.provider.js +142 -0
  245. package/dist/tools/tunnel.provider.js.map +1 -0
  246. package/dist/tools/types.d.ts +16 -0
  247. package/dist/tools/types.d.ts.map +1 -0
  248. package/dist/tools/types.js +2 -0
  249. package/dist/tools/types.js.map +1 -0
  250. package/dist/transfer.d.ts +40 -0
  251. package/dist/transfer.d.ts.map +1 -0
  252. package/dist/transfer.js +363 -0
  253. package/dist/transfer.js.map +1 -0
  254. package/dist/tunnel.d.ts +37 -0
  255. package/dist/tunnel.d.ts.map +1 -0
  256. package/dist/tunnel.js +234 -0
  257. package/dist/tunnel.js.map +1 -0
  258. package/dist/types.d.ts +341 -0
  259. package/dist/types.d.ts.map +1 -0
  260. package/dist/types.js +184 -0
  261. package/dist/types.js.map +1 -0
  262. package/docs/docker.md +22 -0
  263. package/examples/README.md +77 -0
  264. package/mcp.json +21 -0
  265. package/package.json +147 -0
  266. package/registry/ssh-mcp-pro/mcp.json +21 -0
  267. package/server.json +76 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAS/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AASnD,eAAO,MAAM,cAAc,UAAU,CAAC;AACtC,eAAO,MAAM,WAAW,qCAAqC,CAAC;AA4C9D,qBAAa,YAAY;IAKX,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAEb,SAAS,EAAE,YAAY;IAqBpD,OAAO,CAAC,aAAa;IA2HrB,OAAO,CAAC,kBAAkB;IAQpB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpB,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAInD"}
package/dist/mcp.js ADDED
@@ -0,0 +1,159 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CallToolRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ListPromptsRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
+ import { logger } from "./logging.js";
5
+ import { listResources, readResource } from "./resources.js";
6
+ import { getMCPPrompt, listMCPPrompts } from "./prompts.js";
7
+ import { withSpan } from "./telemetry.js";
8
+ import { createToolRegistry } from "./tools/index.js";
9
+ export const SERVER_VERSION = "1.0.0"; // x-release-please-version
10
+ export const SERVER_NAME = "io.github.oaslananka/ssh-mcp-pro";
11
+ function getSessionIdFromArgs(args) {
12
+ if (typeof args !== "object" || args === null || Array.isArray(args)) {
13
+ return undefined;
14
+ }
15
+ const sessionId = args.sessionId;
16
+ if (typeof sessionId !== "string" || sessionId.length === 0) {
17
+ return undefined;
18
+ }
19
+ return sessionId;
20
+ }
21
+ function rateLimitErrorResult(toolName, rateCheck, scope, sessionId) {
22
+ const payload = {
23
+ error: true,
24
+ code: "ERATELIMIT",
25
+ message: scope === "session" && sessionId
26
+ ? `Rate limit exceeded for session ${sessionId} while calling tool: ${toolName}`
27
+ : `Rate limit exceeded for tool: ${toolName}`,
28
+ resetIn: rateCheck.resetIn,
29
+ scope,
30
+ ...(sessionId ? { sessionId } : {}),
31
+ };
32
+ return {
33
+ content: [
34
+ {
35
+ type: "text",
36
+ text: JSON.stringify(payload, null, 2),
37
+ },
38
+ ],
39
+ isError: true,
40
+ };
41
+ }
42
+ export class SSHMCPServer {
43
+ container;
44
+ server;
45
+ registry;
46
+ toolProfile;
47
+ constructor(container) {
48
+ this.container = container;
49
+ this.toolProfile = container.config.get("connector").toolProfile;
50
+ this.server = new Server({
51
+ name: SERVER_NAME,
52
+ version: SERVER_VERSION,
53
+ }, {
54
+ capabilities: {
55
+ tools: {},
56
+ resources: {},
57
+ prompts: {},
58
+ },
59
+ });
60
+ this.registry = createToolRegistry(container);
61
+ this.setupHandlers();
62
+ this.setupErrorHandling();
63
+ }
64
+ setupHandlers() {
65
+ this.server.setRequestHandler(ListResourcesRequestSchema, async () => withSpan("mcp.list_resources", async (span) => {
66
+ span.setAttribute("mcp.request.kind", "list_resources");
67
+ span.setAttribute("mcp.tool_profile", this.toolProfile);
68
+ return listResources(this.toolProfile);
69
+ }, {
70
+ attributes: {
71
+ "mcp.request.kind": "list_resources",
72
+ },
73
+ }));
74
+ this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => withSpan("mcp.read_resource", async (span) => {
75
+ span.setAttribute("mcp.request.kind", "read_resource");
76
+ span.setAttribute("mcp.resource.uri", request.params.uri);
77
+ span.setAttribute("mcp.tool_profile", this.toolProfile);
78
+ return readResource(request.params.uri, this.container, this.toolProfile);
79
+ }, {
80
+ attributes: {
81
+ "mcp.request.kind": "read_resource",
82
+ "mcp.resource.uri": request.params.uri,
83
+ },
84
+ }));
85
+ this.server.setRequestHandler(ListPromptsRequestSchema, async () => withSpan("mcp.list_prompts", async (span) => {
86
+ span.setAttribute("mcp.request.kind", "list_prompts");
87
+ span.setAttribute("mcp.tool_profile", this.toolProfile);
88
+ return listMCPPrompts(this.toolProfile);
89
+ }, {
90
+ attributes: {
91
+ "mcp.request.kind": "list_prompts",
92
+ },
93
+ }));
94
+ this.server.setRequestHandler(GetPromptRequestSchema, async (request) => withSpan("mcp.get_prompt", async (span) => {
95
+ span.setAttribute("mcp.request.kind", "get_prompt");
96
+ span.setAttribute("mcp.prompt.name", request.params.name);
97
+ span.setAttribute("mcp.tool_profile", this.toolProfile);
98
+ return getMCPPrompt(request.params.name, request.params.arguments ?? {}, this.toolProfile);
99
+ }, {
100
+ attributes: {
101
+ "mcp.request.kind": "get_prompt",
102
+ "mcp.prompt.name": request.params.name,
103
+ },
104
+ }));
105
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
106
+ tools: this.registry.getAllTools(),
107
+ }));
108
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => withSpan("mcp.call_tool", async (span) => {
109
+ const { name, arguments: args } = request.params;
110
+ span.setAttribute("mcp.request.kind", "call_tool");
111
+ span.setAttribute("mcp.tool.name", name);
112
+ const rateLimit = this.container.config.get("rateLimit");
113
+ if (rateLimit.enabled) {
114
+ const rateCheck = this.container.rateLimiter.check("global");
115
+ if (!rateCheck.allowed) {
116
+ span.setAttribute("mcp.rate_limited", true);
117
+ span.setAttribute("mcp.rate_limit.scope", "global");
118
+ return rateLimitErrorResult(name, rateCheck, "global");
119
+ }
120
+ const sessionId = getSessionIdFromArgs(args);
121
+ if (sessionId && rateLimit.perSession.enabled) {
122
+ const sessionCheck = this.container.rateLimiter.check(`session:${sessionId}`, {
123
+ maxRequests: rateLimit.perSession.maxRequests,
124
+ windowMs: rateLimit.perSession.windowMs,
125
+ });
126
+ if (!sessionCheck.allowed) {
127
+ span.setAttribute("mcp.rate_limited", true);
128
+ span.setAttribute("mcp.rate_limit.scope", "session");
129
+ span.setAttribute("mcp.session.id", sessionId);
130
+ return rateLimitErrorResult(name, sessionCheck, "session", sessionId);
131
+ }
132
+ }
133
+ }
134
+ span.setAttribute("mcp.rate_limited", false);
135
+ return this.registry.dispatch(name, args ?? {});
136
+ }, {
137
+ attributes: {
138
+ "mcp.request.kind": "call_tool",
139
+ "mcp.tool.name": request.params.name,
140
+ },
141
+ }));
142
+ }
143
+ setupErrorHandling() {
144
+ this.server.onerror = (error) => {
145
+ logger.error("Server error", {
146
+ error: error instanceof Error ? error.message : String(error),
147
+ });
148
+ };
149
+ }
150
+ async run() {
151
+ const transport = new StdioServerTransport();
152
+ await this.connect(transport);
153
+ }
154
+ async connect(transport) {
155
+ await this.server.connect(transport);
156
+ logger.info("SSH MCP Server started successfully");
157
+ }
158
+ }
159
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Metrics data structure
3
+ */
4
+ export interface Metrics {
5
+ sessions: {
6
+ created: number;
7
+ closed: number;
8
+ active: number;
9
+ errors: number;
10
+ };
11
+ commands: {
12
+ executed: number;
13
+ successful: number;
14
+ failed: number;
15
+ totalDurationMs: number;
16
+ avgDurationMs: number;
17
+ };
18
+ files: {
19
+ reads: number;
20
+ writes: number;
21
+ deletes: number;
22
+ bytesRead: number;
23
+ bytesWritten: number;
24
+ };
25
+ transfers: {
26
+ uploads: number;
27
+ downloads: number;
28
+ bytesUploaded: number;
29
+ bytesDownloaded: number;
30
+ };
31
+ tunnels: {
32
+ opened: number;
33
+ closed: number;
34
+ active: number;
35
+ errors: number;
36
+ };
37
+ policy: {
38
+ allowed: number;
39
+ denied: number;
40
+ explainOnly: number;
41
+ };
42
+ uptime: number;
43
+ startedAt: number;
44
+ }
45
+ /**
46
+ * Metrics collector for monitoring and observability
47
+ */
48
+ export declare class MetricsCollector {
49
+ private metrics;
50
+ constructor();
51
+ private createEmptyMetrics;
52
+ /**
53
+ * Record session creation
54
+ */
55
+ recordSessionCreated(): void;
56
+ /**
57
+ * Record session closed
58
+ */
59
+ recordSessionClosed(): void;
60
+ /**
61
+ * Record session error
62
+ */
63
+ recordSessionError(): void;
64
+ /**
65
+ * Record command execution
66
+ */
67
+ recordCommand(durationMs: number, success: boolean): void;
68
+ /**
69
+ * Record file read
70
+ */
71
+ recordFileRead(bytes: number): void;
72
+ /**
73
+ * Record file write
74
+ */
75
+ recordFileWrite(bytes: number): void;
76
+ recordFileDelete(): void;
77
+ recordTransfer(kind: "upload" | "download", bytes: number): void;
78
+ recordTunnelOpened(): void;
79
+ recordTunnelClosed(): void;
80
+ recordTunnelError(): void;
81
+ recordPolicyDecision(allowed: boolean, mode: "enforce" | "explain"): void;
82
+ /**
83
+ * Get current metrics
84
+ */
85
+ getMetrics(): Metrics;
86
+ /**
87
+ * Export metrics in Prometheus format
88
+ */
89
+ exportPrometheus(): string;
90
+ /**
91
+ * Reset all metrics
92
+ */
93
+ reset(): void;
94
+ }
95
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,SAAS,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAU;;IAMzB,OAAO,CAAC,kBAAkB;IAmB1B;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAQ5B;;OAEG;IACH,mBAAmB,IAAI,IAAI;IAQ3B;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAazD;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKpC,gBAAgB,IAAI,IAAI;IAIxB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAWhE,kBAAkB,IAAI,IAAI;IAK1B,kBAAkB,IAAI,IAAI;IAK1B,iBAAiB,IAAI,IAAI;IAIzB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI;IAazE;;OAEG;IACH,UAAU,IAAI,OAAO;IAarB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IA8D1B;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,204 @@
1
+ import { logger } from "./logging.js";
2
+ /**
3
+ * Metrics collector for monitoring and observability
4
+ */
5
+ export class MetricsCollector {
6
+ metrics;
7
+ constructor() {
8
+ this.metrics = this.createEmptyMetrics();
9
+ }
10
+ createEmptyMetrics() {
11
+ return {
12
+ sessions: { created: 0, closed: 0, active: 0, errors: 0 },
13
+ commands: {
14
+ executed: 0,
15
+ successful: 0,
16
+ failed: 0,
17
+ totalDurationMs: 0,
18
+ avgDurationMs: 0,
19
+ },
20
+ files: { reads: 0, writes: 0, deletes: 0, bytesRead: 0, bytesWritten: 0 },
21
+ transfers: { uploads: 0, downloads: 0, bytesUploaded: 0, bytesDownloaded: 0 },
22
+ tunnels: { opened: 0, closed: 0, active: 0, errors: 0 },
23
+ policy: { allowed: 0, denied: 0, explainOnly: 0 },
24
+ uptime: 0,
25
+ startedAt: Date.now(),
26
+ };
27
+ }
28
+ /**
29
+ * Record session creation
30
+ */
31
+ recordSessionCreated() {
32
+ this.metrics.sessions.created++;
33
+ this.metrics.sessions.active++;
34
+ logger.debug("Metrics: session created", {
35
+ active: this.metrics.sessions.active,
36
+ });
37
+ }
38
+ /**
39
+ * Record session closed
40
+ */
41
+ recordSessionClosed() {
42
+ this.metrics.sessions.closed++;
43
+ this.metrics.sessions.active = Math.max(0, this.metrics.sessions.active - 1);
44
+ logger.debug("Metrics: session closed", {
45
+ active: this.metrics.sessions.active,
46
+ });
47
+ }
48
+ /**
49
+ * Record session error
50
+ */
51
+ recordSessionError() {
52
+ this.metrics.sessions.errors++;
53
+ }
54
+ /**
55
+ * Record command execution
56
+ */
57
+ recordCommand(durationMs, success) {
58
+ this.metrics.commands.executed++;
59
+ this.metrics.commands.totalDurationMs += durationMs;
60
+ this.metrics.commands.avgDurationMs =
61
+ this.metrics.commands.totalDurationMs / this.metrics.commands.executed;
62
+ if (success) {
63
+ this.metrics.commands.successful++;
64
+ }
65
+ else {
66
+ this.metrics.commands.failed++;
67
+ }
68
+ }
69
+ /**
70
+ * Record file read
71
+ */
72
+ recordFileRead(bytes) {
73
+ this.metrics.files.reads++;
74
+ this.metrics.files.bytesRead += bytes;
75
+ }
76
+ /**
77
+ * Record file write
78
+ */
79
+ recordFileWrite(bytes) {
80
+ this.metrics.files.writes++;
81
+ this.metrics.files.bytesWritten += bytes;
82
+ }
83
+ recordFileDelete() {
84
+ this.metrics.files.deletes++;
85
+ }
86
+ recordTransfer(kind, bytes) {
87
+ if (kind === "upload") {
88
+ this.metrics.transfers.uploads++;
89
+ this.metrics.transfers.bytesUploaded += bytes;
90
+ return;
91
+ }
92
+ this.metrics.transfers.downloads++;
93
+ this.metrics.transfers.bytesDownloaded += bytes;
94
+ }
95
+ recordTunnelOpened() {
96
+ this.metrics.tunnels.opened++;
97
+ this.metrics.tunnels.active++;
98
+ }
99
+ recordTunnelClosed() {
100
+ this.metrics.tunnels.closed++;
101
+ this.metrics.tunnels.active = Math.max(0, this.metrics.tunnels.active - 1);
102
+ }
103
+ recordTunnelError() {
104
+ this.metrics.tunnels.errors++;
105
+ }
106
+ recordPolicyDecision(allowed, mode) {
107
+ if (mode === "explain") {
108
+ this.metrics.policy.explainOnly++;
109
+ return;
110
+ }
111
+ if (allowed) {
112
+ this.metrics.policy.allowed++;
113
+ }
114
+ else {
115
+ this.metrics.policy.denied++;
116
+ }
117
+ }
118
+ /**
119
+ * Get current metrics
120
+ */
121
+ getMetrics() {
122
+ return {
123
+ ...this.metrics,
124
+ sessions: { ...this.metrics.sessions },
125
+ commands: { ...this.metrics.commands },
126
+ files: { ...this.metrics.files },
127
+ transfers: { ...this.metrics.transfers },
128
+ tunnels: { ...this.metrics.tunnels },
129
+ policy: { ...this.metrics.policy },
130
+ uptime: Date.now() - this.metrics.startedAt,
131
+ };
132
+ }
133
+ /**
134
+ * Export metrics in Prometheus format
135
+ */
136
+ exportPrometheus() {
137
+ const m = this.getMetrics();
138
+ const lines = [
139
+ "# HELP ssh_mcp_sessions_total Total number of SSH sessions",
140
+ "# TYPE ssh_mcp_sessions_total counter",
141
+ `ssh_mcp_sessions_created ${m.sessions.created}`,
142
+ `ssh_mcp_sessions_closed ${m.sessions.closed}`,
143
+ `ssh_mcp_sessions_errors ${m.sessions.errors}`,
144
+ "",
145
+ "# HELP ssh_mcp_sessions_active Current active sessions",
146
+ "# TYPE ssh_mcp_sessions_active gauge",
147
+ `ssh_mcp_sessions_active ${m.sessions.active}`,
148
+ "",
149
+ "# HELP ssh_mcp_commands_total Total number of commands executed",
150
+ "# TYPE ssh_mcp_commands_total counter",
151
+ `ssh_mcp_commands_executed ${m.commands.executed}`,
152
+ `ssh_mcp_commands_successful ${m.commands.successful}`,
153
+ `ssh_mcp_commands_failed ${m.commands.failed}`,
154
+ "",
155
+ "# HELP ssh_mcp_command_duration_ms Average command duration",
156
+ "# TYPE ssh_mcp_command_duration_ms gauge",
157
+ `ssh_mcp_command_duration_avg_ms ${m.commands.avgDurationMs.toFixed(2)}`,
158
+ "",
159
+ "# HELP ssh_mcp_files_total File operations",
160
+ "# TYPE ssh_mcp_files_total counter",
161
+ `ssh_mcp_files_reads ${m.files.reads}`,
162
+ `ssh_mcp_files_writes ${m.files.writes}`,
163
+ `ssh_mcp_files_deletes ${m.files.deletes}`,
164
+ `ssh_mcp_files_bytes_read ${m.files.bytesRead}`,
165
+ `ssh_mcp_files_bytes_written ${m.files.bytesWritten}`,
166
+ "",
167
+ "# HELP ssh_mcp_transfers_total File transfer operations",
168
+ "# TYPE ssh_mcp_transfers_total counter",
169
+ `ssh_mcp_transfers_uploads ${m.transfers.uploads}`,
170
+ `ssh_mcp_transfers_downloads ${m.transfers.downloads}`,
171
+ `ssh_mcp_transfers_bytes_uploaded ${m.transfers.bytesUploaded}`,
172
+ `ssh_mcp_transfers_bytes_downloaded ${m.transfers.bytesDownloaded}`,
173
+ "",
174
+ "# HELP ssh_mcp_tunnels_total SSH tunnel lifecycle events",
175
+ "# TYPE ssh_mcp_tunnels_total counter",
176
+ `ssh_mcp_tunnels_opened ${m.tunnels.opened}`,
177
+ `ssh_mcp_tunnels_closed ${m.tunnels.closed}`,
178
+ `ssh_mcp_tunnels_errors ${m.tunnels.errors}`,
179
+ "",
180
+ "# HELP ssh_mcp_tunnels_active Active SSH tunnels",
181
+ "# TYPE ssh_mcp_tunnels_active gauge",
182
+ `ssh_mcp_tunnels_active ${m.tunnels.active}`,
183
+ "",
184
+ "# HELP ssh_mcp_policy_decisions_total Policy decisions",
185
+ "# TYPE ssh_mcp_policy_decisions_total counter",
186
+ `ssh_mcp_policy_allowed ${m.policy.allowed}`,
187
+ `ssh_mcp_policy_denied ${m.policy.denied}`,
188
+ `ssh_mcp_policy_explain_only ${m.policy.explainOnly}`,
189
+ "",
190
+ "# HELP ssh_mcp_uptime_ms Server uptime in milliseconds",
191
+ "# TYPE ssh_mcp_uptime_ms gauge",
192
+ `ssh_mcp_uptime_ms ${m.uptime}`,
193
+ ];
194
+ return lines.join("\n");
195
+ }
196
+ /**
197
+ * Reset all metrics
198
+ */
199
+ reset() {
200
+ this.metrics = this.createEmptyMetrics();
201
+ logger.info("Metrics reset");
202
+ }
203
+ }
204
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface OAuthVerificationConfig {
2
+ issuer?: string;
3
+ audience?: string;
4
+ jwksUrl?: string;
5
+ requiredScopes: string[];
6
+ allowedAlgorithms?: string[];
7
+ jwksTimeoutMs?: number;
8
+ jwksCooldownMs?: number;
9
+ jwksCacheMaxAgeMs?: number;
10
+ }
11
+ export declare function isOAuthAuthorizationValid(authorization: string | undefined, config: OAuthVerificationConfig): Promise<boolean>;
12
+ export declare function verifyOAuthAuthorization(authorization: string | undefined, config: OAuthVerificationConfig): Promise<Record<string, unknown>>;
13
+ export declare function normalizeOAuthError(error: unknown): Error;
14
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAQD,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4BlC;AAkED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAKzD"}
package/dist/oauth.js ADDED
@@ -0,0 +1,105 @@
1
+ import { createRemoteJWKSet, errors as joseErrors, jwtVerify, } from "jose";
2
+ import { extractBearerToken } from "./auth.js";
3
+ const DEFAULT_ALLOWED_ALGORITHMS = ["RS256"];
4
+ const DEFAULT_JWKS_TIMEOUT_MS = 5000;
5
+ const DEFAULT_JWKS_COOLDOWN_MS = 30_000;
6
+ const DEFAULT_JWKS_CACHE_MAX_AGE_MS = 300_000;
7
+ const jwksCache = new Map();
8
+ export async function isOAuthAuthorizationValid(authorization, config) {
9
+ try {
10
+ await verifyOAuthAuthorization(authorization, config);
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ export async function verifyOAuthAuthorization(authorization, config) {
18
+ if (!config.issuer || !config.audience || !config.jwksUrl) {
19
+ throw new Error("OAuth issuer, audience, and JWKS URL are required");
20
+ }
21
+ const token = extractBearerToken(authorization);
22
+ if (!token) {
23
+ throw new Error("Missing bearer token");
24
+ }
25
+ const algorithms = config.allowedAlgorithms ?? DEFAULT_ALLOWED_ALGORITHMS;
26
+ const { payload, protectedHeader } = await jwtVerify(token, getJwks(config), {
27
+ issuer: config.issuer,
28
+ audience: config.audience,
29
+ algorithms,
30
+ clockTolerance: "5s",
31
+ requiredClaims: ["iss", "aud", "exp", "iat"],
32
+ });
33
+ if (!protectedHeader.kid) {
34
+ throw new Error("JWT kid is required");
35
+ }
36
+ if (!protectedHeader.alg || !algorithms.includes(protectedHeader.alg)) {
37
+ throw new Error("Unsupported JWT algorithm");
38
+ }
39
+ validateClaims(payload, config);
40
+ return payload;
41
+ }
42
+ function getJwks(config) {
43
+ const key = [
44
+ config.jwksUrl,
45
+ config.jwksTimeoutMs ?? DEFAULT_JWKS_TIMEOUT_MS,
46
+ config.jwksCooldownMs ?? DEFAULT_JWKS_COOLDOWN_MS,
47
+ config.jwksCacheMaxAgeMs ?? DEFAULT_JWKS_CACHE_MAX_AGE_MS,
48
+ ].join("|");
49
+ const cached = jwksCache.get(key);
50
+ if (cached) {
51
+ return cached;
52
+ }
53
+ const jwks = createRemoteJWKSet(new URL(config.jwksUrl ?? ""), {
54
+ timeoutDuration: config.jwksTimeoutMs ?? DEFAULT_JWKS_TIMEOUT_MS,
55
+ cooldownDuration: config.jwksCooldownMs ?? DEFAULT_JWKS_COOLDOWN_MS,
56
+ cacheMaxAge: config.jwksCacheMaxAgeMs ?? DEFAULT_JWKS_CACHE_MAX_AGE_MS,
57
+ });
58
+ jwksCache.set(key, jwks);
59
+ return jwks;
60
+ }
61
+ function validateClaims(payload, config) {
62
+ if (payload.iss !== config.issuer) {
63
+ throw new Error("JWT issuer mismatch");
64
+ }
65
+ if (!audienceMatches(payload.aud, config.audience ?? "")) {
66
+ throw new Error("JWT audience mismatch");
67
+ }
68
+ const scopes = extractScopes(payload);
69
+ for (const requiredScope of config.requiredScopes) {
70
+ if (!scopes.has(requiredScope)) {
71
+ throw new Error("JWT required scope is missing");
72
+ }
73
+ }
74
+ }
75
+ function audienceMatches(audience, expected) {
76
+ return audience === expected || (Array.isArray(audience) && audience.includes(expected));
77
+ }
78
+ function extractScopes(payload) {
79
+ const scopes = new Set();
80
+ if (typeof payload.scope === "string") {
81
+ for (const scope of payload.scope.split(/\s+/).filter(Boolean)) {
82
+ scopes.add(scope);
83
+ }
84
+ }
85
+ if (typeof payload.scp === "string") {
86
+ for (const scope of payload.scp.split(/\s+/).filter(Boolean)) {
87
+ scopes.add(scope);
88
+ }
89
+ }
90
+ if (Array.isArray(payload.scp)) {
91
+ for (const scope of payload.scp) {
92
+ if (typeof scope === "string") {
93
+ scopes.add(scope);
94
+ }
95
+ }
96
+ }
97
+ return scopes;
98
+ }
99
+ export function normalizeOAuthError(error) {
100
+ if (error instanceof joseErrors.JOSEError) {
101
+ return new Error(error.message);
102
+ }
103
+ return error instanceof Error ? error : new Error(String(error));
104
+ }
105
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}