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.
- {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/METADATA +460 -139
- mcp_instana-0.2.1.dist-info/RECORD +59 -0
- src/application/application_analyze.py +373 -160
- src/application/application_catalog.py +3 -1
- src/application/application_global_alert_config.py +653 -0
- src/application/application_metrics.py +6 -2
- src/application/application_resources.py +3 -1
- src/application/application_settings.py +966 -370
- src/application/application_topology.py +6 -2
- src/automation/action_catalog.py +416 -0
- src/automation/action_history.py +338 -0
- src/core/server.py +159 -9
- src/core/utils.py +2 -2
- src/event/events_tools.py +602 -275
- src/infrastructure/infrastructure_analyze.py +7 -3
- src/infrastructure/infrastructure_catalog.py +3 -1
- src/infrastructure/infrastructure_metrics.py +6 -2
- src/infrastructure/infrastructure_resources.py +7 -5
- src/infrastructure/infrastructure_topology.py +5 -3
- 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.1.dist-info/RECORD +0 -30
- src/prompts/mcp_prompts.py +0 -900
- src/prompts/prompt_loader.py +0 -29
- src/prompts/prompt_registry.json +0 -21
- {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/WHEEL +0 -0
- {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/entry_points.txt +0 -0
- {mcp_instana-0.1.1.dist-info → mcp_instana-0.2.1.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Website Metrics MCP Tools Module
|
|
3
|
+
|
|
4
|
+
This module provides website metrics-specific MCP tools for Instana monitoring.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from typing import Any, Dict, List, Optional, Union
|
|
10
|
+
|
|
11
|
+
# Import the necessary classes from the SDK
|
|
12
|
+
try:
|
|
13
|
+
from instana_client.api.website_metrics_api import WebsiteMetricsApi
|
|
14
|
+
from instana_client.models.get_website_metrics_v2 import GetWebsiteMetricsV2
|
|
15
|
+
except ImportError as e:
|
|
16
|
+
import logging
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
logger.error(f"Error importing Instana SDK: {e}", 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 WebsiteMetricsMCPTools(BaseInstanaClient):
|
|
27
|
+
"""Tools for website metrics in Instana MCP."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, read_token: str, base_url: str):
|
|
30
|
+
"""Initialize the Website Metrics MCP tools client."""
|
|
31
|
+
super().__init__(read_token=read_token, base_url=base_url)
|
|
32
|
+
|
|
33
|
+
@register_as_tool
|
|
34
|
+
@with_header_auth(WebsiteMetricsApi)
|
|
35
|
+
async def get_website_page_load(self,
|
|
36
|
+
page_id: str,
|
|
37
|
+
timestamp: int,
|
|
38
|
+
ctx=None, api_client=None) -> List[Dict[str, Any]]:
|
|
39
|
+
"""
|
|
40
|
+
Get website monitoring beacons for a specific page load.
|
|
41
|
+
|
|
42
|
+
This API endpoint retrieves detailed beacon information for a specific page load event.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
page_id: Identifier of the page load to be retrieved
|
|
46
|
+
timestamp: Timestamp of the page load to be retrieved
|
|
47
|
+
ctx: The MCP context (optional)
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Dictionary containing page load beacon data or error information
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
if not page_id:
|
|
54
|
+
return [{"error": "page_id parameter is required"}]
|
|
55
|
+
if not timestamp:
|
|
56
|
+
return [{"error": "timestamp parameter is required"}]
|
|
57
|
+
|
|
58
|
+
logger.debug(f"get_website_page_load called with page_id={page_id}, timestamp={timestamp}")
|
|
59
|
+
|
|
60
|
+
# Call the get_page_load method from the SDK
|
|
61
|
+
result = api_client.get_page_load(
|
|
62
|
+
id=page_id,
|
|
63
|
+
timestamp=timestamp
|
|
64
|
+
)
|
|
65
|
+
# Convert the result to a list of dictionaries
|
|
66
|
+
if isinstance(result, list):
|
|
67
|
+
# If it's a list, convert each item to dict if possible
|
|
68
|
+
result_list = []
|
|
69
|
+
for item in result:
|
|
70
|
+
if hasattr(item, 'to_dict'):
|
|
71
|
+
result_list.append(item.to_dict())
|
|
72
|
+
else:
|
|
73
|
+
result_list.append(item)
|
|
74
|
+
elif hasattr(result, 'to_dict'):
|
|
75
|
+
result_list = [result.to_dict()]
|
|
76
|
+
else:
|
|
77
|
+
# If it's already a list or another format, use it as is
|
|
78
|
+
result_list = result
|
|
79
|
+
|
|
80
|
+
logger.debug(f"Result from get_website_page_load: {result_list}")
|
|
81
|
+
return result_list
|
|
82
|
+
|
|
83
|
+
except Exception as e:
|
|
84
|
+
logger.error(f"Error in get_website_page_load: {e}", exc_info=True)
|
|
85
|
+
return [{"error": f"Failed to get website page load: {e!s}"}]
|
|
86
|
+
|
|
87
|
+
@register_as_tool
|
|
88
|
+
@with_header_auth(WebsiteMetricsApi)
|
|
89
|
+
async def get_website_beacon_metrics_v2(self,
|
|
90
|
+
payload: Optional[Union[Dict[str, Any], str]] = None,
|
|
91
|
+
ctx=None, api_client=None) -> Dict[str, Any]:
|
|
92
|
+
"""
|
|
93
|
+
Get website beacon metrics using the v2 API.
|
|
94
|
+
|
|
95
|
+
This API endpoint retrieves one or more supported aggregations of metrics for website monitoring beacons.
|
|
96
|
+
For example, retrieve MEAN aggregation of page load time metric for specific pages or websites.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
payload: Complete request payload as a dictionary or JSON string
|
|
100
|
+
{
|
|
101
|
+
"metrics": [
|
|
102
|
+
{
|
|
103
|
+
"metric": "beaconCount",
|
|
104
|
+
"aggregation": "SUM"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"tagFilterExpression": {
|
|
108
|
+
"type": "EXPRESSION",
|
|
109
|
+
"logicalOperator": "AND",
|
|
110
|
+
"elements": [
|
|
111
|
+
{
|
|
112
|
+
"type": "TAG_FILTER",
|
|
113
|
+
"name": "beacon.website.name",
|
|
114
|
+
"operator": "EQUALS",
|
|
115
|
+
"entity": "NOT_APPLICABLE",
|
|
116
|
+
"value": "robot-shop"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"type": "TAG_FILTER",
|
|
120
|
+
"name": "beacon.location.path",
|
|
121
|
+
"operator": "EQUALS",
|
|
122
|
+
"entity": "NOT_APPLICABLE",
|
|
123
|
+
"value": "/"
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"timeFrame": {
|
|
128
|
+
"to": null,
|
|
129
|
+
"windowSize": 3600000
|
|
130
|
+
},
|
|
131
|
+
"type": "PAGELOAD"
|
|
132
|
+
}
|
|
133
|
+
ctx: The MCP context (optional)
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Dictionary containing website metrics data or error information
|
|
137
|
+
"""
|
|
138
|
+
try:
|
|
139
|
+
logger.debug("get_website_beacon_metrics_v2 called")
|
|
140
|
+
|
|
141
|
+
# Parse the payload
|
|
142
|
+
if isinstance(payload, str):
|
|
143
|
+
logger.debug("Payload is a string, attempting to parse")
|
|
144
|
+
try:
|
|
145
|
+
import json
|
|
146
|
+
try:
|
|
147
|
+
parsed_payload = json.loads(payload)
|
|
148
|
+
logger.debug("Successfully parsed payload as JSON")
|
|
149
|
+
request_body = parsed_payload
|
|
150
|
+
except json.JSONDecodeError as e:
|
|
151
|
+
logger.debug(f"JSON parsing failed: {e}, trying with quotes replaced")
|
|
152
|
+
|
|
153
|
+
# Try replacing single quotes with double quotes
|
|
154
|
+
fixed_payload = payload.replace("'", "\"")
|
|
155
|
+
try:
|
|
156
|
+
parsed_payload = json.loads(fixed_payload)
|
|
157
|
+
logger.debug("Successfully parsed fixed JSON")
|
|
158
|
+
request_body = parsed_payload
|
|
159
|
+
except json.JSONDecodeError:
|
|
160
|
+
# Try as Python literal
|
|
161
|
+
import ast
|
|
162
|
+
try:
|
|
163
|
+
parsed_payload = ast.literal_eval(payload)
|
|
164
|
+
logger.debug("Successfully parsed payload as Python literal")
|
|
165
|
+
request_body = parsed_payload
|
|
166
|
+
except (SyntaxError, ValueError) as e2:
|
|
167
|
+
logger.debug(f"Failed to parse payload string: {e2}")
|
|
168
|
+
return {"error": f"Invalid payload format: {e2}", "payload": payload}
|
|
169
|
+
except Exception as e:
|
|
170
|
+
logger.debug(f"Error parsing payload string: {e}")
|
|
171
|
+
return {"error": f"Failed to parse payload: {e}", "payload": payload}
|
|
172
|
+
else:
|
|
173
|
+
# If payload is already a dictionary, use it directly
|
|
174
|
+
logger.debug("Using provided payload dictionary")
|
|
175
|
+
request_body = payload
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
from instana_client.models.get_website_metrics_v2 import (
|
|
179
|
+
GetWebsiteMetricsV2,
|
|
180
|
+
)
|
|
181
|
+
logger.debug("Successfully imported GetWebsiteMetricsV2")
|
|
182
|
+
except ImportError as e:
|
|
183
|
+
logger.debug(f"Error importing GetWebsiteMetricsV2: {e}")
|
|
184
|
+
return {"error": f"Failed to import GetWebsiteMetricsV2: {e!s}"}
|
|
185
|
+
|
|
186
|
+
# Create an GetWebsiteMetricsV2 object from the request body
|
|
187
|
+
try:
|
|
188
|
+
query_params = {}
|
|
189
|
+
|
|
190
|
+
# Extract required fields from request body
|
|
191
|
+
if request_body:
|
|
192
|
+
# Required field: metrics
|
|
193
|
+
if "metrics" in request_body:
|
|
194
|
+
query_params["metrics"] = request_body["metrics"]
|
|
195
|
+
else:
|
|
196
|
+
return {"error": "Required field 'metrics' is missing from payload"}
|
|
197
|
+
|
|
198
|
+
# Required field: type
|
|
199
|
+
if "type" in request_body:
|
|
200
|
+
query_params["type"] = request_body["type"]
|
|
201
|
+
else:
|
|
202
|
+
return {"error": "Required field 'type' is missing from payload"}
|
|
203
|
+
|
|
204
|
+
# Optional fields
|
|
205
|
+
if "tagFilterExpression" in request_body:
|
|
206
|
+
query_params["tag_filter_expression"] = request_body["tagFilterExpression"]
|
|
207
|
+
elif "tag_filter_expression" in request_body:
|
|
208
|
+
query_params["tag_filter_expression"] = request_body["tag_filter_expression"]
|
|
209
|
+
|
|
210
|
+
if "timeFrame" in request_body:
|
|
211
|
+
query_params["time_frame"] = request_body["timeFrame"]
|
|
212
|
+
elif "time_frame" in request_body:
|
|
213
|
+
query_params["time_frame"] = request_body["time_frame"]
|
|
214
|
+
|
|
215
|
+
logger.debug(f"Creating get_website_beacon_metrics_v2 with params: {query_params}")
|
|
216
|
+
config_object = GetWebsiteMetricsV2(**query_params)
|
|
217
|
+
logger.debug("Successfully created GetWebsiteMetricsV2 object")
|
|
218
|
+
except Exception as e:
|
|
219
|
+
logger.debug(f"Error creating get_website_beacon_metrics_v2: {e}")
|
|
220
|
+
return {"error": f"Failed to get website beacon metrics: {e!s}"}
|
|
221
|
+
|
|
222
|
+
# Call the get_beacon_metrics_v2 method from the SDK
|
|
223
|
+
logger.debug("Calling get_beacon_metrics_v2 with config object")
|
|
224
|
+
result = api_client.get_beacon_metrics_v2(
|
|
225
|
+
get_website_metrics_v2=config_object
|
|
226
|
+
)
|
|
227
|
+
# Convert the result to a dictionary
|
|
228
|
+
if hasattr(result, 'to_dict'):
|
|
229
|
+
result_dict = result.to_dict()
|
|
230
|
+
else:
|
|
231
|
+
# If it's already a dict or another format, use it as is
|
|
232
|
+
result_dict = result or {
|
|
233
|
+
"success": True,
|
|
234
|
+
"message": "Get website beacon metrics"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
logger.debug(f"Result from get_website_beacon_metrics_v2: {result_dict}")
|
|
238
|
+
return result_dict
|
|
239
|
+
except Exception as e:
|
|
240
|
+
logger.error(f"Error in get_website_beacon_metrics_v2: {e}")
|
|
241
|
+
return {"error": f"Failed to get website beacon metrics: {e!s}"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
src/application/__init__.py,sha256=cfWHjA5NzAvL0jcekaIO3NTe5DRtznYRqg9_8hVwSzc,37
|
|
3
|
-
src/application/application_alert_config.py,sha256=7_t-ahjwJgGdQvN7Cx5iopZCbIsabXj7HdYm0dW5Gg0,29769
|
|
4
|
-
src/application/application_analyze.py,sha256=MblKsI167z5-1Hc95ELqzHPMnx_PKamR4y-2YQ1KNWY,17127
|
|
5
|
-
src/application/application_catalog.py,sha256=WzrrhaJPQ4JcvF2OWNAVlGxGQYb4UeS6fWeT56ddPSQ,6193
|
|
6
|
-
src/application/application_metrics.py,sha256=Dk1G9D3Fb6-58N7FXMYVmlTjE4WdUVx47SmBCvSa1AI,14867
|
|
7
|
-
src/application/application_resources.py,sha256=NmhfAlZn9ciTwklN9CZJQl0iDLm8kGkNH1wLAR32H7A,17705
|
|
8
|
-
src/application/application_settings.py,sha256=aPvtNYy_JPCiPsYNZlif1nu9ij6gllab-X2v7Z2IWl8,45111
|
|
9
|
-
src/application/application_topology.py,sha256=T3T2GF4xAowzT2wVDWn5p5rHg-EJmV71aMnMfmPDd6A,4362
|
|
10
|
-
src/core/__init__.py,sha256=gZdGV4TVETqe3XV-_lzQMw0IgyTTCqYYgP3PH9YdWbU,30
|
|
11
|
-
src/core/server.py,sha256=XS145QUEcrLyRCTPmGe7Z0f-m4RiRdbka1oEwKEQ2Z4,16945
|
|
12
|
-
src/core/utils.py,sha256=Haqke88RcwwCp-g94PZS_C4MYYix-6RHk0ZCQsHqLQE,10288
|
|
13
|
-
src/event/__init__.py,sha256=ru-xCHU9xksGf9aJslvI37-6SI2yoBOpsoaED-vbaaQ,31
|
|
14
|
-
src/event/events_tools.py,sha256=NX-GrY4BzqTPbePhvM53LX7mAYXG1icsqsOxzwgL5uI,25096
|
|
15
|
-
src/infrastructure/__init__.py,sha256=xZuRO1Zb2iPyO5G3PRM90dfesaFheL7DMSSJMujtLVk,40
|
|
16
|
-
src/infrastructure/infrastructure_analyze.py,sha256=oU94MrnGh1ETquRVexS_oSEiMhz6jPlKfSQbLio03D4,28874
|
|
17
|
-
src/infrastructure/infrastructure_catalog.py,sha256=wuqU8VUrXL8JS-4dEHcuKNbD_aWEj4EvLbe4ir6eaq8,27041
|
|
18
|
-
src/infrastructure/infrastructure_metrics.py,sha256=y_XOoIXY4Oz0Va6ZJlCALapnjnVJ8gTGUV6Ay44kUG4,6880
|
|
19
|
-
src/infrastructure/infrastructure_resources.py,sha256=IAPlF_0JAOiq7mRd0Fs6DiAJ9qWWvi8fQmpFYs3jrt8,28321
|
|
20
|
-
src/infrastructure/infrastructure_topology.py,sha256=z3AirNtxyP3BkGr3x-rzjEkXUC-0CMQhgEB8PZ4uDkQ,14494
|
|
21
|
-
src/log/__init__.py,sha256=NwPZccMqR5aR6PrISe760gkABtpg7zpbwOK-uMPB-_Y,29
|
|
22
|
-
src/log/log_alert_configuration.py,sha256=OTGxj9MmtTQOupAR65C1fbK_byG2wkkIGMlGTT1kEXU,14746
|
|
23
|
-
src/prompts/mcp_prompts.py,sha256=w68FPFL4Sctfc_ls1wlSPIWC2ZPYaNqlY-D1uMVwjzc,28197
|
|
24
|
-
src/prompts/prompt_loader.py,sha256=cQEKZZ4kB2prhd1m_AXu9DahizGqQvKJNDf0r49ArV8,938
|
|
25
|
-
src/prompts/prompt_registry.json,sha256=jBpgSs1VRaLDKbSkeqUaSrwY3DTDQNzYkscXQ-759h0,645
|
|
26
|
-
mcp_instana-0.1.1.dist-info/METADATA,sha256=cea_swkYt85AScMsptIV10kDUHMlrYcDZ3ErjH9T4dk,36550
|
|
27
|
-
mcp_instana-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
28
|
-
mcp_instana-0.1.1.dist-info/entry_points.txt,sha256=p1aZ9Ks0aJKpoIy6Mk-08cGYAfkXMNbwYIlokm513A4,140
|
|
29
|
-
mcp_instana-0.1.1.dist-info/licenses/LICENSE.md,sha256=Ox7lseFP2kBRXBjsLweW1jLmWiCyrKjwF8ZUvCbKd70,11310
|
|
30
|
-
mcp_instana-0.1.1.dist-info/RECORD,,
|