mcp-instana 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. mcp_instana-0.1.1.dist-info/METADATA +908 -0
  2. mcp_instana-0.1.1.dist-info/RECORD +30 -0
  3. {mcp_instana-0.1.0.dist-info → mcp_instana-0.1.1.dist-info}/WHEEL +1 -1
  4. mcp_instana-0.1.1.dist-info/entry_points.txt +4 -0
  5. mcp_instana-0.1.0.dist-info/LICENSE → mcp_instana-0.1.1.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 +415 -0
  9. src/application/application_catalog.py +153 -0
  10. src/{client/application_metrics_mcp_tools.py → application/application_metrics.py} +107 -129
  11. src/{client/application_resources_mcp_tools.py → application/application_resources.py} +128 -150
  12. src/application/application_settings.py +1135 -0
  13. src/application/application_topology.py +107 -0
  14. src/core/__init__.py +1 -0
  15. src/core/server.py +436 -0
  16. src/core/utils.py +213 -0
  17. src/event/__init__.py +1 -0
  18. src/{client/events_mcp_tools.py → event/events_tools.py} +128 -136
  19. src/infrastructure/__init__.py +1 -0
  20. src/{client/infrastructure_analyze_mcp_tools.py → infrastructure/infrastructure_analyze.py} +200 -203
  21. src/{client/infrastructure_catalog_mcp_tools.py → infrastructure/infrastructure_catalog.py} +194 -264
  22. src/infrastructure/infrastructure_metrics.py +167 -0
  23. src/{client/infrastructure_resources_mcp_tools.py → infrastructure/infrastructure_resources.py} +192 -223
  24. src/{client/infrastructure_topology_mcp_tools.py → infrastructure/infrastructure_topology.py} +105 -106
  25. src/log/__init__.py +1 -0
  26. src/log/log_alert_configuration.py +331 -0
  27. src/prompts/mcp_prompts.py +900 -0
  28. src/prompts/prompt_loader.py +29 -0
  29. src/prompts/prompt_registry.json +21 -0
  30. mcp_instana-0.1.0.dist-info/METADATA +0 -649
  31. mcp_instana-0.1.0.dist-info/RECORD +0 -19
  32. mcp_instana-0.1.0.dist-info/entry_points.txt +0 -3
  33. src/client/What is the sum of queue depth for all q +0 -55
  34. src/client/instana_client_base.py +0 -93
  35. src/client/log_alert_configuration_mcp_tools.py +0 -316
  36. src/client/show the top 5 services with the highest +0 -28
  37. src/mcp_server.py +0 -343
@@ -4,71 +4,50 @@ Application Metrics MCP Tools Module
4
4
  This module provides application metrics-specific MCP tools for Instana monitoring.
