Files
moss-ai/mcp/didatodolist-mcp/tools/project_tools.py
雷雨 8635b84b2d init
2025-12-15 22:05:56 +08:00

280 lines
8.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
项目相关MCP工具
"""
from typing import Dict, List, Optional, Any
from fastmcp import FastMCP
from .adapter import adapter, APIError
# --- 模块级核心逻辑函数 ---
def get_projects_logic() -> List[Dict[str, Any]]:
"""
获取所有项目列表 (逻辑部分)
Returns:
项目列表 (包含 id, name, color, sortOrder, sortType, modifiedTime)
"""
projects = adapter.list_projects()
# 直接返回官方结构的精简版
result: List[Dict[str, Any]] = []
for p in projects:
result.append({k: v for k, v in p.items() if v is not None})
return result
def create_project_logic(
name: str,
color: Optional[str] = None,
view_mode: Optional[str] = None,
kind: Optional[str] = None,
sort_order: Optional[int] = None
) -> Dict[str, Any]:
"""
创建新项目 (逻辑部分)
Args:
name: 项目名称
color: 项目颜色,如 "#FF0000" 表示红色
Returns:
创建的项目信息 (API 原始响应)
"""
payload = {"name": name, "color": color}
if view_mode is not None:
payload["viewMode"] = view_mode
if kind is not None:
payload["kind"] = kind
if sort_order is not None:
payload["sortOrder"] = sort_order
payload = {k: v for k, v in payload.items() if v is not None}
return adapter.create_project(**payload)
def update_project_logic(
project_id_or_name: str,
name: Optional[str] = None,
color: Optional[str] = None,
view_mode: Optional[str] = None,
kind: Optional[str] = None,
sort_order: Optional[int] = None
) -> Dict[str, Any]:
"""
更新项目信息 (逻辑部分)
Args:
project_id_or_name: 项目ID或项目名称
name: 新项目名称
color: 新项目颜色
Returns:
更新操作的结果字典 (包含 success, info, data)
"""
# 获取项目信息
projects = get_projects_logic()
# 查找项目
project = None
project_id = None
# 先尝试按ID查找
for p in projects:
if p.get('id') == project_id_or_name:
project = p
project_id = p.get('id')
break
# 如果没找到,按名称查找
if not project:
for p in projects:
if p.get('name') == project_id_or_name:
project = p
project_id = p.get('id')
break
if not project or not project_id:
return {
"success": False,
"info": f"未找到ID或名称为 '{project_id_or_name}' 的项目",
"data": None
}
try:
# 准备更新数据
update_data = {
"id": project_id,
"name": name if name is not None else project.get('name'),
"color": color if color is not None else project.get('color')
}
if view_mode is not None:
update_data["viewMode"] = view_mode
if kind is not None:
update_data["kind"] = kind
if sort_order is not None:
update_data["sortOrder"] = sort_order
# 移除 name 和 color 为 None 的情况,避免 API 报错
update_data = {k:v for k,v in update_data.items() if v is not None}
# 发送更新请求
response = adapter.update_project(project_id, name=name, color=color)
updated_project_data = response if isinstance(response, dict) else {**update_data, "id": project_id}
updated_project_data['id'] = project_id # 确保 ID 在返回数据中
return {
"success": True,
"info": "项目更新成功",
"data": updated_project_data
}
except Exception as e:
# 更新项目失败禁用print避免干扰JSONRPC
pass
return {
"success": False,
"info": f"更新项目失败: {str(e)}",
"data": None
}
def delete_project_logic(project_id_or_name: str) -> Dict[str, Any]:
"""
删除项目 (逻辑部分)
Args:
project_id_or_name: 项目ID或项目名称
Returns:
删除操作的响应字典 (包含 success, info, data)
"""
# 获取项目信息
projects = get_projects_logic()
# 查找项目
project = None
project_id = None
# 先尝试按ID查找
for p in projects:
if p.get('id') == project_id_or_name:
project = p
project_id = p.get('id')
break
# 如果没找到,按名称查找
if not project:
for p in projects:
if p.get('name') == project_id_or_name:
project = p
project_id = p.get('id')
break
if not project or not project_id:
return {
"success": False,
"info": f"未找到ID或名称为 '{project_id_or_name}' 的项目",
"data": None
}
try:
# 发送删除请求
# 滴答清单删除项目通常不需要请求体直接调用DELETE方法
adapter.delete_project(project_id)
return {
"success": True,
"info": f"成功删除项目 '{project.get('name')}'",
"data": project # 返回被删除项目的信息
}
except Exception as e:
# 删除项目失败禁用print避免干扰JSONRPC
pass
return {
"success": False,
"info": f"删除项目失败: {str(e)}",
"data": None
}
# --- MCP工具注册 ---
def register_project_tools(server: FastMCP, auth_info: Dict[str, Any]):
"""
注册项目相关工具到MCP服务器
Args:
server: MCP服务器实例
auth_info: 认证信息字典包含token或email/password
"""
# 适配层按需初始化,无需在此显式初始化
@server.tool()
def get_projects() -> List[Dict[str, Any]]:
"""
获取所有项目列表
(调用模块级逻辑函数)
Returns:
项目列表
"""
return get_projects_logic()
@server.tool()
def create_project(
name: str,
color: Optional[str] = None,
view_mode: Optional[str] = None,
kind: Optional[str] = None,
sort_order: Optional[int] = None
) -> Dict[str, Any]:
"""
创建新项目
(调用模块级逻辑函数)
Args:
name: 项目名称
color: 项目颜色,如 "#FF0000" 表示红色
Returns:
创建的项目信息 (API 原始响应)
"""
return create_project_logic(name=name, color=color, view_mode=view_mode, kind=kind, sort_order=sort_order)
@server.tool()
def update_project(
project_id_or_name: str,
name: Optional[str] = None,
color: Optional[str] = None,
view_mode: Optional[str] = None,
kind: Optional[str] = None,
sort_order: Optional[int] = None
) -> Dict[str, Any]:
"""
更新项目信息
(调用模块级逻辑函数)
Args:
project_id_or_name: 项目ID或项目名称
name: 新项目名称
color: 新项目颜色
Returns:
更新操作的结果字典 (包含 success, info, data)
"""
return update_project_logic(project_id_or_name=project_id_or_name, name=name, color=color, view_mode=view_mode, kind=kind, sort_order=sort_order)
@server.tool()
def delete_project(project_id_or_name: str) -> Dict[str, Any]:
"""
删除项目
(调用模块级逻辑函数)
Args:
project_id_or_name: 项目ID或项目名称
Returns:
删除操作的响应字典 (包含 success, info, data)
"""
return delete_project_logic(project_id_or_name=project_id_or_name)
# 导出可供外部引用的函数
__all__ = [
'get_projects_logic',
'create_project_logic',
'update_project_logic',
'delete_project_logic',
'register_project_tools'
]