mcp-instana 0.6.2__py3-none-any.whl → 0.7.0__py3-none-any.whl

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 (28) hide show
  1. {mcp_instana-0.6.2.dist-info → mcp_instana-0.7.0.dist-info}/METADATA +179 -120
  2. {mcp_instana-0.6.2.dist-info → mcp_instana-0.7.0.dist-info}/RECORD +28 -21
  3. src/application/application_alert_config.py +397 -146
  4. src/application/application_analyze.py +597 -597
  5. src/application/application_call_group.py +528 -0
  6. src/application/application_catalog.py +0 -8
  7. src/application/application_global_alert_config.py +255 -38
  8. src/application/application_metrics.py +377 -237
  9. src/application/application_resources.py +414 -365
  10. src/application/application_settings.py +605 -1651
  11. src/application/application_topology.py +62 -62
  12. src/core/custom_dashboard_smart_router_tool.py +135 -0
  13. src/core/server.py +92 -119
  14. src/core/smart_router_tool.py +574 -0
  15. src/core/utils.py +17 -8
  16. src/custom_dashboard/custom_dashboard_tools.py +422 -0
  17. src/infrastructure/elicitation_handler.py +338 -0
  18. src/infrastructure/entity_registry.py +329 -0
  19. src/infrastructure/infrastructure_analyze_new.py +600 -0
  20. src/infrastructure/{infrastructure_analyze.py → infrastructure_analyze_old.py} +1 -16
  21. src/infrastructure/infrastructure_catalog.py +7 -28
  22. src/infrastructure/infrastructure_metrics.py +93 -17
  23. src/infrastructure/infrastructure_resources.py +5 -20
  24. src/infrastructure/infrastructure_topology.py +2 -8
  25. src/prompts/application/application_settings.py +58 -0
  26. {mcp_instana-0.6.2.dist-info → mcp_instana-0.7.0.dist-info}/WHEEL +0 -0
  27. {mcp_instana-0.6.2.dist-info → mcp_instana-0.7.0.dist-info}/entry_points.txt +0 -0
  28. {mcp_instana-0.6.2.dist-info → mcp_instana-0.7.0.dist-info}/licenses/LICENSE.md +0 -0
@@ -33,73 +33,341 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
33
33
  """Initialize the Application Alert MCP tools client."""
34
34
  super().__init__(read_token=read_token, base_url=base_url)
35
35
 
36
- @register_as_tool(
37
- title="Find Application Alert Config",
38
- annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
39
- )
36
+ # CRUD Operations Dispatcher - called by smart_router_tool.py
37
+ async def execute_alert_config_operation(
38
+ self,
39
+ operation: str,
40
+ application_id: Optional[str] = None,
41
+ id: Optional[str] = None,
42
+ alert_ids: Optional[List[str]] = None,
43
+ valid_on: Optional[int] = None,
44
+ created: Optional[int] = None,
45
+ payload: Optional[Union[Dict[str, Any], str]] = None,
46
+ ctx=None
47
+ ) -> Dict[str, Any]:
48
+ """
49
+ Execute Application Alert Config CRUD operations.
50
+ Called by the smart router tool.
51
+
52
+ Args:
53
+ operation: Operation to perform (find_active, find_versions, find, create, update, delete, enable, disable, restore, update_baseline)
54
+ application_id: Application ID (for find_active)
55
+ id: Alert config ID
56
+ alert_ids: List of alert IDs to filter
57
+ valid_on: Unix timestamp for specific version
58
+ created: Unix timestamp for restore
59
+ payload: Configuration payload
60
+ ctx: MCP context
61
+
62
+ Returns:
63
+ Operation result dictionary
64
+ """
65
+ try:
66
+ if operation == "find_active":
67
+ return await self._find_active_configs(application_id, alert_ids, ctx)
68
+ elif operation == "find_versions":
69
+ return await self._find_config_versions(id, ctx)
70
+ elif operation == "find":
71
+ return await self._find_config(id, valid_on, ctx)
72
+ elif operation == "create":
73
+ return await self._create_config(payload, ctx)
74
+ elif operation == "update":
75
+ return await self._update_config(id, payload, ctx)
76
+ elif operation == "delete":
77
+ return await self._delete_config(id, ctx)
78
+ elif operation == "enable":
79
+ return await self._enable_config(id, ctx)
80
+ elif operation == "disable":
81
+ return await self._disable_config(id, ctx)
82
+ elif operation == "restore":
83
+ return await self._restore_config(id, created, ctx)
84
+ elif operation == "update_baseline":
85
+ return await self._update_baseline(id, ctx)
86
+ else:
87
+ return {"error": f"Operation '{operation}' not supported"}
88
+
89
+ except Exception as e:
90
+ logger.error(f"Error executing {operation}: {e}", exc_info=True)
91
+ return {"error": f"Error executing {operation}: {e!s}"}
92
+
93
+ # Individual operation functions
94
+
40
95
  @with_header_auth(ApplicationAlertConfigurationApi)
