@samik081/mcp-komodo 0.1.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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +294 -0
  3. package/dist/core/client.d.ts +82 -0
  4. package/dist/core/client.js +41 -0
  5. package/dist/core/config.d.ts +22 -0
  6. package/dist/core/config.js +57 -0
  7. package/dist/core/errors.d.ts +31 -0
  8. package/dist/core/errors.js +46 -0
  9. package/dist/core/formatters.d.ts +36 -0
  10. package/dist/core/formatters.js +511 -0
  11. package/dist/core/logger.d.ts +15 -0
  12. package/dist/core/logger.js +26 -0
  13. package/dist/core/server.d.ts +15 -0
  14. package/dist/core/server.js +30 -0
  15. package/dist/core/tools.d.ts +37 -0
  16. package/dist/core/tools.js +48 -0
  17. package/dist/index.d.ts +10 -0
  18. package/dist/index.js +44 -0
  19. package/dist/tools/actions.d.ts +12 -0
  20. package/dist/tools/actions.js +122 -0
  21. package/dist/tools/alerters.d.ts +13 -0
  22. package/dist/tools/alerters.js +84 -0
  23. package/dist/tools/builders.d.ts +13 -0
  24. package/dist/tools/builders.js +84 -0
  25. package/dist/tools/builds.d.ts +13 -0
  26. package/dist/tools/builds.js +160 -0
  27. package/dist/tools/containers.d.ts +13 -0
  28. package/dist/tools/containers.js +81 -0
  29. package/dist/tools/deployments.d.ts +13 -0
  30. package/dist/tools/deployments.js +282 -0
  31. package/dist/tools/index.d.ts +10 -0
  32. package/dist/tools/index.js +32 -0
  33. package/dist/tools/procedures.d.ts +13 -0
  34. package/dist/tools/procedures.js +130 -0
  35. package/dist/tools/repos.d.ts +13 -0
  36. package/dist/tools/repos.js +132 -0
  37. package/dist/tools/resource-syncs.d.ts +13 -0
  38. package/dist/tools/resource-syncs.js +133 -0
  39. package/dist/tools/servers.d.ts +12 -0
  40. package/dist/tools/servers.js +270 -0
  41. package/dist/tools/stacks.d.ts +13 -0
  42. package/dist/tools/stacks.js +300 -0
  43. package/dist/tools/write.d.ts +13 -0
  44. package/dist/tools/write.js +302 -0
  45. package/dist/types/index.d.ts +12 -0
  46. package/dist/types/index.js +4 -0
  47. package/package.json +55 -0
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Deployment domain tools: list, get, log, deploy, lifecycle, destroy.
3
+ *
4
+ * Registers 6 MCP tools for Komodo Deployment resources.
5
+ * A Deployment is a single Docker container managed by Komodo,
6
+ * deployed to a specific server.
7
+ */
8
+ import { z } from "zod";
9
+ import { Types } from "komodo_client";
10
+ import { handleKomodoError } from "../core/errors.js";
11
+ import { formatDeploymentList, formatDeploymentDetail, formatLog, formatUpdateCreated, } from "../core/formatters.js";
12
+ import { registerTool } from "../core/tools.js";
13
+ export function registerDeploymentTools(server, client, config) {
14
+ // -------------------------------------------------------------------------
15
+ // komodo_list_deployments
16
+ // -------------------------------------------------------------------------
17
+ registerTool(server, config, {
18
+ name: "komodo_list_deployments",
19
+ description: "List all Komodo Deployments. A Deployment is a single Docker " +
20
+ "container managed by Komodo, deployed to a specific server. " +
21
+ "Returns name, state, image, and server for each deployment.",
22
+ accessTier: "read-only",
23
+ category: "deployments",
24
+ annotations: {
25
+ readOnlyHint: true,
26
+ destructiveHint: false,
27
+ idempotentHint: true,
28
+ },
29
+ inputSchema: {
30
+ tag: z.string().optional().describe("Filter deployments by tag name"),
31
+ },
32
+ handler: async (args) => {
33
+ const tag = args.tag;
34
+ try {
35
+ const deployments = await client.read("ListDeployments", {
36
+ query: tag ? { tags: [tag] } : undefined,
37
+ });
38
+ return {
39
+ content: [
40
+ { type: "text", text: formatDeploymentList(deployments) },
41
+ ],
42
+ };
43
+ }
44
+ catch (error) {
45
+ return handleKomodoError("listing deployments", error);
46
+ }
47
+ },
48
+ });
49
+ // -------------------------------------------------------------------------
50
+ // komodo_get_deployment
51
+ // -------------------------------------------------------------------------
52
+ registerTool(server, config, {
53
+ name: "komodo_get_deployment",
54
+ description: "Get detailed information about a specific Komodo Deployment by " +
55
+ "name or ID. A Deployment is a single Docker container managed by " +
56
+ "Komodo. Returns configuration, image, state, container status, " +
57
+ "and current action state.",
58
+ accessTier: "read-only",
59
+ category: "deployments",
60
+ annotations: {
61
+ readOnlyHint: true,
62
+ destructiveHint: false,
63
+ idempotentHint: true,
64
+ },
65
+ inputSchema: {
66
+ deployment: z.string().describe("Deployment name or ID"),
67
+ },
68
+ handler: async (args) => {
69
+ const deployment = args.deployment;
70
+ try {
71
+ const [deploymentData, actionState] = await Promise.all([
72
+ client.read("GetDeployment", { deployment }),
73
+ client.read("GetDeploymentActionState", { deployment }),
74
+ ]);
75
+ return {
76
+ content: [
77
+ {
78
+ type: "text",
79
+ text: formatDeploymentDetail(deploymentData, actionState),
80
+ },
81
+ ],
82
+ };
83
+ }
84
+ catch (error) {
85
+ return handleKomodoError(`getting deployment '${deployment}'`, error);
86
+ }
87
+ },
88
+ });
89
+ // -------------------------------------------------------------------------
90
+ // komodo_get_deployment_log
91
+ // -------------------------------------------------------------------------
92
+ registerTool(server, config, {
93
+ name: "komodo_get_deployment_log",
94
+ description: "Get logs from a Komodo Deployment's Docker container. Optionally " +
95
+ "search for specific terms in the log output. A Deployment is a " +
96
+ "single Docker container managed by Komodo. Returns the most " +
97
+ "recent log lines from the container.",
98
+ accessTier: "read-only",
99
+ category: "deployments",
100
+ annotations: {
101
+ readOnlyHint: true,
102
+ destructiveHint: false,
103
+ idempotentHint: true,
104
+ },
105
+ inputSchema: {
106
+ deployment: z.string().describe("Deployment name or ID"),
107
+ tail: z
108
+ .number()
109
+ .min(1)
110
+ .max(5000)
111
+ .optional()
112
+ .describe("Number of log lines to return (default: 50, max: 5000)"),
113
+ search_terms: z
114
+ .array(z.string())
115
+ .optional()
116
+ .describe("Search for lines matching these terms"),
117
+ search_combinator: z
118
+ .enum(["And", "Or"])
119
+ .optional()
120
+ .describe("How to combine search terms: 'And' = all terms must match, " +
121
+ "'Or' = any term matches (default: 'Or')"),
122
+ },
123
+ handler: async (args) => {
124
+ const deployment = args.deployment;
125
+ const tail = args.tail;
126
+ const search_terms = args.search_terms;
127
+ const search_combinator = args.search_combinator;
128
+ try {
129
+ let log;
130
+ if (search_terms && search_terms.length > 0) {
131
+ log = await client.read("SearchDeploymentLog", {
132
+ deployment,
133
+ terms: search_terms,
134
+ combinator: search_combinator || Types.SearchCombinator.Or,
135
+ });
136
+ }
137
+ else {
138
+ log = await client.read("GetDeploymentLog", {
139
+ deployment,
140
+ tail: tail || 50,
141
+ });
142
+ }
143
+ return {
144
+ content: [{ type: "text", text: formatLog(log) }],
145
+ };
146
+ }
147
+ catch (error) {
148
+ return handleKomodoError(`getting logs for deployment '${deployment}'`, error);
149
+ }
150
+ },
151
+ });
152
+ // -------------------------------------------------------------------------
153
+ // komodo_deploy_deployment
154
+ // -------------------------------------------------------------------------
155
+ registerTool(server, config, {
156
+ name: "komodo_deploy_deployment",
157
+ description: "\u26a0\ufe0f DEPLOY a Komodo Deployment. This stops the current container " +
158
+ "and starts a new one with the latest image and configuration. The " +
159
+ "service will be briefly unavailable during redeployment. A " +
160
+ "Deployment is a single Docker container managed by Komodo.",
161
+ accessTier: "read-execute",
162
+ category: "deployments",
163
+ annotations: {
164
+ readOnlyHint: false,
165
+ destructiveHint: true,
166
+ idempotentHint: false,
167
+ },
168
+ inputSchema: {
169
+ deployment: z.string().describe("Deployment name or ID"),
170
+ },
171
+ handler: async (args) => {
172
+ const deployment = args.deployment;
173
+ try {
174
+ const update = await client.execute("Deploy", { deployment });
175
+ return {
176
+ content: [
177
+ {
178
+ type: "text",
179
+ text: formatUpdateCreated(update, `Deploying deployment '${deployment}'`),
180
+ },
181
+ ],
182
+ };
183
+ }
184
+ catch (error) {
185
+ return handleKomodoError(`deploying deployment '${deployment}'`, error);
186
+ }
187
+ },
188
+ });
189
+ // -------------------------------------------------------------------------
190
+ // komodo_deployment_lifecycle
191
+ // -------------------------------------------------------------------------
192
+ registerTool(server, config, {
193
+ name: "komodo_deployment_lifecycle",
194
+ description: "\u26a0\ufe0f LIFECYCLE: Control a Komodo Deployment's container lifecycle. " +
195
+ "A Deployment is a single Docker container managed by Komodo. " +
196
+ "Actions: 'start' brings container up, 'stop' brings it down " +
197
+ "gracefully, 'restart' stops then starts, 'pause' freezes without " +
198
+ "stopping (uses Docker pause), 'unpause' resumes from pause. " +
199
+ "Stop/restart cause downtime.",
200
+ accessTier: "read-execute",
201
+ category: "deployments",
202
+ annotations: {
203
+ readOnlyHint: false,
204
+ destructiveHint: true,
205
+ idempotentHint: false,
206
+ },
207
+ inputSchema: {
208
+ deployment: z.string().describe("Deployment name or ID"),
209
+ action: z
210
+ .enum(["start", "stop", "restart", "pause", "unpause"])
211
+ .describe("Lifecycle action to perform"),
212
+ },
213
+ handler: async (args) => {
214
+ const deployment = args.deployment;
215
+ const action = args.action;
216
+ try {
217
+ const operationMap = {
218
+ start: "StartDeployment",
219
+ stop: "StopDeployment",
220
+ restart: "RestartDeployment",
221
+ pause: "PauseDeployment",
222
+ unpause: "UnpauseDeployment",
223
+ };
224
+ const update = await client.execute(operationMap[action], {
225
+ deployment,
226
+ });
227
+ return {
228
+ content: [
229
+ {
230
+ type: "text",
231
+ text: formatUpdateCreated(update, `${action} deployment '${deployment}'`),
232
+ },
233
+ ],
234
+ };
235
+ }
236
+ catch (error) {
237
+ return handleKomodoError(`${action} deployment '${deployment}'`, error);
238
+ }
239
+ },
240
+ });
241
+ // -------------------------------------------------------------------------
242
+ // komodo_destroy_deployment
243
+ // -------------------------------------------------------------------------
244
+ registerTool(server, config, {
245
+ name: "komodo_destroy_deployment",
246
+ description: "\ud83d\udd34 DESTROY a Komodo Deployment permanently. This stops the " +
247
+ "container and removes the deployment configuration from Komodo. " +
248
+ "THIS CANNOT BE UNDONE. The container and its data will be " +
249
+ "deleted. Only use this when you're certain the deployment should " +
250
+ "be permanently removed. A Deployment is a single Docker container " +
251
+ "managed by Komodo.",
252
+ accessTier: "read-execute",
253
+ category: "deployments",
254
+ annotations: {
255
+ readOnlyHint: false,
256
+ destructiveHint: true,
257
+ idempotentHint: false,
258
+ },
259
+ inputSchema: {
260
+ deployment: z.string().describe("Deployment name or ID"),
261
+ },
262
+ handler: async (args) => {
263
+ const deployment = args.deployment;
264
+ try {
265
+ const update = await client.execute("DestroyDeployment", {
266
+ deployment,
267
+ });
268
+ return {
269
+ content: [
270
+ {
271
+ type: "text",
272
+ text: formatUpdateCreated(update, `Destroying deployment '${deployment}' - this is permanent`),
273
+ },
274
+ ],
275
+ };
276
+ }
277
+ catch (error) {
278
+ return handleKomodoError(`destroying deployment '${deployment}'`, error);
279
+ }
280
+ },
281
+ });
282
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tool registration barrel file.
3
+ *
4
+ * Imports all domain tool modules and exports a single
5
+ * registerAllTools() function that wires them into the MCP server.
6
+ */
7
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
+ import type { createClient } from "../core/client.js";
9
+ import type { AppConfig } from "../core/config.js";
10
+ export declare function registerAllTools(server: McpServer, client: ReturnType<typeof createClient>, config: AppConfig): void;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Tool registration barrel file.
3
+ *
4
+ * Imports all domain tool modules and exports a single
5
+ * registerAllTools() function that wires them into the MCP server.
6
+ */
7
+ import { registerServerTools } from "./servers.js";
8
+ import { registerStackTools } from "./stacks.js";
9
+ import { registerDeploymentTools } from "./deployments.js";
10
+ import { registerContainerTools } from "./containers.js";
11
+ import { registerBuildTools } from "./builds.js";
12
+ import { registerRepoTools } from "./repos.js";
13
+ import { registerProcedureTools } from "./procedures.js";
14
+ import { registerActionTools } from "./actions.js";
15
+ import { registerBuilderTools } from "./builders.js";
16
+ import { registerAlerterTools } from "./alerters.js";
17
+ import { registerResourceSyncTools } from "./resource-syncs.js";
18
+ import { registerWriteTools } from "./write.js";
19
+ export function registerAllTools(server, client, config) {
20
+ registerServerTools(server, client, config);
21
+ registerStackTools(server, client, config);
22
+ registerDeploymentTools(server, client, config);
23
+ registerContainerTools(server, client, config);
24
+ registerBuildTools(server, client, config);
25
+ registerRepoTools(server, client, config);
26
+ registerProcedureTools(server, client, config);
27
+ registerActionTools(server, client, config);
28
+ registerBuilderTools(server, client, config);
29
+ registerAlerterTools(server, client, config);
30
+ registerResourceSyncTools(server, client, config);
31
+ registerWriteTools(server, client, config);
32
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Procedure domain tools: list, get detail, run.
3
+ *
4
+ * Registers 3 MCP tools for Komodo Procedure resources.
5
+ * A Procedure is an orchestrated sequence of parallel stages that run
6
+ * other Komodo operations (deploy, build, pull, etc.).
7
+ */
8
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ import type { createClient } from "../core/client.js";
10
+ import type { AppConfig } from "../core/config.js";
11
+ type KomodoClient = ReturnType<typeof createClient>;
12
+ export declare function registerProcedureTools(server: McpServer, client: KomodoClient, config: AppConfig): void;
13
+ export {};
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Procedure domain tools: list, get detail, run.
3
+ *
4
+ * Registers 3 MCP tools for Komodo Procedure resources.
5
+ * A Procedure is an orchestrated sequence of parallel stages that run
6
+ * other Komodo operations (deploy, build, pull, etc.).
7
+ */
8
+ import { z } from "zod";
9
+ import { handleKomodoError } from "../core/errors.js";
10
+ import { formatProcedureList, formatProcedureDetail, formatUpdateCreated, } from "../core/formatters.js";
11
+ import { registerTool } from "../core/tools.js";
12
+ export function registerProcedureTools(server, client, config) {
13
+ // -------------------------------------------------------------------------
14
+ // komodo_list_procedures
15
+ // -------------------------------------------------------------------------
16
+ registerTool(server, config, {
17
+ name: "komodo_list_procedures",
18
+ description: "List all Komodo Procedures. A Procedure is an orchestrated " +
19
+ "sequence of parallel stages that run other Komodo operations " +
20
+ "(deploy, build, pull, etc.). Returns name and state for each " +
21
+ "procedure.",
22
+ accessTier: "read-only",
23
+ category: "procedures",
24
+ annotations: {
25
+ readOnlyHint: true,
26
+ destructiveHint: false,
27
+ idempotentHint: true,
28
+ },
29
+ inputSchema: {
30
+ tag: z
31
+ .string()
32
+ .optional()
33
+ .describe("Filter procedures by tag name"),
34
+ },
35
+ handler: async (args) => {
36
+ const tag = args.tag;
37
+ try {
38
+ const procedures = await client.read("ListProcedures", {
39
+ query: tag ? { tags: [tag] } : undefined,
40
+ });
41
+ return {
42
+ content: [
43
+ { type: "text", text: formatProcedureList(procedures) },
44
+ ],
45
+ };
46
+ }
47
+ catch (error) {
48
+ return handleKomodoError("listing procedures", error);
49
+ }
50
+ },
51
+ });
52
+ // -------------------------------------------------------------------------
53
+ // komodo_get_procedure
54
+ // -------------------------------------------------------------------------
55
+ registerTool(server, config, {
56
+ name: "komodo_get_procedure",
57
+ description: "Get detailed information about a specific Komodo Procedure by " +
58
+ "name or ID. A Procedure is an orchestrated sequence of stages. " +
59
+ "Returns stages with their operations and current action state.",
60
+ accessTier: "read-only",
61
+ category: "procedures",
62
+ annotations: {
63
+ readOnlyHint: true,
64
+ destructiveHint: false,
65
+ idempotentHint: true,
66
+ },
67
+ inputSchema: {
68
+ procedure: z.string().describe("Procedure name or ID"),
69
+ },
70
+ handler: async (args) => {
71
+ const procedure = args.procedure;
72
+ try {
73
+ const [procedureData, actionState] = await Promise.all([
74
+ client.read("GetProcedure", { procedure }),
75
+ client.read("GetProcedureActionState", { procedure }),
76
+ ]);
77
+ return {
78
+ content: [
79
+ {
80
+ type: "text",
81
+ text: formatProcedureDetail(procedureData, actionState),
82
+ },
83
+ ],
84
+ };
85
+ }
86
+ catch (error) {
87
+ return handleKomodoError(`getting procedure '${procedure}'`, error);
88
+ }
89
+ },
90
+ });
91
+ // -------------------------------------------------------------------------
92
+ // komodo_run_procedure
93
+ // -------------------------------------------------------------------------
94
+ registerTool(server, config, {
95
+ name: "komodo_run_procedure",
96
+ description: "\u26a0\ufe0f RUN a Komodo Procedure. This executes all stages in sequence, " +
97
+ "where each stage can run multiple operations in parallel. A " +
98
+ "Procedure may deploy stacks, run builds, pull repos, and perform " +
99
+ "other Komodo operations. Procedures can take several minutes " +
100
+ "depending on their stages. A Procedure is an orchestrated sequence " +
101
+ "of parallel stages.",
102
+ accessTier: "read-execute",
103
+ category: "procedures",
104
+ annotations: {
105
+ readOnlyHint: false,
106
+ destructiveHint: true,
107
+ idempotentHint: false,
108
+ },
109
+ inputSchema: {
110
+ procedure: z.string().describe("Procedure name or ID"),
111
+ },
112
+ handler: async (args) => {
113
+ const procedure = args.procedure;
114
+ try {
115
+ const update = await client.execute("RunProcedure", { procedure });
116
+ return {
117
+ content: [
118
+ {
119
+ type: "text",
120
+ text: formatUpdateCreated(update, `Running procedure '${procedure}'`),
121
+ },
122
+ ],
123
+ };
124
+ }
125
+ catch (error) {
126
+ return handleKomodoError(`running procedure '${procedure}'`, error);
127
+ }
128
+ },
129
+ });
130
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Repo domain tools: list, get detail, clone/pull.
3
+ *
4
+ * Registers 3 MCP tools for Komodo Repo resources.
5
+ * A Repo is a Git repository cloned to a server, optionally built
6
+ * using a Builder.
7
+ */
8
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ import type { createClient } from "../core/client.js";
10
+ import type { AppConfig } from "../core/config.js";
11
+ type KomodoClient = ReturnType<typeof createClient>;
12
+ export declare function registerRepoTools(server: McpServer, client: KomodoClient, config: AppConfig): void;
13
+ export {};
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Repo domain tools: list, get detail, clone/pull.
3
+ *
4
+ * Registers 3 MCP tools for Komodo Repo resources.
5
+ * A Repo is a Git repository cloned to a server, optionally built
6
+ * using a Builder.
7
+ */
8
+ import { z } from "zod";
9
+ import { handleKomodoError } from "../core/errors.js";
10
+ import { formatRepoList, formatRepoDetail, formatUpdateCreated, } from "../core/formatters.js";
11
+ import { registerTool } from "../core/tools.js";
12
+ export function registerRepoTools(server, client, config) {
13
+ // -------------------------------------------------------------------------
14
+ // komodo_list_repos
15
+ // -------------------------------------------------------------------------
16
+ registerTool(server, config, {
17
+ name: "komodo_list_repos",
18
+ description: "List all Komodo Repos. A Repo is a Git repository cloned to a " +
19
+ "server, optionally built using a Builder. Returns name, repo URL, " +
20
+ "server, and state for each repo.",
21
+ accessTier: "read-only",
22
+ category: "repos",
23
+ annotations: {
24
+ readOnlyHint: true,
25
+ destructiveHint: false,
26
+ idempotentHint: true,
27
+ },
28
+ inputSchema: {
29
+ tag: z.string().optional().describe("Filter repos by tag name"),
30
+ },
31
+ handler: async (args) => {
32
+ const tag = args.tag;
33
+ try {
34
+ const repos = await client.read("ListRepos", {
35
+ query: tag ? { tags: [tag] } : undefined,
36
+ });
37
+ return {
38
+ content: [{ type: "text", text: formatRepoList(repos) }],
39
+ };
40
+ }
41
+ catch (error) {
42
+ return handleKomodoError("listing repos", error);
43
+ }
44
+ },
45
+ });
46
+ // -------------------------------------------------------------------------
47
+ // komodo_get_repo
48
+ // -------------------------------------------------------------------------
49
+ registerTool(server, config, {
50
+ name: "komodo_get_repo",
51
+ description: "Get detailed information about a specific Komodo Repo by name " +
52
+ "or ID. A Repo is a Git repository cloned to a server. Returns " +
53
+ "clone URL, branch, server, on_clone/on_pull commands, and " +
54
+ "current action state.",
55
+ accessTier: "read-only",
56
+ category: "repos",
57
+ annotations: {
58
+ readOnlyHint: true,
59
+ destructiveHint: false,
60
+ idempotentHint: true,
61
+ },
62
+ inputSchema: {
63
+ repo: z.string().describe("Repo name or ID"),
64
+ },
65
+ handler: async (args) => {
66
+ const repo = args.repo;
67
+ try {
68
+ const [repoData, actionState] = await Promise.all([
69
+ client.read("GetRepo", { repo }),
70
+ client.read("GetRepoActionState", { repo }),
71
+ ]);
72
+ return {
73
+ content: [
74
+ {
75
+ type: "text",
76
+ text: formatRepoDetail(repoData, actionState),
77
+ },
78
+ ],
79
+ };
80
+ }
81
+ catch (error) {
82
+ return handleKomodoError(`getting repo '${repo}'`, error);
83
+ }
84
+ },
85
+ });
86
+ // -------------------------------------------------------------------------
87
+ // komodo_repo_clone_pull
88
+ // -------------------------------------------------------------------------
89
+ registerTool(server, config, {
90
+ name: "komodo_repo_clone_pull",
91
+ description: "\u26a0\ufe0f CLONE or PULL a Komodo Repo on its target server. 'clone' " +
92
+ "performs initial git clone (or pulls if already cloned). 'pull' " +
93
+ "performs git pull to get latest changes. Both may trigger " +
94
+ "on_clone/on_pull commands configured on the repo. A Repo is a " +
95
+ "Git repository cloned to a server.",
96
+ accessTier: "read-execute",
97
+ category: "repos",
98
+ annotations: {
99
+ readOnlyHint: false,
100
+ destructiveHint: true,
101
+ idempotentHint: false,
102
+ },
103
+ inputSchema: {
104
+ repo: z.string().describe("Repo name or ID"),
105
+ action: z
106
+ .enum(["clone", "pull"])
107
+ .describe("Whether to clone or pull the repo"),
108
+ },
109
+ handler: async (args) => {
110
+ const repo = args.repo;
111
+ const action = args.action;
112
+ try {
113
+ const operationMap = {
114
+ clone: "CloneRepo",
115
+ pull: "PullRepo",
116
+ };
117
+ const update = await client.execute(operationMap[action], { repo });
118
+ return {
119
+ content: [
120
+ {
121
+ type: "text",
122
+ text: formatUpdateCreated(update, `${action} repo '${repo}'`),
123
+ },
124
+ ],
125
+ };
126
+ }
127
+ catch (error) {
128
+ return handleKomodoError(`${action} repo '${repo}'`, error);
129
+ }
130
+ },
131
+ });
132
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * ResourceSync domain tools: list, get detail, trigger sync.
3
+ *
4
+ * Registers 3 MCP tools for Komodo ResourceSync resources.
5
+ * A ResourceSync is a GitOps sync that manages Komodo resources from
6
+ * TOML configuration files in a Git repository.
7
+ */
8
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ import type { createClient } from "../core/client.js";
10
+ import type { AppConfig } from "../core/config.js";
11
+ type KomodoClient = ReturnType<typeof createClient>;
12
+ export declare function registerResourceSyncTools(server: McpServer, client: KomodoClient, config: AppConfig): void;
13
+ export {};