5
5
  """
6
6
 
7
- import sys
8
- import traceback
9
- from typing import Dict, Any, Optional, List, Union
7
+ import logging
10
8
  from datetime import datetime
9
+ from typing import Any, Dict, List, Optional
11
10
 
12
11
  # Import the necessary classes from the SDK
13
12
  try:
14
13
  from instana_client.api.application_metrics_api import ApplicationMetricsApi
15
- from instana_client.api_client import ApiClient
16
- from instana_client.configuration import Configuration
17
14
  from instana_client.models.get_application_metrics import GetApplicationMetrics
18
15
  from instana_client.models.get_applications import GetApplications
19
16
  from instana_client.models.get_endpoints import GetEndpoints
20
17
  from instana_client.models.get_services import GetServices
21
18
  except ImportError as e:
22
- print(f"Error importing Instana SDK: {e}", file=sys.stderr)
23
- traceback.print_exc(file=sys.stderr)
19
+ import logging
20
+ logger = logging.getLogger(__name__)
21
+ logger.error(f"Error importing Instana SDK: {e}", exc_info=True)
24
22
  raise
25
23
 
26
- from .instana_client_base import BaseInstanaClient, register_as_tool
24
+ from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
27
25
 
28
- # Helper function for debug printing
29
- def debug_print(*args, **kwargs):
30
- """Print debug information to stderr instead of stdout"""
31
- print(*args, file=sys.stderr, **kwargs)
26
+ # Configure logger for this module
27
+ logger = logging.getLogger(__name__)
32
28
 
33
29
  class ApplicationMetricsMCPTools(BaseInstanaClient):
34
30
  """Tools for application metrics in Instana MCP."""
35
-
31
+
36
32
  def __init__(self, read_token: str, base_url: str):
37
33
  """Initialize the Application Metrics MCP tools client."""
38
34
  super().__init__(read_token=read_token, base_url=base_url)
39
-
40
- try:
41
-
42
- # Configure the API client with the correct base URL and authentication
43
- configuration = Configuration()
44
- configuration.host = base_url
45
- configuration.api_key['ApiKeyAuth'] = read_token
46
- configuration.api_key_prefix['ApiKeyAuth'] = 'apiToken'
47
-
48
- # Create an API client with this configuration
49
- api_client = ApiClient(configuration=configuration)
50
-
51
- # Initialize the Instana SDK's ApplicationMetricsApi with our configured client
52
- self.metrics_api = ApplicationMetricsApi(api_client=api_client)
53
- except Exception as e:
54
- debug_print(f"Error initializing ApplicationMetricsApi: {e}")
55
- traceback.print_exc(file=sys.stderr)
56
- raise
57
-
35
+
58
36
  @register_as_tool
59
- async def get_application_data_metrics_v2(self,
60
- metrics: Optional[List[Dict[str, Any]]] = None,
61
- time_frame: Optional[Dict[str, int]] = None,
62
- application_id: Optional[str] = None,
63
- service_id: Optional[str] = None,
64
- endpoint_id: Optional[str] = None,
65
- ctx=None) -> Dict[str, Any]:
37
+ @with_header_auth(ApplicationMetricsApi)
38
+ async def get_application_data_metrics_v2(self,
39
+ metrics: Optional[List[Dict[str, Any]]] = None,
40
+ time_frame: Optional[Dict[str, int]] = None,
41
+ application_id: Optional[str] = None,
42
+ service_id: Optional[str] = None,
43
+ endpoint_id: Optional[str] = None,
44
+ ctx=None, api_client=None) -> Dict[str, Any]:
66
45
  """
67
46
  Get application data metrics using the v2 API.
68
-
47
+
69
48
  This API endpoint retrieves one or more supported aggregations of metrics for a combination of entities.
70
49
  For example, retrieve MEAN aggregation of latency metric for an Endpoint, Service, and Application.
71
-
50
+
72
51
  Args:
73
52
  metrics: List of metrics to retrieve with their aggregations
74
53
  Example: [{"metric": "latency", "aggregation": "MEAN"}]
@@ -78,13 +57,13 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
78
57
  service_id: ID of the service to get metrics for (optional)
79
58
  endpoint_id: ID of the endpoint to get metrics for (optional)
80
59
  ctx: The MCP context (optional)
81
-
60
+
82
61
  Returns:
83
62
  Dictionary containing metrics data or error information
