tooluniverse 0.2.0__py3-none-any.whl → 1.0.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.
Potentially problematic release.
This version of tooluniverse might be problematic. Click here for more details.
- tooluniverse/__init__.py +340 -4
- tooluniverse/admetai_tool.py +84 -0
- tooluniverse/agentic_tool.py +563 -0
- tooluniverse/alphafold_tool.py +96 -0
- tooluniverse/base_tool.py +129 -6
- tooluniverse/boltz_tool.py +207 -0
- tooluniverse/chem_tool.py +192 -0
- tooluniverse/compose_scripts/__init__.py +1 -0
- tooluniverse/compose_scripts/biomarker_discovery.py +293 -0
- tooluniverse/compose_scripts/comprehensive_drug_discovery.py +186 -0
- tooluniverse/compose_scripts/drug_safety_analyzer.py +89 -0
- tooluniverse/compose_scripts/literature_tool.py +34 -0
- tooluniverse/compose_scripts/output_summarizer.py +279 -0
- tooluniverse/compose_scripts/tool_description_optimizer.py +681 -0
- tooluniverse/compose_scripts/tool_discover.py +705 -0
- tooluniverse/compose_scripts/tool_graph_composer.py +448 -0
- tooluniverse/compose_tool.py +371 -0
- tooluniverse/ctg_tool.py +1002 -0
- tooluniverse/custom_tool.py +81 -0
- tooluniverse/dailymed_tool.py +108 -0
- tooluniverse/data/admetai_tools.json +155 -0
- tooluniverse/data/adverse_event_tools.json +108 -0
- tooluniverse/data/agentic_tools.json +1156 -0
- tooluniverse/data/alphafold_tools.json +87 -0
- tooluniverse/data/boltz_tools.json +9 -0
- tooluniverse/data/chembl_tools.json +16 -0
- tooluniverse/data/clinicaltrials_gov_tools.json +326 -0
- tooluniverse/data/compose_tools.json +202 -0
- tooluniverse/data/dailymed_tools.json +70 -0
- tooluniverse/data/dataset_tools.json +646 -0
- tooluniverse/data/disease_target_score_tools.json +712 -0
- tooluniverse/data/efo_tools.json +17 -0
- tooluniverse/data/embedding_tools.json +319 -0
- tooluniverse/data/enrichr_tools.json +31 -0
- tooluniverse/data/europe_pmc_tools.json +22 -0
- tooluniverse/data/expert_feedback_tools.json +10 -0
- tooluniverse/data/fda_drug_adverse_event_tools.json +491 -0
- tooluniverse/data/fda_drug_labeling_tools.json +1 -1
- tooluniverse/data/fda_drugs_with_brand_generic_names_for_tool.py +76929 -148860
- tooluniverse/data/finder_tools.json +209 -0
- tooluniverse/data/gene_ontology_tools.json +113 -0
- tooluniverse/data/gwas_tools.json +1082 -0
- tooluniverse/data/hpa_tools.json +333 -0
- tooluniverse/data/humanbase_tools.json +47 -0
- tooluniverse/data/idmap_tools.json +74 -0
- tooluniverse/data/mcp_client_tools_example.json +113 -0
- tooluniverse/data/mcpautoloadertool_defaults.json +28 -0
- tooluniverse/data/medlineplus_tools.json +141 -0
- tooluniverse/data/monarch_tools.json +1 -1
- tooluniverse/data/openalex_tools.json +36 -0
- tooluniverse/data/opentarget_tools.json +1 -1
- tooluniverse/data/output_summarization_tools.json +101 -0
- tooluniverse/data/packages/bioinformatics_core_tools.json +1756 -0
- tooluniverse/data/packages/categorized_tools.txt +206 -0
- tooluniverse/data/packages/cheminformatics_tools.json +347 -0
- tooluniverse/data/packages/earth_sciences_tools.json +74 -0
- tooluniverse/data/packages/genomics_tools.json +776 -0
- tooluniverse/data/packages/image_processing_tools.json +38 -0
- tooluniverse/data/packages/machine_learning_tools.json +789 -0
- tooluniverse/data/packages/neuroscience_tools.json +62 -0
- tooluniverse/data/packages/original_tools.txt +0 -0
- tooluniverse/data/packages/physics_astronomy_tools.json +62 -0
- tooluniverse/data/packages/scientific_computing_tools.json +560 -0
- tooluniverse/data/packages/single_cell_tools.json +453 -0
- tooluniverse/data/packages/structural_biology_tools.json +396 -0
- tooluniverse/data/packages/visualization_tools.json +399 -0
- tooluniverse/data/pubchem_tools.json +215 -0
- tooluniverse/data/pubtator_tools.json +68 -0
- tooluniverse/data/rcsb_pdb_tools.json +1332 -0
- tooluniverse/data/reactome_tools.json +19 -0
- tooluniverse/data/semantic_scholar_tools.json +26 -0
- tooluniverse/data/special_tools.json +2 -25
- tooluniverse/data/tool_composition_tools.json +88 -0
- tooluniverse/data/toolfinderkeyword_defaults.json +34 -0
- tooluniverse/data/txagent_client_tools.json +9 -0
- tooluniverse/data/uniprot_tools.json +211 -0
- tooluniverse/data/url_fetch_tools.json +94 -0
- tooluniverse/data/uspto_downloader_tools.json +9 -0
- tooluniverse/data/uspto_tools.json +811 -0
- tooluniverse/data/xml_tools.json +3275 -0
- tooluniverse/dataset_tool.py +296 -0
- tooluniverse/default_config.py +165 -0
- tooluniverse/efo_tool.py +42 -0
- tooluniverse/embedding_database.py +630 -0
- tooluniverse/embedding_sync.py +396 -0
- tooluniverse/enrichr_tool.py +266 -0
- tooluniverse/europe_pmc_tool.py +52 -0
- tooluniverse/execute_function.py +1775 -95
- tooluniverse/extended_hooks.py +444 -0
- tooluniverse/gene_ontology_tool.py +194 -0
- tooluniverse/graphql_tool.py +158 -36
- tooluniverse/gwas_tool.py +358 -0
- tooluniverse/hpa_tool.py +1645 -0
- tooluniverse/humanbase_tool.py +389 -0
- tooluniverse/logging_config.py +254 -0
- tooluniverse/mcp_client_tool.py +764 -0
- tooluniverse/mcp_integration.py +413 -0
- tooluniverse/mcp_tool_registry.py +925 -0
- tooluniverse/medlineplus_tool.py +337 -0
- tooluniverse/openalex_tool.py +228 -0
- tooluniverse/openfda_adv_tool.py +283 -0
- tooluniverse/openfda_tool.py +393 -160
- tooluniverse/output_hook.py +1122 -0
- tooluniverse/package_tool.py +195 -0
- tooluniverse/pubchem_tool.py +158 -0
- tooluniverse/pubtator_tool.py +168 -0
- tooluniverse/rcsb_pdb_tool.py +38 -0
- tooluniverse/reactome_tool.py +108 -0
- tooluniverse/remote/boltz/boltz_mcp_server.py +50 -0
- tooluniverse/remote/depmap_24q2/depmap_24q2_mcp_tool.py +442 -0
- tooluniverse/remote/expert_feedback/human_expert_mcp_tools.py +2013 -0
- tooluniverse/remote/expert_feedback/simple_test.py +23 -0
- tooluniverse/remote/expert_feedback/start_web_interface.py +188 -0
- tooluniverse/remote/expert_feedback/web_only_interface.py +0 -0
- tooluniverse/remote/immune_compass/compass_tool.py +327 -0
- tooluniverse/remote/pinnacle/pinnacle_tool.py +328 -0
- tooluniverse/remote/transcriptformer/transcriptformer_tool.py +586 -0
- tooluniverse/remote/uspto_downloader/uspto_downloader_mcp_server.py +61 -0
- tooluniverse/remote/uspto_downloader/uspto_downloader_tool.py +120 -0
- tooluniverse/remote_tool.py +99 -0
- tooluniverse/restful_tool.py +53 -30
- tooluniverse/scripts/generate_tool_graph.py +408 -0
- tooluniverse/scripts/visualize_tool_graph.py +829 -0
- tooluniverse/semantic_scholar_tool.py +62 -0
- tooluniverse/smcp.py +2452 -0
- tooluniverse/smcp_server.py +975 -0
- tooluniverse/test/mcp_server_test.py +0 -0
- tooluniverse/test/test_admetai_tool.py +370 -0
- tooluniverse/test/test_agentic_tool.py +129 -0
- tooluniverse/test/test_alphafold_tool.py +71 -0
- tooluniverse/test/test_chem_tool.py +37 -0
- tooluniverse/test/test_compose_lieraturereview.py +63 -0
- tooluniverse/test/test_compose_tool.py +448 -0
- tooluniverse/test/test_dailymed.py +69 -0
- tooluniverse/test/test_dataset_tool.py +200 -0
- tooluniverse/test/test_disease_target_score.py +56 -0
- tooluniverse/test/test_drugbank_filter_examples.py +179 -0
- tooluniverse/test/test_efo.py +31 -0
- tooluniverse/test/test_enrichr_tool.py +21 -0
- tooluniverse/test/test_europe_pmc_tool.py +20 -0
- tooluniverse/test/test_fda_adv.py +95 -0
- tooluniverse/test/test_fda_drug_labeling.py +91 -0
- tooluniverse/test/test_gene_ontology_tools.py +66 -0
- tooluniverse/test/test_gwas_tool.py +139 -0
- tooluniverse/test/test_hpa.py +625 -0
- tooluniverse/test/test_humanbase_tool.py +20 -0
- tooluniverse/test/test_idmap_tools.py +61 -0
- tooluniverse/test/test_mcp_server.py +211 -0
- tooluniverse/test/test_mcp_tool.py +247 -0
- tooluniverse/test/test_medlineplus.py +220 -0
- tooluniverse/test/test_openalex_tool.py +32 -0
- tooluniverse/test/test_opentargets.py +28 -0
- tooluniverse/test/test_pubchem_tool.py +116 -0
- tooluniverse/test/test_pubtator_tool.py +37 -0
- tooluniverse/test/test_rcsb_pdb_tool.py +86 -0
- tooluniverse/test/test_reactome.py +54 -0
- tooluniverse/test/test_semantic_scholar_tool.py +24 -0
- tooluniverse/test/test_software_tools.py +147 -0
- tooluniverse/test/test_tool_description_optimizer.py +49 -0
- tooluniverse/test/test_tool_finder.py +26 -0
- tooluniverse/test/test_tool_finder_llm.py +252 -0
- tooluniverse/test/test_tools_find.py +195 -0
- tooluniverse/test/test_uniprot_tools.py +74 -0
- tooluniverse/test/test_uspto_tool.py +72 -0
- tooluniverse/test/test_xml_tool.py +113 -0
- tooluniverse/tool_finder_embedding.py +267 -0
- tooluniverse/tool_finder_keyword.py +693 -0
- tooluniverse/tool_finder_llm.py +699 -0
- tooluniverse/tool_graph_web_ui.py +955 -0
- tooluniverse/tool_registry.py +416 -0
- tooluniverse/uniprot_tool.py +155 -0
- tooluniverse/url_tool.py +253 -0
- tooluniverse/uspto_tool.py +240 -0
- tooluniverse/utils.py +369 -41
- tooluniverse/xml_tool.py +369 -0
- tooluniverse-1.0.1.dist-info/METADATA +387 -0
- tooluniverse-1.0.1.dist-info/RECORD +182 -0
- tooluniverse-1.0.1.dist-info/entry_points.txt +9 -0
- tooluniverse/generate_mcp_tools.py +0 -113
- tooluniverse/mcp_server.py +0 -3340
- tooluniverse-0.2.0.dist-info/METADATA +0 -139
- tooluniverse-0.2.0.dist-info/RECORD +0 -21
- tooluniverse-0.2.0.dist-info/entry_points.txt +0 -4
- {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/WHEEL +0 -0
- {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ToolUniverse MCP Integration Extensions
|
|
3
|
+
|
|
4
|
+
This module extends ToolUniverse with methods to automatically discover and load
|
|
5
|
+
MCP tools from remote servers, providing seamless integration between local tools
|
|
6
|
+
and remote MCP services.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def load_mcp_tools(self, server_urls: List[str] = None, **kwargs):
|
|
13
|
+
"""
|
|
14
|
+
Load MCP tools from remote servers into this ToolUniverse instance.
|
|
15
|
+
|
|
16
|
+
This method automatically discovers tools from MCP servers and registers them
|
|
17
|
+
as ToolUniverse tools, enabling seamless usage of remote capabilities.
|
|
18
|
+
|
|
19
|
+
Parameters:
|
|
20
|
+
===========
|
|
21
|
+
server_urls : list of str, optional
|
|
22
|
+
List of MCP server URLs to load tools from. Examples:
|
|
23
|
+
|
|
24
|
+
- ["http://localhost:8001", "http://analysis-server:8002"]
|
|
25
|
+
- ["ws://localhost:9000"] # WebSocket MCP servers
|
|
26
|
+
|
|
27
|
+
If None, attempts to discover from local MCP tool registry.
|
|
28
|
+
|
|
29
|
+
**kwargs
|
|
30
|
+
Additional configuration options:
|
|
31
|
+
|
|
32
|
+
- tool_prefix (str): Prefix for loaded tool names (default: "mcp_")
|
|
33
|
+
- timeout (int): Connection timeout in seconds (default: 30)
|
|
34
|
+
- auto_register (bool): Whether to auto-register discovered tools (default: True)
|
|
35
|
+
- selected_tools (list): Specific tools to load from each server
|
|
36
|
+
- categories (list): Tool categories to filter by
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
========
|
|
40
|
+
dict
|
|
41
|
+
Summary of loaded tools with counts and any errors encountered.
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
=========
|
|
45
|
+
|
|
46
|
+
Load from specific servers:
|
|
47
|
+
```python
|
|
48
|
+
tu = ToolUniverse()
|
|
49
|
+
|
|
50
|
+
# Load tools from multiple MCP servers
|
|
51
|
+
result = tu.load_mcp_tools([
|
|
52
|
+
"http://localhost:8001", # Local analysis server
|
|
53
|
+
"http://ml-server:8002", # Remote ML server
|
|
54
|
+
"ws://realtime:9000" # WebSocket server
|
|
55
|
+
])
|
|
56
|
+
|
|
57
|
+
print(f"Loaded {result['total_tools']} tools from {result['servers_connected']} servers")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Load with custom configuration:
|
|
61
|
+
```python
|
|
62
|
+
tu.load_mcp_tools(
|
|
63
|
+
server_urls=["http://localhost:8001"],
|
|
64
|
+
tool_prefix="analysis\\_",
|
|
65
|
+
timeout=60,
|
|
66
|
+
selected_tools=["protein_analysis", "drug_interaction"]
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Auto-discovery from local registry:
|
|
71
|
+
```python
|
|
72
|
+
# If you have registered MCP tools locally, auto-discover their servers
|
|
73
|
+
tu.load_mcp_tools() # Uses servers from mcp_tool_registry
|
|
74
|
+
```
|
|
75
|
+
"""
|
|
76
|
+
# Default configuration
|
|
77
|
+
config = {
|
|
78
|
+
"tool_prefix": "mcp_",
|
|
79
|
+
"timeout": 30,
|
|
80
|
+
"auto_register": True,
|
|
81
|
+
"selected_tools": None,
|
|
82
|
+
"categories": None,
|
|
83
|
+
**kwargs,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Get server URLs
|
|
87
|
+
if server_urls is None:
|
|
88
|
+
try:
|
|
89
|
+
from .mcp_tool_registry import get_mcp_tool_urls
|
|
90
|
+
|
|
91
|
+
server_urls = get_mcp_tool_urls()
|
|
92
|
+
except ImportError:
|
|
93
|
+
server_urls = []
|
|
94
|
+
|
|
95
|
+
if not server_urls:
|
|
96
|
+
print("📭 No MCP servers specified or discovered")
|
|
97
|
+
return {"total_tools": 0, "servers_connected": 0, "errors": []}
|
|
98
|
+
|
|
99
|
+
print(f"🔄 Loading MCP tools from {len(server_urls)} servers...")
|
|
100
|
+
|
|
101
|
+
results = {"total_tools": 0, "servers_connected": 0, "servers": {}, "errors": []}
|
|
102
|
+
|
|
103
|
+
for url in server_urls:
|
|
104
|
+
try:
|
|
105
|
+
result = self._load_tools_from_mcp_server(url, config)
|
|
106
|
+
results["servers"][url] = result
|
|
107
|
+
results["total_tools"] += result.get("tools_loaded", 0)
|
|
108
|
+
if result.get("success", False):
|
|
109
|
+
results["servers_connected"] += 1
|
|
110
|
+
except Exception as e:
|
|
111
|
+
error_msg = f"Failed to load from {url}: {str(e)}"
|
|
112
|
+
print(f"❌ {error_msg}")
|
|
113
|
+
results["errors"].append(error_msg)
|
|
114
|
+
|
|
115
|
+
print(
|
|
116
|
+
f"✅ Loaded {results['total_tools']} tools from {results['servers_connected']} servers"
|
|
117
|
+
)
|
|
118
|
+
return results
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _load_tools_from_mcp_server(
|
|
122
|
+
self, server_url: str, config: Dict[str, Any]
|
|
123
|
+
) -> Dict[str, Any]:
|
|
124
|
+
"""Load tools from a specific MCP server."""
|
|
125
|
+
try:
|
|
126
|
+
# Create MCPAutoLoaderTool configuration
|
|
127
|
+
loader_name = f"mcp_loader_{server_url.replace('://', '_').replace(':', '_').replace('/', '_')}"
|
|
128
|
+
|
|
129
|
+
loader_config = {
|
|
130
|
+
"name": loader_name,
|
|
131
|
+
"type": "MCPAutoLoaderTool",
|
|
132
|
+
"server_url": server_url,
|
|
133
|
+
"auto_register": config["auto_register"],
|
|
134
|
+
"tool_prefix": config["tool_prefix"],
|
|
135
|
+
"timeout": config["timeout"],
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# Add selected tools filter if specified
|
|
139
|
+
if config["selected_tools"]:
|
|
140
|
+
loader_config["selected_tools"] = config["selected_tools"]
|
|
141
|
+
|
|
142
|
+
# Add the auto-loader configuration directly to the tools list
|
|
143
|
+
self.all_tools.append(loader_config)
|
|
144
|
+
self.all_tool_dict[loader_name] = loader_config
|
|
145
|
+
|
|
146
|
+
print(f"✅ Created MCP auto-loader for {server_url}")
|
|
147
|
+
|
|
148
|
+
# Try to discover tools immediately to get count (mimic _process_mcp_auto_loaders)
|
|
149
|
+
try:
|
|
150
|
+
# Import the tool registry to get the class
|
|
151
|
+
from .execute_function import tool_type_mappings
|
|
152
|
+
|
|
153
|
+
# Create auto loader instance (same as _process_mcp_auto_loaders)
|
|
154
|
+
auto_loader = tool_type_mappings["MCPAutoLoaderTool"](loader_config)
|
|
155
|
+
|
|
156
|
+
# Run auto-load process (same as _process_mcp_auto_loaders)
|
|
157
|
+
import asyncio
|
|
158
|
+
import warnings
|
|
159
|
+
|
|
160
|
+
async def _run_auto_load():
|
|
161
|
+
"""Run auto-load with proper cleanup"""
|
|
162
|
+
try:
|
|
163
|
+
result = await auto_loader.auto_load_and_register(self)
|
|
164
|
+
return result
|
|
165
|
+
finally:
|
|
166
|
+
# Ensure session cleanup
|
|
167
|
+
await auto_loader._close_session()
|
|
168
|
+
|
|
169
|
+
# Check if we're already in an event loop
|
|
170
|
+
try:
|
|
171
|
+
asyncio.get_running_loop()
|
|
172
|
+
in_event_loop = True
|
|
173
|
+
except RuntimeError:
|
|
174
|
+
in_event_loop = False
|
|
175
|
+
|
|
176
|
+
if in_event_loop:
|
|
177
|
+
# In event loop - create task for later processing
|
|
178
|
+
tools_count = 0
|
|
179
|
+
discovery_error = (
|
|
180
|
+
"Cannot process in event loop - will be processed later"
|
|
181
|
+
)
|
|
182
|
+
else:
|
|
183
|
+
# No event loop, safe to create one (same as _process_mcp_auto_loaders)
|
|
184
|
+
with warnings.catch_warnings():
|
|
185
|
+
warnings.simplefilter("ignore", ResourceWarning)
|
|
186
|
+
|
|
187
|
+
loop = asyncio.new_event_loop()
|
|
188
|
+
asyncio.set_event_loop(loop)
|
|
189
|
+
try:
|
|
190
|
+
result = loop.run_until_complete(_run_auto_load())
|
|
191
|
+
tools_count = result.get("registered_count", 0)
|
|
192
|
+
discovery_error = None
|
|
193
|
+
finally:
|
|
194
|
+
loop.close()
|
|
195
|
+
asyncio.set_event_loop(None)
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
"success": True,
|
|
199
|
+
"tools_loaded": tools_count,
|
|
200
|
+
"loader_name": loader_name,
|
|
201
|
+
"server_url": server_url,
|
|
202
|
+
"discovery_error": discovery_error,
|
|
203
|
+
}
|
|
204
|
+
except Exception as e:
|
|
205
|
+
# Auto-loader created but discovery failed
|
|
206
|
+
return {
|
|
207
|
+
"success": True,
|
|
208
|
+
"tools_loaded": 0,
|
|
209
|
+
"loader_name": loader_name,
|
|
210
|
+
"server_url": server_url,
|
|
211
|
+
"discovery_error": str(e),
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
except Exception as e:
|
|
215
|
+
return {"success": False, "error": str(e), "server_url": server_url}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def discover_mcp_tools(self, server_urls: List[str] = None, **kwargs) -> Dict[str, Any]:
|
|
219
|
+
"""
|
|
220
|
+
Discover available tools from MCP servers without loading them.
|
|
221
|
+
|
|
222
|
+
This method connects to MCP servers to discover what tools are available
|
|
223
|
+
without actually registering them in ToolUniverse. Useful for exploration
|
|
224
|
+
and selective tool loading.
|
|
225
|
+
|
|
226
|
+
Parameters:
|
|
227
|
+
===========
|
|
228
|
+
server_urls : list of str, optional
|
|
229
|
+
List of MCP server URLs to discover from
|
|
230
|
+
**kwargs
|
|
231
|
+
Additional options:
|
|
232
|
+
- timeout (int): Connection timeout (default: 30)
|
|
233
|
+
- include_schemas (bool): Include tool parameter schemas (default: True)
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
========
|
|
237
|
+
dict
|
|
238
|
+
Discovery results with tools organized by server
|
|
239
|
+
|
|
240
|
+
Examples:
|
|
241
|
+
=========
|
|
242
|
+
```python
|
|
243
|
+
tu = ToolUniverse()
|
|
244
|
+
|
|
245
|
+
# Discover what's available
|
|
246
|
+
discovery = tu.discover_mcp_tools([
|
|
247
|
+
"http://localhost:8001",
|
|
248
|
+
"http://ml-server:8002"
|
|
249
|
+
])
|
|
250
|
+
|
|
251
|
+
# Show available tools
|
|
252
|
+
for server, info in discovery["servers"].items():
|
|
253
|
+
print(f"\\n{server}:")
|
|
254
|
+
for tool in info.get("tools", []):
|
|
255
|
+
print(f" - {tool['name']}: {tool['description']}")
|
|
256
|
+
```
|
|
257
|
+
"""
|
|
258
|
+
if server_urls is None:
|
|
259
|
+
try:
|
|
260
|
+
from .mcp_tool_registry import get_mcp_tool_urls
|
|
261
|
+
|
|
262
|
+
server_urls = get_mcp_tool_urls()
|
|
263
|
+
except ImportError:
|
|
264
|
+
server_urls = []
|
|
265
|
+
|
|
266
|
+
if not server_urls:
|
|
267
|
+
return {"servers": {}, "total_tools": 0, "errors": []}
|
|
268
|
+
|
|
269
|
+
config = {"timeout": 30, "include_schemas": True, **kwargs}
|
|
270
|
+
|
|
271
|
+
print(f"🔍 Discovering tools from {len(server_urls)} MCP servers...")
|
|
272
|
+
|
|
273
|
+
results = {"servers": {}, "total_tools": 0, "errors": []}
|
|
274
|
+
|
|
275
|
+
for url in server_urls:
|
|
276
|
+
try:
|
|
277
|
+
# Create temporary discovery client
|
|
278
|
+
discovery_config = {
|
|
279
|
+
"name": f"temp_discovery_{hash(url)}",
|
|
280
|
+
"type": "MCPClientTool",
|
|
281
|
+
"server_url": url,
|
|
282
|
+
"timeout": config["timeout"],
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
# Register temporary tool for discovery
|
|
286
|
+
self.register_custom_tool(
|
|
287
|
+
tool_class=None, tool_type="MCPClientTool", config=discovery_config
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# Discover tools
|
|
291
|
+
discovery_result = self.run_tool(
|
|
292
|
+
discovery_config["name"], {"operation": "list_tools"}
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if discovery_result.get("success", False):
|
|
296
|
+
tools = discovery_result.get("tools", [])
|
|
297
|
+
results["servers"][url] = {
|
|
298
|
+
"tools": tools,
|
|
299
|
+
"count": len(tools),
|
|
300
|
+
"status": "success",
|
|
301
|
+
}
|
|
302
|
+
results["total_tools"] += len(tools)
|
|
303
|
+
print(f"✅ {url}: {len(tools)} tools discovered")
|
|
304
|
+
else:
|
|
305
|
+
error_msg = discovery_result.get("error", "Unknown error")
|
|
306
|
+
results["servers"][url] = {
|
|
307
|
+
"tools": [],
|
|
308
|
+
"count": 0,
|
|
309
|
+
"status": "error",
|
|
310
|
+
"error": error_msg,
|
|
311
|
+
}
|
|
312
|
+
print(f"❌ {url}: {error_msg}")
|
|
313
|
+
|
|
314
|
+
# Clean up temporary tool
|
|
315
|
+
if hasattr(self, "_remove_tool"):
|
|
316
|
+
self._remove_tool(discovery_config["name"])
|
|
317
|
+
|
|
318
|
+
except Exception as e:
|
|
319
|
+
error_msg = f"Discovery failed for {url}: {str(e)}"
|
|
320
|
+
results["errors"].append(error_msg)
|
|
321
|
+
results["servers"][url] = {
|
|
322
|
+
"tools": [],
|
|
323
|
+
"count": 0,
|
|
324
|
+
"status": "error",
|
|
325
|
+
"error": str(e),
|
|
326
|
+
}
|
|
327
|
+
print(f"❌ {error_msg}")
|
|
328
|
+
|
|
329
|
+
print(f"🔍 Discovery complete: {results['total_tools']} total tools found")
|
|
330
|
+
return results
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def list_mcp_connections(self) -> Dict[str, Any]:
|
|
334
|
+
"""
|
|
335
|
+
List all active MCP connections and loaded tools.
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
========
|
|
339
|
+
dict
|
|
340
|
+
Information about MCP connections, auto-loaders, and loaded tools
|
|
341
|
+
|
|
342
|
+
Examples:
|
|
343
|
+
=========
|
|
344
|
+
```python
|
|
345
|
+
tu = ToolUniverse()
|
|
346
|
+
tu.load_mcp_tools(["http://localhost:8001"])
|
|
347
|
+
|
|
348
|
+
connections = tu.list_mcp_connections()
|
|
349
|
+
print(f"Active MCP connections: {len(connections['connections'])}")
|
|
350
|
+
```
|
|
351
|
+
"""
|
|
352
|
+
mcp_tools = {}
|
|
353
|
+
mcp_loaders = {}
|
|
354
|
+
|
|
355
|
+
# Find MCP-related tools in the current tool configuration
|
|
356
|
+
for tool_name, tool_config in getattr(self, "tool_configs", {}).items():
|
|
357
|
+
tool_type = tool_config.get("type", "")
|
|
358
|
+
|
|
359
|
+
if tool_type == "MCPAutoLoaderTool":
|
|
360
|
+
server_url = tool_config.get("server_url", "")
|
|
361
|
+
mcp_loaders[tool_name] = {
|
|
362
|
+
"server_url": server_url,
|
|
363
|
+
"tool_prefix": tool_config.get("tool_prefix", "mcp_"),
|
|
364
|
+
"auto_register": tool_config.get("auto_register", True),
|
|
365
|
+
"config": tool_config,
|
|
366
|
+
}
|
|
367
|
+
elif tool_type in ["MCPClientTool", "MCPProxyTool"]:
|
|
368
|
+
server_url = tool_config.get("server_url", "")
|
|
369
|
+
mcp_tools[tool_name] = {
|
|
370
|
+
"type": tool_type,
|
|
371
|
+
"server_url": server_url,
|
|
372
|
+
"config": tool_config,
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return {
|
|
376
|
+
"connections": {"auto_loaders": mcp_loaders, "direct_tools": mcp_tools},
|
|
377
|
+
"total_mcp_tools": len(mcp_tools) + len(mcp_loaders),
|
|
378
|
+
"servers": list(
|
|
379
|
+
set(
|
|
380
|
+
[config["server_url"] for config in mcp_loaders.values()]
|
|
381
|
+
+ [config["server_url"] for config in mcp_tools.values()]
|
|
382
|
+
)
|
|
383
|
+
),
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
# Monkey patch methods into ToolUniverse
|
|
388
|
+
def _patch_tooluniverse():
|
|
389
|
+
"""Add MCP integration methods to ToolUniverse class."""
|
|
390
|
+
try:
|
|
391
|
+
from .execute_function import ToolUniverse
|
|
392
|
+
|
|
393
|
+
# Add methods to ToolUniverse if they don't exist
|
|
394
|
+
if not hasattr(ToolUniverse, "load_mcp_tools"):
|
|
395
|
+
ToolUniverse.load_mcp_tools = load_mcp_tools
|
|
396
|
+
|
|
397
|
+
if not hasattr(ToolUniverse, "discover_mcp_tools"):
|
|
398
|
+
ToolUniverse.discover_mcp_tools = discover_mcp_tools
|
|
399
|
+
|
|
400
|
+
if not hasattr(ToolUniverse, "list_mcp_connections"):
|
|
401
|
+
ToolUniverse.list_mcp_connections = list_mcp_connections
|
|
402
|
+
|
|
403
|
+
if not hasattr(ToolUniverse, "_load_tools_from_mcp_server"):
|
|
404
|
+
ToolUniverse._load_tools_from_mcp_server = _load_tools_from_mcp_server
|
|
405
|
+
|
|
406
|
+
# print("✅ ToolUniverse MCP integration methods added")
|
|
407
|
+
|
|
408
|
+
except ImportError as e:
|
|
409
|
+
print(f"⚠️ Could not patch ToolUniverse: {e}")
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# Auto-patch when module is imported
|
|
413
|
+
_patch_tooluniverse()
|