Modify the running example to adapt to the camel style
Browse files- owl/run_mcp.py +9 -7
- owl/utils/mcp/mcp_toolkit_manager.py +0 -86
owl/run_mcp.py
CHANGED
@@ -79,10 +79,10 @@ from camel.models import ModelFactory
|
|
79 |
from camel.toolkits import FunctionTool
|
80 |
from camel.types import ModelPlatformType, ModelType
|
81 |
from camel.logger import set_log_level
|
|
|
82 |
|
83 |
from utils.enhanced_role_playing import OwlRolePlaying, run_society
|
84 |
|
85 |
-
from utils.mcp.mcp_toolkit_manager import MCPToolkitManager
|
86 |
|
87 |
|
88 |
load_dotenv()
|
@@ -138,7 +138,7 @@ async def main():
|
|
138 |
Path(__file__).parent / "utils/mcp/mcp_servers_config.json"
|
139 |
)
|
140 |
|
141 |
-
|
142 |
|
143 |
question = (
|
144 |
"I'd like a academic report about Guohao Li, including his research "
|
@@ -146,16 +146,18 @@ async def main():
|
|
146 |
"Then organize the report in Markdown format and save it to my desktop"
|
147 |
)
|
148 |
|
149 |
-
|
150 |
-
async with manager.connection():
|
151 |
-
tools = manager.get_all_tools()
|
152 |
|
153 |
-
|
|
|
154 |
|
155 |
-
|
|
|
|
|
156 |
|
157 |
print(f"\033[94mAnswer: {answer}\033[0m")
|
158 |
|
|
|
159 |
|
160 |
if __name__ == "__main__":
|
161 |
asyncio.run(main())
|
|
|
79 |
from camel.toolkits import FunctionTool
|
80 |
from camel.types import ModelPlatformType, ModelType
|
81 |
from camel.logger import set_log_level
|
82 |
+
from camel.toolkits import MCPToolkit
|
83 |
|
84 |
from utils.enhanced_role_playing import OwlRolePlaying, run_society
|
85 |
|
|
|
86 |
|
87 |
|
88 |
load_dotenv()
|
|
|
138 |
Path(__file__).parent / "utils/mcp/mcp_servers_config.json"
|
139 |
)
|
140 |
|
141 |
+
mcp_toolkit = MCPToolkit(config_path=config_path)
|
142 |
|
143 |
question = (
|
144 |
"I'd like a academic report about Guohao Li, including his research "
|
|
|
146 |
"Then organize the report in Markdown format and save it to my desktop"
|
147 |
)
|
148 |
|
149 |
+
await mcp_toolkit.connect()
|
|
|
|
|
150 |
|
151 |
+
# # Connect to all MCP toolkits
|
152 |
+
tools = [*mcp_toolkit.get_tools()]
|
153 |
|
154 |
+
society = await construct_society(question, tools)
|
155 |
+
|
156 |
+
answer, chat_history, token_count = await run_society(society)
|
157 |
|
158 |
print(f"\033[94mAnswer: {answer}\033[0m")
|
159 |
|
160 |
+
await mcp_toolkit.disconnect()
|
161 |
|
162 |
if __name__ == "__main__":
|
163 |
asyncio.run(main())
|
owl/utils/mcp/mcp_toolkit_manager.py
DELETED
@@ -1,86 +0,0 @@
|
|
1 |
-
import json
|
2 |
-
import os
|
3 |
-
from typing import List, Optional, AsyncGenerator
|
4 |
-
|
5 |
-
from camel.toolkits import MCPToolkit
|
6 |
-
from contextlib import AsyncExitStack, asynccontextmanager
|
7 |
-
|
8 |
-
|
9 |
-
class MCPToolkitManager:
|
10 |
-
r"""MCPToolkitManager is a class for managing multiple MCPToolkit
|
11 |
-
instances and providing unified connection management.
|
12 |
-
|
13 |
-
Attributes:
|
14 |
-
toolkits (List[MCPToolkit]): A list of MCPToolkit instances to be
|
15 |
-
managed.
|
16 |
-
"""
|
17 |
-
|
18 |
-
def __init__(self, toolkits: List[MCPToolkit]):
|
19 |
-
self.toolkits = toolkits
|
20 |
-
self._exit_stack: Optional[AsyncExitStack] = None
|
21 |
-
self._connected = False
|
22 |
-
|
23 |
-
|
24 |
-
@staticmethod
|
25 |
-
def from_config(config_path: str) -> "MCPToolkitManager":
|
26 |
-
r"""Loads an MCPToolkit instance from a JSON configuration file and
|
27 |
-
returns an MCPToolkitManager instance.
|
28 |
-
|
29 |
-
Args:
|
30 |
-
config_path (str): The path to the JSON configuration file.
|
31 |
-
|
32 |
-
Returns:
|
33 |
-
MCPToolkitManager: The MCPToolkitManager instance.
|
34 |
-
"""
|
35 |
-
with open(config_path, "r", encoding="utf-8") as f:
|
36 |
-
data = json.load(f)
|
37 |
-
|
38 |
-
all_toolkits = []
|
39 |
-
|
40 |
-
# "mcpServers" is the MCP server configuration running as stdio mode
|
41 |
-
mcp_servers = data.get("mcpServers", {})
|
42 |
-
for name, cfg in mcp_servers.items():
|
43 |
-
toolkit = MCPToolkit(
|
44 |
-
command_or_url=cfg["command"],
|
45 |
-
args=cfg.get("args", []),
|
46 |
-
env={**os.environ, **cfg.get("env", {})},
|
47 |
-
timeout=cfg.get("timeout", None),
|
48 |
-
)
|
49 |
-
all_toolkits.append(toolkit)
|
50 |
-
|
51 |
-
# "mcpWebServers" is the MCP server configuration running as sse mode
|
52 |
-
mcp_web_servers = data.get("mcpWebServers", {})
|
53 |
-
for name, cfg in mcp_web_servers.items():
|
54 |
-
toolkit = MCPToolkit(
|
55 |
-
command_or_url=cfg["url"],
|
56 |
-
timeout=cfg.get("timeout", None),
|
57 |
-
)
|
58 |
-
all_toolkits.append(toolkit)
|
59 |
-
|
60 |
-
return MCPToolkitManager(all_toolkits)
|
61 |
-
|
62 |
-
@asynccontextmanager
|
63 |
-
async def connection(self) -> AsyncGenerator["MCPToolkitManager", None]:
|
64 |
-
r"""Connect multiple MCPToolkit instances and close them when
|
65 |
-
leaving"""
|
66 |
-
self._exit_stack = AsyncExitStack()
|
67 |
-
try:
|
68 |
-
for tk in self.toolkits:
|
69 |
-
await self._exit_stack.enter_async_context(tk.connection())
|
70 |
-
self._connected = True
|
71 |
-
yield self
|
72 |
-
finally:
|
73 |
-
self._connected = False
|
74 |
-
await self._exit_stack.aclose()
|
75 |
-
self._exit_stack = None
|
76 |
-
|
77 |
-
def is_connected(self) -> bool:
|
78 |
-
r"""Returns whether the MCPToolkitManager is connected."""
|
79 |
-
return self._connected
|
80 |
-
|
81 |
-
def get_all_tools(self):
|
82 |
-
r"""Returns all tools from all MCPToolkit instances."""
|
83 |
-
all_tools = []
|
84 |
-
for tk in self.toolkits:
|
85 |
-
all_tools.extend(tk.get_tools())
|
86 |
-
return all_tools
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|