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.
- mcp_instana-0.1.1.dist-info/METADATA +908 -0
- mcp_instana-0.1.1.dist-info/RECORD +30 -0
- {mcp_instana-0.1.0.dist-info → mcp_instana-0.1.1.dist-info}/WHEEL +1 -1
- mcp_instana-0.1.1.dist-info/entry_points.txt +4 -0
- mcp_instana-0.1.0.dist-info/LICENSE → mcp_instana-0.1.1.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 +415 -0
- src/application/application_catalog.py +153 -0
- src/{client/application_metrics_mcp_tools.py → application/application_metrics.py} +107 -129
- src/{client/application_resources_mcp_tools.py → application/application_resources.py} +128 -150
- src/application/application_settings.py +1135 -0
- src/application/application_topology.py +107 -0
- src/core/__init__.py +1 -0
- src/core/server.py +436 -0
- src/core/utils.py +213 -0
- src/event/__init__.py +1 -0
- src/{client/events_mcp_tools.py → event/events_tools.py} +128 -136
- src/infrastructure/__init__.py +1 -0
- src/{client/infrastructure_analyze_mcp_tools.py → infrastructure/infrastructure_analyze.py} +200 -203
- src/{client/infrastructure_catalog_mcp_tools.py → infrastructure/infrastructure_catalog.py} +194 -264
- src/infrastructure/infrastructure_metrics.py +167 -0
- src/{client/infrastructure_resources_mcp_tools.py → infrastructure/infrastructure_resources.py} +192 -223
- src/{client/infrastructure_topology_mcp_tools.py → infrastructure/infrastructure_topology.py} +105 -106
- src/log/__init__.py +1 -0
- src/log/log_alert_configuration.py +331 -0
- src/prompts/mcp_prompts.py +900 -0
- src/prompts/prompt_loader.py +29 -0
- src/prompts/prompt_registry.json +21 -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/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
|
@@ -4,70 +4,50 @@ Application Resources MCP Tools Module
|
|
|
4
4
|
This module provides application resources-specific MCP tools for Instana monitoring.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
import traceback
|
|
9
|
-
from typing import Dict, Any, Optional, List
|
|
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_resources_api import ApplicationResourcesApi
|
|
15
|
-
|
|
16
|
-
from instana_client.configuration import Configuration
|
|
14
|
+
|
|
17
15
|
except ImportError as e:
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
import logging
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
logger.error(f"Error importing Instana SDK: {e}", exc_info=True)
|
|
20
19
|
raise
|
|
21
20
|
|
|
22
|
-
from .
|
|
21
|
+
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
23
22
|
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
"""Print debug information to stderr instead of stdout"""
|
|
27
|
-
print(*args, file=sys.stderr, **kwargs)
|
|
23
|
+
# Configure logger for this module
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
28
25
|
|
|
29
26
|
class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
30
27
|
"""Tools for application resources in Instana MCP."""
|
|
31
|
-
|
|
28
|
+
|
|
32
29
|
def __init__(self, read_token: str, base_url: str):
|
|
33
30
|
"""Initialize the Application Resources MCP tools client."""
|
|
34
31
|
super().__init__(read_token=read_token, base_url=base_url)
|
|
35
|
-
|
|
36
|
-
try:
|
|
37
|
-
|
|
38
|
-
# Configure the API client with the correct base URL and authentication
|
|
39
|
-
configuration = Configuration()
|
|
40
|
-
configuration.host = base_url
|
|
41
|
-
configuration.api_key['ApiKeyAuth'] = read_token
|
|
42
|
-
configuration.api_key_prefix['ApiKeyAuth'] = 'apiToken'
|
|
43
|
-
|
|
44
|
-
# Create an API client with this configuration
|
|
45
|
-
api_client = ApiClient(configuration=configuration)
|
|
46
|
-
|
|
47
|
-
# Initialize the Instana SDK's ApplicationResourcesApi with our configured client
|
|
48
|
-
self.app_api = ApplicationResourcesApi(api_client=api_client)
|
|
49
|
-
except Exception as e:
|
|
50
|
-
debug_print(f"Error initializing ApplicationResourcesApi: {e}")
|
|
51
|
-
traceback.print_exc(file=sys.stderr)
|
|
52
|
-
raise
|
|
53
|
-
|
|
32
|
+
|
|
54
33
|
@register_as_tool
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
34
|
+
@with_header_auth(ApplicationResourcesApi)
|
|
35
|
+
async def get_application_endpoints(self,
|
|
36
|
+
name_filter: Optional[str] = None,
|
|
37
|
+
types: Optional[List[str]] = None,
|
|
38
|
+
technologies: Optional[List[str]] = None,
|
|
39
|
+
window_size: Optional[int] = None,
|
|
40
|
+
to_time: Optional[int] = None,
|
|
41
|
+
page: Optional[int] = None,
|
|
42
|
+
page_size: Optional[int] = None,
|
|
43
|
+
application_boundary_scope: Optional[str] = None,
|
|
44
|
+
ctx=None, api_client=None) -> Dict[str, Any]:
|
|
65
45
|
"""
|
|
66
46
|
Get endpoints for all services from Instana. Use this API endpoint if one wants to retrieve a list of Endpoints. A use case could be to view the endpoint id of an Endpoint.
|
|
67
|
-
Retrieve a list of application endpoints from Instana. This tool is useful when you need to get information about endpoints across services in your application.
|
|
47
|
+
Retrieve a list of application endpoints from Instana. This tool is useful when you need to get information about endpoints across services in your application.
|
|
68
48
|
You can filter by endpoint name, types, technologies, and other parameters. Use this when you want to see what endpoints exist in your application, understand their IDs, or analyze endpoint performance metrics.
|
|
69
49
|
For example, use this tool when asked about 'application endpoints', 'service endpoints', 'API endpoints in my application','endpoint id of an Endpoint', or when someone wants to 'list all endpoints'.
|
|
70
|
-
|
|
50
|
+
|
|
71
51
|
Args:
|
|
72
52
|
name_filter: Name of service to filter by (optional)
|
|
73
53
|
types: List of endpoint types to filter by (optional)
|
|
@@ -78,22 +58,22 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
78
58
|
page_size: Number of items per page (optional)
|
|
79
59
|
application_boundary_scope: Filter for application scope, e.g., 'INBOUND' or 'ALL' (optional)
|
|
80
60
|
ctx: The MCP context (optional)
|
|
81
|
-
|
|
61
|
+
|
|
82
62
|
Returns:
|
|
83
63
|
Dictionary containing endpoints data or error information
|
|
84
64
|
"""
|
|
85
65
|
try:
|
|
86
|
-
|
|
87
|
-
|
|
66
|
+
logger.debug(f"get_application_endpoints called with name_filter={name_filter}")
|
|
67
|
+
|
|
88
68
|
# Set default time range if not provided
|
|
89
69
|
if not to_time:
|
|
90
70
|
to_time = int(datetime.now().timestamp() * 1000)
|
|
91
|
-
|
|
71
|
+
|
|
92
72
|
if not window_size:
|
|
93
73
|
window_size = 60 * 60 * 1000 # Default to 1 hour
|
|
94
|
-
|
|
74
|
+
|
|
95
75
|
# Call the get_application_endpoints method from the SDK
|
|
96
|
-
result =
|
|
76
|
+
result = api_client.get_application_endpoints(
|
|
97
77
|
name_filter=name_filter,
|
|
98
78
|
types=types,
|
|
99
79
|
technologies=technologies,
|
|
@@ -103,38 +83,37 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
103
83
|
page_size=page_size,
|
|
104
84
|
application_boundary_scope=application_boundary_scope
|
|
105
85
|
)
|
|
106
|
-
|
|
86
|
+
|
|
107
87
|
# Convert the result to a dictionary
|
|
108
88
|
if hasattr(result, 'to_dict'):
|
|
109
89
|
result_dict = result.to_dict()
|
|
110
90
|
else:
|
|
111
91
|
# If it's already a dict or another format, use it as is
|
|
112
92
|
result_dict = result
|
|
113
|
-
|
|
114
|
-
|
|
93
|
+
|
|
94
|
+
logger.debug(f"Result from get_application_endpoints: {result_dict}")
|
|
115
95
|
return result_dict
|
|
116
96
|
except Exception as e:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
97
|
+
logger.error(f"Error in get_application_endpoints: {e}", exc_info=True)
|
|
98
|
+
return {"error": f"Failed to get application endpoints: {e!s}"}
|
|
99
|
+
|
|
121
100
|
@register_as_tool
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
101
|
+
@with_header_auth(ApplicationResourcesApi)
|
|
102
|
+
async def get_application_services(self,
|
|
103
|
+
name_filter: Optional[str] = None,
|
|
104
|
+
window_size: Optional[int] = None,
|
|
105
|
+
to_time: Optional[int] = None,
|
|
106
|
+
page: Optional[int] = None,
|
|
107
|
+
page_size: Optional[int] = None,
|
|
108
|
+
application_boundary_scope: Optional[str] = None,
|
|
109
|
+
include_snapshot_ids: Optional[bool] = None,
|
|
110
|
+
ctx=None, api_client=None) -> Dict[str, Any]:
|
|
131
111
|
"""
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
112
|
+
Retrieve a list of services within application perspectives from Instana. This tool is useful when you need to get information about all services in your monitored applications.
|
|
113
|
+
You can filter by service name and other parameters to narrow down results. Use this when you want to see what services exist in your application,
|
|
114
|
+
understand their IDs, or analyze service-level metrics. This is particularly helpful when you need to retrieve all service IDs present in an Application Perspective for further analysis or monitoring.
|
|
115
|
+
For example, use this tool when asked about 'application services', 'microservices in my application', 'list all services', or when someone wants to 'get service information'. A use case could be to retrieve all service ids present in an Application Perspective.
|
|
136
116
|
|
|
137
|
-
|
|
138
117
|
Args:
|
|
139
118
|
name_filter: Name of application/service to filter by (optional)
|
|
140
119
|
window_size: Size of time window in milliseconds (optional)
|
|
@@ -144,22 +123,22 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
144
123
|
application_boundary_scope: Filter for application scope, e.g., 'INBOUND' or 'ALL' (optional)
|
|
145
124
|
include_snapshot_ids: Whether to include snapshot IDs in the results (optional)
|
|
146
125
|
ctx: The MCP context (optional)
|
|
147
|
-
|
|
126
|
+
|
|
148
127
|
Returns:
|
|
149
128
|
Dictionary containing service labels with their IDs and summary information
|
|
150
129
|
"""
|
|
151
|
-
try:
|
|
152
|
-
|
|
153
|
-
|
|
130
|
+
try:
|
|
131
|
+
logger.debug(f"get_application_services called with name_filter={name_filter}")
|
|
132
|
+
|
|
154
133
|
# Set default time range if not provided
|
|
155
134
|
if not to_time:
|
|
156
135
|
to_time = int(datetime.now().timestamp() * 1000)
|
|
157
|
-
|
|
136
|
+
|
|
158
137
|
if not window_size:
|
|
159
138
|
window_size = 60 * 60 * 1000 # Default to 1 hour
|
|
160
|
-
|
|
139
|
+
|
|
161
140
|
# Call the get_application_services method from the SDK
|
|
162
|
-
result =
|
|
141
|
+
result = api_client.get_application_services(
|
|
163
142
|
name_filter=name_filter,
|
|
164
143
|
window_size=window_size,
|
|
165
144
|
to=to_time,
|
|
@@ -168,27 +147,27 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
168
147
|
application_boundary_scope=application_boundary_scope,
|
|
169
148
|
include_snapshot_ids=include_snapshot_ids
|
|
170
149
|
)
|
|
171
|
-
|
|
150
|
+
|
|
172
151
|
# Convert the result to a dictionary
|
|
173
152
|
if hasattr(result, 'to_dict'):
|
|
174
153
|
result_dict = result.to_dict()
|
|
175
154
|
else:
|
|
176
155
|
# If it's already a dict or another format, use it as is
|
|
177
156
|
result_dict = result
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
157
|
+
|
|
158
|
+
logger.debug(f"Result from get_application_services: {result_dict}")
|
|
159
|
+
|
|
181
160
|
# Extract service labels and IDs from the items
|
|
182
161
|
services = []
|
|
183
162
|
service_labels = []
|
|
184
163
|
items = result_dict.get('items', [])
|
|
185
|
-
|
|
164
|
+
|
|
186
165
|
for item in items:
|
|
187
166
|
if isinstance(item, dict):
|
|
188
167
|
service_id = item.get('id', '')
|
|
189
168
|
label = item.get('label', '')
|
|
190
169
|
technologies = item.get('technologies', [])
|
|
191
|
-
|
|
170
|
+
|
|
192
171
|
if label and service_id:
|
|
193
172
|
service_labels.append(label)
|
|
194
173
|
services.append({
|
|
@@ -203,12 +182,12 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
203
182
|
'label': item.label,
|
|
204
183
|
'technologies': getattr(item, 'technologies', [])
|
|
205
184
|
})
|
|
206
|
-
|
|
185
|
+
|
|
207
186
|
# Sort services by label alphabetically and limit to first 15
|
|
208
187
|
services.sort(key=lambda x: x['label'])
|
|
209
188
|
limited_services = services[:15]
|
|
210
189
|
service_labels = [service['label'] for service in limited_services]
|
|
211
|
-
|
|
190
|
+
|
|
212
191
|
return {
|
|
213
192
|
"message": f"Found {len(services)} services in application perspectives. Showing first {len(limited_services)}:",
|
|
214
193
|
"service_labels": service_labels,
|
|
@@ -216,29 +195,29 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
216
195
|
"total_available": len(services),
|
|
217
196
|
"showing": len(limited_services)
|
|
218
197
|
}
|
|
219
|
-
|
|
198
|
+
|
|
220
199
|
except Exception as e:
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return {"error": f"Failed to get application services: {str(e)}"}
|
|
200
|
+
logger.error(f"Error in get_application_services: {e}", exc_info=True)
|
|
201
|
+
return {"error": f"Failed to get application services: {e!s}"}
|
|
224
202
|
|
|
225
203
|
|
|
226
204
|
@register_as_tool
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
205
|
+
@with_header_auth(ApplicationResourcesApi)
|
|
206
|
+
async def get_applications(self,
|
|
207
|
+
name_filter: Optional[str] = None,
|
|
208
|
+
window_size: Optional[int] = None,
|
|
209
|
+
to_time: Optional[int] = None,
|
|
210
|
+
page: Optional[int] = None,
|
|
211
|
+
page_size: Optional[int] = None,
|
|
212
|
+
application_boundary_scope: Optional[str] = None,
|
|
213
|
+
ctx=None, api_client=None) -> List[str]:
|
|
235
214
|
"""
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
215
|
+
Retrieve a list of Application Perspectives from Instana. This tool is useful when you need to get information about any one application perspective in Instana.
|
|
216
|
+
You can filter by application name and other parameters to narrow down results. Use this tool when you want to see what application perspectives exist, understand their IDs,
|
|
217
|
+
or get an overview of your monitored applications. This is particularly helpful when you need to retrieve application IDs for use with other Instana APIs or when setting up monitoring dashboards.
|
|
218
|
+
For example, use this tool when asked about 'application perspectives', 'list all applications in Instana', 'what applications are being monitored', or when someone wants to 'get application IDs'
|
|
219
|
+
or 'get details about an application'.
|
|
220
|
+
|
|
242
221
|
Args:
|
|
243
222
|
name_filter: Name of application to filter by (optional)
|
|
244
223
|
window_size: Size of time window in milliseconds (optional)
|
|
@@ -247,22 +226,22 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
247
226
|
page_size: Number of items per page (optional)
|
|
248
227
|
application_boundary_scope: Filter for application scope, e.g., 'INBOUND' or 'ALL' (optional)
|
|
249
228
|
ctx: The MCP context (optional)
|
|
250
|
-
|
|
229
|
+
|
|
251
230
|
Returns:
|
|
252
231
|
List of application names
|
|
253
232
|
"""
|
|
254
233
|
try:
|
|
255
|
-
|
|
256
|
-
|
|
234
|
+
logger.debug(f"get_applications called with name_filter={name_filter}")
|
|
235
|
+
|
|
257
236
|
# Set default time range if not provided
|
|
258
237
|
if not to_time:
|
|
259
238
|
to_time = int(datetime.now().timestamp() * 1000)
|
|
260
|
-
|
|
239
|
+
|
|
261
240
|
if not window_size:
|
|
262
241
|
window_size = 60 * 60 * 1000 # Default to 1 hour
|
|
263
|
-
|
|
242
|
+
|
|
264
243
|
# Call the get_applications method from the SDK
|
|
265
|
-
result =
|
|
244
|
+
result = api_client.get_applications(
|
|
266
245
|
name_filter=name_filter,
|
|
267
246
|
window_size=window_size,
|
|
268
247
|
to=to_time,
|
|
@@ -270,20 +249,20 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
270
249
|
page_size=page_size,
|
|
271
250
|
application_boundary_scope=application_boundary_scope
|
|
272
251
|
)
|
|
273
|
-
|
|
252
|
+
|
|
274
253
|
# Convert the result to a dictionary
|
|
275
254
|
if hasattr(result, 'to_dict'):
|
|
276
255
|
result_dict = result.to_dict()
|
|
277
256
|
else:
|
|
278
257
|
# If it's already a dict or another format, use it as is
|
|
279
258
|
result_dict = result
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
259
|
+
|
|
260
|
+
logger.debug(f"Result from get_applications: {result_dict}")
|
|
261
|
+
|
|
283
262
|
# Extract labels from the items
|
|
284
263
|
labels = []
|
|
285
264
|
items = result_dict.get('items', [])
|
|
286
|
-
|
|
265
|
+
|
|
287
266
|
for item in items:
|
|
288
267
|
if isinstance(item, dict):
|
|
289
268
|
label = item.get('label', '')
|
|
@@ -291,34 +270,34 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
291
270
|
labels.append(label)
|
|
292
271
|
elif hasattr(item, 'label'):
|
|
293
272
|
labels.append(item.label)
|
|
294
|
-
|
|
273
|
+
|
|
295
274
|
# Sort labels alphabetically and limit to first 15
|
|
296
275
|
labels.sort()
|
|
297
276
|
return labels[:15]
|
|
298
|
-
|
|
277
|
+
|
|
299
278
|
except Exception as e:
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return [f"Error: Failed to get applications: {str(e)}"]
|
|
279
|
+
logger.error(f"Error in get_applications: {e}", exc_info=True)
|
|
280
|
+
return [f"Error: Failed to get applications: {e!s}"]
|
|
303
281
|
|
|
304
282
|
|
|
305
283
|
@register_as_tool
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
284
|
+
@with_header_auth(ApplicationResourcesApi)
|
|
285
|
+
async def get_services(self,
|
|
286
|
+
name_filter: Optional[str] = None,
|
|
287
|
+
window_size: Optional[int] = None,
|
|
288
|
+
to_time: Optional[int] = None,
|
|
289
|
+
page: Optional[int] = None,
|
|
290
|
+
page_size: Optional[int] = None,
|
|
291
|
+
include_snapshot_ids: Optional[bool] = None,
|
|
292
|
+
ctx=None, api_client=None) -> str:
|
|
314
293
|
"""
|
|
315
294
|
Retrieve a list of services from Instana. A use case could be to view the service id, or details,or information of a Service.
|
|
316
295
|
This tool is useful when you need to get information about all services across your monitored environment,regardless of which application perspective they belong to.
|
|
317
|
-
You can filter by service name and other parameters to narrow down results.Use this when you want to see what services exist in your system, understand their IDs .
|
|
318
|
-
This is particularly helpful when you need to retrieve service IDs for further analysis or monitoring. For example, use this tool when asked about 'all services',
|
|
296
|
+
You can filter by service name and other parameters to narrow down results.Use this when you want to see what services exist in your system, understand their IDs .
|
|
297
|
+
This is particularly helpful when you need to retrieve service IDs for further analysis or monitoring. For example, use this tool when asked about 'all services',
|
|
319
298
|
'list services across applications', or when someone wants to 'get service information without application context'. A use case could be to view the service ID of a specific Service.
|
|
320
299
|
|
|
321
|
-
|
|
300
|
+
|
|
322
301
|
Args:
|
|
323
302
|
name_filter: Name of service to filter by (optional)
|
|
324
303
|
window_size: Size of time window in milliseconds (optional)
|
|
@@ -327,22 +306,22 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
327
306
|
page_size: Number of items per page (optional)
|
|
328
307
|
include_snapshot_ids: Whether to include snapshot IDs in the results (optional)
|
|
329
308
|
ctx: The MCP context (optional)
|
|
330
|
-
|
|
309
|
+
|
|
331
310
|
Returns:
|
|
332
311
|
String containing service names
|
|
333
312
|
"""
|
|
334
313
|
try:
|
|
335
|
-
|
|
336
|
-
|
|
314
|
+
logger.debug(f"get_services called with name_filter={name_filter}")
|
|
315
|
+
|
|
337
316
|
# Set default time range if not provided
|
|
338
317
|
if not to_time:
|
|
339
318
|
to_time = int(datetime.now().timestamp() * 1000)
|
|
340
|
-
|
|
319
|
+
|
|
341
320
|
if not window_size:
|
|
342
321
|
window_size = 60 * 60 * 1000 # Default to 1 hour
|
|
343
|
-
|
|
322
|
+
|
|
344
323
|
# Call the get_services method from the SDK
|
|
345
|
-
result =
|
|
324
|
+
result = api_client.get_services(
|
|
346
325
|
name_filter=name_filter,
|
|
347
326
|
window_size=window_size,
|
|
348
327
|
to=to_time,
|
|
@@ -350,20 +329,20 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
350
329
|
page_size=page_size,
|
|
351
330
|
include_snapshot_ids=include_snapshot_ids
|
|
352
331
|
)
|
|
353
|
-
|
|
332
|
+
|
|
354
333
|
# Convert the result to a dictionary
|
|
355
334
|
if hasattr(result, 'to_dict'):
|
|
356
335
|
result_dict = result.to_dict()
|
|
357
336
|
else:
|
|
358
337
|
# If it's already a dict or another format, use it as is
|
|
359
338
|
result_dict = result
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
339
|
+
|
|
340
|
+
logger.debug(f"Result from get_services: {result_dict}")
|
|
341
|
+
|
|
363
342
|
# Extract labels from the items
|
|
364
343
|
labels = []
|
|
365
344
|
items = result_dict.get('items', [])
|
|
366
|
-
|
|
345
|
+
|
|
367
346
|
for item in items:
|
|
368
347
|
if isinstance(item, dict):
|
|
369
348
|
label = item.get('label', '')
|
|
@@ -371,21 +350,20 @@ class ApplicationResourcesMCPTools(BaseInstanaClient):
|
|
|
371
350
|
labels.append(label)
|
|
372
351
|
elif hasattr(item, 'label'):
|
|
373
352
|
labels.append(item.label)
|
|
374
|
-
|
|
353
|
+
|
|
375
354
|
# Sort labels alphabetically and limit to first 10
|
|
376
355
|
labels.sort()
|
|
377
356
|
limited_labels = labels[:10]
|
|
378
|
-
|
|
357
|
+
|
|
379
358
|
# Return as a formatted string that forces display
|
|
380
359
|
services_text = "Services found in your environment:\n"
|
|
381
360
|
for i, label in enumerate(limited_labels, 1):
|
|
382
361
|
services_text += f"{i}. {label}\n"
|
|
383
|
-
|
|
362
|
+
|
|
384
363
|
services_text += f"\nShowing {len(limited_labels)} out of {len(labels)} total services."
|
|
385
|
-
|
|
364
|
+
|
|
386
365
|
return services_text
|
|
387
|
-
|
|
366
|
+
|
|
388
367
|
except Exception as e:
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return f"Error: Failed to get services: {str(e)}"
|
|
368
|
+
logger.error(f"Error in get_services: {e}", exc_info=True)
|
|
369
|
+
return f"Error: Failed to get services: {e!s}"
|