@lionad/port-key-mcp 0.3.0 → 0.4.2

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 (46) hide show
  1. package/README.md +81 -29
  2. package/dist/config/index.d.ts +26 -0
  3. package/dist/config/index.js +24 -0
  4. package/dist/config/index.js.map +1 -0
  5. package/dist/logger.d.ts +7 -0
  6. package/dist/logger.js +48 -0
  7. package/dist/logger.js.map +1 -0
  8. package/dist/mcp-cli.js +84 -12
  9. package/dist/mcp-cli.js.map +1 -1
  10. package/dist/mcp-server.d.ts +16 -2
  11. package/dist/mcp-server.js +250 -92
  12. package/dist/mcp-server.js.map +1 -1
  13. package/dist/resources/index.d.ts +13 -0
  14. package/dist/resources/index.js +5 -0
  15. package/dist/resources/index.js.map +1 -0
  16. package/dist/resources/port-mapping-config.d.ts +13 -0
  17. package/dist/resources/port-mapping-config.js +22 -0
  18. package/dist/resources/port-mapping-config.js.map +1 -0
  19. package/dist/resources/project-port-history.d.ts +15 -0
  20. package/dist/resources/project-port-history.js +30 -0
  21. package/dist/resources/project-port-history.js.map +1 -0
  22. package/dist/session-manager.d.ts +35 -0
  23. package/dist/session-manager.js +66 -0
  24. package/dist/session-manager.js.map +1 -0
  25. package/dist/tools/check-port-availability.d.ts +25 -0
  26. package/dist/tools/check-port-availability.js +65 -0
  27. package/dist/tools/check-port-availability.js.map +1 -0
  28. package/dist/tools/get-design-philosophy.d.ts +24 -0
  29. package/dist/tools/get-design-philosophy.js +52 -0
  30. package/dist/tools/get-design-philosophy.js.map +1 -0
  31. package/dist/tools/get-port-occupancy.d.ts +25 -0
  32. package/dist/tools/get-port-occupancy.js +69 -0
  33. package/dist/tools/get-port-occupancy.js.map +1 -0
  34. package/dist/tools/index.d.ts +94 -0
  35. package/dist/tools/index.js +11 -0
  36. package/dist/tools/index.js.map +1 -0
  37. package/dist/tools/map-project-name-to-port.d.ts +27 -0
  38. package/dist/tools/map-project-name-to-port.js +51 -0
  39. package/dist/tools/map-project-name-to-port.js.map +1 -0
  40. package/dist/utils/logger.d.ts +7 -0
  41. package/dist/utils/logger.js +55 -0
  42. package/dist/utils/logger.js.map +1 -0
  43. package/dist/utils/session-manager.d.ts +35 -0
  44. package/dist/utils/session-manager.js +66 -0
  45. package/dist/utils/session-manager.js.map +1 -0
  46. package/package.json +11 -5