84
63
  """
85
64
  try:
86
- debug_print(f"get_application_data_metrics_v2 called with application_id={application_id}, service_id={service_id}, endpoint_id={endpoint_id}")
87
-
65
+ logger.debug(f"get_application_data_metrics_v2 called with application_id={application_id}, service_id={service_id}, endpoint_id={endpoint_id}")
66
+
88
67
  # Set default time range if not provided
89
68
  if not time_frame:
90
69
  to_time = int(datetime.now().timestamp() * 1000)
@@ -93,7 +72,7 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
93
72
  "from": from_time,
94
73
  "to": to_time
95
74
  }
96
-
75
+
97
76
  # Set default metrics if not provided
98
77
  if not metrics:
99
78
  metrics = [
@@ -102,13 +81,13 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
102
81
  "aggregation": "MEAN"
103
82
  }
104
83
  ]
105
-
84
+
106
85
  # Create the request body
107
86
  request_body = {
108
87
  "metrics": metrics,
109
88
  "timeFrame": time_frame
110
89
  }
111
-
90
+
112
91
  # Add entity IDs if provided
113
92
  if application_id:
114
93
  request_body["applicationId"] = application_id
@@ -116,41 +95,41 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
116
95
  request_body["serviceId"] = service_id
117
96
  if endpoint_id:
118
97
  request_body["endpointId"] = endpoint_id
119
-
98
+
120
99
  # Create the GetApplicationMetrics object
121
100
  get_app_metrics = GetApplicationMetrics(**request_body)
122
-
101
+
123
102
  # Call the get_application_data_metrics_v2 method from the SDK
124
- result = self.metrics_api.get_application_data_metrics_v2(
103
+ result = api_client.get_application_data_metrics_v2(
125
104
  get_application_metrics=get_app_metrics
126
105
  )
127
-
106
+
128
107
  # Convert the result to a dictionary
129
108
  if hasattr(result, 'to_dict'):
130
109
  result_dict = result.to_dict()
131
110
  else:
132
111
  # If it's already a dict or another format, use it as is
133
112
  result_dict = result
134
-
135
- debug_print(f"Result from get_application_data_metrics_v2: {result_dict}")
113
+
114
+ logger.debug(f"Result from get_application_data_metrics_v2: {result_dict}")
136
115
  return result_dict
137
116
  except Exception as e:
138
- debug_print(f"Error in get_application_data_metrics_v2: {e}")
139
- traceback.print_exc(file=sys.stderr)
140
- return {"error": f"Failed to get application data metrics: {str(e)}"}
141
-
117
+ logger.error(f"Error in get_application_data_metrics_v2: {e}", exc_info=True)
118
+ return {"error": f"Failed to get application data metrics: {e!s}"}
119
+
142
120
  @register_as_tool
143
- async def get_application_metrics(self,
144
- application_ids: Optional[List[str]] = None,
145
- metrics: Optional[List[Dict[str, str]]] = None,
146
- time_frame: Optional[Dict[str, int]] = None,
147
- fill_time_series: Optional[bool] = True,
148
- ctx=None) -> Dict[str, Any]:
121
+ @with_header_auth(ApplicationMetricsApi)
122
+ async def get_application_metrics(self,
123
+ application_ids: Optional[List[str]] = None,
124
+ metrics: Optional[List[Dict[str, str]]] = None,
125
+ time_frame: Optional[Dict[str, int]] = None,
126
+ fill_time_series: Optional[bool] = True,
127
+ ctx=None, api_client=None) -> Dict[str, Any]:
149
128
  """
150
129
  Get metrics for specific applications.
151
-
130
+
152
131
  This API endpoint retrieves one or more supported aggregations of metrics for an Application Perspective.
153
-
132
+
154
133
  Args:
155
134
  application_ids: List of application IDs to get metrics for
156
135
  metrics: List of metrics to retrieve with their aggregations
@@ -159,13 +138,13 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
159
138
  Example: {"from": 1617994800000, "to": 1618081200000}
160
139
  fill_time_series: Whether to fill missing data points with timestamp and value 0
161
140
  ctx: The MCP context (optional)
162
-
141
+
163
142
  Returns:
164
143
  Dictionary containing application metrics data or error information
165
144
  """
166
145
  try:
167
- debug_print(f"get_application_metrics called with application_ids={application_ids}")
168
-
146
+ logger.debug(f"get_application_metrics called with application_ids={application_ids}")
147
+
169
148
  # Set default time range if not provided
170
149
  if not time_frame:
171
150
  to_time = int(datetime.now().timestamp() * 1000)
@@ -174,7 +153,7 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
174
153
  "from": from_time,
175
154
  "to": to_time
176
155
  }
177
-
156
+
178
157
  # Set default metrics if not provided
179
158
  if not metrics:
180
159
  metrics = [
@@ -183,52 +162,52 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
183
162
  "aggregation": "MEAN"
184
163
  }
185
164
  ]
186
-
165
+
187
166
  # Create the request body
188
167
  request_body = {
189
168
  "metrics": metrics,
190
169
  "timeFrame": time_frame
191
170
  }
192
-
171
+
193
172
  # Add application IDs if provided
194
173
  if application_ids:
195
174
  request_body["applicationIds"] = application_ids
196
-
175
+
197
176
  # Create the GetApplications object
198
177
  get_applications = GetApplications(**request_body)
199
-
178
+
200
179
  # Call the get_application_metrics method from the SDK
201
- result = self.metrics_api.get_application_metrics(
180
+ result = api_client.get_application_metrics(
202
181
  fill_time_series=fill_time_series,
203
182
  get_applications=get_applications
204
183
  )
205
-
184
+
206
185
  # Convert the result to a dictionary
207
186
  if hasattr(result, 'to_dict'):
208
187
  result_dict = result.to_dict()
209
188
  else:
210
189
  # If it's already a dict or another format, use it as is
211
190
  result_dict = result
212
-
213
- debug_print(f"Result from get_application_metrics: {result_dict}")
191
+
192
+ logger.debug(f"Result from get_application_metrics: {result_dict}")
214
193
  return result_dict
215
194
  except Exception as e:
216
- debug_print(f"Error in get_application_metrics: {e}")
217
- traceback.print_exc(file=sys.stderr)
218
- return {"error": f"Failed to get application metrics: {str(e)}"}
219
-
195
+ logger.error(f"Error in get_application_metrics: {e}", exc_info=True)
196
+ return {"error": f"Failed to get application metrics: {e!s}"}
197
+
220
198
  @register_as_tool
221
- async def get_endpoints_metrics(self,
222
- endpoint_ids: Optional[List[str]] = None,
223
- metrics: Optional[List[Dict[str, str]]] = None,
224
- time_frame: Optional[Dict[str, int]] = None,
225
- fill_time_series: Optional[bool] = True,
226
- ctx=None) -> Dict[str, Any]:
199
+ @with_header_auth(ApplicationMetricsApi)
200
+ async def get_endpoints_metrics(self,
201
+ endpoint_ids: Optional[List[str]] = None,
202
+ metrics: Optional[List[Dict[str, str]]] = None,
203
+ time_frame: Optional[Dict[str, int]] = None,
204
+ fill_time_series: Optional[bool] = True,
205
+ ctx=None, api_client=None) -> Dict[str, Any]:
227
206
  """
