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.
- mcp_instana-0.2.0.dist-info/METADATA +1229 -0
- mcp_instana-0.2.0.dist-info/RECORD +59 -0
- {mcp_instana-0.1.0.dist-info → mcp_instana-0.2.0.dist-info}/WHEEL +1 -1
- mcp_instana-0.2.0.dist-info/entry_points.txt +4 -0
- mcp_instana-0.1.0.dist-info/LICENSE → mcp_instana-0.2.0.dist-info/licenses/LICENSE.md +3 -3
- src/application/__init__.py +1 -0
- src/{client/application_alert_config_mcp_tools.py → application/application_alert_config.py} +251 -273
- src/application/application_analyze.py +628 -0
- src/application/application_catalog.py +155 -0
- src/application/application_global_alert_config.py +653 -0
- src/{client/application_metrics_mcp_tools.py → application/application_metrics.py} +113 -131
- src/{client/application_resources_mcp_tools.py → application/application_resources.py} +131 -151
- src/application/application_settings.py +1731 -0
- src/application/application_topology.py +111 -0
- src/automation/action_catalog.py +416 -0
- src/automation/action_history.py +338 -0
- src/core/__init__.py +1 -0
- src/core/server.py +586 -0
- src/core/utils.py +213 -0
- src/event/__init__.py +1 -0
- src/event/events_tools.py +850 -0
- src/infrastructure/__init__.py +1 -0
- src/{client/infrastructure_analyze_mcp_tools.py → infrastructure/infrastructure_analyze.py} +207 -206
- src/{client/infrastructure_catalog_mcp_tools.py → infrastructure/infrastructure_catalog.py} +197 -265
- src/infrastructure/infrastructure_metrics.py +171 -0
- src/{client/infrastructure_resources_mcp_tools.py → infrastructure/infrastructure_resources.py} +198 -227
- src/{client/infrastructure_topology_mcp_tools.py → infrastructure/infrastructure_topology.py} +110 -109
- src/log/__init__.py +1 -0
- src/log/log_alert_configuration.py +331 -0
- src/prompts/__init__.py +16 -0
- src/prompts/application/__init__.py +1 -0
- src/prompts/application/application_alerts.py +54 -0
- src/prompts/application/application_catalog.py +26 -0
- src/prompts/application/application_metrics.py +57 -0
- src/prompts/application/application_resources.py +26 -0
- src/prompts/application/application_settings.py +75 -0
- src/prompts/application/application_topology.py +30 -0
- src/prompts/events/__init__.py +1 -0
- src/prompts/events/events_tools.py +161 -0
- src/prompts/infrastructure/infrastructure_analyze.py +72 -0
- src/prompts/infrastructure/infrastructure_catalog.py +53 -0
- src/prompts/infrastructure/infrastructure_metrics.py +45 -0
- src/prompts/infrastructure/infrastructure_resources.py +74 -0
- src/prompts/infrastructure/infrastructure_topology.py +38 -0
- src/prompts/settings/__init__.py +0 -0
- src/prompts/settings/custom_dashboard.py +157 -0
- src/prompts/website/__init__.py +1 -0
- src/prompts/website/website_analyze.py +35 -0
- src/prompts/website/website_catalog.py +40 -0
- src/prompts/website/website_configuration.py +105 -0
- src/prompts/website/website_metrics.py +34 -0
- src/settings/__init__.py +1 -0
- src/settings/custom_dashboard_tools.py +417 -0
- src/website/__init__.py +0 -0
- src/website/website_analyze.py +433 -0
- src/website/website_catalog.py +171 -0
- src/website/website_configuration.py +770 -0
- src/website/website_metrics.py +241 -0
- mcp_instana-0.1.0.dist-info/METADATA +0 -649
- mcp_instana-0.1.0.dist-info/RECORD +0 -19
- mcp_instana-0.1.0.dist-info/entry_points.txt +0 -3
- src/client/What is the sum of queue depth for all q +0 -55
- src/client/events_mcp_tools.py +0 -531
- src/client/instana_client_base.py +0 -93
- src/client/log_alert_configuration_mcp_tools.py +0 -316
- src/client/show the top 5 services with the highest +0 -28
- 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
|