@hanzo/platform-mcp 1.4.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 (83) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +534 -0
  3. package/build/http-server.js +286 -0
  4. package/build/index.js +35 -0
  5. package/build/mcp/tools/application/applicationCleanQueues.js +23 -0
  6. package/build/mcp/tools/application/applicationCreate.js +39 -0
  7. package/build/mcp/tools/application/applicationDelete.js +21 -0
  8. package/build/mcp/tools/application/applicationDeploy.js +21 -0
  9. package/build/mcp/tools/application/applicationMarkRunning.js +23 -0
  10. package/build/mcp/tools/application/applicationMove.js +22 -0
  11. package/build/mcp/tools/application/applicationOne.js +26 -0
  12. package/build/mcp/tools/application/applicationReadAppMonitoring.js +26 -0
  13. package/build/mcp/tools/application/applicationReadTraefikConfig.js +26 -0
  14. package/build/mcp/tools/application/applicationRedeploy.js +23 -0
  15. package/build/mcp/tools/application/applicationRefreshToken.js +23 -0
  16. package/build/mcp/tools/application/applicationReload.js +22 -0
  17. package/build/mcp/tools/application/applicationSaveBitbucketProvider.js +49 -0
  18. package/build/mcp/tools/application/applicationSaveBuildType.js +56 -0
  19. package/build/mcp/tools/application/applicationSaveDockerProvider.js +43 -0
  20. package/build/mcp/tools/application/applicationSaveEnvironment.js +33 -0
  21. package/build/mcp/tools/application/applicationSaveGitProvider.js +49 -0
  22. package/build/mcp/tools/application/applicationSaveGiteaProvider.js +43 -0
  23. package/build/mcp/tools/application/applicationSaveGithubProvider.js +51 -0
  24. package/build/mcp/tools/application/applicationSaveGitlabProvider.js +48 -0
  25. package/build/mcp/tools/application/applicationStart.js +21 -0
  26. package/build/mcp/tools/application/applicationStop.js +21 -0
  27. package/build/mcp/tools/application/applicationUpdate.js +319 -0
  28. package/build/mcp/tools/application/applicationUpdateTraefikConfig.js +26 -0
  29. package/build/mcp/tools/application/index.js +24 -0
  30. package/build/mcp/tools/compose/composeCreate.js +31 -0
  31. package/build/mcp/tools/compose/composeDeploy.js +26 -0
  32. package/build/mcp/tools/compose/composeOne.js +24 -0
  33. package/build/mcp/tools/compose/composeReload.js +28 -0
  34. package/build/mcp/tools/compose/composeRemove.js +26 -0
  35. package/build/mcp/tools/compose/composeSaveEnvironment.js +28 -0
  36. package/build/mcp/tools/compose/composeStart.js +26 -0
  37. package/build/mcp/tools/compose/composeStop.js +26 -0
  38. package/build/mcp/tools/compose/composeUpdate.js +34 -0
  39. package/build/mcp/tools/compose/index.js +9 -0
  40. package/build/mcp/tools/index.js +12 -0
  41. package/build/mcp/tools/mysql/index.js +13 -0
  42. package/build/mcp/tools/mysql/mysqlChangeStatus.js +24 -0
  43. package/build/mcp/tools/mysql/mysqlCreate.js +50 -0
  44. package/build/mcp/tools/mysql/mysqlDeploy.js +21 -0
  45. package/build/mcp/tools/mysql/mysqlMove.js +24 -0
  46. package/build/mcp/tools/mysql/mysqlOne.js +23 -0
  47. package/build/mcp/tools/mysql/mysqlRebuild.js +21 -0
  48. package/build/mcp/tools/mysql/mysqlReload.js +22 -0
  49. package/build/mcp/tools/mysql/mysqlRemove.js +21 -0
  50. package/build/mcp/tools/mysql/mysqlSaveEnvironment.js +26 -0
  51. package/build/mcp/tools/mysql/mysqlSaveExternalPort.js +25 -0
  52. package/build/mcp/tools/mysql/mysqlStart.js +21 -0
  53. package/build/mcp/tools/mysql/mysqlStop.js +21 -0
  54. package/build/mcp/tools/mysql/mysqlUpdate.js +103 -0
  55. package/build/mcp/tools/postgres/index.js +13 -0
  56. package/build/mcp/tools/postgres/postgresChangeStatus.js +26 -0
  57. package/build/mcp/tools/postgres/postgresCreate.js +48 -0
  58. package/build/mcp/tools/postgres/postgresDeploy.js +23 -0
  59. package/build/mcp/tools/postgres/postgresMove.js +26 -0
  60. package/build/mcp/tools/postgres/postgresOne.js +26 -0
  61. package/build/mcp/tools/postgres/postgresRebuild.js +23 -0
  62. package/build/mcp/tools/postgres/postgresReload.js +26 -0
  63. package/build/mcp/tools/postgres/postgresRemove.js +23 -0
  64. package/build/mcp/tools/postgres/postgresSaveEnvironment.js +28 -0
  65. package/build/mcp/tools/postgres/postgresSaveExternalPort.js +27 -0
  66. package/build/mcp/tools/postgres/postgresStart.js +23 -0
  67. package/build/mcp/tools/postgres/postgresStop.js +23 -0
  68. package/build/mcp/tools/postgres/postgresUpdate.js +97 -0
  69. package/build/mcp/tools/project/index.js +6 -0
  70. package/build/mcp/tools/project/projectAll.js +68 -0
  71. package/build/mcp/tools/project/projectCreate.js +30 -0
  72. package/build/mcp/tools/project/projectDuplicate.js +54 -0
  73. package/build/mcp/tools/project/projectOne.js +24 -0
  74. package/build/mcp/tools/project/projectRemove.js +21 -0
  75. package/build/mcp/tools/project/projectUpdate.js +39 -0
  76. package/build/mcp/tools/toolFactory.js +60 -0
  77. package/build/server.js +12 -0
  78. package/build/types/platform.js +3 -0
  79. package/build/utils/apiClient.js +126 -0
  80. package/build/utils/clientConfig.js +37 -0
  81. package/build/utils/logger.js +38 -0
  82. package/build/utils/responseFormatter.js +33 -0
  83. package/package.json +63 -0
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env node
2
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
3
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
5
+ import express from "express";
6
+ import { randomUUID } from "node:crypto";
7
+ import { createServer } from "./server.js";
8
+ import { createLogger } from "./utils/logger.js";
9
+ // Container always uses port 3000 internally
10
+ const PORT = 3000;
11
+ const logger = createLogger("MCP-HTTP-Server");
12
+ export async function main() {
13
+ const app = express();
14
+ app.use(express.json());
15
+ // Store active transports by session ID for different transport types
16
+ const transports = {
17
+ streamable: {},
18
+ sse: {},
19
+ };
20
+ // Health check endpoint
21
+ app.get("/health", (_req, res) => {
22
+ res.json({ status: "ok", timestamp: new Date().toISOString() });
23
+ });
24
+ // Modern Streamable HTTP endpoint for POST requests (client-to-server)
25
+ app.post("/mcp", async (req, res) => {
26
+ try {
27
+ // Check for existing session ID
28
+ const sessionId = req.headers["mcp-session-id"];
29
+ let transport;
30
+ if (sessionId && transports.streamable[sessionId]) {
31
+ // Reuse existing transport
32
+ transport = transports.streamable[sessionId];
33
+ }
34
+ else if (!sessionId && isInitializeRequest(req.body)) {
35
+ // New initialization request
36
+ transport = new StreamableHTTPServerTransport({
37
+ sessionIdGenerator: () => randomUUID(),
38
+ onsessioninitialized: (sessionId) => {
39
+ // Store the transport by session ID
40
+ transports.streamable[sessionId] = transport;
41
+ logger.info("New MCP session initialized", { sessionId });
42
+ },
43
+ });
44
+ // Clean up transport when closed
45
+ transport.onclose = () => {
46
+ if (transport.sessionId) {
47
+ logger.info("MCP session closed", {
48
+ sessionId: transport.sessionId,
49
+ });
50
+ delete transports.streamable[transport.sessionId];
51
+ }
52
+ };
53
+ // Create and connect server first
54
+ const server = createServer();
55
+ // The transport will have sessionId after initialization
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ await server.connect(transport);
58
+ // Log after successful connection
59
+ logger.info("New MCP session server connected", {
60
+ sessionId: transport.sessionId,
61
+ });
62
+ }
63
+ else {
64
+ // Invalid request
65
+ res.status(400).json({
66
+ jsonrpc: "2.0",
67
+ error: {
68
+ code: -32000,
69
+ message: "Bad Request: No valid session ID provided for existing session or invalid initialization request",
70
+ },
71
+ id: null,
72
+ });
73
+ return;
74
+ }
75
+ // Handle the request
76
+ await transport.handleRequest(req, res, req.body);
77
+ }
78
+ catch (error) {
79
+ logger.error("Error handling HTTP request", {
80
+ error: error instanceof Error ? error.message : String(error),
81
+ sessionId: req.headers["mcp-session-id"],
82
+ });
83
+ if (!res.headersSent) {
84
+ res.status(500).json({
85
+ jsonrpc: "2.0",
86
+ error: {
87
+ code: -32603,
88
+ message: "Internal server error",
89
+ },
90
+ id: null,
91
+ });
92
+ }
93
+ }
94
+ });
95
+ // Reusable handler for GET and DELETE requests (Streamable HTTP)
96
+ const handleSessionRequest = async (req, res) => {
97
+ const sessionId = req.headers["mcp-session-id"];
98
+ if (!sessionId || !transports.streamable[sessionId]) {
99
+ res.status(400).json({
100
+ jsonrpc: "2.0",
101
+ error: {
102
+ code: -32000,
103
+ message: "Invalid or missing session ID",
104
+ },
105
+ id: null,
106
+ });
107
+ return;
108
+ }
109
+ try {
110
+ const transport = transports.streamable[sessionId];
111
+ await transport.handleRequest(req, res);
112
+ }
113
+ catch (error) {
114
+ logger.error("Error handling session request", {
115
+ error: error instanceof Error ? error.message : String(error),
116
+ sessionId,
117
+ method: req.method,
118
+ });
119
+ if (!res.headersSent) {
120
+ res.status(500).json({
121
+ jsonrpc: "2.0",
122
+ error: {
123
+ code: -32603,
124
+ message: "Internal server error",
125
+ },
126
+ id: null,
127
+ });
128
+ }
129
+ }
130
+ };
131
+ // Handle GET requests for server-to-client notifications via SSE
132
+ app.get("/mcp", handleSessionRequest);
133
+ // Handle DELETE requests for session termination
134
+ app.delete("/mcp", async (req, res) => {
135
+ const sessionId = req.headers["mcp-session-id"];
136
+ if (!sessionId || !transports.streamable[sessionId]) {
137
+ res.status(400).json({
138
+ jsonrpc: "2.0",
139
+ error: {
140
+ code: -32000,
141
+ message: "Invalid or missing session ID",
142
+ },
143
+ id: null,
144
+ });
145
+ return;
146
+ }
147
+ try {
148
+ const transport = transports.streamable[sessionId];
149
+ await transport.handleRequest(req, res);
150
+ // Clean up after session termination
151
+ if (transports.streamable[sessionId]) {
152
+ logger.info("MCP session terminated", { sessionId });
153
+ delete transports.streamable[sessionId];
154
+ }
155
+ }
156
+ catch (error) {
157
+ logger.error("Error handling DELETE request", {
158
+ error: error instanceof Error ? error.message : String(error),
159
+ sessionId,
160
+ });
161
+ if (!res.headersSent) {
162
+ res.status(500).json({
163
+ jsonrpc: "2.0",
164
+ error: {
165
+ code: -32603,
166
+ message: "Internal server error",
167
+ },
168
+ id: null,
169
+ });
170
+ }
171
+ }
172
+ });
173
+ // Legacy SSE endpoint for older clients (protocol version 2024-11-05)
174
+ app.get("/sse", async (_req, res) => {
175
+ try {
176
+ // Create SSE transport for legacy clients
177
+ const transport = new SSEServerTransport("/messages", res);
178
+ transports.sse[transport.sessionId] = transport;
179
+ res.on("close", () => {
180
+ logger.info("Legacy SSE session closed", {
181
+ sessionId: transport.sessionId,
182
+ });
183
+ delete transports.sse[transport.sessionId];
184
+ });
185
+ // Create and connect server for this transport
186
+ const server = createServer();
187
+ await server.connect(transport);
188
+ logger.info("New legacy SSE session initialized", {
189
+ sessionId: transport.sessionId,
190
+ });
191
+ }
192
+ catch (error) {
193
+ logger.error("Error handling SSE request", {
194
+ error: error instanceof Error ? error.message : String(error),
195
+ });
196
+ if (!res.headersSent) {
197
+ res.status(500).json({
198
+ jsonrpc: "2.0",
199
+ error: {
200
+ code: -32603,
201
+ message: "Internal server error",
202
+ },
203
+ id: null,
204
+ });
205
+ }
206
+ }
207
+ });
208
+ // Legacy message endpoint for older clients
209
+ app.post("/messages", async (req, res) => {
210
+ try {
211
+ const sessionId = req.query.sessionId;
212
+ if (!sessionId) {
213
+ logger.warn("No sessionId provided in message request");
214
+ res.status(400).json({
215
+ jsonrpc: "2.0",
216
+ error: {
217
+ code: -32000,
218
+ message: "sessionId query parameter is required",
219
+ },
220
+ id: null,
221
+ });
222
+ return;
223
+ }
224
+ const transport = transports.sse[sessionId];
225
+ if (!transport) {
226
+ logger.warn("No SSE transport found for sessionId", { sessionId });
227
+ res.status(400).json({
228
+ jsonrpc: "2.0",
229
+ error: {
230
+ code: -32000,
231
+ message: "No transport found for sessionId",
232
+ },
233
+ id: null,
234
+ });
235
+ return;
236
+ }
237
+ await transport.handlePostMessage(req, res, req.body);
238
+ }
239
+ catch (error) {
240
+ logger.error("Error handling legacy message request", {
241
+ error: error instanceof Error ? error.message : String(error),
242
+ sessionId: req.query.sessionId,
243
+ });
244
+ if (!res.headersSent) {
245
+ res.status(500).json({
246
+ jsonrpc: "2.0",
247
+ error: {
248
+ code: -32603,
249
+ message: "Internal server error",
250
+ },
251
+ id: null,
252
+ });
253
+ }
254
+ }
255
+ });
256
+ // Start the server
257
+ app.listen(PORT, () => {
258
+ logger.info("MCP Platform server started", {
259
+ port: PORT,
260
+ protocols: [
261
+ "Streamable HTTP (MCP 2025-03-26)",
262
+ "Legacy SSE (MCP 2024-11-05)",
263
+ ],
264
+ endpoints: {
265
+ modern: {
266
+ mcp: `http://localhost:${PORT}/mcp`,
267
+ health: `http://localhost:${PORT}/health`,
268
+ },
269
+ legacy: {
270
+ sse: `http://localhost:${PORT}/sse`,
271
+ messages: `http://localhost:${PORT}/messages`,
272
+ },
273
+ },
274
+ });
275
+ });
276
+ }
277
+ // Only run if this file is executed directly
278
+ if (import.meta.url === `file://${process.argv[1]}`) {
279
+ main().catch((error) => {
280
+ logger.error("Fatal error occurred", {
281
+ error: error instanceof Error ? error.message : String(error),
282
+ stack: error instanceof Error ? error.stack : undefined,
283
+ });
284
+ process.exit(1);
285
+ });
286
+ }
package/build/index.js ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createServer } from "./server.js";
4
+ import { createLogger } from "./utils/logger.js";
5
+ const logger = createLogger("MCP-Entry");
6
+ async function main() {
7
+ // Check if running in HTTP mode
8
+ const args = process.argv.slice(2);
9
+ const httpMode = args.includes("--http") ||
10
+ args.includes("--sse") ||
11
+ process.env.MCP_TRANSPORT === "http" ||
12
+ process.env.MCP_TRANSPORT === "sse";
13
+ if (httpMode) {
14
+ // Dynamic import to avoid loading Express dependencies when not needed
15
+ const httpModule = await import("./http-server.js");
16
+ if (typeof httpModule.main === "function") {
17
+ return httpModule.main();
18
+ }
19
+ else {
20
+ throw new Error("HTTP server module does not export main function");
21
+ }
22
+ }
23
+ // Default: stdio mode
24
+ const server = createServer();
25
+ const transport = new StdioServerTransport();
26
+ await server.connect(transport);
27
+ logger.info("MCP Platform CLI server running via stdio");
28
+ }
29
+ main().catch((error) => {
30
+ logger.error("Fatal error occurred", {
31
+ error: error.message,
32
+ stack: error.stack,
33
+ });
34
+ process.exit(1);
35
+ });
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationCleanQueues = createTool({
6
+ name: "application-cleanQueues",
7
+ description: "Cleans the queues for an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z
10
+ .string()
11
+ .describe("The ID of the application to clean queues for."),
12
+ }),
13
+ annotations: {
14
+ title: "Clean Application Queues",
15
+ destructiveHint: false,
16
+ idempotentHint: true,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const response = await apiClient.post("/application.cleanQueues", input);
21
+ return ResponseFormatter.success(`Queues for application "${input.applicationId}" cleaned successfully`, response.data);
22
+ },
23
+ });
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { createTool } from "../toolFactory.js";
4
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
5
+ export const applicationCreate = createTool({
6
+ name: "application-create",
7
+ description: "Creates a new application in Platform.",
8
+ schema: z.object({
9
+ name: z.string().min(1).describe("The name of the application."),
10
+ appName: z
11
+ .string()
12
+ .optional()
13
+ .describe("The app name for the application."),
14
+ description: z
15
+ .string()
16
+ .nullable()
17
+ .optional()
18
+ .describe("An optional description for the application."),
19
+ projectId: z
20
+ .string()
21
+ .min(1)
22
+ .describe("The ID of the project where the application will be created."),
23
+ serverId: z
24
+ .string()
25
+ .nullable()
26
+ .optional()
27
+ .describe("The ID of the server where the application will be deployed."),
28
+ }),
29
+ annotations: {
30
+ title: "Create Application",
31
+ destructiveHint: false,
32
+ idempotentHint: false,
33
+ openWorldHint: true,
34
+ },
35
+ handler: async (input) => {
36
+ const response = await apiClient.post("/application.create", input);
37
+ return ResponseFormatter.success(`Application "${input.name}" created successfully in project "${input.projectId}"`, response.data);
38
+ },
39
+ });
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationDelete = createTool({
6
+ name: "application-delete",
7
+ description: "Deletes an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z.string().describe("The ID of the application to delete."),
10
+ }),
11
+ annotations: {
12
+ title: "Delete Application",
13
+ destructiveHint: true,
14
+ idempotentHint: false,
15
+ openWorldHint: true,
16
+ },
17
+ handler: async (input) => {
18
+ const response = await apiClient.post("/application.delete", input);
19
+ return ResponseFormatter.success(`Application "${input.applicationId}" deleted successfully`, response.data);
20
+ },
21
+ });
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationDeploy = createTool({
6
+ name: "application-deploy",
7
+ description: "Deploys an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z.string().describe("The ID of the application to deploy."),
10
+ }),
11
+ annotations: {
12
+ title: "Deploy Application",
13
+ destructiveHint: false,
14
+ idempotentHint: false,
15
+ openWorldHint: true,
16
+ },
17
+ handler: async (input) => {
18
+ const response = await apiClient.post("/application.deploy", input);
19
+ return ResponseFormatter.success(`Application "${input.applicationId}" deployment started successfully`, response.data);
20
+ },
21
+ });
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationMarkRunning = createTool({
6
+ name: "application-markRunning",
7
+ description: "Marks an application as running in Platform.",
8
+ schema: z.object({
9
+ applicationId: z
10
+ .string()
11
+ .describe("The ID of the application to mark as running."),
12
+ }),
13
+ annotations: {
14
+ title: "Mark Application as Running",
15
+ destructiveHint: false,
16
+ idempotentHint: true,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const response = await apiClient.post("/application.markRunning", input);
21
+ return ResponseFormatter.success(`Application "${input.applicationId}" marked as running successfully`, response.data);
22
+ },
23
+ });
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationMove = createTool({
6
+ name: "application-move",
7
+ description: "Moves an application to a different project in Platform.",
8
+ schema: z.object({
9
+ applicationId: z.string().describe("The ID of the application to move."),
10
+ targetProjectId: z.string().describe("The ID of the destination project."),
11
+ }),
12
+ annotations: {
13
+ title: "Move Application",
14
+ destructiveHint: true,
15
+ idempotentHint: false,
16
+ openWorldHint: true,
17
+ },
18
+ handler: async (input) => {
19
+ const response = await apiClient.post("/application.move", input);
20
+ return ResponseFormatter.success(`Application "${input.applicationId}" moved to project "${input.targetProjectId}" successfully`, response.data);
21
+ },
22
+ });
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { createTool } from "../toolFactory.js";
4
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
5
+ export const applicationOne = createTool({
6
+ name: "application-one",
7
+ description: "Gets a specific application by its ID in Platform.",
8
+ schema: z.object({
9
+ applicationId: z
10
+ .string()
11
+ .describe("The ID of the application to retrieve."),
12
+ }),
13
+ annotations: {
14
+ title: "Get Application Details",
15
+ readOnlyHint: true,
16
+ idempotentHint: true,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const application = await apiClient.get(`/application.one?applicationId=${input.applicationId}`);
21
+ if (!application?.data) {
22
+ return ResponseFormatter.error("Failed to fetch application", `Application with ID "${input.applicationId}" not found`);
23
+ }
24
+ return ResponseFormatter.success(`Successfully fetched application "${input.applicationId}"`, application.data);
25
+ },
26
+ });
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationReadAppMonitoring = createTool({
6
+ name: "application-readAppMonitoring",
7
+ description: "Reads monitoring data for an application in Platform.",
8
+ schema: z.object({
9
+ appName: z
10
+ .string()
11
+ .describe("The app name of the application to get monitoring data for."),
12
+ }),
13
+ annotations: {
14
+ title: "Read Application Monitoring",
15
+ readOnlyHint: true,
16
+ idempotentHint: true,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const response = await apiClient.get(`/application.readAppMonitoring?appName=${input.appName}`);
21
+ if (!response?.data) {
22
+ return ResponseFormatter.error("Failed to fetch application monitoring data", `No monitoring data found for application "${input.appName}"`);
23
+ }
24
+ return ResponseFormatter.success(`Successfully fetched monitoring data for application "${input.appName}"`, response.data);
25
+ },
26
+ });
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationReadTraefikConfig = createTool({
6
+ name: "application-readTraefikConfig",
7
+ description: "Reads Traefik configuration for an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z
10
+ .string()
11
+ .describe("The ID of the application to get Traefik config for."),
12
+ }),
13
+ annotations: {
14
+ title: "Read Application Traefik Config",
15
+ readOnlyHint: true,
16
+ idempotentHint: true,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const response = await apiClient.get(`/application.readTraefikConfig?applicationId=${input.applicationId}`);
21
+ if (!response?.data) {
22
+ return ResponseFormatter.error("Failed to fetch application Traefik configuration", `No Traefik configuration found for application "${input.applicationId}"`);
23
+ }
24
+ return ResponseFormatter.success(`Successfully fetched Traefik configuration for application "${input.applicationId}"`, response.data);
25
+ },
26
+ });
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationRedeploy = createTool({
6
+ name: "application-redeploy",
7
+ description: "Redeploys an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z
10
+ .string()
11
+ .describe("The ID of the application to redeploy."),
12
+ }),
13
+ annotations: {
14
+ title: "Redeploy Application",
15
+ destructiveHint: false,
16
+ idempotentHint: false,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const response = await apiClient.post("/application.redeploy", input);
21
+ return ResponseFormatter.success(`Application "${input.applicationId}" redeployment started successfully`, response.data);
22
+ },
23
+ });
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationRefreshToken = createTool({
6
+ name: "application-refreshToken",
7
+ description: "Refreshes the token for an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z
10
+ .string()
11
+ .describe("The ID of the application to refresh token for."),
12
+ }),
13
+ annotations: {
14
+ title: "Refresh Application Token",
15
+ destructiveHint: false,
16
+ idempotentHint: false,
17
+ openWorldHint: true,
18
+ },
19
+ handler: async (input) => {
20
+ const response = await apiClient.post("/application.refreshToken", input);
21
+ return ResponseFormatter.success(`Token for application "${input.applicationId}" refreshed successfully`, response.data);
22
+ },
23
+ });
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ import apiClient from "../../../utils/apiClient.js";
3
+ import { ResponseFormatter } from "../../../utils/responseFormatter.js";
4
+ import { createTool } from "../toolFactory.js";
5
+ export const applicationReload = createTool({
6
+ name: "application-reload",
7
+ description: "Reloads an application in Platform.",
8
+ schema: z.object({
9
+ applicationId: z.string().describe("The ID of the application to reload."),
10
+ appName: z.string().describe("The app name of the application to reload."),
11
+ }),
12
+ annotations: {
13
+ title: "Reload Application",
14
+ destructiveHint: false,
15
+ idempotentHint: false,
16
+ openWorldHint: true,
17
+ },
18
+ handler: async (input) => {
19
+ const response = await apiClient.post("/application.reload", input);
20
+ return ResponseFormatter.success(`Application "${input.applicationId}" reloaded successfully`, response.data);
21
+ },
22
+ });