update format
This commit is contained in:
parent
6e45490412
commit
5ae32c91e5
@ -1,11 +1,12 @@
|
||||
import asyncio
|
||||
from typing import Optional
|
||||
from contextlib import AsyncExitStack
|
||||
import os
|
||||
from contextlib import AsyncExitStack
|
||||
from typing import Optional
|
||||
|
||||
from mcp import ClientSession, StdioServerParameters
|
||||
from mcp.client.stdio import stdio_client
|
||||
|
||||
|
||||
class OpenManusClient:
|
||||
def __init__(self):
|
||||
# Initialize session and client objects
|
||||
@ -20,7 +21,7 @@ class OpenManusClient:
|
||||
Args:
|
||||
server_script_path: Path to the server script
|
||||
"""
|
||||
if not server_script_path.endswith('.py'):
|
||||
if not server_script_path.endswith(".py"):
|
||||
raise ValueError("Server script must be a .py file")
|
||||
|
||||
# Get the current directory to add to PYTHONPATH
|
||||
@ -31,21 +32,27 @@ class OpenManusClient:
|
||||
env = os.environ.copy() # Copy current environment
|
||||
|
||||
# Add current directory and project root to PYTHONPATH
|
||||
path_separator = ';' if os.name == 'nt' else ':' # Use ; for Windows, : for Unix
|
||||
if 'PYTHONPATH' in env:
|
||||
env['PYTHONPATH'] = f"{current_dir}{path_separator}{project_root}{path_separator}{env['PYTHONPATH']}"
|
||||
path_separator = (
|
||||
";" if os.name == "nt" else ":"
|
||||
) # Use ; for Windows, : for Unix
|
||||
if "PYTHONPATH" in env:
|
||||
env[
|
||||
"PYTHONPATH"
|
||||
] = f"{current_dir}{path_separator}{project_root}{path_separator}{env['PYTHONPATH']}"
|
||||
else:
|
||||
env['PYTHONPATH'] = f"{current_dir}{path_separator}{project_root}"
|
||||
env["PYTHONPATH"] = f"{current_dir}{path_separator}{project_root}"
|
||||
|
||||
server_params = StdioServerParameters(
|
||||
command="python",
|
||||
args=[server_script_path],
|
||||
env=env
|
||||
command="python", args=[server_script_path], env=env
|
||||
)
|
||||
|
||||
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
|
||||
stdio_transport = await self.exit_stack.enter_async_context(
|
||||
stdio_client(server_params)
|
||||
)
|
||||
self.stdio, self.write = stdio_transport
|
||||
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
|
||||
self.session = await self.exit_stack.enter_async_context(
|
||||
ClientSession(self.stdio, self.write)
|
||||
)
|
||||
await self.session.initialize()
|
||||
|
||||
# List available tools
|
||||
@ -59,8 +66,7 @@ class OpenManusClient:
|
||||
try:
|
||||
print("\nExample 1: Google Search")
|
||||
search_result = await self.session.call_tool(
|
||||
"google_search",
|
||||
{"query": "Model Context Protocol", "num_results": 5}
|
||||
"google_search", {"query": "Model Context Protocol", "num_results": 5}
|
||||
)
|
||||
print(f"Search results: {search_result.content}")
|
||||
|
||||
@ -73,8 +79,7 @@ for i in range(1, 10):
|
||||
print(f"Calculation result: {result}")
|
||||
"""
|
||||
python_result = await self.session.call_tool(
|
||||
"python_execute",
|
||||
{"code": code, "timeout": 3}
|
||||
"python_execute", {"code": code, "timeout": 3}
|
||||
)
|
||||
print(f"Python execution result: {python_result.content}")
|
||||
|
||||
@ -83,24 +88,20 @@ print(f"Calculation result: {result}")
|
||||
"file_saver",
|
||||
{
|
||||
"content": "This is a test file content saved through MCP",
|
||||
"file_path": "mcp_test_file.txt"
|
||||
}
|
||||
"file_path": "mcp_test_file.txt",
|
||||
},
|
||||
)
|
||||
print(f"File save result: {file_result.content}")
|
||||
|
||||
print("\nExample 4: Browser Usage")
|
||||
# Navigate to webpage
|
||||
browser_result = await self.session.call_tool(
|
||||
"browser_use",
|
||||
{"action": "navigate", "url": "https://www.example.com"}
|
||||
"browser_use", {"action": "navigate", "url": "https://www.example.com"}
|
||||
)
|
||||
print(f"Browser navigation result: {browser_result.content}")
|
||||
|
||||
# Get browser state
|
||||
state_result = await self.session.call_tool(
|
||||
"get_browser_state",
|
||||
{}
|
||||
)
|
||||
state_result = await self.session.call_tool("get_browser_state", {})
|
||||
print(f"Browser state: {state_result.content}")
|
||||
|
||||
except Exception as e:
|
||||
@ -110,13 +111,15 @@ print(f"Calculation result: {result}")
|
||||
"""Run an interactive chat loop for testing tools"""
|
||||
print("\nOpenManus MCP Client Started!")
|
||||
print("Type your commands or 'quit' to exit.")
|
||||
print("Available commands: google_search, python_execute, file_saver, browser_use, get_browser_state")
|
||||
print(
|
||||
"Available commands: google_search, python_execute, file_saver, browser_use, get_browser_state"
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
command = input("\nCommand: ").strip()
|
||||
|
||||
if command.lower() == 'quit':
|
||||
if command.lower() == "quit":
|
||||
break
|
||||
|
||||
# Parse command and parameters
|
||||
@ -130,7 +133,9 @@ print(f"Calculation result: {result}")
|
||||
try:
|
||||
tool_args = eval(parts[1]) # Convert string to dict
|
||||
except:
|
||||
print("Invalid arguments format. Please provide a valid Python dictionary.")
|
||||
print(
|
||||
"Invalid arguments format. Please provide a valid Python dictionary."
|
||||
)
|
||||
continue
|
||||
|
||||
result = await self.session.call_tool(tool_name, tool_args)
|
||||
@ -146,6 +151,7 @@ print(f"Calculation result: {result}")
|
||||
await self.exit_stack.aclose()
|
||||
print("\nClosed MCP client connection")
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main entry point"""
|
||||
import sys
|
||||
@ -170,5 +176,6 @@ async def main():
|
||||
finally:
|
||||
await client.cleanup()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
@ -1,11 +1,13 @@
|
||||
from typing import Optional
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import argparse
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
|
||||
# Add current directory to Python path
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@ -15,18 +17,18 @@ sys.path.insert(0, current_dir)
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
logger = logging.getLogger("mcp-server")
|
||||
|
||||
# Import OpenManus tools
|
||||
from app.tool.browser_use_tool import BrowserUseTool
|
||||
from app.tool.file_saver import FileSaver
|
||||
from app.tool.google_search import GoogleSearch
|
||||
from app.tool.python_execute import PythonExecute
|
||||
from app.tool.file_saver import FileSaver
|
||||
from app.tool.terminate import Terminate
|
||||
|
||||
|
||||
# Initialize FastMCP server
|
||||
openmanus = FastMCP("openmanus")
|
||||
|
||||
@ -37,6 +39,7 @@ python_execute_tool = PythonExecute()
|
||||
file_saver_tool = FileSaver()
|
||||
terminate_tool = Terminate()
|
||||
|
||||
|
||||
# Browser tool
|
||||
@openmanus.tool()
|
||||
async def browser_use(
|
||||
@ -79,10 +82,11 @@ async def browser_use(
|
||||
text=text,
|
||||
script=script,
|
||||
scroll_amount=scroll_amount,
|
||||
tab_id=tab_id
|
||||
tab_id=tab_id,
|
||||
)
|
||||
return json.dumps(result.model_dump())
|
||||
|
||||
|
||||
@openmanus.tool()
|
||||
async def get_browser_state() -> str:
|
||||
"""Get current browser state, including URL, title, tabs and interactive elements."""
|
||||
@ -90,6 +94,7 @@ async def get_browser_state() -> str:
|
||||
result = await browser_tool.get_current_state()
|
||||
return json.dumps(result.model_dump())
|
||||
|
||||
|
||||
# Google search tool
|
||||
@openmanus.tool()
|
||||
async def google_search(query: str, num_results: int = 10) -> str:
|
||||
@ -103,6 +108,7 @@ async def google_search(query: str, num_results: int = 10) -> str:
|
||||
results = await google_search_tool.execute(query=query, num_results=num_results)
|
||||
return json.dumps(results)
|
||||
|
||||
|
||||
# Python execution tool
|
||||
@openmanus.tool()
|
||||
async def python_execute(code: str, timeout: int = 5) -> str:
|
||||
@ -116,6 +122,7 @@ async def python_execute(code: str, timeout: int = 5) -> str:
|
||||
result = await python_execute_tool.execute(code=code, timeout=timeout)
|
||||
return json.dumps(result)
|
||||
|
||||
|
||||
# File saver tool
|
||||
@openmanus.tool()
|
||||
async def file_saver(content: str, file_path: str, mode: str = "w") -> str:
|
||||
@ -127,9 +134,12 @@ async def file_saver(content: str, file_path: str, mode: str = "w") -> str:
|
||||
mode: File open mode (default is 'w')
|
||||
"""
|
||||
logger.info(f"Saving file: {file_path}")
|
||||
result = await file_saver_tool.execute(content=content, file_path=file_path, mode=mode)
|
||||
result = await file_saver_tool.execute(
|
||||
content=content, file_path=file_path, mode=mode
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
# Terminate tool
|
||||
@openmanus.tool()
|
||||
async def terminate(status: str) -> str:
|
||||
@ -142,16 +152,21 @@ async def terminate(status: str) -> str:
|
||||
result = await terminate_tool.execute(status=status)
|
||||
return result
|
||||
|
||||
|
||||
# Clean up resources
|
||||
async def cleanup():
|
||||
"""Clean up all tool resources"""
|
||||
logger.info("Cleaning up resources")
|
||||
await browser_tool.cleanup()
|
||||
|
||||
|
||||
# Register cleanup function
|
||||
import atexit
|
||||
|
||||
|
||||
atexit.register(lambda: asyncio.run(cleanup()))
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""Parse command line arguments"""
|
||||
parser = argparse.ArgumentParser(description="OpenManus MCP Server")
|
||||
@ -159,21 +174,17 @@ def parse_args():
|
||||
"--transport",
|
||||
choices=["stdio", "http"],
|
||||
default="stdio",
|
||||
help="Communication method: stdio or http (default: stdio)"
|
||||
help="Communication method: stdio or http (default: stdio)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
default="127.0.0.1",
|
||||
help="HTTP server host (default: 127.0.0.1)"
|
||||
"--host", default="127.0.0.1", help="HTTP server host (default: 127.0.0.1)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--port",
|
||||
type=int,
|
||||
default=8000,
|
||||
help="HTTP server port (default: 8000)"
|
||||
"--port", type=int, default=8000, help="HTTP server port (default: 8000)"
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user