41
- async def find_application_alert_config(self,
42
- id: str,
43
- valid_on: Optional[int] = None,
96
+ async def _find_active_configs(
97
+ self,
98
+ application_id: Optional[str],
99
+ alert_ids: Optional[List[str]],
100
+ ctx=None,
101
+ api_client=None
102
+ ) -> Dict[str, Any]:
103
+ """Find active application alert configs."""
104
+ if not application_id:
105
+ return {"error": "application_id is required for find_active operation"}
106
+
107
+ return await self.find_active_application_alert_configs(
108
+ application_id=application_id,
109
+ alert_ids=alert_ids,
110
+ ctx=ctx,
111
+ api_client=api_client
112
+ )
113
+
114
+ @with_header_auth(ApplicationAlertConfigurationApi)
115
+ async def _find_config_versions(
116
+ self,
117
+ id: Optional[str],
118
+ ctx=None,
119
+ api_client=None
120
+ ) -> Dict[str, Any]:
121
+ """Find all versions of an application alert config."""
122
+ if not id:
123
+ return {"error": "id is required for find_versions operation"}
124
+
125
+ return await self.find_application_alert_config_versions(
126
+ id=id,
127
+ ctx=ctx,
128
+ api_client=api_client
129
+ )
130
+
131
+ @with_header_auth(ApplicationAlertConfigurationApi)
132
+ async def _find_config(
133
+ self,
134
+ id: Optional[str],
135
+ valid_on: Optional[int],
136
+ ctx=None,
137
+ api_client=None
138
+ ) -> Dict[str, Any]:
139
+ """Find a specific application alert config."""
140
+ return await self.find_application_alert_config(
141
+ id=id,
142
+ valid_on=valid_on,
143
+ ctx=ctx,
144
+ api_client=api_client
145
+ )
146
+
147
+ @with_header_auth(ApplicationAlertConfigurationApi)
148
+ async def _create_config(
149
+ self,
150
+ payload: Optional[Union[Dict[str, Any], str]],
151
+ ctx=None,
152
+ api_client=None
153
+ ) -> Dict[str, Any]:
154
+ """Create a new application alert config."""
155
+ if not payload:
156
+ return {"error": "payload is required for create operation"}
157
+
158
+ return await self.create_application_alert_config(
159
+ payload=payload,
160
+ ctx=ctx,
161
+ api_client=api_client
162
+ )
163
+
164
+ @with_header_auth(ApplicationAlertConfigurationApi)
165
+ async def _update_config(
166
+ self,
167
+ id: Optional[str],
168
+ payload: Optional[Union[Dict[str, Any], str]],
169
+ ctx=None,
170
+ api_client=None
171
+ ) -> Dict[str, Any]:
172
+ """Update an existing application alert config."""
173
+ if not id:
174
+ return {"error": "id is required for update operation"}
175
+ if not payload:
176
+ return {"error": "payload is required for update operation"}
177
+
178
+ return await self.update_application_alert_config(
179
+ id=id,
180
+ payload=payload,
181
+ ctx=ctx,
182
+ api_client=api_client
183
+ )
184
+
185
+ @with_header_auth(ApplicationAlertConfigurationApi)
186
+ async def _delete_config(
187
+ self,
188
+ id: Optional[str],
189
+ ctx=None,
190
+ api_client=None
191
+ ) -> Dict[str, Any]:
192
+ """Delete an application alert config."""
193
+ if not id:
194
+ return {"error": "id is required for delete operation"}
195
+
196
+ return await self.delete_application_alert_config(
197
+ id=id,
198
+ ctx=ctx,
199
+ api_client=api_client
200
+ )
201
+
202
+ @with_header_auth(ApplicationAlertConfigurationApi)
203
+ async def _enable_config(
204
+ self,
205
+ id: Optional[str],
206
+ ctx=None,
207
+ api_client=None
208
+ ) -> Dict[str, Any]:
209
+ """Enable an application alert config."""
210
+ if not id:
211
+ return {"error": "id is required for enable operation"}
212
+
213
+ return await self.enable_application_alert_config(
214
+ id=id,
215
+ ctx=ctx,
216
+ api_client=api_client
217
+ )
218
+
219
+ @with_header_auth(ApplicationAlertConfigurationApi)
220
+ async def _disable_config(
221
+ self,
222
+ id: Optional[str],
223
+ ctx=None,
224
+ api_client=None
225
+ ) -> Dict[str, Any]:
226
+ """Disable an application alert config."""
227
+ if not id:
228
+ return {"error": "id is required for disable operation"}
229
+
230
+ return await self.disable_application_alert_config(
231
+ id=id,
232
+ ctx=ctx,
233
+ api_client=api_client
234
+ )
235
+
236
+ @with_header_auth(ApplicationAlertConfigurationApi)
237
+ async def _restore_config(
238
+ self,
239
+ id: Optional[str],
240
+ created: Optional[int],
241
+ ctx=None,
242
+ api_client=None
243
+ ) -> Dict[str, Any]:
244
+ """Restore a deleted application alert config."""
245
+ if not id:
246
+ return {"error": "id is required for restore operation"}
247
+ if not created:
248
+ return {"error": "created timestamp is required for restore operation"}
249
+
250
+ return await self.restore_application_alert_config(
251
+ id=id,
252
+ created=created,
253
+ ctx=ctx,
254
+ api_client=api_client
255
+ )
256
+
257
+ @with_header_auth(ApplicationAlertConfigurationApi)
258
+ async def _update_baseline(
259
+ self,
260
+ id: Optional[str],
261
+ ctx=None,
262
+ api_client=None
263
+ ) -> Dict[str, Any]:
264
+ """Update baseline for an application alert config."""
265
+ if not id:
266
+ return {"error": "id is required for update_baseline operation"}
267
+
268
+ return await self.update_application_alert_config_baseline(
269
+ id=id,
270
+ ctx=ctx,
271
+ api_client=api_client
272
+ )
273
+
274
+ # Original individual methods - no @register_as_tool decorator
275
+ # These are called internally by the operation functions above
276
+
277
+ @with_header_auth(ApplicationAlertConfigurationApi)
278
+ async def find_active_application_alert_configs(self,
279
+ application_id: str,
280
+ alert_ids: Optional[List[str]] = None,
44
281
  ctx=None, api_client=None) -> Dict[str, Any]:
45
282
  """
46
- Get a specific Smart Alert Configuration.
283
+ Get All Smart Alert Configuration.
47
284
 
48
- This tool retrieves a specific Smart Alert Configuration by its ID.
285
+ This tool retrieves all Smart Alert Configuration, filtered by application ID and alert IDs.
49
286
  This may return a deleted Configuration.
50
287
 
288
+ Configurations are sorted by creation date in descending order.
289
+
51
290
  Args:
52
- id: The ID of the Smart Alert Configuration
53
- valid_on: Optional timestamp (in milliseconds) to retrieve the configuration as it was at that time
291
+ application_id: The ID of a specific application.
292
+ alert_ids: A list of Smart Alert Configuration IDs. This allows fetching of a specific set of Configurations. This query can be repeated to use multiple IDs.
54
293
  ctx: The MCP context (optional)
55
294
 
56
295
  Returns:
57
296
  Dictionary containing the Smart Alert Configuration or error information
58
297
  """
59
298
  try:
60
- logger.debug(f"find_application_alert_config called with id={id}, valid_on={valid_on}")
299
+ logger.debug(f"find_active_application_alert_configs called with application_id={application_id}, alert_ids={alert_ids}")
61
300
 
62
301
  # Validate required parameters
63
- if not id:
64
- return {"error": "id is required"}
302
+ if not application_id:
303
+ return {"error": "application_id is required"}
65
304
 
66
- # Call the find_application_alert_config method from the SDK
67
- logger.debug(f"Calling find_application_alert_config with id={id}, valid_on={valid_on}")
68
- result = api_client.find_application_alert_config(
69
- id=id,
70
- valid_on=valid_on
305
+ # Call the find_active_application_alert_configs method from the SDK
306
+ logger.debug(f"Calling find_active_application_alert_configs with application_id={application_id}, alert_ids={alert_ids}")
307
+ response = api_client.find_active_application_alert_configs_without_preload_content(
308
+ application_id=application_id,
309
+ alert_ids=alert_ids
71
310
  )
72
311
 
73
- # Convert the result to a dictionary
74
- if hasattr(result, 'to_dict'):
75
- result_dict = result.to_dict()
76
- else:
77
- # If it's already a dict or another format, use it as is
78
- result_dict = result
312
+ import json
313
+
314
+ raw_data = response.data.decode('utf-8')
315
+ logger.debug(f"Raw data: {raw_data}")
316
+
317
+ try:
318
+ result = json.loads(raw_data)
319
+ logger.debug(f"Parsed JSON result: {result}")
320
+
321
+ if isinstance(result, list):
322
+ configs = result
323
+ else:
324
+ configs = [result] if result else []
325
+
326
+ # Limit to first 10 results
327
+ total_count = len(configs)
328
+ limited_configs = configs[:10]
329
+
330
+ # Provide helpful feedback based on the result
331
+ if not configs:
332
+ return {
333
+ "configs": [],
334
+ "count": 0,
335
+ "total": 0,
336
+ "showing": 0,
337
+ "message": f"No active alert configurations found for application ID: {application_id}",
338
+ "suggestion": "You can create a new alert configuration using the 'create' operation."
339
+ }
340
+ else:
341
+ return {
342
+ "configs": limited_configs,
343
+ "count": len(limited_configs),
344
+ "total": total_count,
345
+ "showing": len(limited_configs),
346
+ "message": f"Found {total_count} active alert configuration(s) for application ID: {application_id}. Showing first {len(limited_configs)}."
347
+ }
348
+
349
+ except json.JSONDecodeError as e:
350
+ error_msg = f"Failed to parse response JSON: {e}"
351
+ logger.error(error_msg)
352
+ return {"error": error_msg}
79
353
 
80
- logger.debug(f"Result from find_application_alert_config: {result_dict}")
81
- return result_dict
82
354
  except Exception as e:
83
- logger.error(f"Error in find_application_alert_config: {e}", exc_info=True)
84
- return {"error": f"Failed to get application alert config: {e!s}"}
355
+ logger.error(f"Error in find_active_application_alert_configs: {e}", exc_info=True)
356
+ return {"error": f"Failed to get active application alert config: {e!s}"}
85
357
 
86
358
 
87
- @register_as_tool(
88
- title="Find Application Alert Config Versions",
89
- annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
90
- )
91
359
  @with_header_auth(ApplicationAlertConfigurationApi)
92
360
  async def find_application_alert_config_versions(self,
93
361
  id: str,
94
362
  ctx=None, api_client=None) -> Dict[str, Any]:
95
363
  """
96
- Get Smart Alert Config Versions . Get all versions of a Smart Alert Configuration.
364
+ Get Smart Alert Config Versions. Get all versions of Smart Alert Configuration.
97
365
 
98
- This tool retrieves all versions of a Smart Alert Configuration by its ID.
366
+ This tool retrieves all versions of a Smart Alert Configuration.
99
367
  This may return deleted Configurations. Configurations are sorted by creation date in descending order.
100
368
 
101
369
  Args:
102
- id: The ID of the Smart Alert Configuration
370
+ id: ID of a specific Smart Alert Configuration to retrieve.
103
371
  ctx: The MCP context (optional)
104
372
 
105
373
  Returns:
@@ -135,37 +403,32 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
135
403
  logger.error(f"Error in find_application_alert_config_versions: {e}", exc_info=True)
136
404
  return {"error": f"Failed to get application alert config versions: {e!s}"}
137
405
 
138
- @register_as_tool(
139
- title="Get Application Alert Configs",
140
- annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
141
- )
142
406
  @with_header_auth(ApplicationAlertConfigurationApi)
143
- async def get_application_alert_configs(self,
144
- application_id: Optional[str] = None,
145
- alert_ids: Optional[List[str]] = None,
407
+ async def find_application_alert_config(self,
408
+ id: Optional[str] = None,
409
+ valid_on: Optional[int] = None,
146
410
  ctx=None, api_client=None) -> Dict[str, Any]:
147
411
  """
148
- Get Smart Alert Configurations for a specific application.
412
+ Gets a specific Smart Alert Configuration. This may return a deleted Configuration.
149
413
 
150
- This tool retrieves Smart Alert Configurations, optionally filtered by application ID and alert IDs.
151
- Configurations are sorted by creation date in descending order.
414
+ This tool retrieves Smart Alert Configurations, filtered by id and valid on.
152
415
 
153
416
  Args:
154
- application_id: Optional ID of the application to filter configurations
155
- alert_ids: Optional list of alert IDs to filter configurations
417
+ id: ID of a specific Smart Alert Configuration to retrieve
418
+ valid_on: A Unix timestamp representing a specific time the Configuration was active. If no timestamp is provided, the latest active version will be retrieved.
156
419
  ctx: The MCP context (optional)
157
420
 
158
421
  Returns:
159
422
  Dictionary containing Smart Alert Configurations or error information
160
423
  """
161
424
  try:
162
- logger.debug(f"get_application_alert_configs called with application_id={application_id}, alert_ids={alert_ids}")
425
+ logger.debug(f"find_application_alert_config called with id={id}, valid_on={valid_on}")
163
426
 
164
- # Call the find_active_application_alert_configs method from the SDK
165
- logger.debug(f"Calling find_active_application_alert_configs with application_id={application_id}, alert_ids={alert_ids}")
166
- result = api_client.find_active_application_alert_configs(
167
- application_id=application_id,
168
- alert_ids=alert_ids
427
+ # Call the find_application_alert_config method from the SDK
428
+ logger.debug(f"Calling find_application_alert_config with id={id}, valid_on={valid_on}")
429
+ result = api_client.find_application_alert_config(
430
+ id=id,
431
+ valid_on=valid_on
169
432
  )
170
433
 
171
434
  # Convert the result to a dictionary
@@ -179,28 +442,24 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
179
442
  # If it's already a dict or another format, use it as is
180
443
  result_dict = result if isinstance(result, dict) else {"data": result}
181
444
 
182
- logger.debug(f"Result from find_active_application_alert_configs: {result_dict}")
445
+ logger.debug(f"Result from find_application_alert_config: {result_dict}")
183
446
  return result_dict
184
447
  except Exception as e:
185
- logger.error(f"Error in get_application_alert_configs: {e}", exc_info=True)
448
+ logger.error(f"Error in find_application_alert_config: {e}", exc_info=True)
186
449
  return {"error": f"Failed to get application alert configs: {e!s}"}
187
450
 
188
- @register_as_tool(
189
- title="Delete Application Alert Config",
190
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=True)
191
- )
192
451
  @with_header_auth(ApplicationAlertConfigurationApi)
193
452
  async def delete_application_alert_config(self,
194
453
  id: str,
195
454
  ctx=None, api_client=None) -> Dict[str, Any]:
196
455
  """
197
- Delete a Smart Alert Configuration.
456
+ Deletes a Smart Alert Configuration.
198
457
 
199
458
  This tool deletes a specific Smart Alert Configuration by its ID.
200
459
  Once deleted, the configuration will no longer trigger alerts.
201
460
 
202
461
  Args:
203
- id: The ID of the Smart Alert Configuration to delete
462
+ id: ID of a specific Smart Alert Configuration to delete.
204
463
  ctx: The MCP context (optional)
205
464
 
206
465
  Returns:
@@ -229,10 +488,6 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
229
488
  logger.error(f"Error in delete_application_alert_config: {e}", exc_info=True)
230
489
  return {"error": f"Failed to delete application alert config: {e!s}"}
231
490
 
232
- @register_as_tool(
233
- title="Enable Application Alert Config",
234
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
235
- )
236
491
  @with_header_auth(ApplicationAlertConfigurationApi)
237
492
  async def enable_application_alert_config(self,
238
493
  id: str,
@@ -244,7 +499,7 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
244
499
  Once enabled, the configuration will start triggering alerts when conditions are met.
245
500
 
246
501
  Args:
247
- id: The ID of the Smart Alert Configuration to enable
502
+ id: ID of a specific Smart Alert Configuration to enable.
248
503
  ctx: The MCP context (optional)
249
504
 
250
505
  Returns:
@@ -277,10 +532,6 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
277
532
  logger.error(f"Error in enable_application_alert_config: {e}", exc_info=True)
278
533
  return {"error": f"Failed to enable application alert config: {e!s}"}
279
534
 
280
- @register_as_tool(
281
- title="Disable Application Alert Config",
282
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
283
- )
284
535
  @with_header_auth(ApplicationAlertConfigurationApi)
285
536
  async def disable_application_alert_config(self,
286
537
  id: str,
@@ -292,7 +543,7 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
292
543
  Once disabled, the configuration will stop triggering alerts even when conditions are met.
293
544
 
294
545
  Args:
295
- id: The ID of the Smart Alert Configuration to disable
546
+ id: ID of a specific Smart Alert Configuration to disable.
296
547
  ctx: The MCP context (optional)
297
548
 
298
549
  Returns:
@@ -325,10 +576,6 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
325
576
  logger.error(f"Error in disable_application_alert_config: {e}", exc_info=True)
326
577
  return {"error": f"Failed to disable application alert config: {e!s}"}
327
578
 
328
- @register_as_tool(
329
- title="Restore Application Alert Config",
330
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
331
- )
332
579
  @with_header_auth(ApplicationAlertConfigurationApi)
333
580
  async def restore_application_alert_config(self,
334
581
  id: str,
@@ -341,7 +588,7 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
341
588
  Once restored, the configuration will be active again and can trigger alerts when conditions are met.
342
589
 
343
590
  Args:
344
- id: The ID of the Smart Alert Configuration to restore
591
+ id: ID of a specific Smart Alert Configuration to restore.
345
592
  created: Unix timestamp representing the creation time of the specific Smart Alert Configuration version
346
593
  ctx: The MCP context (optional)
347
594
 
@@ -378,10 +625,6 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
378
625
  logger.error(f"Error in restore_application_alert_config: {e}", exc_info=True)
379
626
  return {"error": f"Failed to restore application alert config: {e!s}"}
380
627
 
381
- @register_as_tool(
382
- title="Update Application Alert Config Baseline",
383
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
384
- )
385
628
  @with_header_auth(ApplicationAlertConfigurationApi)
386
629
  async def update_application_alert_config_baseline(self,
387
630
  id: str,
@@ -393,7 +636,7 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
393
636
  The 'LastUpdated' field of the Configuration is changed to the current time.
394
637
 
395
638
  Args:
396
- id: The ID of the Smart Alert Configuration to recalculate
639
+ id: ID of a specific Smart Alert Configuration to recalculate.
397
640
  ctx: The MCP context (optional)
398
641
 
399
642
  Returns:
@@ -426,43 +669,51 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
426
669
  logger.error(f"Error in update_application_alert_config_baseline: {e}", exc_info=True)
427
670
  return {"error": f"Failed to update application alert config baseline: {e!s}"}
428
671
 
429
- @register_as_tool(
430
- title="Create Application Alert Config",
431
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
432
- )
433
672
  @with_header_auth(ApplicationAlertConfigurationApi)
434
673
  async def create_application_alert_config(self,
435
674
  payload: Union[Dict[str, Any], str],
436
675
  ctx=None, api_client=None) -> Dict[str, Any]:
437
676
  """
438
- Create a new Smart Alert Configuration.
677
+ Creates a new Smart Alert Configuration.
439
678
 
440
679
  This tool creates a new Smart Alert Configuration with the provided configuration details.
441
680
  Once created, the configuration will be active and can trigger alerts when conditions are met.
442
681
 
443
682
  Sample payload:
444
683
  {
445
- "name": "My Alert Config",
446
- "description": "Alert for high CPU usage",
447
- "severity": 10,
448
- "triggering": true,
449
- "enabled": true,
450
- "rule": {
451
- "alertType": "...",
452
- "metricName": "...",
453
- "aggregation": "...",
454
- "conditionOperator": "...",
455
- "conditionValue": 90
456
- },
457
- "applicationId": "your-application-id",
458
- "boundaryScope": "...",
459
- "tagFilterExpression": {
460
- "type": "EXPRESSION",
461
- "logicalOperator": "AND",
462
- "elements": []
463
- },
464
- "granularity": 60000,
465
- "timeThreshold": 300000
684
+ "name": "Slow calls than usual",
685
+ "description": "Calls are slower or equal to 2 ms based on latency (90th).",
686
+ "boundaryScope": "INBOUND",
687
+ "applicationId": "j02SxMRTSf-NCBXf5IdsjQ",
688
+ "services": {},
689
+ "severity": 5,
690
+ "triggering": false,
691
+ "tagFilterExpression": {
692
+ "type": "EXPRESSION",
693
+ "logicalOperator": "AND",
694
+ "elements": []
695
+ },
696
+ "includeInternal": false,
697
+ "includeSynthetic": false,
698
+ "rule": {
699
+ "alertType": "slowness",
700
+ "aggregation": "P90",
701
+ "metricName": "latency"
702
+ },
703
+ "threshold": {
704
+ "type": "staticThreshold",
705
+ "operator": ">=",
706
+ "value": 2,
707
+ "lastUpdated": 0
708
+ },
709
+ "alertChannelIds": [],
710
+ "granularity": 600000,
711
+ "timeThreshold": {
712
+ "type": "violationsInSequence",
713
+ "timeWindow": 600000
714
+ },
715
+ "evaluationType": "PER_AP",
716
+ "customPayloadFields": []
466
717
  }
467
718
 
468
719
  Args:
@@ -470,7 +721,7 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
470
721
  ctx: The MCP context (optional)
471
722
 
472
723
  Returns:
473
- Dictionary containing the created Smart Alert Configuration or error information
724
+ Dictionary containing the created new Smart Alert Configuration or error information
474
725
  """
475
726
  try:
476
727
  logger.debug(f"create_application_alert_config called with payload={payload}")
@@ -525,16 +776,11 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
525
776
  logger.debug(f"Error importing ApplicationAlertConfig: {e}")
526
777
  return {"error": f"Failed to import ApplicationAlertConfig: {e!s}"}
527
778
 
528
- # Create an ApplicationAlertConfig object from the request body using from_dict
529
- # This properly handles nested objects and discriminators
779
+ # Create an ApplicationAlertConfig object from the request body
530
780
  try:
531
781
  logger.debug(f"Creating ApplicationAlertConfig with params: {request_body}")
532
- config_object = ApplicationAlertConfig.from_dict(request_body)
782
+ config_object = ApplicationAlertConfig(**request_body)
533
783
  logger.debug("Successfully created config object")
534
-
535
- # Debug: Log what will be sent to API
536
- config_dict = config_object.to_dict()
537
- logger.debug(f"Config object as dict (what will be sent to API): {config_dict}")
538
784
  except Exception as e:
539
785
  logger.debug(f"Error creating ApplicationAlertConfig: {e}")
540
786
  return {"error": f"Failed to create config object: {e!s}"}
@@ -556,10 +802,6 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
556
802
  logger.error(f"Error in create_application_alert_config: {e}", exc_info=True)
557
803
  return {"error": f"Failed to create application alert config: {e!s}"}
558
804
 
559
- @register_as_tool(
560
- title="Update Application Alert Config",
561
- annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
562
- )
563
805
  @with_header_auth(ApplicationAlertConfigurationApi)
564
806
  async def update_application_alert_config(self,
565
807
  id: str,
@@ -573,27 +815,39 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
573
815
 
574
816
  Sample payload:
575
817
  {
576
- "name": "Updated Alert Config",
577
- "description": "Updated alert for high CPU usage",
578
- "severity": 5,
579
- "triggering": true,
580
- "enabled": true,
581
- "rule": {
582
- "alertType": "...",
583
- "metricName": "...",
584
- "aggregation": "...",
585
- "conditionOperator": "...",
586
- "conditionValue": 95
587
- },
588
- "applicationId": "your-application-id",
589
- "boundaryScope": "...",
590
- "tagFilterExpression": {
591
- "type": "EXPRESSION",
592
- "logicalOperator": "AND",
593
- "elements": []
594
- },
595
- "granularity": 60000,
596
- "timeThreshold": 300000
818
+ "name": "Slow calls than usual",
819
+ "description": "Calls are slower or equal to 2 ms based on latency (90th).",
820
+ "boundaryScope": "INBOUND",
821
+ "applicationId": "j02SxMRTSf-NCBXf5IdsjQ",
822
+ "services": {},
823
+ "severity": 5,
824
+ "triggering": false,
825
+ "tagFilterExpression": {
826
+ "type": "EXPRESSION",
827
+ "logicalOperator": "AND",
828
+ "elements": []
829
+ },
830
+ "includeInternal": false,
831
+ "includeSynthetic": false,
832
+ "rule": {
833
+ "alertType": "slowness",
834
+ "aggregation": "P90",
835
+ "metricName": "latency"
836
+ },
837
+ "threshold": {
838
+ "type": "staticThreshold",
839
+ "operator": ">=",
840
+ "value": 2,
841
+ "lastUpdated": 0
842
+ },
843
+ "alertChannelIds": [],
844
+ "granularity": 600000,
845
+ "timeThreshold": {
846
+ "type": "violationsInSequence",
847
+ "timeWindow": 600000
848
+ },
849
+ "evaluationType": "PER_AP",
850
+ "customPayloadFields": []
597
851
  }
598
852
 
599
853
  Args:
@@ -660,11 +914,10 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
660
914
  logger.debug(f"Error importing ApplicationAlertConfig: {e}")
661
915
  return {"error": f"Failed to import ApplicationAlertConfig: {e!s}"}
662
916
 
663
- # Create an ApplicationAlertConfig object from the request body using from_dict
664
- # This properly handles nested objects and discriminators
917
+ # Create an ApplicationAlertConfig object from the request body
665
918
  try:
666
919
  logger.debug(f"Creating ApplicationAlertConfig with params: {request_body}")
667
- config_object = ApplicationAlertConfig.from_dict(request_body)
920
+ config_object = ApplicationAlertConfig(**request_body)
668
921
  logger.debug("Successfully created config object")
669
922
  except Exception as e:
670
923
  logger.debug(f"Error creating ApplicationAlertConfig: {e}")
@@ -693,5 +946,3 @@ class ApplicationAlertMCPTools(BaseInstanaClient):
693
946
  logger.error(f"Error in update_application_alert_config: {e}")
694
947
  return {"error": f"Failed to update application alert config: {e!s}"}
695
948
 
696
-
697
-