"""
README工具模块
提供README文档生成相关工具。
"""
from typing import Optional, List
from pathlib import Path
from mcp.server.fastmcp import FastMCP
from pydantic import BaseModel, Field
from middleware.logging import log_performance
from middleware.error_handler import handle_errors
from services.document_service import DocumentService
from data_access.file_system import FileSystemInterface
from data_access.cache import CacheError
class GenerateReadmeInput(BaseModel):
"""生成README输入模型"""
folder_path: str = Field(..., description="要生成README的文件夹路径")
template_name: str = Field(default="simple", description="使用的模板名称")
force_update: bool = Field(default=False, description="是否强制更新已存在的README")
include_hidden: bool = Field(default=False, description="是否包含隐藏文件")
def register_readme_tools(
mcp_server: FastMCP,
document_service: DocumentService,
file_system: FileSystemInterface
):
"""
注册README相关工具
Args:
mcp_server: FastMCP服务器实例
document_service: 文档服务实例
file_system: 文件系统接口实例
"""
@mcp_server.tool()
@log_performance("generate_readme")
@handle_errors("generate_readme")
async def folder_docs_generate_readme(
folder_path: str,
template_name: str = "simple",
force_update: bool = False,
include_hidden: bool = False
) -> dict:
"""
生成README文档
Args:
folder_path: 要生成README的文件夹路径
template_name: 使用的模板名称
force_update: 是否强制更新已存在的README
include_hidden: 是否包含隐藏文件
Returns:
生成结果
"""
try:
# 验证路径
is_valid, error_msg = await file_system.validate_path(folder_path)
if not is_valid:
return {
"success": False,
"error": f"路径验证失败: {error_msg}"
}
# 生成README
result = await document_service.generate_readme(
folder_path=folder_path,
template_name=template_name,
force_update=force_update,
include_hidden=include_hidden
)
return result
except (RuntimeError, ValueError) as e:
return {
"success": False,
"error": f"生成README失败: {str(e)}"
}
@mcp_server.tool()
@log_performance("preview_readme")
@handle_errors("preview_readme")
async def folder_docs_preview_readme(
folder_path: str,
template_name: str = "simple",
include_hidden: bool = False
) -> dict:
"""
预览README内容
Args:
folder_path: 要生成README的文件夹路径
template_name: 使用的模板名称
include_hidden: 是否包含隐藏文件
Returns:
预览结果
"""
try:
# 验证路径
is_valid, error_msg = await file_system.validate_path(folder_path)
if not is_valid:
return {
"success": False,
"error": f"路径验证失败: {error_msg}"
}
# 预览README
result = await document_service.preview_readme(
folder_path=folder_path,
template_name=template_name,
include_hidden=include_hidden
)
return result
except (RuntimeError, ValueError) as e:
return {
"success": False,
"error": f"预览README失败: {str(e)}"
}
@mcp_server.tool()
@log_performance("check_readme_exists")
@handle_errors("check_readme_exists")
async def folder_docs_check_readme_exists(folder_path: str) -> dict:
"""
检查README是否存在
Args:
folder_path: 要检查的文件夹路径
Returns:
检查结果
"""
try:
# 验证路径
is_valid, error_msg = await file_system.validate_path(folder_path)
if not is_valid:
return {
"success": False,
"error": f"路径验证失败: {error_msg}"
}
# 检查README文件
readme_paths = [
Path(folder_path) / "README.md",
Path(folder_path) / "readme.md",
Path(folder_path) / "README.txt"
]
existing_readmes = []
for readme_path in readme_paths:
if readme_path.exists():
existing_readmes.append({
"path": str(readme_path),
"size": readme_path.stat().st_size,
"modified": readme_path.stat().st_mtime
})
return {
"success": True,
"exists": len(existing_readmes) > 0,
"readme_files": existing_readmes,
"folder_path": folder_path
}
except (RuntimeError, ValueError) as e:
return {
"success": False,
"error": f"检查README失败: {str(e)}"
}