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