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
@@ -0,0 +1,338 @@
1
+ """
2
+ Automation Action History MCP Tools Module
3
+
4
+ This module provides automation action history tools for Instana Automation.
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.action_history_api import (
13
+ ActionHistoryApi,
14
+ )
15
+ except ImportError:
16
+ import logging
17
+ logger = logging.getLogger(__name__)
18
+ logger.error("Failed to import action history API", exc_info=True)
19
+ raise
20
+
21
+
22
+ from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
23
+
24
+ # Configure logger for this module
25
+ logger = logging.getLogger(__name__)
26
+
27
+ class ActionHistoryMCPTools(BaseInstanaClient):
28
+ """Tools for automation action history in Instana MCP."""
29
+
30
+ def __init__(self, read_token: str, base_url: str):
31
+ """Initialize the Action History MCP tools client."""
32
+ super().__init__(read_token=read_token, base_url=base_url)
33
+
34
+ @register_as_tool
35
+ @with_header_auth(ActionHistoryApi)
36
+ async def submit_automation_action(self,
37
+ payload: Union[Dict[str, Any], str],
38
+ ctx=None,
39
+ api_client=None) -> Dict[str, Any]:
40
+ """
41
+ Submit an automation action for execution on an agent.
42
+ The automation action to execute and the agent on which to execute the action must be specified as actionId and hostId. For more details on the request payload see the request sample.
43
+
44
+ Args:
45
+ Sample payload:
46
+ {
47
+ "hostId": "aHostId",
48
+ "actionId": "d473c1b0-0740-4d08-95fe-31e5d0a9faff",
49
+ "policyId": "2nIOVtEW-iPbsEIi89-yDqJabc",
50
+ "inputParameters": [
51
+ {
52
+ "name": "name",
53
+ "type": "type",
54
+ "value": "value"
55
+ }
56
+ ],
57
+ "eventId": "M3wuBxuaSDyecZJ7ICioiw",
58
+ "async": "true",
59
+ "timeout": "600"
60
+ }
61
+
62
+ Required fields:
63
+ - actionId: Action identifier of the action to run
64
+ - hostId: Agent host identifier on which to run the action
65
+
66
+ Optional fields:
67
+ - async: "true" if the action should be run in asynchronous mode, "false" otherwise. Default is "true"
68
+ - eventId: Event identifier (incident or issue) associated with the policy
69
+ - policyId: Policy identifier that associates the action trigger to the action to run
70
+ - timeout: Action run time out. Default is 30 seconds
71
+ - inputParameters: Array of action run input parameters
72
+
73
+ ctx: Optional[Dict[str, Any]]: The context for the action execution
74
+ api_client: Optional[ActionHistoryApi]: The API client for action execution
75
+
76
+ Returns:
77
+ Dict[str, Any]: The result of the automation action submission
78
+ """
79
+ try:
80
+ if not payload:
81
+ return {"error": "payload is required"}
82
+
83
+ # Parse the payload if it's a string
84
+ if isinstance(payload, str):
85
+ logger.debug("Payload is a string, attempting to parse")
86
+ try:
87
+ import json
88
+ try:
89
+ parsed_payload = json.loads(payload)
90
+ logger.debug("Successfully parsed payload as JSON")
91
+ request_body = parsed_payload
92
+ except json.JSONDecodeError as e:
93
+ logger.debug(f"JSON parsing failed: {e}, trying with quotes replaced")
94
+
95
+ # Try replacing single quotes with double quotes
96
+ fixed_payload = payload.replace("'", "\"")
97
+ try:
98
+ parsed_payload = json.loads(fixed_payload)
99
+ logger.debug("Successfully parsed fixed JSON")
100
+ request_body = parsed_payload
101
+ except json.JSONDecodeError:
102
+ # Try as Python literal
103
+ import ast
104
+ try:
105
+ parsed_payload = ast.literal_eval(payload)
106
+ logger.debug("Successfully parsed payload as Python literal")
107
+ request_body = parsed_payload
108
+ except (SyntaxError, ValueError) as e2:
109
+ logger.debug(f"Failed to parse payload string: {e2}")
110
+ return {"error": f"Invalid payload format: {e2}", "payload": payload}
111
+ except Exception as e:
112
+ logger.debug(f"Error parsing payload string: {e}")
113
+ return {"error": f"Failed to parse payload: {e}", "payload": payload}
114
+ else:
115
+ # If payload is already a dictionary, use it directly
116
+ logger.debug("Using provided payload dictionary")
117
+ request_body = payload
118
+
119
+ # Validate required fields in the payload
120
+ required_fields = ["actionId", "hostId"]
121
+ for field in required_fields:
122
+ if field not in request_body:
123
+ logger.warning(f"Missing required field: {field}")
124
+ return {"error": f"Missing required field: {field}"}
125
+
126
+ # Import the ActionInstanceRequest class
127
+ try:
128
+ from instana_client.models.action_instance_request import (
129
+ ActionInstanceRequest,
130
+ )
131
+ logger.debug("Successfully imported ActionInstanceRequest")
132
+ except ImportError as e:
133
+ logger.debug(f"Error importing ActionInstanceRequest: {e}")
134
+ return {"error": f"Failed to import ActionInstanceRequest: {e!s}"}
135
+
136
+ # Create an ActionInstanceRequest object from the request body
137
+ try:
138
+ logger.debug(f"Creating ActionInstanceRequest with params: {request_body}")
139
+ config_object = ActionInstanceRequest(**request_body)
140
+ logger.debug("Successfully created config object")
141
+ except Exception as e:
142
+ logger.debug(f"Error creating ActionInstanceRequest: {e}")
143
+ return {"error": f"Failed to create config object: {e!s}"}
144
+
145
+ # Call the add_action_instance method from the SDK
146
+ logger.debug("Calling add_action_instance with config object")
147
+ result = api_client.add_action_instance(
148
+ action_instance_request=config_object,
149
+ )
150
+
151
+ # Convert the result to a dictionary
152
+ if hasattr(result, 'to_dict'):
153
+ result_dict = result.to_dict()
154
+ else:
155
+ # If it's already a dict or another format, use it as is
156
+ result_dict = result or {
157
+ "success": True,
158
+ "message": "Automation action submitted successfully"
159
+ }
160
+
161
+ logger.debug(f"Result from add_action_instance: {result_dict}")
162
+ return result_dict
163
+ except Exception as e:
164
+ logger.error(f"Error in submit_automation_action: {e}")
165
+ return {"error": f"Failed to submit automation action: {e!s}"}
166
+
167
+ @register_as_tool
168
+ @with_header_auth(ActionHistoryApi)
169
+ async def get_action_instance_details(self,
170
+ action_instance_id: str,
171
+ window_size: Optional[int] = None,
172
+ to: Optional[int] = None,
173
+ ctx=None,
174
+ api_client=None) -> Dict[str, Any]:
175
+ """
176
+ Get the details of an automation action run result by ID from action run history.
177
+
178
+ Args:
179
+ action_instance_id: Action run result ID to get action run result details (required)
180
+ window_size: Window size in milliseconds. This value is used to compute the from date (from = to - windowSize) to get the action run result details. The default windowSize is set to 10 minutes if this value is not provided.
181
+ to: To date filter in milliseconds (13-digit) to get the action run result details. The default to date is set to System.currentTimeMillis() if this value is not provided.
182
+ ctx: Optional[Dict[str, Any]]: The context for the action instance retrieval
183
+ api_client: Optional[ActionHistoryApi]: The API client for action history
184
+
185
+ Returns:
186
+ Dict[str, Any]: The details of the automation action run result
187
+ """
188
+ try:
189
+ if not action_instance_id:
190
+ return {"error": "action_instance_id is required"}
191
+
192
+ logger.debug(f"Getting action instance details for ID: {action_instance_id}")
193
+ result = api_client.get_action_instance(
194
+ action_instance_id=action_instance_id,
195
+ window_size=window_size,
196
+ to=to,
197
+ )
198
+
199
+ # Convert the result to a dictionary
200
+ if hasattr(result, 'to_dict'):
201
+ result_dict = result.to_dict()
202
+ else:
203
+ # If it's already a dict or another format, use it as is
204
+ result_dict = result or {
205
+ "success": True,
206
+ "message": "Action instance details retrieved successfully"
207
+ }
208
+
209
+ logger.debug(f"Result from get_action_instance: {result_dict}")
210
+ return result_dict
211
+ except Exception as e:
212
+ logger.error(f"Error in get_action_instance_details: {e}")
213
+ return {"error": f"Failed to get action instance details: {e!s}"}
214
+
215
+ @register_as_tool
216
+ @with_header_auth(ActionHistoryApi)
217
+ async def list_action_instances(self,
218
+ window_size: Optional[int] = None,
219
+ to: Optional[int] = None,
220
+ page: Optional[int] = None,
221
+ page_size: Optional[int] = None,
222
+ target_snapshot_id: Optional[str] = None,
223
+ event_id: Optional[str] = None,
224
+ event_specification_id: Optional[str] = None,
225
+ search: Optional[str] = None,
226
+ types: Optional[List[str]] = None,
227
+ action_statuses: Optional[List[str]] = None,
228
+ order_by: Optional[str] = None,
229
+ order_direction: Optional[str] = None,
230
+ ctx=None,
231
+ api_client=None) -> Dict[str, Any]:
232
+ """
233
+ Get the details of automation action run results from action run history.
234
+
235
+ Args:
236
+ window_size: Window size filter in milliseconds (to compute the from date) to get the action run result details
237
+ to: To date filter in milliseconds (13-digit) to get the action run result details
238
+ page: Page to fetch -- used for paging the action run result records
239
+ page_size: Number of records to return in each page -- used for paging the action run result records
240
+ target_snapshot_id: Target snapshot ID filter to get the action run result details
241
+ event_id: Event ID filter to get the action run result details
242
+ event_specification_id: Event specification ID filter to get the action run result details
243
+ search: Text in action run result name, description and event name filter to get the action run result details
244
+ types: Action type filter to get the action run result details
245
+ action_statuses: Action status filter to get the action run result details
246
+ order_by: Action run result column to order the result set
247
+ order_direction: Sort order direction
248
+
249
+ ctx: Optional[Dict[str, Any]]: The context for the action instances retrieval
250
+ api_client: Optional[ActionHistoryApi]: The API client for action history
251
+
252
+ Returns:
253
+ Dict[str, Any]: The paginated list of automation action run results
254
+ """
255
+ try:
256
+ logger.debug("Getting action instances with parameters")
257
+ result = api_client.get_action_instances(
258
+ window_size=window_size,
259
+ to=to,
260
+ page=page,
261
+ page_size=page_size,
262
+ target_snapshot_id=target_snapshot_id,
263
+ event_id=event_id,
264
+ event_specification_id=event_specification_id,
265
+ search=search,
266
+ types=types,
267
+ action_statuses=action_statuses,
268
+ order_by=order_by,
269
+ order_direction=order_direction
270
+ )
271
+
272
+ # Convert the result to a dictionary
273
+ if hasattr(result, 'to_dict'):
274
+ result_dict = result.to_dict()
275
+ else:
276
+ # If it's already a dict or another format, use it as is
277
+ result_dict = result or {
278
+ "success": True,
279
+ "message": "Action instances retrieved successfully"
280
+ }
281
+
282
+ logger.debug(f"Result from get_action_instances: {result_dict}")
283
+ return result_dict
284
+ except Exception as e:
285
+ logger.error(f"Error in list_action_instances: {e}")
286
+ return {"error": f"Failed to list action instances: {e!s}"}
287
+
288
+ @register_as_tool
289
+ @with_header_auth(ActionHistoryApi)
290
+ async def delete_action_instance(self,
291
+ action_instance_id: str,
292
+ from_time: int,
293
+ to_time: int,
294
+ ctx=None,
295
+ api_client=None) -> Dict[str, Any]:
296
+ """
297
+ Delete an automation action run result from the action run history by ID.
298
+
299
+ Args:
300
+ action_instance_id: Automation action run result ID to delete (required)
301
+ from_time: From date filter in milliseconds (13-digit) to look up the action run result ID (required)
302
+ to_time: To date filter in milliseconds (13-digit) to look up the action run result ID (required)
303
+ ctx: Optional[Dict[str, Any]]: The context for the action instance deletion
304
+ api_client: Optional[ActionHistoryApi]: The API client for action history
305
+
306
+ Returns:
307
+ Dict[str, Any]: The result of the action instance deletion
308
+ """
309
+ try:
310
+ if not action_instance_id:
311
+ return {"error": "action_instance_id is required"}
312
+ if not from_time:
313
+ return {"error": "from_time is required"}
314
+ if not to_time:
315
+ return {"error": "to_time is required"}
316
+
317
+ logger.debug(f"Deleting action instance with ID: {action_instance_id}")
318
+ result = api_client.delete_action_instance(
319
+ action_instance_id=action_instance_id,
320
+ var_from=from_time,
321
+ to=to_time,
322
+ )
323
+
324
+ # Convert the result to a dictionary
325
+ if hasattr(result, 'to_dict'):
326
+ result_dict = result.to_dict()
327
+ else:
328
+ # If it's already a dict or another format, use it as is
329
+ result_dict = result or {
330
+ "success": True,
331
+ "message": "Action instance deleted successfully"
332
+ }
333
+
334
+ logger.debug(f"Result from delete_action_instance: {result_dict}")
335
+ return result_dict
336
+ except Exception as e:
337
+ logger.error(f"Error in delete_action_instance: {e}")
338
+ return {"error": f"Failed to delete action instance: {e!s}"}
src/core/__init__.py ADDED
@@ -0,0 +1 @@
1
+ # Core module for MCP Instana