projects.pyโข8.92 kB
"""Project management tools for POEditor MCP server."""
from typing import Any, Dict, List, Optional, Union
from mcp.types import Tool, TextContent, INVALID_PARAMS
from mcp import McpError
from ..poeditor_client import POEditorClient, POEditorError
import json
def get_project_tools() -> List[Tool]:
"""Get all project-related tools."""
return [
Tool(
name="list_projects",
description="List all POEditor projects",
inputSchema={
"type": "object",
"properties": {},
"required": []
}
),
Tool(
name="view_project",
description="View details of a specific project",
inputSchema={
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Project ID"
}
},
"required": ["project_id"]
}
),
Tool(
name="create_project",
description="Create a new project",
inputSchema={
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Project name"
},
"description": {
"type": "string",
"description": "Project description (optional)"
}
},
"required": ["name"]
}
),
Tool(
name="update_project",
description="Update an existing project",
inputSchema={
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Project ID"
},
"name": {
"type": "string",
"description": "New project name (optional)"
},
"description": {
"type": "string",
"description": "New project description (optional)"
}
},
"required": ["project_id"]
}
),
Tool(
name="delete_project",
description="Delete a project",
inputSchema={
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Project ID"
}
},
"required": ["project_id"]
}
)
]
async def handle_list_projects(
client: POEditorClient,
arguments: Dict[str, Any]
) -> List[TextContent]:
"""Handle list_projects tool call."""
try:
projects = await client.list_projects()
# Format the response
if not projects:
return [TextContent(
type="text",
text="No projects found."
)]
output = "**POEditor Projects:**\n\n"
for project in projects:
output += f"**{project.get('name', 'Unnamed')}** (ID: {project.get('id')})\n"
output += f" - Description: {project.get('description', 'No description')}\n"
output += f" - Created: {project.get('created', 'Unknown')}\n"
output += f" - Open: {project.get('open', 'Unknown')}\n"
output += f" - Public: {project.get('public', 'Unknown')}\n"
output += f" - Reference Language: {project.get('reference_language', 'None')}\n\n"
return [TextContent(type="text", text=output)]
except POEditorError as e:
raise McpError(INVALID_PARAMS, f"POEditor API error: {e}")
except Exception as e:
raise McpError(INVALID_PARAMS, f"Unexpected error: {e}")
async def handle_view_project(
client: POEditorClient,
arguments: Dict[str, Any]
) -> List[TextContent]:
"""Handle view_project tool call."""
project_id = arguments.get("project_id")
if not project_id:
raise McpError(INVALID_PARAMS, "project_id is required")
try:
project = await client.view_project(project_id)
output = f"**Project Details: {project.get('name', 'Unnamed')}**\n\n"
output += f"- **ID:** {project.get('id')}\n"
output += f"- **Description:** {project.get('description', 'No description')}\n"
output += f"- **Created:** {project.get('created', 'Unknown')}\n"
output += f"- **Open:** {project.get('open', 'Unknown')}\n"
output += f"- **Public:** {project.get('public', 'Unknown')}\n"
output += f"- **Reference Language:** {project.get('reference_language', 'None')}\n"
output += f"- **Terms:** {project.get('terms', 0)}\n"
# Show languages if available
if 'languages' in project:
languages = project['languages']
output += f"- **Languages:** {len(languages)}\n"
for lang in languages:
percentage = lang.get('percentage', 0)
output += f" - {lang.get('name', 'Unknown')} ({lang.get('code', 'unknown')}): {percentage}% translated\n"
return [TextContent(type="text", text=output)]
except POEditorError as e:
raise McpError(INVALID_PARAMS, f"POEditor API error: {e}")
except Exception as e:
raise McpError(INVALID_PARAMS, f"Unexpected error: {e}")
async def handle_create_project(
client: POEditorClient,
arguments: Dict[str, Any]
) -> List[TextContent]:
"""Handle create_project tool call."""
name = arguments.get("name")
if not name:
raise McpError(INVALID_PARAMS, "name is required")
description = arguments.get("description")
try:
project = await client.create_project(name, description)
output = f"**Project Created Successfully!**\n\n"
output += f"- **Name:** {project.get('name')}\n"
output += f"- **ID:** {project.get('id')}\n"
output += f"- **Description:** {project.get('description', 'No description')}\n"
output += f"- **Created:** {project.get('created', 'Now')}\n"
return [TextContent(type="text", text=output)]
except POEditorError as e:
raise McpError(INVALID_PARAMS, f"POEditor API error: {e}")
except Exception as e:
raise McpError(INVALID_PARAMS, f"Unexpected error: {e}")
async def handle_update_project(
client: POEditorClient,
arguments: Dict[str, Any]
) -> List[TextContent]:
"""Handle update_project tool call."""
project_id = arguments.get("project_id")
if not project_id:
raise McpError(INVALID_PARAMS, "project_id is required")
name = arguments.get("name")
description = arguments.get("description")
if not name and not description:
raise McpError(INVALID_PARAMS, "At least name or description must be provided")
try:
project = await client.update_project(project_id, name, description)
output = f"**Project Updated Successfully!**\n\n"
output += f"- **ID:** {project.get('id')}\n"
output += f"- **Name:** {project.get('name')}\n"
output += f"- **Description:** {project.get('description', 'No description')}\n"
return [TextContent(type="text", text=output)]
except POEditorError as e:
raise McpError(INVALID_PARAMS, f"POEditor API error: {e}")
except Exception as e:
raise McpError(INVALID_PARAMS, f"Unexpected error: {e}")
async def handle_delete_project(
client: POEditorClient,
arguments: Dict[str, Any]
) -> List[TextContent]:
"""Handle delete_project tool call."""
project_id = arguments.get("project_id")
if not project_id:
raise McpError(INVALID_PARAMS, "project_id is required")
try:
success = await client.delete_project(project_id)
if success:
output = f"**Project {project_id} deleted successfully!**"
else:
output = f"**Failed to delete project {project_id}**"
return [TextContent(type="text", text=output)]
except POEditorError as e:
raise McpError(INVALID_PARAMS, f"POEditor API error: {e}")
except Exception as e:
raise McpError(INVALID_PARAMS, f"Unexpected error: {e}")
# Tool handler mapping
PROJECT_HANDLERS = {
"list_projects": handle_list_projects,
"view_project": handle_view_project,
"create_project": handle_create_project,
"update_project": handle_update_project,
"delete_project": handle_delete_project,
}