CoolFace
Apppublic

creativesar/taskflow

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes
mcp_server.py352 linesDownload Raw Back to root
1"""2MCP Server Implementation3Phase III: AI Chatbot - MCP Tools for Task Management4 5This module implements the MCP server with 5 tools:6- add_task: Create a new task7- list_tasks: Retrieve tasks from user's list8- complete_task: Mark a task as complete9- delete_task: Remove a task from the list10- update_task: Modify task title or description11"""12 13from typing import Optional, List, Dict, Any14from mcp.server import Server15from mcp.types import Tool, TextContent16import json17from sqlmodel.ext.asyncio.session import AsyncSession18 19# Import database and service functions20from db import get_session, engine21from services import task_service22 23# Initialize MCP server24mcp_server = Server("todo-server")25 26 27def get_mcp_tools() -> List[Tool]:28    """29    Returns the list of all MCP tools available to the agent.30 31    Returns:32        List of Tool objects that can be used by OpenAI Agents SDK33    """34    tools = [35        Tool(36            name="add_task",37            description="Create a new task for the user",38            inputSchema={39                "type": "object",40                "properties": {41                    "user_id": {42                        "type": "string",43                        "description": "The user ID who owns the task"44                    },45                    "title": {46                        "type": "string",47                        "description": "Task title (1-200 characters)"48                    },49                    "description": {50                        "type": "string",51                        "description": "Optional task description (0-1000 characters)"52                    }53                },54                "required": ["user_id", "title"]55            }56        ),57        Tool(58            name="list_tasks",59            description="Retrieve tasks from the user's list",60            inputSchema={61                "type": "object",62                "properties": {63                    "user_id": {64                        "type": "string",65                        "description": "The user ID whose tasks to retrieve"66                    },67                    "status": {68                        "type": "string",69                        "enum": ["all", "pending", "completed"],70                        "description": "Filter tasks by status (default: all)"71                    }72                },73                "required": ["user_id"]74            }75        ),76        Tool(77            name="complete_task",78            description="Mark a task as complete or toggle completion status",79            inputSchema={80                "type": "object",81                "properties": {82                    "user_id": {83                        "type": "string",84                        "description": "The user ID who owns the task"85                    },86                    "task_id": {87                        "type": "integer",88                        "description": "The ID of the task to complete"89                    }90                },91                "required": ["user_id", "task_id"]92            }93        ),94        Tool(95            name="delete_task",96            description="Remove a task from the list",97            inputSchema={98                "type": "object",99                "properties": {100                    "user_id": {101                        "type": "string",102                        "description": "The user ID who owns the task"103                    },104                    "task_id": {105                        "type": "integer",106                        "description": "The ID of the task to delete"107                    }108                },109                "required": ["user_id", "task_id"]110            }111        ),112        Tool(113            name="update_task",114            description="Modify task title or description",115            inputSchema={116                "type": "object",117                "properties": {118                    "user_id": {119                        "type": "string",120                        "description": "The user ID who owns the task"121                    },122                    "task_id": {123                        "type": "integer",124                        "description": "The ID of the task to update"125                    },126                    "title": {127                        "type": "string",128                        "description": "New task title (1-200 characters)"129                    },130                    "description": {131                        "type": "string",132                        "description": "New task description (0-1000 characters)"133                    }134                },135                "required": ["user_id", "task_id"]136            }137        )138    ]139    return tools140 141 142# MCP Tool Implementations (T-306 to T-310)143 144async def add_task(user_id: str, title: str, description: Optional[str] = None) -> Dict[str, Any]:145    """146    Create a new task for the user.147 148    Args:149        user_id: The user ID who owns the task150        title: Task title (1-200 characters)151        description: Optional task description (0-1000 characters)152 153    Returns:154        Dict with task_id, status, and title155 156    Raises:157        ValueError: If validation fails158    """159    # Validate title160    if not title or len(title) < 1 or len(title) > 200:161        raise ValueError("Title must be 1-200 characters")162 163    # Validate description164    if description and len(description) > 1000:165        raise ValueError("Description cannot exceed 1000 characters")166 167    # Create task in database168    async with AsyncSession(engine) as session:169        task = await task_service.create_task(session, user_id, title, description)170 171        return {172            "task_id": task.id,173            "status": "created",174            "title": task.title175        }176 177 178async def list_tasks(user_id: str, status: str = "all") -> List[Dict[str, Any]]:179    """180    Retrieve tasks from the user's list.181 182    Args:183        user_id: The user ID whose tasks to retrieve184        status: Filter by status ("all", "pending", "completed")185 186    Returns:187        List of task dictionaries188 189    Raises:190        ValueError: If status is invalid191    """192    # Validate status193    if status not in ["all", "pending", "completed"]:194        raise ValueError("Invalid status. Use 'all', 'pending', or 'completed'")195 196    # Query tasks197    async with AsyncSession(engine) as session:198        tasks = await task_service.list_tasks(session, user_id)199 200        # Filter by status201        if status == "pending":202            tasks = [t for t in tasks if not t.completed]203        elif status == "completed":204            tasks = [t for t in tasks if t.completed]205 206        # Convert to dict format207        return [208            {209                "id": task.id,210                "title": task.title,211                "description": task.description,212                "completed": task.completed,213                "created_at": task.created_at.isoformat()214            }215            for task in tasks216        ]217 218 219async def complete_task(user_id: str, task_id: int) -> Dict[str, Any]:220    """221    Mark a task as complete or toggle completion status.222 223    Args:224        user_id: The user ID who owns the task225        task_id: The ID of the task to complete226 227    Returns:228        Dict with task_id, status, and title229 230    Raises:231        ValueError: If task not found or access denied232    """233    async with AsyncSession(engine) as session:234        task = await task_service.toggle_completion(session, task_id, user_id)235 236        if not task:237            raise ValueError("Task not found or access denied")238 239        return {240            "task_id": task.id,241            "status": "completed" if task.completed else "pending",242            "title": task.title243        }244 245 246async def delete_task(user_id: str, task_id: int) -> Dict[str, Any]:247    """248    Remove a task from the list.249 250    Args:251        user_id: The user ID who owns the task252        task_id: The ID of the task to delete253 254    Returns:255        Dict with task_id, status, and title256 257    Raises:258        ValueError: If task not found or access denied259    """260    async with AsyncSession(engine) as session:261        # Get task first to return its title262        task = await task_service.get_task(session, task_id, user_id)263 264        if not task:265            raise ValueError("Task not found or access denied")266 267        title = task.title268 269        # Delete task270        deleted = await task_service.delete_task(session, task_id, user_id)271 272        if not deleted:273            raise ValueError("Failed to delete task")274 275        return {276            "task_id": task_id,277            "status": "deleted",278            "title": title279        }280 281 282async def update_task(283    user_id: str,284    task_id: int,285    title: Optional[str] = None,286    description: Optional[str] = None287) -> Dict[str, Any]:288    """289    Modify task title or description.290 291    Args:292        user_id: The user ID who owns the task293        task_id: The ID of the task to update294        title: New task title (1-200 characters)295        description: New task description (0-1000 characters)296 297    Returns:298        Dict with task_id, status, and title299 300    Raises:301        ValueError: If validation fails or task not found302    """303    # Validate title if provided304    if title and (len(title) < 1 or len(title) > 200):305        raise ValueError("Title must be 1-200 characters")306 307    # Validate description if provided308    if description and len(description) > 1000:309        raise ValueError("Description cannot exceed 1000 characters")310 311    async with AsyncSession(engine) as session:312        # Get existing task313        task = await task_service.get_task(session, task_id, user_id)314 315        if not task:316            raise ValueError("Task not found or access denied")317 318        # Use existing values if not provided319        new_title = title if title else task.title320        new_description = description if description is not None else task.description321 322        # Update task323        updated_task = await task_service.update_task(324            session, task_id, user_id, new_title, new_description325        )326 327        if not updated_task:328            raise ValueError("Failed to update task")329 330        return {331            "task_id": updated_task.id,332            "status": "updated",333            "title": updated_task.title334        }335 336 337# Verify imports work correctly338if __name__ == "__main__":339    print("[OK] MCP SDK imported successfully")340    print(f"[OK] MCP server '{mcp_server.name}' initialized")341    tools = get_mcp_tools()342    print(f"[OK] {len(tools)} MCP tools defined:")343    for tool in tools:344        print(f"     - {tool.name}: {tool.description}")345    print("\n[OK] All 5 MCP tool implementations completed:")346    print("     - add_task: Create new tasks")347    print("     - list_tasks: Retrieve tasks with filtering")348    print("     - complete_task: Toggle task completion")349    print("     - delete_task: Remove tasks")350    print("     - update_task: Modify task details")351    print("\nMCP server is ready for integration with OpenAI Agents SDK.")352