@@ -1,103 +1,261 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { z } from "zod";
3
- import { mapToPort } from "@lionad/port-key";
4
- import { readFile } from "node:fs/promises";
5
- import { dirname, join } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
- const SUPPORTED_LANGUAGES = ["cn", "es", "fr", "de", "ja", "ko", "ru", "ar", "pt", "it"];
10
- async function loadLocale(lang) {
11
- const localePath = join(__dirname, "..", "locales", `${lang}.json`);
12
- try {
13
- const content = await readFile(localePath, "utf-8");
14
- const locale = JSON.parse(content);
15
- return locale.designPhilosophy || "";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
+ import { randomUUID } from "node:crypto";
5
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
6
+ import Fastify from "fastify";
7
+ import cors from "@fastify/cors";
8
+ import { tools } from "./tools/index.js";
9
+ import { resources } from "./resources/index.js";
10
+ import config from "./config/index.js";
11
+ import logger from "./utils/logger.js";
12
+ import { SessionManager } from "./utils/session-manager.js";
13
+ // Session manager for HTTP transport
14
+ const sessionManager = new SessionManager(config.session);
15
+ export class MCPServerApp {
16
+ server;
17
+ constructor() {
18
+ this.server = this.createServer();
16
19
  }
17
- catch {
18
- return "";
20
+ createServer() {
21
+ const server = new McpServer({
22
+ name: "PortKey",
23
+ // ! AUTO GENERATED VERSION - DO NOT EDIT
24
+ version: "0.4.2",
25
+ });
26
+ this.registerTools(server);
27
+ this.registerResources(server);
28
+ return server;
19
29
  }
20
- }
21
- const mcpServer = new McpServer({
22
- name: "PortKey",
23
- version: "0.1.5",
24
- });
25
- mcpServer.registerTool("map-project-name-to-port", {
26
- title: "Map Project Name to Port",
27
- description: "Map a project name to a port number using keyboard-based letter-to-number mapping",
28
- inputSchema: {
29
- projectName: z.string().min(1),
30
- map: z.string().optional(),
31
- preferDigitCount: z.number().int().min(2).max(5).optional(),
32
- minPort: z.number().int().min(0).max(65535).optional(),
33
- maxPort: z.number().int().min(0).max(65535).optional(),
34
- blockedPorts: z.array(z.number().int().min(0).max(65535)).optional(),
35
- },
36
- }, async ({ projectName, map, preferDigitCount, minPort, maxPort, blockedPorts }) => {
37
- try {
38
- let customMap = undefined;
39
- if (map && map !== "") {
40
- customMap = JSON.parse(map);
30
+ registerTools(server, isLocal = true) {
31
+ for (const tool of tools) {
32
+ // 云端执行时,不注册依赖本地工具的工具
33
+ if (!isLocal && tool.isLocal) {
34
+ continue;
35
+ }
36
+ server.registerTool(tool.name, {
37
+ description: tool.description,
38
+ inputSchema: tool.inputSchema,
39
+ }, tool.execute);
41
40
  }
42
- const options = {
43
- preferDigitCount,
44
- minPort,
45
- maxPort,
46
- blockedPorts: blockedPorts ? new Set(blockedPorts) : undefined,
47
- };
48
- const result = mapToPort(projectName, customMap, options);
49
- return {
50
- content: [
51
- {
52
- type: "text",
53
- text: JSON.stringify(result, null, 2),
54
- },
55
- ],
56
- };
57
41
  }
58
- catch (error) {
59
- const errorMessage = error && typeof error === "object" && "message" in error ? String(error.message) : String(error);
60
- return {
61
- content: [
62
- {
63
- type: "text",
64
- text: JSON.stringify({ error: errorMessage }),
65
- },
66
- ],
67
- isError: true,
68
- };
42
+ registerResources(server) {
43
+ for (const resource of resources) {
44
+ if (typeof resource.resourceUri === 'string') {
45
+ server.registerResource(resource.name, resource.resourceUri, {
46
+ title: resource.title,
47
+ description: resource.description,
48
+ mimeType: resource.mimeType,
49
+ }, async (uri) => {
50
+ const result = await resource.execute(uri);
51
+ return result;
52
+ });
53
+ }
54
+ else {
55
+ server.registerResource(resource.name, resource.resourceUri, {
56
+ title: resource.title,
57
+ description: resource.description,
58
+ mimeType: resource.mimeType,
59
+ }, async (uri, params) => {
60
+ const result = await resource.execute(uri, params);
61
+ return result;
62
+ });
63
+ }
64
+ }
69
65
  }
70
- });
71
- mcpServer.registerTool("get-design-philosophy", {
72
- title: "Get PortKey Design Philosophy",
73
- description: "Get design philosophy and background of PortKey",
74
- inputSchema: {
75
- lang: z.enum([...SUPPORTED_LANGUAGES]).default("cn"),
76
- },
77
- }, async ({ lang = "cn" }) => {
78
- try {
79
- const philosophy = await loadLocale(lang);
80
- return {
81
- content: [
82
- {
83
- type: "text",
84
- text: philosophy,
85
- },
86
- ],
87
- };
66
+ getMcpServer() {
67
+ return this.server;
68
+ }
69
+ async runStdio() {
70
+ logger.info("Starting PortKey MCP Server in Stdio mode");
71
+ try {
72
+ const transport = new StdioServerTransport();
73
+ await this.server.connect(transport);
74
+ logger.info("PortKey MCP Server connected to Stdio transport");
75
+ }
76
+ catch (error) {
77
+ logger.error("Failed to start Stdio server", error);
78
+ process.exit(1);
79
+ }
88
80
  }
89
- catch (error) {
90
- const errorMessage = error && typeof error === "object" && "message" in error ? String(error.message) : String(error);
91
- return {
92
- content: [
93
- {
94
- type: "text",
95
- text: JSON.stringify({ error: errorMessage }),
81
+ async runHttp(port = config.server.port) {
82
+ logger.info(`Starting PortKey MCP Server in HTTP mode on port ${port}`);
83
+ const fastify = Fastify({
84
+ logger: false, // We use our own logger
85
+ });
86
+ // Register CORS
87
+ await fastify.register(cors, {
88
+ origin: true, // Allow all origins for now, can be configured
89
+ exposedHeaders: ["mcp-session-id"],
90
+ allowedHeaders: ["Content-Type", "mcp-session-id", "mcp-protocol-version"],
91
+ });
92
+ // Health check endpoint
93
+ fastify.get("/health", async () => {
94
+ // Basic health check
95
+ const memoryUsage = process.memoryUsage();
96
+ const healthStatus = {
97
+ status: "ok",
98
+ uptime: process.uptime(),
99
+ memory: {
100
+ rss: Math.round(memoryUsage.rss / 1024 / 1024) + "MB",
101
+ heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024) + "MB",
102
+ heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024) + "MB",
96
103
  },
97
- ],
98
- isError: true,
104
+ sessions: sessionManager.size,
105
+ };
106
+ return healthStatus;
107
+ });
108
+ // Handle POST requests for client-to-server communication
109
+ fastify.post("/mcp", async (request, reply) => {
110
+ const sessionId = request.headers["mcp-session-id"];
111
+ let transport;
112
+ // Reuse existing transport if session ID provided
113
+ if (sessionId) {
114
+ transport = sessionManager.get(sessionId);
115
+ }
116
+ // Initialize new transport
117
+ if (!transport && isInitializeRequest(request.body)) {
118
+ const allowedHosts = [
119
+ `127.0.0.1:${port}`,
120
+ `localhost:${port}`,
121
+ `[::1]:${port}`,
122
+ ];
123
+ transport = new StreamableHTTPServerTransport({
124
+ sessionIdGenerator: () => randomUUID(),
125
+ onsessioninitialized: (id) => {
126
+ if (transport) {
127
+ sessionManager.set(id, transport);
128
+ }
129
+ },
130
+ // DNS rebinding protection
131
+ enableDnsRebindingProtection: true,
132
+ allowedHosts,
133
+ });
134
+ transport.onclose = () => {
135
+ if (transport?.sessionId) {
136
+ sessionManager.remove(transport.sessionId);
137
+ }
138
+ };
139
+ // Connect a new server instance to this transport
140
+ // Each HTTP session needs its own server instance to maintain state isolation
141
+ const sessionServer = this.createServer();
142
+ await sessionServer.connect(transport);
143
+ }
144
+ else if (!transport) {
145
+ return reply.code(400).send({
146
+ jsonrpc: "2.0",
147
+ error: {
148
+ code: -32000,
149
+ message: "Bad Request: No valid session ID provided or invalid initialization",
150
+ },
151
+ id: null,
152
+ });
153
+ }
154
+ // Handle the request
155
+ // @ts-ignore - Fastify types compatibility
156
+ await transport.handleRequest(request.raw, reply.raw, request.body);
157
+ });
158
+ // Handle GET requests for server-to-client notifications
159
+ fastify.get("/mcp", async (request, reply) => {
160
+ const sessionId = request.headers["mcp-session-id"];
161
+ if (!sessionId) {
162
+ return reply.code(400).send("Invalid or missing session ID");
163
+ }
164
+ const transport = sessionManager.get(sessionId);
165
+ if (!transport) {
166
+ return reply.code(400).send("Session not found");
167
+ }
168
+ // @ts-ignore
169
+ await transport.handleRequest(request.raw, reply.raw);
170
+ });
171
+ // Handle DELETE requests for session termination
172
+ fastify.delete("/mcp", async (request, reply) => {
173
+ const sessionId = request.headers["mcp-session-id"];
174
+ if (!sessionId) {
175
+ return reply.code(400).send("Invalid or missing session ID");
176
+ }
177
+ const transport = sessionManager.get(sessionId);
178
+ if (!transport) {
179
+ return reply.code(400).send("Session not found");
180
+ }
181
+ // @ts-ignore
182
+ await transport.handleRequest(request.raw, reply.raw);
183
+ sessionManager.remove(sessionId);
184
+ });
185
+ try {
186
+ await fastify.listen({ port, host: "127.0.0.1" });
187
+ logger.info(`PortKey MCP Server listening on http://127.0.0.1:${port}`);
188
+ logger.info(`Health check available at http://127.0.0.1:${port}/health`);
189
+ logger.info(`MCP endpoint available at http://127.0.0.1:${port}/mcp`);
190
+ }
191
+ catch (err) {
192
+ const code = err && typeof err === "object" && "code" in err ? err.code : undefined;
193
+ if (code === "EADDRINUSE") {
194
+ try {
195
+ const res = await fetch(`http://127.0.0.1:${port}/health`, {
196
+ signal: AbortSignal.timeout(1000),
197
+ headers: { Accept: "application/json" },
198
+ });
199
+ if (res.ok) {
200
+ const body = await res.json().catch(() => null);
201
+ if (body && typeof body === "object" && body.status === "ok") {
202
+ logger.info(`PortKey MCP Server already running on http://127.0.0.1:${port}`);
203
+ return;
204
+ }
205
+ }
206
+ }
207
+ catch {
208
+ }
209
+ }
210
+ logger.error("Failed to start HTTP server", err);
211
+ process.exit(1);
212
+ }
213
+ }
214
+ async run(options = {}) {
215
+ // Graceful shutdown
216
+ const shutdown = () => {
217
+ logger.info("Shutting down PortKey MCP Server...");
218
+ sessionManager.destroy();
219
+ process.exit(0);
99
220
  };
221
+ process.on("SIGINT", shutdown);
222
+ process.on("SIGTERM", shutdown);
223
+ // Re-register tools based on options.local
224
+ // By default local is true unless explicitly set to false
225
+ const isLocal = options.local !== false;
226
+ // Clear existing tools registration and re-register
227
+ // Note: Since we register in createServer(), we might need to recreate server or just register again
228
+ // But sdk doesn't support unregister. So we should create server with correct tools from start or
229
+ // modify registerTools to take options.
230
+ // Since createServer is called in constructor, we need a way to re-init or filter tools.
231
+ // Better approach: We should register tools in run() or have a separate init()
232
+ // But since constructor calls createServer, let's just create a NEW server instance if we need to filter tools
233
+ // However, this.server is already assigned.
234
+ // Let's modify createServer to accept options, but we can't change constructor signature easily without breaking things.
235
+ // Instead, let's re-create the server instance here if we need to filter tools.
236
+ if (isLocal === false) {
237
+ this.server = new McpServer({
238
+ name: "PortKey",
239
+ version: "0.1.5", // Should match what was in createServer
240
+ });
241
+ // Register only non-local tools
242
+ this.registerTools(this.server, false);
243
+ this.registerResources(this.server);
244
+ }
245
+ else {
246
+ // If isLocal is true (default), we already registered all tools in constructor
247
+ // But to be safe and consistent, we could re-register or just ensure constructor did the right thing.
248
+ // The constructor calls createServer which calls registerTools without args (so all tools).
249
+ // So if isLocal is true, we are good with default instance.
250
+ }
251
+ if (options.streamable || config.server.streamable) {
252
+ await this.runHttp(options.port || config.server.port);
253
+ }
254
+ else {
255
+ await this.runStdio();
256
+ }
100
257
  }
101
- });
102
- export { mcpServer };
258
+ }
259
+ // Export a singleton for backward compatibility if needed, though class usage is preferred
260
+ export const mcpServerApp = new MCPServerApp();
103
261
  //# sourceMappingURL=mcp-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,eAAe,CAAC;AAEjC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,qCAAqC;AACrC,MAAM,cAAc,GAAG,IAAI,cAAc,CAAgC,MAAM,CAAC,OAAO,CAAC,CAAC;AAEzF,MAAM,OAAO,YAAY;IACf,MAAM,CAAY;IAE1B;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;IACpC,CAAC;IAEO,YAAY;QAClB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,SAAS;YACf,yCAAyC;YACzC,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAE/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,aAAa,CAAC,MAAiB,EAAE,UAAmB,IAAI;QAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,qBAAqB;YACrB,IAAI,CAAC,OAAO,IAAK,IAAY,CAAC,OAAO,EAAE,CAAC;gBACtC,SAAS;YACX,CAAC;YACD,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT;gBACE,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,EACD,IAAI,CAAC,OAAc,CACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,MAAiB;QACzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAM,CAAC,gBAAgB,CACrB,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,WAAW,EACpB;oBACE,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,WAAW,EAAE,QAAQ,CAAC,WAAW;oBACjC,QAAQ,EAAG,QAAgB,CAAC,QAAQ;iBACrC,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;oBACZ,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBAC3C,OAAO,MAAM,CAAC;gBAChB,CAAC,CACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,gBAAgB,CACrB,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,WAAW,EACpB;oBACE,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,WAAW,EAAE,QAAQ,CAAC,WAAW;oBACjC,QAAQ,EAAG,QAAgB,CAAC,QAAQ;iBACrC,EACD,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;oBACpB,MAAM,MAAM,GAAG,MAAO,QAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC5D,OAAO,MAAM,CAAC;gBAChB,CAAC,CACF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAEM,YAAY;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;YAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAe,MAAM,CAAC,MAAM,CAAC,IAAI;QACpD,MAAM,CAAC,IAAI,CAAC,oDAAoD,IAAI,EAAE,CAAC,CAAC;QAExE,MAAM,OAAO,GAAG,OAAO,CAAC;YACtB,MAAM,EAAE,KAAK,EAAE,wBAAwB;SACxC,CAAC,CAAC;QAEH,gBAAgB;QAChB,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC3B,MAAM,EAAE,IAAI,EAAE,+CAA+C;YAC7D,cAAc,EAAE,CAAC,gBAAgB,CAAC;YAClC,cAAc,EAAE,CAAC,cAAc,EAAE,gBAAgB,EAAE,sBAAsB,CAAC;SAC3E,CAAC,CAAC;QAEH,wBAAwB;QACxB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YAChC,qBAAqB;YACrB,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,YAAY,GAAG;gBACnB,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;gBACxB,MAAM,EAAE;oBACN,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI;oBACrD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI;oBACjE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI;iBAChE;gBACD,QAAQ,EAAE,cAAc,CAAC,IAAI;aAC9B,CAAC;YAEF,OAAO,YAAY,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,0DAA0D;QAC1D,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;YAE1E,IAAI,SAAoD,CAAC;YAEzD,kDAAkD;YAClD,IAAI,SAAS,EAAE,CAAC;gBACd,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC5C,CAAC;YAED,2BAA2B;YAC3B,IAAI,CAAC,SAAS,IAAI,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpD,MAAM,YAAY,GAAG;oBACnB,aAAa,IAAI,EAAE;oBACnB,aAAa,IAAI,EAAE;oBACnB,SAAS,IAAI,EAAE;iBAChB,CAAC;gBAEF,SAAS,GAAG,IAAI,6BAA6B,CAAC;oBAC5C,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;oBACtC,oBAAoB,EAAE,CAAC,EAAE,EAAE,EAAE;wBAC3B,IAAI,SAAS,EAAE,CAAC;4BACd,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;wBACpC,CAAC;oBACH,CAAC;oBACD,2BAA2B;oBAC3B,4BAA4B,EAAE,IAAI;oBAClC,YAAY;iBACb,CAAC,CAAC;gBAEH,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;oBACvB,IAAI,SAAS,EAAE,SAAS,EAAE,CAAC;wBACzB,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;oBAC7C,CAAC;gBACH,CAAC,CAAC;gBAEF,kDAAkD;gBAClD,8EAA8E;gBAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC1C,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACzC,CAAC;iBAAM,IAAI,CAAC,SAAS,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE;wBACL,IAAI,EAAE,CAAC,KAAK;wBACZ,OAAO,EAAE,qEAAqE;qBAC/E;oBACD,EAAE,EAAE,IAAI;iBACT,CAAC,CAAC;YACL,CAAC;YAED,qBAAqB;YACrB,2CAA2C;YAC3C,MAAM,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;YAE1E,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC/D,CAAC;YAED,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACnD,CAAC;YAED,aAAa;YACb,MAAM,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,iDAAiD;QACjD,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;YAE1E,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC/D,CAAC;YAED,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACnD,CAAC;YAED,aAAa;YACb,MAAM,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACtD,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,oDAAoD,IAAI,EAAE,CAAC,CAAC;YACxE,MAAM,CAAC,IAAI,CAAC,8CAA8C,IAAI,SAAS,CAAC,CAAC;YACzE,MAAM,CAAC,IAAI,CAAC,8CAA8C,IAAI,MAAM,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAE,GAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7F,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,SAAS,EAAE;wBACzD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;wBACjC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;qBACxC,CAAC,CAAC;oBACH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;wBACX,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;wBAChD,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAK,IAAY,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;4BACtE,MAAM,CAAC,IAAI,CAAC,0DAA0D,IAAI,EAAE,CAAC,CAAC;4BAC9E,OAAO;wBACT,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;gBACT,CAAC;YACH,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,UAAoE,EAAE;QACrF,oBAAoB;QACpB,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACnD,cAAc,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEhC,2CAA2C;QAC3C,0DAA0D;QAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC;QAExC,oDAAoD;QACpD,qGAAqG;QACrG,kGAAkG;QAClG,yCAAyC;QACzC,yFAAyF;QAEzF,+EAA+E;QAC/E,+GAA+G;QAC/G,4CAA4C;QAE5C,yHAAyH;QACzH,gFAAgF;QAEhF,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC;gBAC3B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,OAAO,EAAE,wCAAwC;aAC3D,CAAC,CAAC;YACH,gCAAgC;YAChC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACvC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACL,+EAA+E;YAC/E,sGAAsG;YACtG,4FAA4F;YAC5F,4DAA4D;QAC/D,CAAC;QAED,IAAI,OAAO,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACnD,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AAED,2FAA2F;AAC3F,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const resources: {
2
+ name: string;
3
+ resourceUri: string;
4
+ title: string;
5
+ description: string;
6
+ mimeType: string;
7
+ execute: (uri: URL) => Promise<{
8
+ contents: {
9
+ uri: string;
10
+ text: string;
11
+ }[];
12
+ }>;
13
+ }[];
@@ -0,0 +1,5 @@
1
+ import { portMappingConfigResource } from './port-mapping-config.js';
2
+ export const resources = [
3
+ portMappingConfigResource,
4
+ ];
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAErE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,yBAAyB;CAC1B,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const portMappingConfigResource: {
2
+ name: string;
3
+ resourceUri: string;
4
+ title: string;
5
+ description: string;
6
+ mimeType: string;
7
+ execute: (uri: URL) => Promise<{
8
+ contents: {
9
+ uri: string;
10
+ text: string;
11
+ }[];
12
+ }>;
13
+ };
@@ -0,0 +1,22 @@
1
+ import { DEFAULT_MAP, DEFAULT_BLOCKED_PORTS } from "@lionad/port-key";
2
+ export const portMappingConfigResource = {
3
+ name: "config",
4
+ resourceUri: "config://port-mapping",
5
+ title: "Port Mapping Configuration",
6
+ description: "Default port mapping configuration and blocked ports",
7
+ mimeType: "application/json",
8
+ execute: async (uri) => {
9
+ return {
10
+ contents: [
11
+ {
12
+ uri: uri.href,
13
+ text: JSON.stringify({
14
+ defaultMap: DEFAULT_MAP,
15
+ defaultBlockedPorts: Array.from(DEFAULT_BLOCKED_PORTS),
16
+ }, null, 2),
17
+ },
18
+ ],
19
+ };
20
+ }
21
+ };
22
+ //# sourceMappingURL=port-mapping-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-mapping-config.js","sourceRoot":"","sources":["../../src/resources/port-mapping-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEtE,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,uBAAuB;IACpC,KAAK,EAAE,4BAA4B;IACnC,WAAW,EAAE,sDAAsD;IACnE,QAAQ,EAAE,kBAAkB;IAC5B,OAAO,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;QAC1B,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,UAAU,EAAE,WAAW;wBACvB,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;qBACvD,EAAE,IAAI,EAAE,CAAC,CAAC;iBACZ;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare const projectPortHistoryResource: {
3
+ name: string;
4
+ resourceUri: ResourceTemplate;
5
+ title: string;
6
+ description: string;
7
+ execute: (uri: URL, { projectName }: {
8
+ projectName: string;
9
+ }) => Promise<{
10
+ contents: {
11
+ uri: string;
12
+ text: string;
13
+ }[];
14
+ }>;
15
+ };
@@ -0,0 +1,30 @@
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { mapToPort } from "@lionad/port-key";
3
+ export const projectPortHistoryResource = {
4
+ name: "project-port-history",
5
+ resourceUri: new ResourceTemplate("projects://{projectName}/port-history", { list: undefined }),
6
+ title: "Project Port History",
7
+ description: "History of port assignments for a project",
8
+ execute: async (uri, { projectName }) => {
9
+ // In a real application, this would fetch from a database or log file
10
+ // For now, we simulate history by generating the current port assignment
11
+ const result = mapToPort(projectName);
12
+ const history = [
13
+ {
14
+ timestamp: new Date().toISOString(),
15
+ projectName,
16
+ assignedPort: result.port,
17
+ digits: result.digits,
18
+ }
19
+ ];
20
+ return {
21
+ contents: [
22
+ {
23
+ uri: uri.href,
24
+ text: JSON.stringify(history, null, 2),
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ };
30
+ //# sourceMappingURL=project-port-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-port-history.js","sourceRoot":"","sources":["../../src/resources/project-port-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,IAAI,gBAAgB,CAAC,uCAAuC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC/F,KAAK,EAAE,sBAAsB;IAC7B,WAAW,EAAE,2CAA2C;IACxD,OAAO,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE,WAAW,EAA2B,EAAE,EAAE;QACpE,sEAAsE;QACtE,yEAAyE;QACzE,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QAEtC,MAAM,OAAO,GAAG;YACd;gBACE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW;gBACX,YAAY,EAAE,MAAM,CAAC,IAAI;gBACzB,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB;SACF,CAAC;QAEF,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,35 @@
1
+ interface SessionOptions {
2
+ ttl: number;
3
+ timeout: number;
4
+ }
5
+ export declare class SessionManager<T> {
6
+ private sessions;
7
+ private options;
8
+ private cleanupInterval;
9
+ constructor(options?: SessionOptions);
10
+ /**
11
+ * Set a session with the given ID and data
12
+ */
13
+ set(id: string, data: T): void;
14
+ /**
15
+ * Get a session by ID. Updates the expiration time (sliding window).
16
+ */
17
+ get(id: string): T | undefined;
18
+ /**
19
+ * Remove a session by ID
20
+ */
21
+ remove(id: string): void;
22
+ /**
23
+ * Get the number of active sessions
24
+ */
25
+ get size(): number;
26
+ /**
27
+ * Cleanup expired sessions
28
+ */
29
+ private cleanup;
30
+ /**
31
+ * Stop the cleanup interval and clear all sessions
32
+ */
33
+ destroy(): void;
34
+ }
35
+ export {};
@@ -0,0 +1,66 @@
1
+ import config from './config/index.js';
2
+ export class SessionManager {
3
+ sessions;
4
+ options;
5
+ cleanupInterval;
6
+ constructor(options = config.session) {
7
+ this.sessions = new Map();
8
+ this.options = options;
9
+ // Cleanup every minute to remove expired sessions
10
+ this.cleanupInterval = setInterval(() => this.cleanup(), 60000);
11
+ }
12
+ /**
13
+ * Set a session with the given ID and data
14
+ */
15
+ set(id, data) {
16
+ const expiresAt = Date.now() + this.options.ttl * 1000;
17
+ this.sessions.set(id, { data, expiresAt });
18
+ }
19
+ /**
20
+ * Get a session by ID. Updates the expiration time (sliding window).
21
+ */
22
+ get(id) {
23
+ const session = this.sessions.get(id);
24
+ if (!session)
25
+ return undefined;
26
+ // Check if expired
27
+ if (Date.now() > session.expiresAt) {
28
+ this.sessions.delete(id);
29
+ return undefined;
30
+ }
31
+ // Refresh expiration
32
+ session.expiresAt = Date.now() + this.options.ttl * 1000;
33
+ return session.data;
34
+ }
35
+ /**
36
+ * Remove a session by ID
37
+ */
38
+ remove(id) {
39
+ this.sessions.delete(id);
40
+ }
41
+ /**
42
+ * Get the number of active sessions
43
+ */
44
+ get size() {
45
+ return this.sessions.size;
46
+ }
47
+ /**
48
+ * Cleanup expired sessions
49
+ */
50
+ cleanup() {
51
+ const now = Date.now();
52
+ for (const [id, session] of this.sessions.entries()) {
53
+ if (now > session.expiresAt) {
54
+ this.sessions.delete(id);
55
+ }
56
+ }
57
+ }
58
+ /**
59
+ * Stop the cleanup interval and clear all sessions
60
+ */
61
+ destroy() {
62
+ clearInterval(this.cleanupInterval);
63
+ this.sessions.clear();
64
+ }
65
+ }
66
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAYvC,MAAM,OAAO,cAAc;IACjB,QAAQ,CAAiC;IACzC,OAAO,CAAiB;IACxB,eAAe,CAAiB;IAExC,YAAY,UAA0B,MAAM,CAAC,OAAO;QAClD,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,kDAAkD;QAClD,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,EAAU,EAAE,IAAO;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;QACvD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,EAAU;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAE/B,mBAAmB;QACnB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACzB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,qBAAqB;QACrB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;QACzD,OAAO,OAAO,CAAC,IAAI,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,EAAU;QACf,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,IAAI,GAAG,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;gBAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ export declare const checkPortAvailabilityTool: {
3
+ name: string;
4
+ title: string;
5
+ isLocal: boolean;
6
+ description: string;
7
+ inputSchema: {
8
+ port: z.ZodNumber;
9
+ };
10
+ execute: ({ port }: {
11
+ port: number;
12
+ }) => Promise<{
13
+ content: {
14
+ type: string;
15
+ text: string;
16
+ }[];
17
+ isError?: undefined;
18
+ } | {
19
+ content: {
20
+ type: string;
21
+ text: string;
22
+ }[];
23
+ isError: boolean;
24
+ }>;
25
+ };