228
207
  Get metrics for specific endpoints.
229
-
208
+
230
209
  This API endpoint retrieves one or more supported aggregations of metrics for an Endpoint.
231
-
210
+
232
211
  Args:
233
212
  endpoint_ids: List of endpoint IDs to get metrics for
234
213
  metrics: List of metrics to retrieve with their aggregations
@@ -237,13 +216,13 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
237
216
  Example: {"from": 1617994800000, "to": 1618081200000}
238
217
  fill_time_series: Whether to fill missing data points with timestamp and value 0
239
218
  ctx: The MCP context (optional)
240
-
219
+
241
220
  Returns:
242
221
  Dictionary containing endpoint metrics data or error information
243
222
  """
244
223
  try:
245
- debug_print(f"get_endpoints_metrics called with endpoint_ids={endpoint_ids}")
246
-
224
+ logger.debug(f"get_endpoints_metrics called with endpoint_ids={endpoint_ids}")
225
+
247
226
  # Set default time range if not provided
248
227
  if not time_frame:
249
228
  to_time = int(datetime.now().timestamp() * 1000)
@@ -252,7 +231,7 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
252
231
  "from": from_time,
253
232
  "to": to_time
254
233
  }
255
-
234
+
256
235
  # Set default metrics if not provided
257
236
  if not metrics:
258
237
  metrics = [
@@ -261,53 +240,53 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
261
240
  "aggregation": "MEAN"
262
241
  }
263
242
  ]
264
-
243
+
265
244
  # Create the request body
266
245
  request_body = {
267
246
  "metrics": metrics,
268
247
  "timeFrame": time_frame
269
248
  }
270
-
249
+
271
250
  # Add endpoint IDs if provided
272
251
  if endpoint_ids:
273
252
  request_body["endpointIds"] = endpoint_ids
274
-
253
+
275
254
  # Create the GetEndpoints object
276
255
  get_endpoints = GetEndpoints(**request_body)
277
-
256
+
278
257
  # Call the get_endpoints_metrics method from the SDK
279
- result = self.metrics_api.get_endpoints_metrics(
258
+ result = api_client.get_endpoints_metrics(
280
259
  fill_time_series=fill_time_series,
281
260
  get_endpoints=get_endpoints
282
261
  )
283
-
262
+
284
263
  # Convert the result to a dictionary
285
264
  if hasattr(result, 'to_dict'):
286
265
  result_dict = result.to_dict()
287
266
  else:
288
267
  # If it's already a dict or another format, use it as is
289
268
  result_dict = result
290
-
291
- debug_print(f"Result from get_endpoints_metrics: {result_dict}")
269
+
270
+ logger.debug(f"Result from get_endpoints_metrics: {result_dict}")
292
271
  return result_dict
293
272
  except Exception as e:
294
- debug_print(f"Error in get_endpoints_metrics: {e}")
295
- traceback.print_exc(file=sys.stderr)
296
- return {"error": f"Failed to get endpoints metrics: {str(e)}"}
297
-
273
+ logger.error(f"Error in get_endpoints_metrics: {e}", exc_info=True)
274
+ return {"error": f"Failed to get endpoints metrics: {e!s}"}
275
+
298
276
  @register_as_tool
299
- async def get_services_metrics(self,
300
- service_ids: Optional[List[str]] = None,
301
- metrics: Optional[List[Dict[str, str]]] = None,
302
- time_frame: Optional[Dict[str, int]] = None,
303
- fill_time_series: Optional[bool] = True,
304
- include_snapshot_ids: Optional[bool] = False,
305
- ctx=None) -> Dict[str, Any]:
277
+ @with_header_auth(ApplicationMetricsApi)
278
+ async def get_services_metrics(self,
279
+ service_ids: Optional[List[str]] = None,
280
+ metrics: Optional[List[Dict[str, str]]] = None,
281
+ time_frame: Optional[Dict[str, int]] = None,
282
+ fill_time_series: Optional[bool] = True,
283
+ include_snapshot_ids: Optional[bool] = False,
284
+ ctx=None, api_client=None) -> Dict[str, Any]:
306
285
  """
