Files
dinlo 017135fe0e Initial commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:45:22 +08:00

142 lines
5.4 KiB
Python

import os
import sys
import json
import asyncio
import platform
import subprocess
from typing import List, Dict, Any
from mcp.types import Tool
# --- ОПРЕДЕЛЕНИЕ ИНСТРУМЕНТОВ ---
def get_tool_definitions() -> List[Tool]:
return [
Tool(
name="run_script",
description="Запускает Python скрипт в указанной директории.",
inputSchema={
"type": "object",
"properties": {
"script_path": {"type": "string", "description": "Путь к скрипту (например, main.py)"},
"working_dir": {"type": "string", "description": "Рабочая директория"}
},
"required": ["script_path"]
}
),
Tool(
name="install_package",
description="Устанавливает пакет через pip.",
inputSchema={
"type": "object",
"properties": {
"package_name": {"type": "string", "description": "Имя пакета"},
"working_dir": {"type": "string", "description": "Директория проекта (опционально)"}
},
"required": ["package_name"]
}
),
Tool(
name="list_files",
description="Выводит список файлов и папок.",
inputSchema={
"type": "object",
"properties": {
"path": {"type": "string", "description": "Путь к папке"}
},
"required": ["path"]
}
),
Tool(
name="read_file",
description="Читает содержимое текстового файла.",
inputSchema={
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Путь к файлу"}
},
"required": ["file_path"]
}
),
Tool(
name="get_env_info",
description="Информация о системе и Python окружении.",
inputSchema={"type": "object", "properties": {}}
)
]
# --- ЛОГИКА ВЫПОЛНЕНИЯ ---
async def execute_tool(name: str, arguments: Dict[str, Any]) -> str:
"""Маршрутизатор вызовов."""
if name == "run_script":
return await _run_script(arguments.get("script_path"), arguments.get("working_dir"))
elif name == "install_package":
return await _install_package(arguments.get("package_name"), arguments.get("working_dir"))
elif name == "list_files":
return await _list_files(arguments.get("path", "."))
elif name == "read_file":
return await _read_file(arguments.get("file_path"))
elif name == "get_env_info":
return await _get_env_info()
else:
return f"Ошибка: Инструмент '{name}' не найден."
# --- ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ---
async def _run_command(cmd: List[str], cwd: str = None) -> str:
"""Асинхронный запуск команды."""
try:
process = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd=cwd
)
stdout, stderr = await process.communicate()
result = f"STDOUT:\n{stdout.decode('utf-8', errors='replace')}"
if stderr:
result += f"\nSTDERR:\n{stderr.decode('utf-8', errors='replace')}"
if process.returncode != 0:
result += f"\n[Код завершения: {process.returncode}]"
return result
except Exception as e:
return f"Ошибка выполнения команды: {e}"
async def _run_script(script_path: str, working_dir: str = None) -> str:
if not working_dir:
working_dir = os.path.dirname(script_path) or os.getcwd()
return await _run_command([sys.executable, script_path], cwd=working_dir)
async def _install_package(package_name: str, working_dir: str = None) -> str:
cmd = [sys.executable, "-m", "pip", "install", package_name]
return await _run_command(cmd, cwd=working_dir)
async def _list_files(path: str) -> str:
try:
if not os.path.exists(path):
return f"Путь не найден: {path}"
items = os.listdir(path)
files = [i for i in items if os.path.isfile(os.path.join(path, i))]
dirs = [i + "/" for i in items if os.path.isdir(os.path.join(path, i))]
return "Папки:\n" + "\n".join(sorted(dirs)) + "\n\nФайлы:\n" + "\n".join(sorted(files))
except Exception as e:
return f"Ошибка чтения: {e}"
async def _read_file(file_path: str) -> str:
try:
if not os.path.exists(file_path):
return f"Файл не найден: {file_path}"
with open(file_path, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
return f"Ошибка чтения: {e}"
async def _get_env_info() -> str:
info = {
"os": platform.system(),
"python": platform.python_version(),
"cwd": os.getcwd()
}
return json.dumps(info, indent=2, ensure_ascii=False)