mcp-instana 0.2.1__py3-none-any.whl → 0.3.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.1.dist-info → mcp_instana-0.3.0.dist-info}/METADATA +2 -1
- {mcp_instana-0.2.1.dist-info → mcp_instana-0.3.0.dist-info}/RECORD +29 -29
- src/application/application_alert_config.py +45 -12
- src/application/application_analyze.py +28 -6
- src/application/application_catalog.py +11 -2
- src/application/application_global_alert_config.py +60 -21
- src/application/application_metrics.py +20 -4
- src/application/application_resources.py +20 -4
- src/application/application_settings.py +111 -35
- src/application/application_topology.py +22 -14
- src/automation/action_catalog.py +165 -188
- src/automation/action_history.py +21 -6
- src/core/server.py +7 -1
- src/core/utils.py +42 -5
- src/event/events_tools.py +30 -7
- src/infrastructure/infrastructure_analyze.py +18 -4
- src/infrastructure/infrastructure_catalog.py +72 -16
- src/infrastructure/infrastructure_metrics.py +5 -1
- src/infrastructure/infrastructure_resources.py +30 -11
- src/infrastructure/infrastructure_topology.py +10 -2
- src/log/log_alert_configuration.py +106 -31
- src/settings/custom_dashboard_tools.py +30 -7
- src/website/website_analyze.py +10 -2
- src/website/website_catalog.py +14 -3
- src/website/website_configuration.py +54 -13
- src/website/website_metrics.py +10 -2
- {mcp_instana-0.2.1.dist-info → mcp_instana-0.3.0.dist-info}/WHEEL +0 -0
- {mcp_instana-0.2.1.dist-info → mcp_instana-0.3.0.dist-info}/entry_points.txt +0 -0
- {mcp_instana-0.2.1.dist-info → mcp_instana-0.3.0.dist-info}/licenses/LICENSE.md +0 -0
src/event/events_tools.py
CHANGED
|
@@ -25,6 +25,8 @@ except ImportError:
|
|
|
25
25
|
logger.error("Failed to import event resources API", exc_info=True)
|
|
26
26
|
raise
|
|
27
27
|
|
|
28
|
+
from mcp.types import ToolAnnotations
|
|
29
|
+
|
|
28
30
|
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
29
31
|
|
|
30
32
|
logger = logging.getLogger(__name__)
|
|
@@ -153,7 +155,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
153
155
|
|
|
154
156
|
return summary
|
|
155
157
|
|
|
156
|
-
@register_as_tool
|
|
158
|
+
@register_as_tool(
|
|
159
|
+
title="Get Event",
|
|
160
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
161
|
+
)
|
|
157
162
|
@with_header_auth(EventsApi)
|
|
158
163
|
async def get_event(self, event_id: str, ctx=None, api_client=None) -> Dict[str, Any]:
|
|
159
164
|
"""
|
|
@@ -238,7 +243,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
238
243
|
logger.error(f"Error in get_event: {e}", exc_info=True)
|
|
239
244
|
return {"error": f"Failed to get event: {e!s}", "event_id": event_id}
|
|
240
245
|
|
|
241
|
-
@register_as_tool
|
|
246
|
+
@register_as_tool(
|
|
247
|
+
title="Get Kubernetes Info Events",
|
|
248
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
249
|
+
)
|
|
242
250
|
@with_header_auth(EventsApi)
|
|
243
251
|
async def get_kubernetes_info_events(self,
|
|
244
252
|
from_time: Optional[int] = None,
|
|
@@ -383,7 +391,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
383
391
|
"details": str(e)
|
|
384
392
|
}
|
|
385
393
|
|
|
386
|
-
@register_as_tool
|
|
394
|
+
@register_as_tool(
|
|
395
|
+
title="Get Agent Monitoring Events",
|
|
396
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
397
|
+
)
|
|
387
398
|
@with_header_auth(EventsApi)
|
|
388
399
|
async def get_agent_monitoring_events(self,
|
|
389
400
|
query: Optional[str] = None,
|
|
@@ -525,7 +536,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
525
536
|
}
|
|
526
537
|
|
|
527
538
|
|
|
528
|
-
@register_as_tool
|
|
539
|
+
@register_as_tool(
|
|
540
|
+
title="Get Issues",
|
|
541
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
542
|
+
)
|
|
529
543
|
@with_header_auth(EventsApi)
|
|
530
544
|
async def get_issues(self,
|
|
531
545
|
query: Optional[str] = None,
|
|
@@ -593,7 +607,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
593
607
|
logger.error(f"Error in get_issue_events: {e}", exc_info=True)
|
|
594
608
|
return {"error": f"Failed to get issue events: {e!s}"}
|
|
595
609
|
|
|
596
|
-
@register_as_tool
|
|
610
|
+
@register_as_tool(
|
|
611
|
+
title="Get Incidents",
|
|
612
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
613
|
+
)
|
|
597
614
|
@with_header_auth(EventsApi)
|
|
598
615
|
async def get_incidents(self,
|
|
599
616
|
query: Optional[str] = None,
|
|
@@ -661,7 +678,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
661
678
|
logger.error(f"Error in get_incident_events: {e}", exc_info=True)
|
|
662
679
|
return {"error": f"Failed to get incident events: {e!s}"}
|
|
663
680
|
|
|
664
|
-
@register_as_tool
|
|
681
|
+
@register_as_tool(
|
|
682
|
+
title="Get Changes",
|
|
683
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
684
|
+
)
|
|
665
685
|
@with_header_auth(EventsApi)
|
|
666
686
|
async def get_changes(self,
|
|
667
687
|
query: Optional[str] = None,
|
|
@@ -729,7 +749,10 @@ class AgentMonitoringEventsMCPTools(BaseInstanaClient):
|
|
|
729
749
|
logger.error(f"Error in get_change_events: {e}", exc_info=True)
|
|
730
750
|
return {"error": f"Failed to get change events: {e!s}"}
|
|
731
751
|
|
|
732
|
-
@register_as_tool
|
|
752
|
+
@register_as_tool(
|
|
753
|
+
title="Get Events By IDs",
|
|
754
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
755
|
+
)
|
|
733
756
|
@with_header_auth(EventsApi)
|
|
734
757
|
async def get_events_by_ids(
|
|
735
758
|
self,
|
|
@@ -33,6 +33,8 @@ except ImportError as e:
|
|
|
33
33
|
logger.error(f"Error importing Instana SDK: {e}", exc_info=True)
|
|
34
34
|
raise
|
|
35
35
|
|
|
36
|
+
from mcp.types import ToolAnnotations
|
|
37
|
+
|
|
36
38
|
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
37
39
|
|
|
38
40
|
# Configure logger for this module
|
|
@@ -50,7 +52,10 @@ class InfrastructureAnalyzeMCPTools(BaseInstanaClient):
|
|
|
50
52
|
"""Initialize the Infrastructure Analyze MCP tools client."""
|
|
51
53
|
super().__init__(read_token=read_token, base_url=base_url)
|
|
52
54
|
|
|
53
|
-
@register_as_tool
|
|
55
|
+
@register_as_tool(
|
|
56
|
+
title="Get Available Metrics",
|
|
57
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
58
|
+
)
|
|
54
59
|
@with_header_auth(InfrastructureAnalyzeApi)
|
|
55
60
|
async def get_available_metrics(self,
|
|
56
61
|
payload: Optional[Union[Dict[str, Any], str]] = None,
|
|
@@ -186,7 +191,10 @@ class InfrastructureAnalyzeMCPTools(BaseInstanaClient):
|
|
|
186
191
|
logger.error(f"Error in get_available_metrics: {e}", exc_info=True)
|
|
187
192
|
return {"error": f"Failed to get available metrics: {e!s}"}
|
|
188
193
|
|
|
189
|
-
@register_as_tool
|
|
194
|
+
@register_as_tool(
|
|
195
|
+
title="Get Entities",
|
|
196
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
197
|
+
)
|
|
190
198
|
@with_header_auth(InfrastructureAnalyzeApi)
|
|
191
199
|
async def get_entities(self,
|
|
192
200
|
payload: Optional[Union[Dict[str, Any], str]] = None,
|
|
@@ -301,7 +309,10 @@ class InfrastructureAnalyzeMCPTools(BaseInstanaClient):
|
|
|
301
309
|
logger.error(f"Error in get_entities: {e}", exc_info=True)
|
|
302
310
|
return {"error": f"Failed to get entities: {e!s}"}
|
|
303
311
|
|
|
304
|
-
@register_as_tool
|
|
312
|
+
@register_as_tool(
|
|
313
|
+
title="Get Aggregated Entity Groups",
|
|
314
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
315
|
+
)
|
|
305
316
|
@with_header_auth(InfrastructureAnalyzeApi)
|
|
306
317
|
async def get_aggregated_entity_groups(self,
|
|
307
318
|
payload: Optional[Union[Dict[str, Any], str]] = None,
|
|
@@ -502,7 +513,10 @@ class InfrastructureAnalyzeMCPTools(BaseInstanaClient):
|
|
|
502
513
|
"error": f"Failed to summarize results: {e!s}"
|
|
503
514
|
}
|
|
504
515
|
|
|
505
|
-
@register_as_tool
|
|
516
|
+
@register_as_tool(
|
|
517
|
+
title="Get Available Plugins",
|
|
518
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
519
|
+
)
|
|
506
520
|
@with_header_auth(InfrastructureAnalyzeApi)
|
|
507
521
|
async def get_available_plugins(self,
|
|
508
522
|
payload: Optional[Union[Dict[str, Any], str]] = None,
|
|
@@ -20,6 +20,8 @@ except ImportError as e:
|
|
|
20
20
|
logger.error(f"Error importing Instana SDK: {e}", exc_info=True)
|
|
21
21
|
raise
|
|
22
22
|
|
|
23
|
+
from mcp.types import ToolAnnotations
|
|
24
|
+
|
|
23
25
|
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
24
26
|
|
|
25
27
|
# Configure logger for this module
|
|
@@ -32,7 +34,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
32
34
|
"""Initialize the Infrastructure Catalog MCP tools client."""
|
|
33
35
|
super().__init__(read_token=read_token, base_url=base_url)
|
|
34
36
|
|
|
35
|
-
@register_as_tool
|
|
37
|
+
@register_as_tool(
|
|
38
|
+
title="Get Available Payload Keys By Plugin ID",
|
|
39
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
40
|
+
)
|
|
36
41
|
@with_header_auth(InfrastructureCatalogApi)
|
|
37
42
|
async def get_available_payload_keys_by_plugin_id(self,
|
|
38
43
|
plugin_id: str,
|
|
@@ -123,7 +128,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
123
128
|
return {"error": f"Failed to get payload keys: {e!s}", "plugin_id": plugin_id}
|
|
124
129
|
|
|
125
130
|
|
|
126
|
-
@register_as_tool
|
|
131
|
+
@register_as_tool(
|
|
132
|
+
title="Get Infrastructure Catalog Metrics",
|
|
133
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
134
|
+
)
|
|
127
135
|
@with_header_auth(InfrastructureCatalogApi)
|
|
128
136
|
async def get_infrastructure_catalog_metrics(self,
|
|
129
137
|
plugin: str,
|
|
@@ -160,10 +168,22 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
160
168
|
|
|
161
169
|
# Handle different response types
|
|
162
170
|
if isinstance(result, list):
|
|
163
|
-
# If it's a list of metric names,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
171
|
+
# If it's a list of metric objects or names, extract metric names
|
|
172
|
+
metric_names = []
|
|
173
|
+
for item in result[:50]: # Limit to first 50
|
|
174
|
+
if isinstance(item, str):
|
|
175
|
+
# Already a string (metric name)
|
|
176
|
+
metric_names.append(item)
|
|
177
|
+
elif isinstance(item, dict):
|
|
178
|
+
# Extract metric name from metric object
|
|
179
|
+
metric_name = item.get('metricId') or item.get('label') or str(item)
|
|
180
|
+
metric_names.append(metric_name)
|
|
181
|
+
else:
|
|
182
|
+
# Convert to string
|
|
183
|
+
metric_names.append(str(item))
|
|
184
|
+
|
|
185
|
+
logger.debug(f"Received {len(result)} metrics for plugin {plugin}, returning first {len(metric_names)}")
|
|
186
|
+
return metric_names
|
|
167
187
|
|
|
168
188
|
elif hasattr(result, 'to_dict'):
|
|
169
189
|
# If it's an SDK object with to_dict method
|
|
@@ -171,14 +191,35 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
171
191
|
|
|
172
192
|
# Check if the dict contains a list of metrics
|
|
173
193
|
if isinstance(result_dict, list):
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
194
|
+
metric_names = []
|
|
195
|
+
for item in result_dict[:50]: # Limit to first 50
|
|
196
|
+
if isinstance(item, str):
|
|
197
|
+
metric_names.append(item)
|
|
198
|
+
elif isinstance(item, dict):
|
|
199
|
+
metric_name = item.get('metricId') or item.get('label') or str(item)
|
|
200
|
+
metric_names.append(metric_name)
|
|
201
|
+
else:
|
|
202
|
+
metric_names.append(str(item))
|
|
203
|
+
|
|
204
|
+
logger.debug(f"Received {len(result_dict)} metrics for plugin {plugin}, returning first {len(metric_names)}")
|
|
205
|
+
return metric_names
|
|
177
206
|
elif isinstance(result_dict, dict):
|
|
178
207
|
# Try to extract metric names from dict structure
|
|
179
208
|
if 'metrics' in result_dict:
|
|
180
|
-
|
|
181
|
-
|
|
209
|
+
metrics_list = result_dict['metrics']
|
|
210
|
+
if isinstance(metrics_list, list):
|
|
211
|
+
metric_names = []
|
|
212
|
+
for item in metrics_list[:50]: # Limit to first 50
|
|
213
|
+
if isinstance(item, str):
|
|
214
|
+
metric_names.append(item)
|
|
215
|
+
elif isinstance(item, dict):
|
|
216
|
+
metric_name = item.get('metricId') or item.get('label') or str(item)
|
|
217
|
+
metric_names.append(metric_name)
|
|
218
|
+
else:
|
|
219
|
+
metric_names.append(str(item))
|
|
220
|
+
return metric_names
|
|
221
|
+
else:
|
|
222
|
+
return [f"Metrics field is not a list for plugin {plugin}"]
|
|
182
223
|
else:
|
|
183
224
|
return [f"Unexpected dict structure for plugin {plugin}"]
|
|
184
225
|
else:
|
|
@@ -193,7 +234,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
193
234
|
return [f"Error: Failed to get metric catalog for plugin '{plugin}': {e!s}"]
|
|
194
235
|
|
|
195
236
|
|
|
196
|
-
@register_as_tool
|
|
237
|
+
@register_as_tool(
|
|
238
|
+
title="Get Infrastructure Catalog Plugins",
|
|
239
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
240
|
+
)
|
|
197
241
|
@with_header_auth(InfrastructureCatalogApi)
|
|
198
242
|
async def get_infrastructure_catalog_plugins(self, ctx=None, api_client=None) -> Dict[str, Any]:
|
|
199
243
|
"""
|
|
@@ -263,7 +307,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
263
307
|
|
|
264
308
|
|
|
265
309
|
|
|
266
|
-
@register_as_tool
|
|
310
|
+
@register_as_tool(
|
|
311
|
+
title="Get Infrastructure Catalog Plugins With Custom Metrics",
|
|
312
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
313
|
+
)
|
|
267
314
|
@with_header_auth(InfrastructureCatalogApi)
|
|
268
315
|
async def get_infrastructure_catalog_plugins_with_custom_metrics(self, ctx=None, api_client=None) -> Dict[str, Any] | List[Dict[str, Any]]:
|
|
269
316
|
"""
|
|
@@ -303,7 +350,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
303
350
|
return {"error": f"Failed to get plugins with custom metrics: {e!s}"}
|
|
304
351
|
|
|
305
352
|
|
|
306
|
-
@register_as_tool
|
|
353
|
+
@register_as_tool(
|
|
354
|
+
title="Get Tag Catalog",
|
|
355
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
356
|
+
)
|
|
307
357
|
@with_header_auth(InfrastructureCatalogApi)
|
|
308
358
|
async def get_tag_catalog(self, plugin: str, ctx=None, api_client=None) -> Dict[str, Any]:
|
|
309
359
|
"""
|
|
@@ -388,7 +438,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
388
438
|
return {"error": f"Failed to get tag catalog: {e!s}"}
|
|
389
439
|
|
|
390
440
|
|
|
391
|
-
@register_as_tool
|
|
441
|
+
@register_as_tool(
|
|
442
|
+
title="Get Tag Catalog All",
|
|
443
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
444
|
+
)
|
|
392
445
|
@with_header_auth(InfrastructureCatalogApi)
|
|
393
446
|
async def get_tag_catalog_all(self, ctx=None, api_client=None) -> Dict[str, Any]:
|
|
394
447
|
"""
|
|
@@ -507,7 +560,10 @@ class InfrastructureCatalogMCPTools(BaseInstanaClient):
|
|
|
507
560
|
return summary
|
|
508
561
|
|
|
509
562
|
|
|
510
|
-
@register_as_tool
|
|
563
|
+
@register_as_tool(
|
|
564
|
+
title="Get Infrastructure Catalog Search Fields",
|
|
565
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
566
|
+
)
|
|
511
567
|
@with_header_auth(InfrastructureCatalogApi)
|
|
512
568
|
async def get_infrastructure_catalog_search_fields(self, ctx=None, api_client=None) -> List[str] | Dict[str, Any]:
|
|
513
569
|
"""
|
|
@@ -9,6 +9,7 @@ import logging
|
|
|
9
9
|
from datetime import datetime
|
|
10
10
|
from typing import Any, Dict, List, Optional, Union
|
|
11
11
|
|
|
12
|
+
from mcp.types import ToolAnnotations
|
|
12
13
|
from pydantic import StrictBool
|
|
13
14
|
|
|
14
15
|
from src.core.utils import (
|
|
@@ -40,7 +41,10 @@ class InfrastructureMetricsMCPTools(BaseInstanaClient):
|
|
|
40
41
|
"""Initialize the Infrastructure Analyze MCP tools client."""
|
|
41
42
|
super().__init__(read_token=read_token, base_url=base_url)
|
|
42
43
|
|
|
43
|
-
@register_as_tool
|
|
44
|
+
@register_as_tool(
|
|
45
|
+
title="Get Infrastructure Metrics",
|
|
46
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
47
|
+
)
|
|
44
48
|
@with_header_auth(InfrastructureMetricsApi)
|
|
45
49
|
async def get_infrastructure_metrics(self,
|
|
46
50
|
offline: Optional[StrictBool] = False,
|
|
@@ -25,6 +25,8 @@ except ImportError:
|
|
|
25
25
|
logger.error("Failed to import infrastructure resources API", exc_info=True)
|
|
26
26
|
raise
|
|
27
27
|
|
|
28
|
+
from mcp.types import ToolAnnotations
|
|
29
|
+
|
|
28
30
|
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
29
31
|
|
|
30
32
|
# Configure logger for this module
|
|
@@ -37,7 +39,10 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
37
39
|
"""Initialize the Infrastructure Resources MCP tools client."""
|
|
38
40
|
super().__init__(read_token=read_token, base_url=base_url)
|
|
39
41
|
|
|
40
|
-
@register_as_tool
|
|
42
|
+
@register_as_tool(
|
|
43
|
+
title="Get Monitoring State",
|
|
44
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
45
|
+
)
|
|
41
46
|
@with_header_auth(InfrastructureResourcesApi)
|
|
42
47
|
async def get_monitoring_state(self, ctx=None, api_client=None) -> Dict[str, Any]:
|
|
43
48
|
"""
|
|
@@ -63,7 +68,10 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
63
68
|
logger.error(f"Error in get_monitoring_state: {e}", exc_info=True)
|
|
64
69
|
return {"error": f"Failed to get monitoring state: {e!s}"}
|
|
65
70
|
|
|
66
|
-
@register_as_tool
|
|
71
|
+
@register_as_tool(
|
|
72
|
+
title="Get Plugin Payload",
|
|
73
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
74
|
+
)
|
|
67
75
|
@with_header_auth(InfrastructureResourcesApi)
|
|
68
76
|
async def get_plugin_payload(self,
|
|
69
77
|
snapshot_id: str,
|
|
@@ -104,7 +112,10 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
104
112
|
logger.error(f"Error in get_plugin_payload: {e}", exc_info=True)
|
|
105
113
|
return {"error": f"Failed to get plugin payload: {e!s}"}
|
|
106
114
|
|
|
107
|
-
@register_as_tool
|
|
115
|
+
@register_as_tool(
|
|
116
|
+
title="Get Snapshot",
|
|
117
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
118
|
+
)
|
|
108
119
|
@with_header_auth(InfrastructureResourcesApi)
|
|
109
120
|
async def get_snapshot(self,
|
|
110
121
|
snapshot_id: str,
|
|
@@ -212,7 +223,10 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
212
223
|
logger.error(f"Error in get_snapshot: {e}", exc_info=True)
|
|
213
224
|
return {"error": f"Failed to get snapshot: {e!s}"}
|
|
214
225
|
|
|
215
|
-
@register_as_tool
|
|
226
|
+
@register_as_tool(
|
|
227
|
+
title="Get Snapshots",
|
|
228
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
229
|
+
)
|
|
216
230
|
@with_header_auth(InfrastructureResourcesApi)
|
|
217
231
|
async def get_snapshots(self,
|
|
218
232
|
query: Optional[str] = None,
|
|
@@ -367,7 +381,10 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
367
381
|
|
|
368
382
|
|
|
369
383
|
|
|
370
|
-
@register_as_tool
|
|
384
|
+
@register_as_tool(
|
|
385
|
+
title="Post Snapshots",
|
|
386
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False)
|
|
387
|
+
)
|
|
371
388
|
@with_header_auth(InfrastructureResourcesApi)
|
|
372
389
|
async def post_snapshots(self,
|
|
373
390
|
snapshot_ids: Union[List[str], str],
|
|
@@ -414,13 +431,12 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
414
431
|
from instana_client.models.get_snapshots_query import (
|
|
415
432
|
GetSnapshotsQuery, #type: ignore
|
|
416
433
|
)
|
|
434
|
+
from instana_client.models.time_frame import TimeFrame #type: ignore
|
|
417
435
|
|
|
436
|
+
time_frame = TimeFrame(to=to_time, windowSize=window_size)
|
|
418
437
|
query_obj = GetSnapshotsQuery(
|
|
419
|
-
|
|
420
|
-
time_frame
|
|
421
|
-
"to": to_time,
|
|
422
|
-
"windowSize": window_size
|
|
423
|
-
}
|
|
438
|
+
snapshotIds=snapshot_ids if isinstance(snapshot_ids, list) else [snapshot_ids],
|
|
439
|
+
timeFrame=time_frame
|
|
424
440
|
)
|
|
425
441
|
|
|
426
442
|
logger.debug("Making SDK request with without_preload_content...")
|
|
@@ -546,7 +562,10 @@ class InfrastructureResourcesMCPTools(BaseInstanaClient):
|
|
|
546
562
|
|
|
547
563
|
|
|
548
564
|
|
|
549
|
-
@register_as_tool
|
|
565
|
+
@register_as_tool(
|
|
566
|
+
title="Software Versions",
|
|
567
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
568
|
+
)
|
|
550
569
|
@with_header_auth(InfrastructureResourcesApi)
|
|
551
570
|
async def software_versions(self, ctx=None, api_client=None) -> Dict[str, Any]:
|
|
552
571
|
"""
|
|
@@ -22,6 +22,8 @@ except ImportError:
|
|
|
22
22
|
logger.error("Failed to import infrastructure topology API", exc_info=True)
|
|
23
23
|
raise
|
|
24
24
|
|
|
25
|
+
from mcp.types import ToolAnnotations
|
|
26
|
+
|
|
25
27
|
from src.core.utils import BaseInstanaClient, register_as_tool, with_header_auth
|
|
26
28
|
|
|
27
29
|
# Configure logger for this module
|
|
@@ -49,7 +51,10 @@ class InfrastructureTopologyMCPTools(BaseInstanaClient):
|
|
|
49
51
|
"""Initialize the Infrastructure Topology MCP tools client."""
|
|
50
52
|
super().__init__(read_token=read_token, base_url=base_url)
|
|
51
53
|
|
|
52
|
-
@register_as_tool
|
|
54
|
+
@register_as_tool(
|
|
55
|
+
title="Get Related Hosts",
|
|
56
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
57
|
+
)
|
|
53
58
|
@with_header_auth(InfrastructureTopologyApi)
|
|
54
59
|
async def get_related_hosts(self,
|
|
55
60
|
snapshot_id: str,
|
|
@@ -110,7 +115,10 @@ class InfrastructureTopologyMCPTools(BaseInstanaClient):
|
|
|
110
115
|
logger.error(f"Error in get_related_hosts: {e}", exc_info=True)
|
|
111
116
|
return {"error": f"Failed to get related hosts: {e!s}"}
|
|
112
117
|
|
|
113
|
-
@register_as_tool
|
|
118
|
+
@register_as_tool(
|
|
119
|
+
title="Get Topology",
|
|
120
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False)
|
|
121
|
+
)
|
|
114
122
|
@with_header_auth(InfrastructureTopologyApi)
|
|
115
123
|
async def get_topology(self,
|
|
116
124
|
include_data: Optional[bool] = False,
|