307
286
  Get metrics for specific services.
308
-
287
+
309
288
  This API endpoint retrieves one or more supported aggregations of metrics for a Service.
310
-
289
+
311
290
  Args:
312
291
  service_ids: List of service IDs to get metrics for
313
292
  metrics: List of metrics to retrieve with their aggregations
@@ -317,13 +296,13 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
317
296
  fill_time_series: Whether to fill missing data points with timestamp and value 0
318
297
  include_snapshot_ids: Whether to include snapshot IDs in the results
319
298
  ctx: The MCP context (optional)
320
-
299
+
321
300
  Returns:
322
301
  Dictionary containing service metrics data or error information
323
302
  """
324
303
  try:
325
- debug_print(f"get_services_metrics called with service_ids={service_ids}")
326
-
304
+ logger.debug(f"get_services_metrics called with service_ids={service_ids}")
305
+
327
306
  # Set default time range if not provided
328
307
  if not time_frame:
329
308
  to_time = int(datetime.now().timestamp() * 1000)
@@ -332,7 +311,7 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
332
311
  "from": from_time,
333
312
  "to": to_time
334
313
  }
335
-
314
+
336
315
  # Set default metrics if not provided
337
316
  if not metrics:
338
317
  metrics = [
@@ -341,37 +320,36 @@ class ApplicationMetricsMCPTools(BaseInstanaClient):
341
320
  "aggregation": "MEAN"
342
321
  }
343
322
  ]
344
-
323
+
345
324
  # Create the request body
346
325
  request_body = {
347
326
  "metrics": metrics,
348
327
  "timeFrame": time_frame
349
328
  }
350
-
329
+
351
330
  # Add service IDs if provided
352
331
  if service_ids:
353
332
  request_body["serviceIds"] = service_ids
354
-
333
+
355
334
  # Create the GetServices object
356
335
  get_services = GetServices(**request_body)
357
-
336
+
358
337
  # Call the get_services_metrics method from the SDK
359
- result = self.metrics_api.get_services_metrics(
338
+ result = api_client.get_services_metrics(
360
339
  fill_time_series=fill_time_series,
361
340
  include_snapshot_ids=include_snapshot_ids,
362
341
  get_services=get_services
363
342
  )
364
-
343
+
365
344
  # Convert the result to a dictionary
366
345
  if hasattr(result, 'to_dict'):
367
346
  result_dict = result.to_dict()
368
347
  else:
369
348
  # If it's already a dict or another format, use it as is
370
349
  result_dict = result
371
-
372
- debug_print(f"Result from get_services_metrics: {result_dict}")
350
+
351
+ logger.debug(f"Result from get_services_metrics: {result_dict}")
373
352
  return result_dict
374
353
  except Exception as e:
375
- debug_print(f"Error in get_services_metrics: {e}")
376
- traceback.print_exc(file=sys.stderr)
377
- return {"error": f"Failed to get services metrics: {str(e)}"}
354
+ logger.error(f"Error in get_services_metrics: {e}", exc_info=True)
355
+ return {"error": f"Failed to get services metrics: {e!s}"}