BladeSzaSza's picture
🥚 Initial DigiPal deployment to HuggingFace Spaces🤖 Generated with [Claude Code](https://claude.ai/code)Co-Authored-By: Claude <[email protected]>
4399e64
raw
history blame
10.2 kB
#!/usr/bin/env python3
"""
CLI tool for DigiPal MCP server.
This module provides a command-line interface for starting and managing
the DigiPal MCP server.
"""
import argparse
import asyncio
import logging
import sys
import tempfile
from pathlib import Path
# Add the project root to the Python path
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
from digipal.core.digipal_core import DigiPalCore
from digipal.storage.storage_manager import StorageManager
from digipal.ai.communication import AICommunication
from digipal.mcp.server import MCPServer
def setup_logging(level: str = "INFO"):
"""Setup logging configuration."""
logging.basicConfig(
level=getattr(logging, level.upper()),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
async def start_server(args):
"""Start the MCP server."""
print("Starting DigiPal MCP Server...")
print(f"Database: {args.database}")
print(f"Assets: {args.assets}")
print(f"Server name: {args.name}")
try:
# Initialize components
storage_manager = StorageManager(args.database, args.assets)
ai_communication = AICommunication()
digipal_core = DigiPalCore(storage_manager, ai_communication)
# Initialize MCP server
mcp_server = MCPServer(digipal_core, args.name)
print("MCP Server initialized successfully!")
print("Available tools:")
print("- get_pet_status: Get current status of a user's DigiPal")
print("- interact_with_pet: Send text message to DigiPal")
print("- apply_care_action: Apply care actions (feeding, training, etc.)")
print("- create_new_pet: Create new DigiPal for a user")
print("- get_pet_statistics: Get comprehensive pet statistics")
print("- trigger_evolution: Manually trigger evolution")
print("- get_available_actions: Get available care actions")
print()
print("Server is ready to accept MCP connections...")
# Start the server
await mcp_server.start_server()
except KeyboardInterrupt:
print("\nShutting down server...")
except Exception as e:
print(f"Error starting server: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
async def demo_mode(args):
"""Run interactive demo of MCP server functionality."""
print("DigiPal MCP Server Demo Mode")
print("=" * 40)
# Use temporary database for demo
with tempfile.NamedTemporaryFile(delete=False, suffix='.db') as f:
temp_db_path = f.name
try:
# Initialize components
print("Initializing DigiPal components...")
storage_manager = StorageManager(temp_db_path, "demo_assets")
ai_communication = AICommunication()
digipal_core = DigiPalCore(storage_manager, ai_communication)
# Initialize MCP server
mcp_server = MCPServer(digipal_core, "demo-server")
# Create demo user
demo_user = "demo_user"
storage_manager.create_user(demo_user, "Demo User")
mcp_server.authenticate_user(demo_user)
print(f"✓ Demo user '{demo_user}' created and authenticated")
while True:
print("\nAvailable MCP Tools:")
print("1. create_new_pet - Create a new DigiPal")
print("2. get_pet_status - Get pet status")
print("3. interact_with_pet - Send message to pet")
print("4. apply_care_action - Apply care action")
print("5. get_pet_statistics - Get detailed statistics")
print("6. trigger_evolution - Force evolution")
print("7. get_available_actions - List care actions")
print("0. Exit demo")
choice = input("\nSelect tool (0-7): ").strip()
if choice == "0":
break
elif choice == "1":
await demo_create_pet(mcp_server, demo_user)
elif choice == "2":
await demo_get_status(mcp_server, demo_user)
elif choice == "3":
await demo_interact(mcp_server, demo_user)
elif choice == "4":
await demo_care_action(mcp_server, demo_user)
elif choice == "5":
await demo_statistics(mcp_server, demo_user)
elif choice == "6":
await demo_evolution(mcp_server, demo_user)
elif choice == "7":
await demo_available_actions(mcp_server, demo_user)
else:
print("Invalid choice. Please select 0-7.")
print("\nDemo completed. Cleaning up...")
mcp_server.shutdown()
except KeyboardInterrupt:
print("\nDemo interrupted by user.")
except Exception as e:
print(f"Demo error: {e}")
import traceback
traceback.print_exc()
finally:
# Cleanup
import os
if os.path.exists(temp_db_path):
os.unlink(temp_db_path)
async def demo_create_pet(mcp_server, user_id):
"""Demo create_new_pet tool."""
print("\n--- Create New Pet ---")
# Check if pet already exists
existing = await mcp_server._handle_get_pet_status({"user_id": user_id})
if not existing.isError:
print("User already has a pet. Cannot create another.")
return
egg_type = input("Enter egg type (red/blue/green): ").strip().lower()
if egg_type not in ["red", "blue", "green"]:
print("Invalid egg type. Using 'red'.")
egg_type = "red"
name = input("Enter pet name (or press Enter for 'DigiPal'): ").strip()
if not name:
name = "DigiPal"
result = await mcp_server._handle_create_new_pet({
"user_id": user_id,
"egg_type": egg_type,
"name": name
})
print(f"\nResult: {result.content[0].text}")
async def demo_get_status(mcp_server, user_id):
"""Demo get_pet_status tool."""
print("\n--- Get Pet Status ---")
result = await mcp_server._handle_get_pet_status({"user_id": user_id})
print(f"\nResult:\n{result.content[0].text}")
async def demo_interact(mcp_server, user_id):
"""Demo interact_with_pet tool."""
print("\n--- Interact with Pet ---")
message = input("Enter message to send to pet: ").strip()
if not message:
message = "Hello!"
result = await mcp_server._handle_interact_with_pet({
"user_id": user_id,
"message": message
})
print(f"\nResult: {result.content[0].text}")
async def demo_care_action(mcp_server, user_id):
"""Demo apply_care_action tool."""
print("\n--- Apply Care Action ---")
# Show available actions first
actions_result = await mcp_server._handle_get_available_actions({"user_id": user_id})
if not actions_result.isError:
print("Available actions:")
print(actions_result.content[0].text)
action = input("\nEnter care action: ").strip().lower()
if not action:
action = "meat"
result = await mcp_server._handle_apply_care_action({
"user_id": user_id,
"action": action
})
print(f"\nResult: {result.content[0].text}")
async def demo_statistics(mcp_server, user_id):
"""Demo get_pet_statistics tool."""
print("\n--- Get Pet Statistics ---")
result = await mcp_server._handle_get_pet_statistics({"user_id": user_id})
print(f"\nResult:\n{result.content[0].text}")
async def demo_evolution(mcp_server, user_id):
"""Demo trigger_evolution tool."""
print("\n--- Trigger Evolution ---")
force = input("Force evolution regardless of requirements? (y/n): ").strip().lower()
force_bool = force.startswith('y')
result = await mcp_server._handle_trigger_evolution({
"user_id": user_id,
"force": force_bool
})
print(f"\nResult: {result.content[0].text}")
async def demo_available_actions(mcp_server, user_id):
"""Demo get_available_actions tool."""
print("\n--- Get Available Actions ---")
result = await mcp_server._handle_get_available_actions({"user_id": user_id})
print(f"\nResult:\n{result.content[0].text}")
def main():
"""Main CLI entry point."""
parser = argparse.ArgumentParser(
description="DigiPal MCP Server CLI",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Start MCP server with default settings
python -m digipal.mcp.cli start
# Start with custom database and assets
python -m digipal.mcp.cli start --database /path/to/digipal.db --assets /path/to/assets
# Run interactive demo
python -m digipal.mcp.cli demo
# Start with debug logging
python -m digipal.mcp.cli start --log-level DEBUG
"""
)
parser.add_argument(
"--log-level",
choices=["DEBUG", "INFO", "WARNING", "ERROR"],
default="INFO",
help="Set logging level (default: INFO)"
)
subparsers = parser.add_subparsers(dest="command", help="Available commands")
# Start server command
start_parser = subparsers.add_parser("start", help="Start MCP server")
start_parser.add_argument(
"--database",
default="digipal.db",
help="Path to SQLite database file (default: digipal.db)"
)
start_parser.add_argument(
"--assets",
default="assets",
help="Path to assets directory (default: assets)"
)
start_parser.add_argument(
"--name",
default="digipal-mcp-server",
help="MCP server name (default: digipal-mcp-server)"
)
# Demo command
demo_parser = subparsers.add_parser("demo", help="Run interactive demo")
args = parser.parse_args()
# Setup logging
setup_logging(args.log_level)
if args.command == "start":
asyncio.run(start_server(args))
elif args.command == "demo":
asyncio.run(demo_mode(args))
else:
parser.print_help()
if __name__ == "__main__":
main()