ncloud-mcp-server 1.1.0 → 1.1.1

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.
@@ -1,596 +1,533 @@
1
1
  import { z } from "zod";
2
2
  import { toolText } from "./_response.js";
3
+ // Cloud Insight Plugin / Custom Resource / Schema / Planned Maintenance APIs
4
+ // Base: https://cw.apigw.ntruss.com. 경로/메서드/필드는 공식 docs(management-cloudinsight-*) 기준.
5
+ // - Plugin(process/port/file): prefix /cw_server/real/api/plugin/...
6
+ // - Custom Resource / Schema / Planned Maintenance: prefix /cw_fea/real/cw/api/...
7
+ const CW_SERVER = "/cw_server/real/api/plugin";
8
+ const CW = "/cw_fea/real/cw/api";
9
+ const targetType = z
10
+ .enum(["vpcserver", "classicserver", "cloudhadoop"])
11
+ .optional()
12
+ .describe("Target type (default 'vpcserver')");
3
13
  export function registerCloudInsightPluginTools(server, client) {
4
- // --- Plugin Tools ---
5
- // ncloud_list_process_plugins Get process plugin list
6
- server.tool("ncloud_list_process_plugins", "Get the list of Cloud Insight process monitoring plugins.", {
7
- instanceNo: z.string().optional().describe("Server instance number to filter plugins"),
8
- }, async (params) => {
14
+ // ─── Process plugin ─────────────────────────────────────────────────────
15
+ server.tool("ncloud_list_process_plugins", "Get the full list of Cloud Insight process monitoring plugins.", {}, async () => {
9
16
  try {
10
- const body = {};
11
- if (params.instanceNo !== undefined)
12
- body.instanceNo = params.instanceNo;
13
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/process", body);
17
+ const result = await client.requestRaw("GET", `${CW_SERVER}/process`);
14
18
  return toolText(result);
15
19
  }
16
20
  catch (error) {
17
21
  return { content: [{ type: "text", text: error.message }], isError: true };
18
22
  }
19
23
  });
20
- // ncloud_add_process_plugin Add a process monitoring plugin
21
- server.tool("ncloud_add_process_plugin", "Add a process monitoring plugin to Cloud Insight for monitoring specific processes on a server.", {
22
- instanceNo: z.string().describe("Server instance number to add the plugin to"),
23
- processName: z.string().describe("Name of the process to monitor"),
24
- }, async (params) => {
24
+ server.tool("ncloud_get_process_plugin", "Get process monitoring plugin configuration for a specific server instance.", { instanceNo: z.string().describe("Server instance number") }, async (params) => {
25
25
  try {
26
- const body = {
27
- instanceNo: params.instanceNo,
28
- processName: params.processName,
29
- };
30
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/process/add", body);
26
+ const result = await client.requestRaw("GET", `${CW_SERVER}/process/instanceNo/${params.instanceNo}`);
31
27
  return toolText(result);
32
28
  }
33
29
  catch (error) {
34
30
  return { content: [{ type: "text", text: error.message }], isError: true };
35
31
  }
36
32
  });
37
- // ncloud_remove_process_plugin Remove a process monitoring plugin
38
- server.tool("ncloud_remove_process_plugin", "⚠️ Destructive: Remove a process monitoring plugin from Cloud Insight.", {
33
+ server.tool("ncloud_add_process_plugin", "Add process monitoring plugin(s) to a server instance. Provide one or more process names (wildcards like *abc* allowed).", {
39
34
  instanceNo: z.string().describe("Server instance number"),
40
- processName: z.string().describe("Name of the process plugin to remove"),
41
- confirm: z.boolean().optional().describe("Must be true to execute deletion. If false or omitted, returns a confirmation prompt."),
35
+ configList: z.array(z.string()).min(1).describe("Process names to monitor"),
36
+ type: targetType,
42
37
  }, async (params) => {
43
38
  try {
44
- if (!params.confirm) {
45
- return {
46
- content: [{
47
- type: "text",
48
- text: `⚠️ This will permanently remove process plugin [${params.processName}] from instance [${params.instanceNo}]. Do you want to proceed? (yes/no)\n\nTo confirm, call this tool again with confirm=true.`,
49
- }],
50
- };
51
- }
52
- const body = {
53
- instanceNo: params.instanceNo,
54
- processName: params.processName,
55
- };
56
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/process/remove", body);
39
+ const body = { instanceNo: params.instanceNo, configList: params.configList };
40
+ if (params.type !== undefined)
41
+ body.type = params.type;
42
+ const result = await client.postRequest(`${CW_SERVER}/process/add`, body);
57
43
  return toolText(result);
58
44
  }
59
45
  catch (error) {
60
46
  return { content: [{ type: "text", text: error.message }], isError: true };
61
47
  }
62
48
  });
63
- // ncloud_list_port_plugins Get port plugin list
64
- server.tool("ncloud_list_port_plugins", "Get the list of Cloud Insight port monitoring plugins.", {
65
- instanceNo: z.string().optional().describe("Server instance number to filter plugins"),
49
+ server.tool("ncloud_remove_process_plugin", "⚠️ Destructive: Remove process monitoring plugin(s) from a server instance. Set confirm=true to execute.", {
50
+ instanceNo: z.string().describe("Server instance number"),
51
+ configList: z.array(z.string()).min(1).describe("Process names to remove"),
52
+ type: targetType,
53
+ confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
66
54
  }, async (params) => {
67
55
  try {
68
- const body = {};
69
- if (params.instanceNo !== undefined)
70
- body.instanceNo = params.instanceNo;
71
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/port", body);
56
+ if (!params.confirm) {
57
+ return { content: [{ type: "text", text: `⚠️ This will remove process plugins [${params.configList.join(", ")}] from instance [${params.instanceNo}]. To execute, call again with confirm=true.` }] };
58
+ }
59
+ const body = { instanceNo: params.instanceNo, configList: params.configList };
60
+ if (params.type !== undefined)
61
+ body.type = params.type;
62
+ const result = await client.postRequest(`${CW_SERVER}/process/remove`, body);
72
63
  return toolText(result);
73
64
  }
74
65
  catch (error) {
75
66
  return { content: [{ type: "text", text: error.message }], isError: true };
76
67
  }
77
68
  });
78
- // ncloud_add_port_plugin Add a port monitoring plugin
79
- server.tool("ncloud_add_port_plugin", "Add a port monitoring plugin to Cloud Insight for monitoring specific ports on a server.", {
80
- instanceNo: z.string().describe("Server instance number to add the plugin to"),
81
- portNumber: z.number().describe("Port number to monitor"),
69
+ server.tool("ncloud_set_process_plugins", "Replace the full set of process monitoring plugins for a server instance (sends the entire list).", {
70
+ instanceNo: z.string().describe("Server instance number"),
71
+ configList: z.array(z.string()).describe("Full list of process names to monitor (replaces existing)"),
72
+ type: targetType,
82
73
  }, async (params) => {
83
74
  try {
84
- const body = {
85
- instanceNo: params.instanceNo,
86
- portNumber: params.portNumber,
87
- };
88
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/port/add", body);
75
+ const body = { instanceNo: params.instanceNo, configList: params.configList };
76
+ if (params.type !== undefined)
77
+ body.type = params.type;
78
+ const result = await client.postRequest(`${CW_SERVER}/process`, body);
89
79
  return toolText(result);
90
80
  }
91
81
  catch (error) {
92
82
  return { content: [{ type: "text", text: error.message }], isError: true };
93
83
  }
94
84
  });
95
- // ncloud_remove_port_plugin Remove a port monitoring plugin
96
- server.tool("ncloud_remove_port_plugin", "⚠️ Destructive: Remove a port monitoring plugin from Cloud Insight.", {
97
- instanceNo: z.string().describe("Server instance number"),
98
- portNumber: z.number().describe("Port number of the plugin to remove"),
99
- confirm: z.boolean().optional().describe("Must be true to execute deletion. If false or omitted, returns a confirmation prompt."),
100
- }, async (params) => {
85
+ // ─── Port plugin ────────────────────────────────────────────────────────
86
+ server.tool("ncloud_list_port_plugins", "Get the full list of Cloud Insight port monitoring plugins.", {}, async () => {
101
87
  try {
102
- if (!params.confirm) {
103
- return {
104
- content: [{
105
- type: "text",
106
- text: `⚠️ This will permanently remove port plugin [${params.portNumber}] from instance [${params.instanceNo}]. Do you want to proceed? (yes/no)\n\nTo confirm, call this tool again with confirm=true.`,
107
- }],
108
- };
109
- }
110
- const body = {
111
- instanceNo: params.instanceNo,
112
- portNumber: params.portNumber,
113
- };
114
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/port/remove", body);
88
+ const result = await client.requestRaw("GET", `${CW_SERVER}/port`);
115
89
  return toolText(result);
116
90
  }
117
91
  catch (error) {
118
92
  return { content: [{ type: "text", text: error.message }], isError: true };
119
93
  }
120
94
  });
121
- // ncloud_list_file_plugins Get file plugin list
122
- server.tool("ncloud_list_file_plugins", "Get the list of Cloud Insight file monitoring plugins.", {
123
- instanceNo: z.string().optional().describe("Server instance number to filter plugins"),
124
- }, async (params) => {
95
+ server.tool("ncloud_get_port_plugin", "Get port monitoring plugin configuration for a specific server instance.", { instanceNo: z.string().describe("Server instance number") }, async (params) => {
125
96
  try {
126
- const body = {};
127
- if (params.instanceNo !== undefined)
128
- body.instanceNo = params.instanceNo;
129
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/file", body);
97
+ const result = await client.requestRaw("GET", `${CW_SERVER}/port/instanceNo/${params.instanceNo}`);
130
98
  return toolText(result);
131
99
  }
132
100
  catch (error) {
133
101
  return { content: [{ type: "text", text: error.message }], isError: true };
134
102
  }
135
103
  });
136
- // ncloud_add_file_plugin Add a file monitoring plugin
137
- server.tool("ncloud_add_file_plugin", "Add a file monitoring plugin to Cloud Insight for monitoring specific file paths on a server.", {
138
- instanceNo: z.string().describe("Server instance number to add the plugin to"),
139
- filePath: z.string().describe("File path to monitor"),
104
+ server.tool("ncloud_add_port_plugin", "Add port monitoring plugin(s) to a server instance.", {
105
+ instanceNo: z.string().describe("Server instance number"),
106
+ portList: z.array(z.number()).min(1).describe("Port numbers to monitor"),
107
+ type: targetType,
140
108
  }, async (params) => {
141
109
  try {
142
- const body = {
143
- instanceNo: params.instanceNo,
144
- filePath: params.filePath,
145
- };
146
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/file/add", body);
110
+ const body = { instanceNo: params.instanceNo, portList: params.portList };
111
+ if (params.type !== undefined)
112
+ body.type = params.type;
113
+ const result = await client.postRequest(`${CW_SERVER}/port/add`, body);
147
114
  return toolText(result);
148
115
  }
149
116
  catch (error) {
150
117
  return { content: [{ type: "text", text: error.message }], isError: true };
151
118
  }
152
119
  });
153
- // ncloud_remove_file_plugin Remove a file monitoring plugin
154
- server.tool("ncloud_remove_file_plugin", "⚠️ Destructive: Remove a file monitoring plugin from Cloud Insight.", {
120
+ server.tool("ncloud_remove_port_plugin", "⚠️ Destructive: Remove port monitoring plugin(s) from a server instance. Set confirm=true to execute.", {
155
121
  instanceNo: z.string().describe("Server instance number"),
156
- filePath: z.string().describe("File path of the plugin to remove"),
157
- confirm: z.boolean().optional().describe("Must be true to execute deletion. If false or omitted, returns a confirmation prompt."),
122
+ portList: z.array(z.number()).min(1).describe("Port numbers to remove"),
123
+ type: targetType,
124
+ confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
158
125
  }, async (params) => {
159
126
  try {
160
127
  if (!params.confirm) {
161
- return {
162
- content: [{
163
- type: "text",
164
- text: `⚠️ This will permanently remove file plugin [${params.filePath}] from instance [${params.instanceNo}]. Do you want to proceed? (yes/no)\n\nTo confirm, call this tool again with confirm=true.`,
165
- }],
166
- };
128
+ return { content: [{ type: "text", text: `⚠️ This will remove port plugins [${params.portList.join(", ")}] from instance [${params.instanceNo}]. To execute, call again with confirm=true.` }] };
167
129
  }
168
- const body = {
169
- instanceNo: params.instanceNo,
170
- filePath: params.filePath,
171
- };
172
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/file/remove", body);
130
+ const body = { instanceNo: params.instanceNo, portList: params.portList };
131
+ if (params.type !== undefined)
132
+ body.type = params.type;
133
+ const result = await client.postRequest(`${CW_SERVER}/port/remove`, body);
173
134
  return toolText(result);
174
135
  }
175
136
  catch (error) {
176
137
  return { content: [{ type: "text", text: error.message }], isError: true };
177
138
  }
178
139
  });
179
- // --- Custom Resource Tools ---
180
- // ncloud_list_custom_resources Get custom resource list
181
- server.tool("ncloud_list_custom_resources", "Get the list of user-defined custom resources in Cloud Insight.", {
182
- prodKey: z.string().optional().describe("Product key to filter custom resources"),
140
+ server.tool("ncloud_set_port_plugins", "Replace the full set of port monitoring plugins for a server instance (sends the entire list).", {
141
+ instanceNo: z.string().describe("Server instance number"),
142
+ portList: z.array(z.number()).describe("Full list of port numbers to monitor (replaces existing)"),
143
+ type: targetType,
183
144
  }, async (params) => {
184
145
  try {
185
- const body = {};
186
- if (params.prodKey !== undefined)
187
- body.prodKey = params.prodKey;
188
- const result = await client.postRequest("/cw_fea/real/cw/api/custom/resource", body);
146
+ const body = { instanceNo: params.instanceNo, portList: params.portList };
147
+ if (params.type !== undefined)
148
+ body.type = params.type;
149
+ const result = await client.postRequest(`${CW_SERVER}/port`, body);
189
150
  return toolText(result);
190
151
  }
191
152
  catch (error) {
192
153
  return { content: [{ type: "text", text: error.message }], isError: true };
193
154
  }
194
155
  });
195
- // ncloud_get_custom_resource Get custom resource details
196
- server.tool("ncloud_get_custom_resource", "Get detailed information about a specific user-defined custom resource in Cloud Insight.", {
197
- resourceId: z.string().describe("Custom resource ID to retrieve details for"),
198
- }, async (params) => {
156
+ // ─── File plugin ────────────────────────────────────────────────────────
157
+ server.tool("ncloud_list_file_plugins", "Get the full list of Cloud Insight file monitoring plugins.", {}, async () => {
199
158
  try {
200
- const body = {
201
- resourceId: params.resourceId,
202
- };
203
- const result = await client.postRequest("/cw_fea/real/cw/api/custom/resource/detail", body);
159
+ const result = await client.requestRaw("GET", `${CW_SERVER}/file`);
204
160
  return toolText(result);
205
161
  }
206
162
  catch (error) {
207
163
  return { content: [{ type: "text", text: error.message }], isError: true };
208
164
  }
209
165
  });
210
- // ncloud_create_custom_resource Create a custom resource
211
- server.tool("ncloud_create_custom_resource", "Create a user-defined custom resource in Cloud Insight for custom monitoring targets.", {
212
- prodKey: z.string().describe("Product key (cw_key) for the custom schema"),
213
- resourceName: z.string().describe("Name of the custom resource"),
214
- dimensions: z.record(z.string()).describe("Dimension key-value pairs identifying the resource"),
215
- }, async (params) => {
166
+ server.tool("ncloud_get_file_plugin", "Get file monitoring plugin configuration for a specific server instance.", { instanceNo: z.string().describe("Server instance number") }, async (params) => {
216
167
  try {
217
- const body = {
218
- prodKey: params.prodKey,
219
- resourceName: params.resourceName,
220
- dimensions: params.dimensions,
221
- };
222
- const result = await client.postRequest("/cw_fea/real/cw/api/custom/resource/create", body);
168
+ const result = await client.requestRaw("GET", `${CW_SERVER}/file/instanceNo/${params.instanceNo}`);
223
169
  return toolText(result);
224
170
  }
225
171
  catch (error) {
226
172
  return { content: [{ type: "text", text: error.message }], isError: true };
227
173
  }
228
174
  });
229
- // ncloud_delete_custom_resource Delete a custom resource
230
- server.tool("ncloud_delete_custom_resource", "⚠️ Destructive: Delete a user-defined custom resource from Cloud Insight.", {
231
- resourceId: z.string().describe("Custom resource ID to delete"),
232
- confirm: z.boolean().optional().describe("Must be true to execute deletion. If false or omitted, returns a confirmation prompt."),
175
+ server.tool("ncloud_add_file_plugin", "Add file monitoring plugin(s) to a server instance.", {
176
+ instanceNo: z.string().describe("Server instance number"),
177
+ configList: z.array(z.string()).min(1).describe("File paths to monitor"),
178
+ type: targetType,
233
179
  }, async (params) => {
234
180
  try {
235
- if (!params.confirm) {
236
- return {
237
- content: [{
238
- type: "text",
239
- text: `⚠️ This will permanently delete custom resource [${params.resourceId}]. Do you want to proceed? (yes/no)\n\nTo confirm, call this tool again with confirm=true.`,
240
- }],
241
- };
242
- }
243
- const body = {
244
- resourceId: params.resourceId,
245
- };
246
- const result = await client.postRequest("/cw_fea/real/cw/api/custom/resource/delete", body);
181
+ const body = { instanceNo: params.instanceNo, configList: params.configList };
182
+ if (params.type !== undefined)
183
+ body.type = params.type;
184
+ const result = await client.postRequest(`${CW_SERVER}/file/add`, body);
247
185
  return toolText(result);
248
186
  }
249
187
  catch (error) {
250
188
  return { content: [{ type: "text", text: error.message }], isError: true };
251
189
  }
252
190
  });
253
- // --- Schema Tools ---
254
- // ncloud_get_schema_keys Get system schema product keys
255
- server.tool("ncloud_get_schema_keys", "Get the list of product keys (cw_key) available in Cloud Insight schema.", {}, async () => {
191
+ server.tool("ncloud_remove_file_plugin", "⚠️ Destructive: Remove file monitoring plugin(s) from a server instance. Set confirm=true to execute.", {
192
+ instanceNo: z.string().describe("Server instance number"),
193
+ configList: z.array(z.string()).min(1).describe("File paths to remove"),
194
+ type: targetType,
195
+ confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
196
+ }, async (params) => {
256
197
  try {
257
- const result = await client.requestRaw("GET", "/cw_fea/real/cw/api/schema/system/list");
198
+ if (!params.confirm) {
199
+ return { content: [{ type: "text", text: `⚠️ This will remove file plugins [${params.configList.join(", ")}] from instance [${params.instanceNo}]. To execute, call again with confirm=true.` }] };
200
+ }
201
+ const body = { instanceNo: params.instanceNo, configList: params.configList };
202
+ if (params.type !== undefined)
203
+ body.type = params.type;
204
+ const result = await client.postRequest(`${CW_SERVER}/file/remove`, body);
258
205
  return toolText(result);
259
206
  }
260
207
  catch (error) {
261
208
  return { content: [{ type: "text", text: error.message }], isError: true };
262
209
  }
263
210
  });
264
- // ncloud_get_product_schema Get product schema details
265
- server.tool("ncloud_get_product_schema", "Get the schema definition for a specific product in Cloud Insight, including available metrics and dimensions.", {
266
- prodKey: z.string().describe("Product key (cw_key) to get schema for"),
211
+ server.tool("ncloud_set_file_plugins", "Replace the full set of file monitoring plugins for a server instance (sends the entire list).", {
212
+ instanceNo: z.string().describe("Server instance number"),
213
+ configList: z.array(z.string()).describe("Full list of file paths to monitor (replaces existing)"),
214
+ type: targetType,
267
215
  }, async (params) => {
268
216
  try {
269
- const body = {
270
- prodKey: params.prodKey,
271
- };
272
- const result = await client.postRequest("/cw_fea/real/cw/api/schema", body);
217
+ const body = { instanceNo: params.instanceNo, configList: params.configList };
218
+ if (params.type !== undefined)
219
+ body.type = params.type;
220
+ const result = await client.postRequest(`${CW_SERVER}/file`, body);
273
221
  return toolText(result);
274
222
  }
275
223
  catch (error) {
276
224
  return { content: [{ type: "text", text: error.message }], isError: true };
277
225
  }
278
226
  });
279
- // --- Plugin Detail/Update Tools ---
280
- // ncloud_get_process_plugin Get process plugin for a specific instance
281
- server.tool("ncloud_get_process_plugin", "Get process monitoring plugin details for a specific server instance.", {
282
- instanceNo: z.string().describe("Server instance number"),
227
+ // ─── Custom Resource ────────────────────────────────────────────────────
228
+ server.tool("ncloud_list_custom_resources", "Get the list of user-defined custom resources in Cloud Insight.", {
229
+ resourceTypeId: z.string().optional().describe("Resource type ID (default 'DEFAULT')"),
230
+ query: z.string().optional().describe("Filter keyword"),
283
231
  }, async (params) => {
284
232
  try {
285
- const body = { instanceNo: params.instanceNo };
286
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/process/instance", body);
233
+ const q = {};
234
+ if (params.resourceTypeId !== undefined)
235
+ q.resourceTypeId = params.resourceTypeId;
236
+ if (params.query !== undefined)
237
+ q.query = params.query;
238
+ const result = await client.requestRaw("GET", `${CW}/custom/resource/list`, q);
287
239
  return toolText(result);
288
240
  }
289
241
  catch (error) {
290
242
  return { content: [{ type: "text", text: error.message }], isError: true };
291
243
  }
292
244
  });
293
- // ncloud_get_port_plugin — Get port plugin for a specific instance
294
- server.tool("ncloud_get_port_plugin", "Get port monitoring plugin details for a specific server instance.", {
295
- instanceNo: z.string().describe("Server instance number"),
296
- }, async (params) => {
245
+ server.tool("ncloud_get_custom_resource", "Get detailed information about a specific custom resource in Cloud Insight.", { resourceId: z.string().describe("Custom resource ID") }, async (params) => {
297
246
  try {
298
- const body = { instanceNo: params.instanceNo };
299
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/port/instance", body);
247
+ const result = await client.requestRaw("GET", `${CW}/custom/resource/${params.resourceId}`);
300
248
  return toolText(result);
301
249
  }
302
250
  catch (error) {
303
251
  return { content: [{ type: "text", text: error.message }], isError: true };
304
252
  }
305
253
  });
306
- // ncloud_get_file_plugin Get file plugin for a specific instance
307
- server.tool("ncloud_get_file_plugin", "Get file monitoring plugin details for a specific server instance.", {
308
- instanceNo: z.string().describe("Server instance number"),
254
+ server.tool("ncloud_create_custom_resource", "Create a user-defined custom resource in Cloud Insight.", {
255
+ resourceName: z.string().describe("Name of the custom resource"),
256
+ resourceData: z
257
+ .object({
258
+ organizationCode: z.string().describe("Organization code"),
259
+ projectId: z.string().describe("Project ID"),
260
+ serverIp: z.string().describe("Server IP"),
261
+ serverType: z.string().describe("Server type"),
262
+ serverName: z.string().optional().describe("Server name"),
263
+ })
264
+ .describe("Resource data"),
265
+ resourceTypeId: z.string().optional().describe("Resource type ID (default 'DEFAULT')"),
266
+ resourceId: z.string().optional().describe("Resource ID (auto-generated if omitted)"),
309
267
  }, async (params) => {
310
268
  try {
311
- const body = { instanceNo: params.instanceNo };
312
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/file/instance", body);
269
+ const body = { resourceName: params.resourceName, resourceData: params.resourceData };
270
+ if (params.resourceTypeId !== undefined)
271
+ body.resourceTypeId = params.resourceTypeId;
272
+ if (params.resourceId !== undefined)
273
+ body.resourceId = params.resourceId;
274
+ const result = await client.postRequest(`${CW}/custom/resource`, body);
313
275
  return toolText(result);
314
276
  }
315
277
  catch (error) {
316
278
  return { content: [{ type: "text", text: error.message }], isError: true };
317
279
  }
318
280
  });
319
- // ncloud_update_process_plugin Update process plugin settings
320
- server.tool("ncloud_update_process_plugin", "Update process monitoring plugin settings in Cloud Insight.", {
321
- instanceNo: z.string().describe("Server instance number"),
322
- processName: z.string().describe("Process name to update"),
323
- newProcessName: z.string().optional().describe("New process name"),
281
+ server.tool("ncloud_update_custom_resource", "Update a user-defined custom resource in Cloud Insight.", {
282
+ resourceId: z.string().describe("Custom resource ID to update"),
283
+ resourceName: z.string().describe("Name of the custom resource"),
284
+ resourceData: z
285
+ .object({
286
+ organizationCode: z.string().describe("Organization code"),
287
+ projectId: z.string().describe("Project ID"),
288
+ serverIp: z.string().describe("Server IP"),
289
+ serverType: z.string().describe("Server type"),
290
+ serverName: z.string().optional().describe("Server name"),
291
+ })
292
+ .describe("Resource data"),
324
293
  }, async (params) => {
325
294
  try {
326
- const body = {
327
- instanceNo: params.instanceNo,
328
- processName: params.processName,
329
- };
330
- if (params.newProcessName !== undefined)
331
- body.newProcessName = params.newProcessName;
332
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/process/update", body);
295
+ const body = { resourceName: params.resourceName, resourceData: params.resourceData };
296
+ const result = await client.putRequest(`${CW}/custom/resource/${params.resourceId}`, body);
333
297
  return toolText(result);
334
298
  }
335
299
  catch (error) {
336
300
  return { content: [{ type: "text", text: error.message }], isError: true };
337
301
  }
338
302
  });
339
- // ncloud_update_port_plugin Update port plugin settings
340
- server.tool("ncloud_update_port_plugin", "Update port monitoring plugin settings in Cloud Insight.", {
341
- instanceNo: z.string().describe("Server instance number"),
342
- portNumber: z.number().describe("Current port number"),
343
- newPortNumber: z.number().optional().describe("New port number"),
303
+ server.tool("ncloud_delete_custom_resource", "⚠️ Destructive: Delete a user-defined custom resource from Cloud Insight. Set confirm=true to execute.", {
304
+ resourceId: z.string().describe("Custom resource ID to delete"),
305
+ confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
344
306
  }, async (params) => {
345
307
  try {
346
- const body = {
347
- instanceNo: params.instanceNo,
348
- portNumber: params.portNumber,
349
- };
350
- if (params.newPortNumber !== undefined)
351
- body.newPortNumber = params.newPortNumber;
352
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/port/update", body);
308
+ if (!params.confirm) {
309
+ return { content: [{ type: "text", text: `⚠️ This will permanently delete custom resource [${params.resourceId}]. To execute, call again with confirm=true.` }] };
310
+ }
311
+ const result = await client.requestRaw("DELETE", `${CW}/custom/resource/${params.resourceId}`);
353
312
  return toolText(result);
354
313
  }
355
314
  catch (error) {
356
315
  return { content: [{ type: "text", text: error.message }], isError: true };
357
316
  }
358
317
  });
359
- // ncloud_update_file_plugin Update file plugin settings
360
- server.tool("ncloud_update_file_plugin", "Update file monitoring plugin settings in Cloud Insight.", {
361
- instanceNo: z.string().describe("Server instance number"),
362
- filePath: z.string().describe("Current file path"),
363
- newFilePath: z.string().optional().describe("New file path"),
364
- }, async (params) => {
318
+ // ─── Schema ─────────────────────────────────────────────────────────────
319
+ server.tool("ncloud_get_schema_keys", "Get the list of system schema product keys (cw_key) available in Cloud Insight.", {}, async () => {
365
320
  try {
366
- const body = {
367
- instanceNo: params.instanceNo,
368
- filePath: params.filePath,
369
- };
370
- if (params.newFilePath !== undefined)
371
- body.newFilePath = params.newFilePath;
372
- const result = await client.postRequest("/cw_fea/real/cw/api/plugin/file/update", body);
321
+ const result = await client.requestRaw("GET", `${CW}/schema/system/list`);
373
322
  return toolText(result);
374
323
  }
375
324
  catch (error) {
376
325
  return { content: [{ type: "text", text: error.message }], isError: true };
377
326
  }
378
327
  });
379
- // --- Additional Schema Tools ---
380
- // ncloud_create_custom_schema Create a custom schema
381
- server.tool("ncloud_create_custom_schema", "Create a user-defined custom schema in Cloud Insight for custom metrics.", {
382
- prodName: z.string().describe("Product name for the custom schema"),
383
- fields: z.array(z.object({
384
- fieldName: z.string().describe("Field name"),
385
- fieldType: z.enum(["STRING", "INTEGER", "LONG", "FLOAT"]).describe("Field data type"),
386
- dimension: z.boolean().optional().describe("Whether this field is a dimension (default: false)"),
387
- })).describe("Schema field definitions"),
328
+ server.tool("ncloud_get_product_schema", "Get the schema definition for a specific product in Cloud Insight (metrics and dimensions).", {
329
+ prodName: z.string().describe("Product name to get schema for"),
330
+ cw_key: z.string().optional().describe("Product key (cw_key) for custom schema"),
388
331
  }, async (params) => {
389
332
  try {
390
- const body = {
391
- prodName: params.prodName,
392
- fields: params.fields,
393
- };
394
- const result = await client.postRequest("/cw_fea/real/cw/api/schema/create", body);
333
+ const q = { prodName: params.prodName };
334
+ if (params.cw_key !== undefined)
335
+ q.cw_key = params.cw_key;
336
+ const result = await client.requestRaw("GET", `${CW}/schema`, q);
395
337
  return toolText(result);
396
338
  }
397
339
  catch (error) {
398
340
  return { content: [{ type: "text", text: error.message }], isError: true };
399
341
  }
400
342
  });
401
- // ncloud_delete_product_schema Delete a custom schema
402
- server.tool("ncloud_delete_product_schema", "⚠️ Destructive: Delete a user-defined custom schema from Cloud Insight.", {
403
- prodKey: z.string().describe("Product key (cw_key) of the schema to delete"),
404
- confirm: z.boolean().optional().describe("Must be true to execute deletion."),
343
+ const schemaField = z.object({
344
+ fieldName: z.string().describe("Field name"),
345
+ fieldType: z.enum(["STRING", "INTEGER", "LONG", "FLOAT"]).describe("Field data type"),
346
+ dimension: z.boolean().optional().describe("Whether this field is a dimension"),
347
+ });
348
+ server.tool("ncloud_create_custom_schema", "Create a user-defined custom schema in Cloud Insight for custom metrics.", {
349
+ prodName: z.array(z.string()).describe("Product name(s) for the custom schema"),
350
+ fields: z.array(schemaField).describe("Schema field definitions"),
351
+ useCustomResource: z.boolean().optional().describe("Whether to use custom resource (default false)"),
405
352
  }, async (params) => {
406
353
  try {
407
- if (!params.confirm) {
408
- return {
409
- content: [{
410
- type: "text",
411
- text: `⚠️ This will permanently delete custom schema [${params.prodKey}]. To confirm, call this tool again with confirm=true.`,
412
- }],
413
- };
414
- }
415
- const body = { prodKey: params.prodKey };
416
- const result = await client.postRequest("/cw_fea/real/cw/api/schema/delete", body);
354
+ const body = { prodName: params.prodName, fields: params.fields };
355
+ if (params.useCustomResource !== undefined)
356
+ body.useCustomResource = params.useCustomResource;
357
+ const result = await client.postRequest(`${CW}/schema`, body);
417
358
  return toolText(result);
418
359
  }
419
360
  catch (error) {
420
361
  return { content: [{ type: "text", text: error.message }], isError: true };
421
362
  }
422
363
  });
423
- // ncloud_update_product_schema — Update a custom schema
424
364
  server.tool("ncloud_update_product_schema", "Update a user-defined custom schema in Cloud Insight.", {
425
- prodKey: z.string().describe("Product key (cw_key) of the schema to update"),
426
- fields: z.array(z.object({
427
- fieldName: z.string().describe("Field name"),
428
- fieldType: z.enum(["STRING", "INTEGER", "LONG", "FLOAT"]).describe("Field data type"),
429
- dimension: z.boolean().optional().describe("Whether this field is a dimension"),
430
- })).describe("Updated schema field definitions"),
365
+ prodName: z.string().describe("Product name of the schema to update"),
366
+ cw_key: z.string().describe("Product key (cw_key) of the schema to update"),
367
+ fields: z.array(schemaField).describe("Updated schema field definitions"),
431
368
  }, async (params) => {
432
369
  try {
433
- const body = {
434
- prodKey: params.prodKey,
435
- fields: params.fields,
436
- };
437
- const result = await client.postRequest("/cw_fea/real/cw/api/schema/update", body);
370
+ const body = { prodName: params.prodName, cw_key: params.cw_key, fields: params.fields };
371
+ const result = await client.putRequest(`${CW}/schema`, body);
438
372
  return toolText(result);
439
373
  }
440
374
  catch (error) {
441
375
  return { content: [{ type: "text", text: error.message }], isError: true };
442
376
  }
443
377
  });
444
- // ncloud_get_extended_status Get extended metric status
445
- server.tool("ncloud_get_extended_status", "Get the Extended Metric collection status for a specific instance in Cloud Insight.", {
446
- instanceNo: z.string().describe("Server instance number to check extended metric status"),
378
+ server.tool("ncloud_delete_product_schema", "⚠️ Destructive: Delete a user-defined custom schema from Cloud Insight. Set confirm=true to execute.", {
379
+ prodName: z.string().describe("Product name of the schema to delete"),
380
+ cw_key: z.string().describe("Product key (cw_key) of the schema to delete"),
381
+ confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
447
382
  }, async (params) => {
448
383
  try {
449
- const body = { instanceNo: params.instanceNo };
450
- const result = await client.postRequest("/cw_fea/real/cw/api/schema/extended/status", body);
384
+ if (!params.confirm) {
385
+ return { content: [{ type: "text", text: `⚠️ This will permanently delete custom schema [${params.prodName} / ${params.cw_key}]. To execute, call again with confirm=true.` }] };
386
+ }
387
+ const result = await client.requestRaw("DELETE", `${CW}/schema`, { cw_key: params.cw_key, prodName: params.prodName });
451
388
  return toolText(result);
452
389
  }
453
390
  catch (error) {
454
391
  return { content: [{ type: "text", text: error.message }], isError: true };
455
392
  }
456
393
  });
457
- // ncloud_update_extended_enable Enable extended metric collection
458
- server.tool("ncloud_update_extended_enable", "Enable Extended Metric collection for a specific instance in Cloud Insight.", {
459
- instanceNo: z.string().describe("Server instance number to enable extended metrics for"),
394
+ // ─── Extended metric ─────────────────────────────────────────────────────
395
+ server.tool("ncloud_get_extended_status", "Get the Extended Metric collection status for servers in Cloud Insight.", {
396
+ prodKey: z.string().describe("Product key (cw_key)"),
397
+ servers: z.array(z.string()).describe("Server instance numbers to check"),
460
398
  }, async (params) => {
461
399
  try {
462
- const body = { instanceNo: params.instanceNo };
463
- const result = await client.postRequest("/cw_fea/real/cw/api/schema/extended/enable", body);
400
+ const body = { prodKey: params.prodKey, servers: params.servers };
401
+ const result = await client.postRequest(`${CW}/schema/extended/status`, body);
464
402
  return toolText(result);
465
403
  }
466
404
  catch (error) {
467
405
  return { content: [{ type: "text", text: error.message }], isError: true };
468
406
  }
469
407
  });
470
- // ncloud_update_extended_disable Disable extended metric collection
471
- server.tool("ncloud_update_extended_disable", "Disable Extended Metric collection for a specific instance in Cloud Insight.", {
472
- instanceNo: z.string().describe("Server instance number to disable extended metrics for"),
408
+ server.tool("ncloud_update_extended_enable", "Enable Extended Metric collection for instances in Cloud Insight.", {
409
+ cw_key: z.string().describe("Product key (cw_key)"),
410
+ instanceIds: z.string().describe("Comma-separated server instance numbers"),
473
411
  }, async (params) => {
474
412
  try {
475
- const body = { instanceNo: params.instanceNo };
476
- const result = await client.postRequest("/cw_fea/real/cw/api/schema/extended/disable", body);
413
+ const result = await client.requestRaw("PUT", `${CW}/schema/extended/enable`, { cw_key: params.cw_key, instanceIds: params.instanceIds });
477
414
  return toolText(result);
478
415
  }
479
416
  catch (error) {
480
417
  return { content: [{ type: "text", text: error.message }], isError: true };
481
418
  }
482
419
  });
483
- // --- Custom Resource Update ---
484
- // ncloud_update_custom_resource Update a custom resource
485
- server.tool("ncloud_update_custom_resource", "Update a user-defined custom resource in Cloud Insight.", {
486
- resourceId: z.string().describe("Custom resource ID to update"),
487
- resourceName: z.string().optional().describe("New name for the custom resource"),
488
- dimensions: z.record(z.string()).optional().describe("Updated dimension key-value pairs"),
420
+ server.tool("ncloud_update_extended_disable", "Disable Extended Metric collection for instances in Cloud Insight.", {
421
+ cw_key: z.string().describe("Product key (cw_key)"),
422
+ instanceIds: z.string().describe("Comma-separated server instance numbers"),
489
423
  }, async (params) => {
490
424
  try {
491
- const body = {
492
- resourceId: params.resourceId,
493
- };
494
- if (params.resourceName !== undefined)
495
- body.resourceName = params.resourceName;
496
- if (params.dimensions !== undefined)
497
- body.dimensions = params.dimensions;
498
- const result = await client.postRequest("/cw_fea/real/cw/api/custom/resource/update", body);
425
+ const result = await client.requestRaw("PUT", `${CW}/schema/extended/disable`, { cw_key: params.cw_key, instanceIds: params.instanceIds });
499
426
  return toolText(result);
500
427
  }
501
428
  catch (error) {
502
429
  return { content: [{ type: "text", text: error.message }], isError: true };
503
430
  }
504
431
  });
505
- // --- Planned Maintenance Tools ---
506
- // ncloud_list_maintenances Get planned maintenance list
507
- server.tool("ncloud_list_maintenances", "Get the list of planned maintenance schedules in Cloud Insight.", {}, async () => {
432
+ // ─── Planned Maintenance ─────────────────────────────────────────────────
433
+ server.tool("ncloud_list_maintenances", "Get the list of planned maintenance schedules in Cloud Insight (paged). The API requires a filter: either a time range (from/to/timeType) OR a resource (resourceId+productKey). If none is given, a default ±180-day window by startTime is applied.", {
434
+ pageNum: z.number().optional().default(1).describe("Page number (>= 1)"),
435
+ pageSize: z.number().optional().default(100).describe("Page size (>= 1)"),
436
+ from: z.number().optional().describe("Filter start (epoch ms), used with 'to' and 'timeType'"),
437
+ to: z.number().optional().describe("Filter end (epoch ms)"),
438
+ timeType: z.enum(["startTime", "endTime"]).optional().describe("Which time the from/to filter applies to (default startTime)"),
439
+ resourceId: z.string().optional().describe("Filter by resource ID (use together with productKey instead of a time range)"),
440
+ productKey: z.string().optional().describe("Filter by product key (use together with resourceId)"),
441
+ }, async (params) => {
508
442
  try {
509
- const result = await client.postRequest("/cw_fea/real/cw/api/maintenance/list", {});
443
+ const q = { pageNum: params.pageNum ?? 1, pageSize: params.pageSize ?? 100 };
444
+ if (params.resourceId !== undefined && params.productKey !== undefined) {
445
+ // 리소스 필터 모드
446
+ q.resourceId = params.resourceId;
447
+ q.productKey = params.productKey;
448
+ }
449
+ else {
450
+ // 시간범위 필터 모드 — 미지정 시 ±180일 기본창 주입(API가 필터를 요구하므로 무인자 400 방지)
451
+ const DAY = 86_400_000;
452
+ q.from = params.from ?? Date.now() - 180 * DAY;
453
+ q.to = params.to ?? Date.now() + 180 * DAY;
454
+ q.timeType = params.timeType ?? "startTime";
455
+ }
456
+ const result = await client.requestRaw("GET", `${CW}/planned-maintenances`, q);
510
457
  return toolText(result);
511
458
  }
512
459
  catch (error) {
513
460
  return { content: [{ type: "text", text: error.message }], isError: true };
514
461
  }
515
462
  });
516
- // ncloud_get_maintenance_detail Get planned maintenance detail
517
- server.tool("ncloud_get_maintenance_detail", "Get detailed information about a specific planned maintenance schedule.", {
518
- maintenanceId: z.string().describe("Maintenance ID to retrieve details for"),
519
- }, async (params) => {
463
+ server.tool("ncloud_get_maintenance_detail", "Get detailed information about a specific planned maintenance schedule.", { maintenanceId: z.string().describe("Planned maintenance ID") }, async (params) => {
520
464
  try {
521
- const body = { maintenanceId: params.maintenanceId };
522
- const result = await client.postRequest("/cw_fea/real/cw/api/maintenance/detail", body);
465
+ const result = await client.requestRaw("GET", `${CW}/planned-maintenances/${params.maintenanceId}`);
523
466
  return toolText(result);
524
467
  }
525
468
  catch (error) {
526
469
  return { content: [{ type: "text", text: error.message }], isError: true };
527
470
  }
528
471
  });
529
- // ncloud_create_maintenance — Create a planned maintenance schedule
530
472
  server.tool("ncloud_create_maintenance", "Create a new planned maintenance schedule in Cloud Insight.", {
531
473
  title: z.string().describe("Maintenance title"),
532
474
  startTime: z.number().describe("Start time in Unix epoch milliseconds"),
533
475
  endTime: z.number().describe("End time in Unix epoch milliseconds"),
534
- description: z.string().optional().describe("Maintenance description"),
476
+ dimensions: z.record(z.unknown()).describe("Target dimensions (resource identifiers)"),
477
+ desc: z.string().optional().describe("Maintenance description"),
535
478
  }, async (params) => {
536
479
  try {
537
480
  const body = {
538
481
  title: params.title,
539
482
  startTime: params.startTime,
540
483
  endTime: params.endTime,
484
+ dimensions: params.dimensions,
541
485
  };
542
- if (params.description !== undefined)
543
- body.description = params.description;
544
- const result = await client.postRequest("/cw_fea/real/cw/api/maintenance/create", body);
486
+ if (params.desc !== undefined)
487
+ body.desc = params.desc;
488
+ const result = await client.postRequest(`${CW}/planned-maintenances`, body);
545
489
  return toolText(result);
546
490
  }
547
491
  catch (error) {
548
492
  return { content: [{ type: "text", text: error.message }], isError: true };
549
493
  }
550
494
  });
551
- // ncloud_update_maintenance — Update a planned maintenance schedule
552
495
  server.tool("ncloud_update_maintenance", "Update an existing planned maintenance schedule in Cloud Insight.", {
553
- maintenanceId: z.string().describe("Maintenance ID to update"),
554
- title: z.string().optional().describe("New maintenance title"),
555
- startTime: z.number().optional().describe("New start time in Unix epoch milliseconds"),
556
- endTime: z.number().optional().describe("New end time in Unix epoch milliseconds"),
557
- description: z.string().optional().describe("New maintenance description"),
496
+ maintenanceId: z.string().describe("Planned maintenance ID to update"),
497
+ title: z.string().optional().describe("Maintenance title"),
498
+ startTime: z.number().optional().describe("Start time in Unix epoch milliseconds"),
499
+ endTime: z.number().optional().describe("End time in Unix epoch milliseconds"),
500
+ dimensions: z.record(z.unknown()).optional().describe("Target dimensions"),
501
+ desc: z.string().optional().describe("Maintenance description"),
558
502
  }, async (params) => {
559
503
  try {
560
- const body = {
561
- maintenanceId: params.maintenanceId,
562
- };
504
+ const body = {};
563
505
  if (params.title !== undefined)
564
506
  body.title = params.title;
565
507
  if (params.startTime !== undefined)
566
508
  body.startTime = params.startTime;
567
509
  if (params.endTime !== undefined)
568
510
  body.endTime = params.endTime;
569
- if (params.description !== undefined)
570
- body.description = params.description;
571
- const result = await client.postRequest("/cw_fea/real/cw/api/maintenance/update", body);
511
+ if (params.dimensions !== undefined)
512
+ body.dimensions = params.dimensions;
513
+ if (params.desc !== undefined)
514
+ body.desc = params.desc;
515
+ const result = await client.putRequest(`${CW}/planned-maintenances/${params.maintenanceId}`, body);
572
516
  return toolText(result);
573
517
  }
574
518
  catch (error) {
575
519
  return { content: [{ type: "text", text: error.message }], isError: true };
576
520
  }
577
521
  });
578
- // ncloud_delete_maintenance Delete a planned maintenance schedule
579
- server.tool("ncloud_delete_maintenance", "⚠️ Destructive: Delete a planned maintenance schedule from Cloud Insight.", {
580
- maintenanceId: z.string().describe("Maintenance ID to delete"),
581
- confirm: z.boolean().optional().describe("Must be true to execute deletion."),
522
+ server.tool("ncloud_delete_maintenance", "⚠️ Destructive: Delete a planned maintenance schedule from Cloud Insight. Set confirm=true to execute.", {
523
+ maintenanceId: z.string().describe("Planned maintenance ID to delete"),
524
+ confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
582
525
  }, async (params) => {
583
526
  try {
584
527
  if (!params.confirm) {
585
- return {
586
- content: [{
587
- type: "text",
588
- text: `⚠️ This will permanently delete maintenance schedule [${params.maintenanceId}]. To confirm, call this tool again with confirm=true.`,
589
- }],
590
- };
528
+ return { content: [{ type: "text", text: `⚠️ This will permanently delete maintenance schedule [${params.maintenanceId}]. To execute, call again with confirm=true.` }] };
591
529
  }
592
- const body = { maintenanceId: params.maintenanceId };
593
- const result = await client.postRequest("/cw_fea/real/cw/api/maintenance/delete", body);
530
+ const result = await client.requestRaw("DELETE", `${CW}/planned-maintenances/${params.maintenanceId}`);
594
531
  return toolText(result);
595
532
  }
596
533
  catch (error) {