#!/usr/bin/env python3
"""
MCP server for: Create a simple test MCP with a single ping tool that returns pong
Generated by KEN-MCP on 2025-06-27

TODO: Claude, please customize this MCP server based on these requirements:
Create a simple test MCP with a single ping tool that returns pong
Analysis Results:
- Domain: general
- Primary actions: create, validate
- Key entities: 
- Operations: filtering

Instructions:
1. Rename the placeholder tools to match the actual functionality needed
2. Update tool descriptions and parameters based on requirements
3. Implement the actual logic in each tool function
4. Add/remove tools, resources, and prompts as needed
5. Update dependencies in pyproject.toml if additional packages are required

IMPORTANT: If the MCP fails to load in Claude:
- Run: python diagnose.py to check for common issues
- Never use print() statements - use logger.info() instead
- Ensure all output goes to stderr, not stdout
"""

from fastmcp import FastMCP, Context
from fastmcp.exceptions import ToolError
from typing import Dict, List, Any, Optional
from pathlib import Path
import json
import os
import sys
import logging

# CRITICAL: Configure logging to use stderr ONLY - stdout is reserved for MCP protocol
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    stream=sys.stderr  # All logs MUST go to stderr, never stdout!
)
logger = logging.getLogger(__name__)

# Initialize the MCP server with clean stdout (no redirection needed)
mcp = FastMCP(
    name="test-v357-mcp",
    instructions="""
    MCP server for: Create a simple test MCP with a single ping tool that returns pong
    
    Original Requirements:
    Create a simple test MCP with a single ping tool that returns pong
Analysis Results:
- Domain: general
- Primary actions: create, validate
- Key entities: 
- Operations: filtering
    
    TODO: Claude should update these instructions based on the actual implementation.
    """
)

# IMPORTANT: NEVER use print() statements!
# Use logger.info(), logger.debug(), etc. instead
# Any output to stdout will break the MCP protocol


@mcp.tool
async def fetch_data(
    ctx: Context,
    data_id: str
) -> Dict[str, Any]:
    """Read operation for data.

Domain: general
Related operations: filtering

TODO: Claude, implement this tool based on the requirements:
Create a simple test MCP with a single ping tool that returns pong

Consider:
- What specific data operations are needed
- What validation should be performed
- What error cases to handle
- What response format makes sense"""
    # Implementation for getting a specific item
    try:
        await ctx.info(f"Fetching item...")
        
        # TODO: Validate ID format
        # TODO: Fetch from data source
        # TODO: Handle not found case
        
        item = {}  # TODO: Fetch actual item
        
        if not item:
            raise ToolError("Item not found")
            
        return {
            "status": "success",
            "data": item
        }
    except Exception as e:
        raise ToolError(f"Failed to get item: {e}")

@mcp.tool
async def process_data(
    ctx: Context,
    input_data: Any,
    options: Optional[Dict[str, Any]]
) -> Dict[str, Any]:
    """Process operation for data.

Domain: general
Related operations: filtering

TODO: Claude, implement this tool based on the requirements:
Create a simple test MCP with a single ping tool that returns pong

Consider:
- What specific data operations are needed
- What validation should be performed
- What error cases to handle
- What response format makes sense"""
    # Implementation for processing/analysis
    try:
        await ctx.info(f"Processing data...")
        
        # TODO: Validate input data
        # TODO: Perform processing/analysis
        # TODO: Return results
        
        results = {}  # TODO: Process actual data
        
        return {
            "status": "success",
            "results": results
        }
    except Exception as e:
        raise ToolError(f"Failed to process: {e}")

@mcp.tool
async def store_result(
    ctx: Context,
    data: Any,
    destination: Any
) -> Dict[str, Any]:
    """Write operation for result.

Domain: general
Related operations: filtering

TODO: Claude, implement this tool based on the requirements:
Create a simple test MCP with a single ping tool that returns pong

Consider:
- What specific result operations are needed
- What validation should be performed
- What error cases to handle
- What response format makes sense"""
    # TODO: Claude, implement this tool based on the requirements in the docstring above
    # Consider:
    # - What data sources or APIs might be needed
    # - What processing or transformations are required
    # - What error cases should be handled
    # - What progress updates would be helpful
    
    try:
        # FastMCP Context Methods Reference:
        # - await ctx.info("message") - Log information
        # - await ctx.report_progress(current, total, "message") - Show progress
        # - await ctx.read_resource("uri") - Read from a resource
        
        await ctx.info(f"Starting store_result...")
        
        # TODO: Add parameter validation
        # Example patterns:
        # if not input_data:
        #     raise ToolError("input_data is required")
        # 
        # if not isinstance(input_data, str):
        #     raise ToolError("input_data must be a string")
        #
        # if len(input_data) > 1000:
        #     raise ToolError("input_data too long (max 1000 chars)")
        
        # TODO: Implement the main functionality
        # Common patterns by use case:
        #
        # For data storage:
        #   storage_dir = Path.home() / ".mcp_data" / "store_result"
        #   storage_dir.mkdir(parents=True, exist_ok=True)
        #
        # For API calls:
        #   import httpx
        #   async with httpx.AsyncClient() as client:
        #       response = await client.get(url)
        #
        # For file processing:
        #   from pathlib import Path
        #   file = Path(file_path)
        #   if not file.exists():
        #       raise ToolError(f"File not found: {file_path}")
        
        # TODO: Add progress updates for long operations
        # await ctx.report_progress(25, 100, "Loading data...")
        # await ctx.report_progress(50, 100, "Processing...")
        # await ctx.report_progress(75, 100, "Finalizing...")
        
        # TODO: Return appropriate result
        # Success pattern:
        # return {
        #     "success": True,
        #     "data": processed_data,
        #     "count": len(results),
        #     "message": "Operation completed successfully"
        # }
        
        result = {
            "status": "not_implemented",
            "message": f"TODO: Implement store_result",
            "tool": "store_result",
            "description": "Write operation for result.\n\nDomain: general\nRelated operations: filtering\n\nTODO: Claude, implement this tool based on the requirements:\nCreate a simple test MCP with a single ping tool that returns pong\n\nConsider:\n- What specific result operations are needed\n- What validation should be performed\n- What error cases to handle\n- What response format makes sense",
            "input": locals()  # Shows all parameters for debugging
        }
        
        await ctx.info(f"store_result completed")
        return result
        
    except Exception as e:
        # Always use ToolError for user-facing errors
        raise ToolError(f"store_result error: {str(e)}")


# Resources - TODO: Claude, implement these based on requirements

@mcp.resource("system://status")
async def resource_status() -> List[Dict[str, Any]]:
    """System status for general - TODO: Implement health checks"""
    # TODO: Implement this resource based on requirements
    # Consider what data should be exposed here
    return [{
        "status": "not_implemented", 
        "message": "TODO: Implement resource for system://status",
        "description": "System status for general - TODO: Implement health checks"
    }]

# Prompts - TODO: Claude, implement these based on requirements

@mcp.prompt
def help(topic: Optional[str]) -> str:
    """Get help with general operations - TODO: Customize for this MCP"""
    # TODO: Implement this prompt based on requirements
    # Return a string that will be converted to a user message
    # or return a PromptMessage object for more control
    return f"TODO: Implement help prompt - {locals()}"


if __name__ == "__main__":
    mcp.run()
