mcp-instana 0.1.1__py3-none-any.whl → 0.2.1__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 (55) hide show
  1. {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/METADATA +460 -139
  2. mcp_instana-0.2.1.dist-info/RECORD +59 -0
  3. src/application/application_analyze.py +373 -160
  4. src/application/application_catalog.py +3 -1
  5. src/application/application_global_alert_config.py +653 -0
  6. src/application/application_metrics.py +6 -2
  7. src/application/application_resources.py +3 -1
  8. src/application/application_settings.py +966 -370
  9. src/application/application_topology.py +6 -2
  10. src/automation/action_catalog.py +416 -0
  11. src/automation/action_history.py +338 -0
  12. src/core/server.py +159 -9
  13. src/core/utils.py +2 -2
  14. src/event/events_tools.py +602 -275
  15. src/infrastructure/infrastructure_analyze.py +7 -3
  16. src/infrastructure/infrastructure_catalog.py +3 -1
  17. src/infrastructure/infrastructure_metrics.py +6 -2
  18. src/infrastructure/infrastructure_resources.py +7 -5
  19. src/infrastructure/infrastructure_topology.py +5 -3
  20. src/prompts/__init__.py +16 -0
  21. src/prompts/application/__init__.py +1 -0
  22. src/prompts/application/application_alerts.py +54 -0
  23. src/prompts/application/application_catalog.py +26 -0
  24. src/prompts/application/application_metrics.py +57 -0
  25. src/prompts/application/application_resources.py +26 -0
  26. src/prompts/application/application_settings.py +75 -0
  27. src/prompts/application/application_topology.py +30 -0
  28. src/prompts/events/__init__.py +1 -0
  29. src/prompts/events/events_tools.py +161 -0
  30. src/prompts/infrastructure/infrastructure_analyze.py +72 -0
  31. src/prompts/infrastructure/infrastructure_catalog.py +53 -0
  32. src/prompts/infrastructure/infrastructure_metrics.py +45 -0
  33. src/prompts/infrastructure/infrastructure_resources.py +74 -0
  34. src/prompts/infrastructure/infrastructure_topology.py +38 -0
  35. src/prompts/settings/__init__.py +0 -0
  36. src/prompts/settings/custom_dashboard.py +157 -0
  37. src/prompts/website/__init__.py +1 -0
  38. src/prompts/website/website_analyze.py +35 -0
  39. src/prompts/website/website_catalog.py +40 -0
  40. src/prompts/website/website_configuration.py +105 -0
  41. src/prompts/website/website_metrics.py +34 -0
  42. src/settings/__init__.py +1 -0
  43. src/settings/custom_dashboard_tools.py +417 -0
  44. src/website/__init__.py +0 -0
  45. src/website/website_analyze.py +433 -0
  46. src/website/website_catalog.py +171 -0
  47. src/website/website_configuration.py +770 -0
  48. src/website/website_metrics.py +241 -0
  49. mcp_instana-0.1.1.dist-info/RECORD +0 -30
  50. src/prompts/mcp_prompts.py +0 -900
  51. src/prompts/prompt_loader.py +0 -29
  52. src/prompts/prompt_registry.json +0 -21
  53. {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/WHEEL +0 -0
  54. {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/entry_points.txt +0 -0
  55. {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/licenses/LICENSE.md +0 -0
@@ -18,7 +18,9 @@ from src.core.utils import (
18
18
  )
19
19
 
20
20
  try:
21
- from instana_client.api.application_catalog_api import ApplicationCatalogApi
21
+ from instana_client.api.application_catalog_api import (
22
+ ApplicationCatalogApi,
23
+ )
22
24
 
23
25
  except ImportError as e:
24
26
  import logging
@@ -0,0 +1,653 @@
1
+ """
2
+ Application Alert MCP Tools Module
3
+
4
+ This module provides application alert configuration tools for Instana monitoring.
5
+ """
6
+
7
+ import logging
8
+ from typing import Any, Dict, List, Optional, Union
9
+
10
+ # Import the necessary classes from the SDK
11
+ try:
12
+ from instana_client.api.global_application_alert_configuration_api import (
13
+ GlobalApplicationAlertConfigurationApi,
14
+ )
15
+ except ImportError:
16
+ import logging
17
+ logger = logging.getLogger(__name__)
18
+ logger.error("Failed to import application alert configuration API", exc_info=True)
19
+ raise
20
+
21
+ from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
22
+
23
+ # Configure logger for this module
24
+ logger = logging.getLogger(__name__)
25
+
26
+ class ApplicationGlobalAlertMCPTools(BaseInstanaClient):
27
+ """Tools for application alerts in Instana MCP."""
28
+
29
+ def __init__(self, read_token: str, base_url: str):
30
+ """Initialize the Application Alert MCP tools client."""
31
+ super().__init__(read_token=read_token, base_url=base_url)
32
+
33
+ @register_as_tool
34
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
35
+ async def find_active_global_application_alert_configs(self,
36
+ application_id: str,
37
+ alert_ids: Optional[List[str]] = None,
38
+ ctx=None, api_client=None) -> Dict[str, Any]:
39
+ """
40
+ Get All Global Smart Alert Configuration.
41
+
42
+ This tool retrieves all Global Smart Alert Configuration, filtered by application ID and alert IDs.
43
+ This may return a deleted Configuration.
44
+
45
+ Configurations are sorted by creation date in descending order.
46
+
47
+ Args:
48
+ id: The ID of a specific global application.
49
+ valid_on: A list of Global Smart Alert Configuration IDs. This allows fetching of a specific set of Configurations. This query can be repeated to use multiple IDs.
50
+ ctx: The MCP context (optional)
51
+
52
+ Returns:
53
+ Dictionary containing the Smart Alert Configuration or error information
54
+ """
55
+ try:
56
+ logger.debug(f"find_active_global_application_alert_configs called with application_id={application_id}, alert_ids={alert_ids}")
57
+
58
+ # Validate required parameters
59
+ if not application_id:
60
+ return {"error": "application_id is required"}
61
+
62
+ # Call the find_active_global_application_alert_configs method from the SDK
63
+ logger.debug(f"Calling find_active_global_application_alert_configs with application_id={application_id}, alert_ids={alert_ids}")
64
+ result = api_client.find_active_global_application_alert_configs(
65
+ application_id=application_id,
66
+ alert_ids=alert_ids
67
+ )
68
+
69
+ # Convert the result to a dictionary
70
+ if hasattr(result, 'to_dict'):
71
+ result_dict = result.to_dict()
72
+ else:
73
+ # If it's already a dict or another format, use it as is
74
+ result_dict = result
75
+
76
+ logger.debug(f"Result from find_active_global_application_alert_configs: {result_dict}")
77
+ return result_dict
78
+ except Exception as e:
79
+ logger.error(f"Error in find_active_global_application_alert_configs: {e}", exc_info=True)
80
+ return {"error": f"Failed to get active global application alert config: {e!s}"}
81
+
82
+
83
+ @register_as_tool
84
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
85
+ async def find_global_application_alert_config_versions(self,
86
+ id: str,
87
+ ctx=None, api_client=None) -> Dict[str, Any]:
88
+ """
89
+ Get Global Smart Alert Config Versions . Get all versions of Global Smart Alert Configuration.
90
+
91
+ This tool retrievesGets all versions of a Global Smart Alert Configuration.
92
+ This may return deleted Configurations. Configurations are sorted by creation date in descending order.
93
+
94
+ Args:
95
+ id: ID of a specific Global Smart Alert Configuration to retrieve.
96
+ ctx: The MCP context (optional)
97
+
98
+ Returns:
99
+ Dictionary containing the Smart Alert Configuration versions or error information
100
+ """
101
+ try:
102
+ logger.debug(f"find_global_application_alert_config_versions called with id={id}")
103
+
104
+ # Validate required parameters
105
+ if not id:
106
+ return {"error": "id is required"}
107
+
108
+ # Call the find_global_application_alert_config_versions method from the SDK
109
+ logger.debug(f"Calling find_global_application_alert_config_versions with id={id}")
110
+ result = api_client.find_global_application_alert_config_versions(
111
+ id=id
112
+ )
113
+
114
+ # Convert the result to a dictionary
115
+ if isinstance(result, list):
116
+ # If result is a list, convert each item to a dictionary and wrap in a dict
117
+ items = [item.to_dict() if hasattr(item, 'to_dict') else item for item in result]
118
+ result_dict = {"versions": items}
119
+ elif hasattr(result, 'to_dict'):
120
+ result_dict = result.to_dict()
121
+ else:
122
+ # If it's already a dict or another format, use it as is
123
+ result_dict = result if isinstance(result, dict) else {"data": result}
124
+
125
+ logger.debug(f"Result from find_global_application_alert_config_versions: {result_dict}")
126
+ return result_dict
127
+ except Exception as e:
128
+ logger.error(f"Error in find_global_application_alert_config_versions: {e}", exc_info=True)
129
+ return {"error": f"Failed to get global application alert config versions: {e!s}"}
130
+
131
+ @register_as_tool
132
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
133
+ async def find_global_application_alert_config(self,
134
+ id: Optional[str] = None,
135
+ valid_on: Optional[int] = None,
136
+ ctx=None, api_client=None) -> Dict[str, Any]:
137
+ """
138
+ Gets a specific Global Smart Alert Configuration. This may return a deleted Configuration.
139
+
140
+ This tool retrieves Global Smart Alert Configurations, filtered by id and valid on.
141
+
142
+ Args:
143
+ id: ID of a specific Global Smart Alert Configuration to retrieve
144
+ 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.
145
+ ctx: The MCP context (optional)
146
+
147
+ Returns:
148
+ Dictionary containing Smart Alert Configurations or error information
149
+ """
150
+ try:
151
+ logger.debug(f"get_application_alert_configs called with id={id}, valid_on={valid_on}")
152
+
153
+ # Call the find_global_application_alert_config method from the SDK
154
+ logger.debug(f"Calling find_global_application_alert_config with id={id}, valid_on={valid_on}")
155
+ result = api_client.find_global_application_alert_config(
156
+ id=id,
157
+ valid_on=valid_on
158
+ )
159
+
160
+ # Convert the result to a dictionary
161
+ if isinstance(result, list):
162
+ # If result is a list, convert each item to a dictionary and wrap in a dict
163
+ items = [item.to_dict() if hasattr(item, 'to_dict') else item for item in result]
164
+ result_dict = {"configs": items}
165
+ elif hasattr(result, 'to_dict'):
166
+ result_dict = result.to_dict()
167
+ else:
168
+ # If it's already a dict or another format, use it as is
169
+ result_dict = result if isinstance(result, dict) else {"data": result}
170
+
171
+ logger.debug(f"Result from find_global_application_alert_config: {result_dict}")
172
+ return result_dict
173
+ except Exception as e:
174
+ logger.error(f"Error in find_global_application_alert_config: {e}", exc_info=True)
175
+ return {"error": f"Failed to get global application alert configs: {e!s}"}
176
+
177
+ @register_as_tool
178
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
179
+ async def delete_global_application_alert_config(self,
180
+ id: str,
181
+ ctx=None, api_client=None) -> Dict[str, Any]:
182
+ """
183
+ Deletes a Global Smart Alert Configuration.
184
+
185
+ This tool deletes a specific Global Smart Alert Configuration by its ID.
186
+ Once deleted, the configuration will no longer trigger alerts.
187
+
188
+ Args:
189
+ id: ID of a specific Global Smart Alert Configuration to delete.
190
+ ctx: The MCP context (optional)
191
+
192
+ Returns:
193
+ Dictionary containing the result of the deletion operation or error information
194
+ """
195
+ try:
196
+ logger.debug(f"delete_global_application_alert_config called with id={id}")
197
+
198
+ # Validate required parameters
199
+ if not id:
200
+ return {"error": "id is required"}
201
+
202
+ # Call the delete_global_application_alert_config method from the SDK
203
+ logger.debug(f"Calling delete_global_application_alert_config with id={id}")
204
+ api_client.delete_global_application_alert_config(id=id)
205
+
206
+ # The delete operation doesn't return a result, so we'll create a success message
207
+ result_dict = {
208
+ "success": True,
209
+ "message": f"Global Smart Alert Configuration with ID '{id}' has been successfully deleted"
210
+ }
211
+
212
+ logger.debug(f"Result from delete_global_application_alert_config: {result_dict}")
213
+ return result_dict
214
+ except Exception as e:
215
+ logger.error(f"Error in delete_global_application_alert_config: {e}", exc_info=True)
216
+ return {"error": f"Failed to delete global application alert config: {e!s}"}
217
+
218
+ @register_as_tool
219
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
220
+ async def enable_global_application_alert_config(self,
221
+ id: str,
222
+ ctx=None, api_client=None) -> Dict[str, Any]:
223
+ """
224
+ Enable a Global Smart Alert Configuration.
225
+
226
+ This tool enables a specific Global Smart Alert Configuration by its ID.
227
+ Once enabled, the configuration will start triggering alerts when conditions are met.
228
+
229
+ Args:
230
+ id: ID of a specific Global Smart Alert Configuration to enable.
231
+ ctx: The MCP context (optional)
232
+
233
+ Returns:
234
+ Dictionary containing the result of the enable operation or error information
235
+ """
236
+ try:
237
+ logger.debug(f"enable_global_application_alert_config called with id={id}")
238
+
239
+ # Validate required parameters
240
+ if not id:
241
+ return {"error": "id is required"}
242
+
243
+ # Call the enable_global_application_alert_config method from the SDK
244
+ logger.debug(f"Calling enable_global_application_alert_config with id={id}")
245
+ result = api_client.enable_global_application_alert_config(id=id)
246
+
247
+ # Convert the result to a dictionary
248
+ if hasattr(result, 'to_dict'):
249
+ result_dict = result.to_dict()
250
+ else:
251
+ # If it's already a dict or another format, use it as is
252
+ result_dict = result or {
253
+ "success": True,
254
+ "message": f"Global Smart Alert Configuration with ID '{id}' has been successfully enabled"
255
+ }
256
+
257
+ logger.debug(f"Result from enable_global_application_alert_config: {result_dict}")
258
+ return result_dict
259
+ except Exception as e:
260
+ logger.error(f"Error in enable_global_application_alert_config: {e}", exc_info=True)
261
+ return {"error": f"Failed to enable global application alert config: {e!s}"}
262
+
263
+ @register_as_tool
264
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
265
+ async def disable_global_application_alert_config(self,
266
+ id: str,
267
+ ctx=None, api_client=None) -> Dict[str, Any]:
268
+ """
269
+ Disable a Global Smart Alert Configuration.
270
+
271
+ This tool disables a specific Smart Alert Configuration by its ID.
272
+ Once disabled, the configuration will stop triggering alerts even when conditions are met.
273
+
274
+ Args:
275
+ id: ID of a specific Global Smart Alert Configuration to disable.
276
+ ctx: The MCP context (optional)
277
+
278
+ Returns:
279
+ Dictionary containing the result of the disable operation or error information
280
+ """
281
+ try:
282
+ logger.debug(f"disable_global_application_alert_config called with id={id}")
283
+
284
+ # Validate required parameters
285
+ if not id:
286
+ return {"error": "id is required"}
287
+
288
+ # Call the disable_global_application_alert_config method from the SDK
289
+ logger.debug(f"Calling disable_global_application_alert_config with id={id}")
290
+ result = api_client.disable_global_application_alert_config(id=id)
291
+
292
+ # Convert the result to a dictionary
293
+ if hasattr(result, 'to_dict'):
294
+ result_dict = result.to_dict()
295
+ else:
296
+ # If it's already a dict or another format, use it as is
297
+ result_dict = result or {
298
+ "success": True,
299
+ "message": f"Smart Alert Configuration with ID '{id}' has been successfully disabled"
300
+ }
301
+
302
+ logger.debug(f"Result from disable_global_application_alert_config: {result_dict}")
303
+ return result_dict
304
+ except Exception as e:
305
+ logger.error(f"Error in disable_global_application_alert_config: {e}", exc_info=True)
306
+ return {"error": f"Failed to disable global application alert config: {e!s}"}
307
+
308
+ @register_as_tool
309
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
310
+ async def restore_global_application_alert_config(self,
311
+ id: str,
312
+ created: int,
313
+ ctx=None, api_client=None) -> Dict[str, Any]:
314
+ """
315
+ Restore a deleted Global Smart Alert Configuration.
316
+
317
+ This tool restores a previously deleted Global Smart Alert Configuration by its ID and creation timestamp.
318
+ Once restored, the configuration will be active again and can trigger alerts when conditions are met.
319
+
320
+ Args:
321
+ id: ID of a specific Global Smart Alert Configuration to restore.
322
+ created: Unix timestamp representing the creation time of the specific Global Smart Alert Configuration version
323
+ ctx: The MCP context (optional)
324
+
325
+ Returns:
326
+ Dictionary containing the result of the restore operation or error information
327
+ """
328
+ try:
329
+ logger.debug(f"restore_global_application_alert_config called with id={id}, created={created}")
330
+
331
+ # Validate required parameters
332
+ if not id:
333
+ return {"error": "id is required"}
334
+
335
+ if not created:
336
+ return {"error": "created timestamp is required"}
337
+
338
+ # Call the restore_global_application_alert_config method from the SDK
339
+ logger.debug(f"Calling restore_global_application_alert_config with id={id}, created={created}")
340
+ result = api_client.restore_global_application_alert_config(id=id, created=created)
341
+
342
+ # Convert the result to a dictionary
343
+ if hasattr(result, 'to_dict'):
344
+ result_dict = result.to_dict()
345
+ else:
346
+ # If it's already a dict or another format, use it as is
347
+ result_dict = result or {
348
+ "success": True,
349
+ "message": f"Global Smart Alert Configuration with ID '{id}' and creation timestamp '{created}' has been successfully restored"
350
+ }
351
+
352
+ logger.debug(f"Result from restore_global_application_alert_config: {result_dict}")
353
+ return result_dict
354
+ except Exception as e:
355
+ logger.error(f"Error in restore_global_application_alert_config: {e}", exc_info=True)
356
+ return {"error": f"Failed to restore global application alert config: {e!s}"}
357
+
358
+ @register_as_tool
359
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
360
+ async def create_global_application_alert_config(self,
361
+ payload: Union[Dict[str, Any], str],
362
+ ctx=None, api_client=None) -> Dict[str, Any]:
363
+ """
364
+ Creates a new Global Smart Alert Configuration.
365
+
366
+ This tool creates a new Global Smart Alert Configuration with the provided configuration details.
367
+ Once created, the configuration will be active and can trigger alerts when conditions are met.
368
+
369
+ Sample payload:
370
+ {
371
+ "name": "Slow calls than usual",
372
+ "description": "Calls are slower or equal to 2 ms based on latency (90th).",
373
+ "boundaryScope": "INBOUND",
374
+ "applications": {
375
+ "j02SxMRTSf-NCBXf5IdsjQ": {
376
+ "applicationId": "j02SxMRTSf-NCBXf5IdsjQ",
377
+ "inclusive": true,
378
+ "services": {}
379
+ }
380
+ },
381
+ "applicationIds": [
382
+ "j02SxMRTSf-NCBXf5IdsjQ"
383
+ ],
384
+ "severity": 5,
385
+ "triggering": false,
386
+ "tagFilterExpression": {
387
+ "type": "EXPRESSION",
388
+ "logicalOperator": "AND",
389
+ "elements": []
390
+ },
391
+ "includeInternal": false,
392
+ "includeSynthetic": false,
393
+ "rule": {
394
+ "alertType": "slowness",
395
+ "aggregation": "P90",
396
+ "metricName": "latency"
397
+ },
398
+ "threshold": {
399
+ "type": "staticThreshold",
400
+ "operator": ">=",
401
+ "value": 2,
402
+ "lastUpdated": 0
403
+ },
404
+ "alertChannelIds": [],
405
+ "granularity": 600000,
406
+ "timeThreshold": {
407
+ "type": "violationsInSequence",
408
+ "timeWindow": 600000
409
+ },
410
+ "evaluationType": "PER_AP",
411
+ "customPayloadFields": []
412
+ }
413
+
414
+ Args:
415
+ payload: The Global Smart Alert Configuration details as a dictionary or JSON string
416
+ ctx: The MCP context (optional)
417
+
418
+ Returns:
419
+ Dictionary containing the created new Global Smart Alert Configuration or error information
420
+ """
421
+ try:
422
+ logger.debug(f"create_global_application_alert_config called with payload={payload}")
423
+
424
+ # Parse the payload if it's a string
425
+ if isinstance(payload, str):
426
+ logger.debug("Payload is a string, attempting to parse")
427
+ try:
428
+ import json
429
+ try:
430
+ parsed_payload = json.loads(payload)
431
+ logger.debug("Successfully parsed payload as JSON")
432
+ request_body = parsed_payload
433
+ except json.JSONDecodeError as e:
434
+ logger.debug(f"JSON parsing failed: {e}, trying with quotes replaced")
435
+
436
+ # Try replacing single quotes with double quotes
437
+ fixed_payload = payload.replace("'", "\"")
438
+ try:
439
+ parsed_payload = json.loads(fixed_payload)
440
+ logger.debug("Successfully parsed fixed JSON")
441
+ request_body = parsed_payload
442
+ except json.JSONDecodeError:
443
+ # Try as Python literal
444
+ import ast
445
+ try:
446
+ parsed_payload = ast.literal_eval(payload)
447
+ logger.debug("Successfully parsed payload as Python literal")
448
+ request_body = parsed_payload
449
+ except (SyntaxError, ValueError) as e2:
450
+ logger.debug(f"Failed to parse payload string: {e2}")
451
+ return {"error": f"Invalid payload format: {e2}", "payload": payload}
452
+ except Exception as e:
453
+ logger.debug(f"Error parsing payload string: {e}")
454
+ return {"error": f"Failed to parse payload: {e}", "payload": payload}
455
+ else:
456
+ # If payload is already a dictionary, use it directly
457
+ logger.debug("Using provided payload dictionary")
458
+ request_body = payload
459
+
460
+ # Validate the payload
461
+ if not request_body:
462
+ return {"error": "Payload is required"}
463
+
464
+ # Import the GlobalApplicationsAlertConfig class
465
+ try:
466
+ from instana_client.models.global_applications_alert_config import (
467
+ GlobalApplicationsAlertConfig,
468
+ )
469
+ logger.debug("Successfully imported GlobalApplicationsAlertConfig")
470
+ except ImportError as e:
471
+ logger.debug(f"Error importing GlobalApplicationsAlertConfig: {e}")
472
+ return {"error": f"Failed to import GlobalApplicationsAlertConfig: {e!s}"}
473
+
474
+ # Create an GlobalApplicationsAlertConfig object from the request body
475
+ try:
476
+ logger.debug(f"Creating GlobalApplicationsAlertConfig with params: {request_body}")
477
+ config_object = GlobalApplicationsAlertConfig(**request_body)
478
+ logger.debug("Successfully created config object")
479
+ except Exception as e:
480
+ logger.debug(f"Error creating GlobalApplicationsAlertConfig: {e}")
481
+ return {"error": f"Failed to create config object: {e!s}"}
482
+
483
+ # Call the create_global_application_alert_config method from the SDK
484
+ logger.debug("Calling create_global_application_alert_config with config object")
485
+ result = api_client.create_global_application_alert_config(global_applications_alert_config=config_object)
486
+
487
+ # Convert the result to a dictionary
488
+ if hasattr(result, 'to_dict'):
489
+ result_dict = result.to_dict()
490
+ else:
491
+ # If it's already a dict or another format, use it as is
492
+ result_dict = result
493
+
494
+ logger.debug(f"Result from create_global_application_alert_config: {result_dict}")
495
+ return result_dict
496
+ except Exception as e:
497
+ logger.error(f"Error in create_global_application_alert_config: {e}", exc_info=True)
498
+ return {"error": f"Failed to create global application alert config: {e!s}"}
499
+
500
+ @register_as_tool
501
+ @with_header_auth(GlobalApplicationAlertConfigurationApi)
502
+ async def update_global_application_alert_config(self,
503
+ id: str,
504
+ payload: Union[Dict[str, Any], str],
505
+ ctx=None, api_client=None) -> Dict[str, Any]:
506
+ """
507
+ Update an existing Global Smart Alert Configuration.
508
+
509
+ This tool updates an existing Global Smart Alert Configuration with the provided configuration details.
510
+ The configuration is identified by its ID, and the payload contains the updated configuration.
511
+
512
+ Sample payload:
513
+ {
514
+ "name": "Slow calls than usual",
515
+ "description": "Calls are slower or equal to 2 ms based on latency (90th).",
516
+ "boundaryScope": "INBOUND",
517
+ "applications": {
518
+ "j02SxMRTSf-NCBXf5IdsjQ": {
519
+ "applicationId": "j02SxMRTSf-NCBXf5IdsjQ",
520
+ "inclusive": true,
521
+ "services": {}
522
+ }
523
+ },
524
+ "applicationIds": [
525
+ "j02SxMRTSf-NCBXf5IdsjQ"
526
+ ],
527
+ "severity": 5,
528
+ "triggering": false,
529
+ "tagFilterExpression": {
530
+ "type": "EXPRESSION",
531
+ "logicalOperator": "AND",
532
+ "elements": []
533
+ },
534
+ "includeInternal": false,
535
+ "includeSynthetic": false,
536
+ "rule": {
537
+ "alertType": "slowness",
538
+ "aggregation": "P90",
539
+ "metricName": "latency"
540
+ },
541
+ "threshold": {
542
+ "type": "staticThreshold",
543
+ "operator": ">=",
544
+ "value": 2,
545
+ "lastUpdated": 0
546
+ },
547
+ "alertChannelIds": [],
548
+ "granularity": 600000,
549
+ "timeThreshold": {
550
+ "type": "violationsInSequence",
551
+ "timeWindow": 600000
552
+ },
553
+ "evaluationType": "PER_AP",
554
+ "customPayloadFields": []
555
+ }
556
+
557
+ Args:
558
+ id: The ID of the Global Smart Alert Configuration to update
559
+ payload: The updated Global Smart Alert Configuration details as a dictionary or JSON string
560
+ ctx: The MCP context (optional)
561
+
562
+ Returns:
563
+ Dictionary containing the updated Global Smart Alert Configuration or error information
564
+ """
565
+ try:
566
+ logger.debug(f"update_global_application_alert_config called with id={id}, payload={payload}")
567
+
568
+ # Validate required parameters
569
+ if not id:
570
+ return {"error": "id is required"}
571
+
572
+ if not payload:
573
+ return {"error": "payload is required"}
574
+
575
+ # Parse the payload if it's a string
576
+ if isinstance(payload, str):
577
+ logger.debug("Payload is a string, attempting to parse")
578
+ try:
579
+ import json
580
+ try:
581
+ parsed_payload = json.loads(payload)
582
+ logger.debug("Successfully parsed payload as JSON")
583
+ request_body = parsed_payload
584
+ except json.JSONDecodeError as e:
585
+ logger.debug(f"JSON parsing failed: {e}, trying with quotes replaced")
586
+
587
+ # Try replacing single quotes with double quotes
588
+ fixed_payload = payload.replace("'", "\"")
589
+ try:
590
+ parsed_payload = json.loads(fixed_payload)
591
+ logger.debug("Successfully parsed fixed JSON")
592
+ request_body = parsed_payload
593
+ except json.JSONDecodeError:
594
+ # Try as Python literal
595
+ import ast
596
+ try:
597
+ parsed_payload = ast.literal_eval(payload)
598
+ logger.debug("Successfully parsed payload as Python literal")
599
+ request_body = parsed_payload
600
+ except (SyntaxError, ValueError) as e2:
601
+ logger.debug(f"Failed to parse payload string: {e2}")
602
+ return {"error": f"Invalid payload format: {e2}", "payload": payload}
603
+ except Exception as e:
604
+ logger.debug(f"Error parsing payload string: {e}")
605
+ return {"error": f"Failed to parse payload: {e}", "payload": payload}
606
+ else:
607
+ # If payload is already a dictionary, use it directly
608
+ logger.debug("Using provided payload dictionary")
609
+ request_body = payload
610
+
611
+ # Import the GlobalApplicationsAlertConfig class
612
+ try:
613
+ from instana_client.models.global_applications_alert_config import (
614
+ GlobalApplicationsAlertConfig,
615
+ )
616
+ logger.debug("Successfully imported GlobalApplicationsAlertConfig")
617
+ except ImportError as e:
618
+ logger.debug(f"Error importing GlobalApplicationsAlertConfig: {e}")
619
+ return {"error": f"Failed to import GlobalApplicationsAlertConfig: {e!s}"}
620
+
621
+ # Create an GlobalApplicationsAlertConfig object from the request body
622
+ try:
623
+ logger.debug(f"Creating GlobalApplicationsAlertConfig with params: {request_body}")
624
+ config_object = GlobalApplicationsAlertConfig(**request_body)
625
+ logger.debug("Successfully created config object")
626
+ except Exception as e:
627
+ logger.debug(f"Error creating ApplicationAlertConfig: {e}")
628
+ return {"error": f"Failed to create config object: {e!s}"}
629
+
630
+ # Call the update_global_application_alert_config method from the SDK
631
+ logger.debug(f"Calling update_global_application_alert_config with id={id} and config object")
632
+ result = api_client.update_global_application_alert_config(
633
+ id=id,
634
+ global_applications_alert_config=config_object
635
+ )
636
+
637
+ # Convert the result to a dictionary
638
+ if hasattr(result, 'to_dict'):
639
+ result_dict = result.to_dict()
640
+ else:
641
+ # If it's already a dict or another format, use it as is
642
+ result_dict = result or {
643
+ "success": True,
644
+ "message": f"Smart Global Alert Configuration with ID '{id}' has been successfully updated"
645
+ }
646
+
647
+ logger.debug(f"Result from update_global_application_alert_config: {result_dict}")
648
+ return result_dict
649
+ except Exception as e:
650
+ logger.error(f"Error in update_global_application_alert_config: {e}")
651
+ return {"error": f"Failed to update global application alert config: {e!s}"}
652
+
653
+
@@ -10,8 +10,12 @@ from typing import Any, Dict, List, Optional
10
10
 
11
11
  # Import the necessary classes from the SDK
12
12
  try:
13
- from instana_client.api.application_metrics_api import ApplicationMetricsApi
14
- from instana_client.models.get_application_metrics import GetApplicationMetrics
13
+ from instana_client.api.application_metrics_api import (
14
+ ApplicationMetricsApi,
15
+ )
16
+ from instana_client.models.get_application_metrics import (
17
+ GetApplicationMetrics,
18
+ )
15
19
  from instana_client.models.get_applications import GetApplications
16
20
  from instana_client.models.get_endpoints import GetEndpoints
17
21
  from instana_client.models.get_services import GetServices