comfortool / server.py
Sandra Sanchez
Adapt script to make first 3 working mcp tools
4f79b3e
"""
Comfortool MCP Server
Provides tools for creating autism-friendly social stories with cultural adaptation
"""
from fastmcp import FastMCP
from openai import OpenAI
import os
from dotenv import load_dotenv
import base64
import io
from PIL import Image
from pathlib import Path
import json
# Load environment variables
load_dotenv()
# Initialize FastMCP server
mcp = FastMCP("comfortool")
# Constants
TEMPLATES_DIR = Path(__file__).resolve().parent / "mcp_server" / "templates"
GENERATED_IMAGES_DIR = Path(__file__).resolve().parent / "generated_images"
GENERATED_IMAGES_DIR.mkdir(exist_ok=True)
# Vibe descriptions for image generation (exported for use in app.py)
VIBE_DESCRIPTIONS = {
"Comic": "comic-style illustration, comic strip format with exactly 4 panels, bold outlines, dynamic poses, speech bubbles, vibrant colors. If there is text, translate it to the selected language with perfect ortography",
"Kawaii": "kawaii-style illustration, pastel colors, cute rounded characters, big eyes.",
"Pictorial": "pictorial illustration, painted with a brush, gentle and calm atmosphere",
"Basic B&W": "black and white illustration, simple lines, no other colors allowed, like a coloring book.Absolutely only use black and white.",
"Cartoon": "cartoon-style illustration, exaggerated features, bright colors, playful mood",
"Soft Pastel": "Only use soft pastel colours, smooth textures, calming feeling"
}
# Valid OpenAI voices for TTS (exported for use in app.py)
VALID_VOICES = {"nova", "shimmer", "echo", "onyx", "fable", "alloy", "ash", "sage", "coral"}
# Initialize OpenAI client
def get_openai_client():
api_key = os.environ.get("OPENAI_API_KEY")
if not api_key:
raise ValueError("OPENAI_API_KEY not found in environment variables")
return OpenAI(api_key=api_key)
# Helper functions (not exposed as tools)
def _adapt_story_impl(
story: str,
culture: str = "default",
age: str = "7",
gender: str = "female",
vibe: str = "Cartoon",
comfort_character: str = "Koala"
) -> str:
"""Internal implementation of adapt_story"""
prompt = (
f"Adapt the following story for an autistic child of age {age}, gender {gender}, from {culture} culture. "
f"Include '{comfort_character}' as a supportive friend, use the style '{vibe}', and make the story concrete, supportive, and easy to understand. "
"Avoid excessive emotion and exclamation marks. "
"Adapt language according to age, simpler sentences for smaller (ages 2 to 4) kids. "
"The absolute max length is 640 characters. "
"Do not mention any info related to format, like pages, panels or scenes. It is just one story. "
"Do not translate. Return only the adapted story in English."
f"\n\nStory:\n{story}"
)
client = get_openai_client()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content.strip()
def _translate_story_impl(
story: str,
language: str = "en",
gender: str = "female"
) -> str:
"""Internal implementation of translate_story"""
if language.lower() == "en":
return story
prompt = (
f"Translate the following story to {language} and the corresponding regional or cultural variant if mentioned. "
f"Use correct grammatical gender and pronouns, adapted to the selected gender of the kid ('{gender}'). "
"If the story mentions an animal or character, translate its name to the most culturally and linguistically appropriate version for the target language and region. "
"For example, if the story mentions 'fox', translate it as 'zorro' for Spanish from Spain. "
"Return only the translated story, using the regional variety requested."
f"\n\nStory:\n{story}"
)
client = get_openai_client()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content.strip()
@mcp.tool()
def adapt_story(
story: str,
culture: str = "default",
age: str = "7",
gender: str = "female",
vibe: str = "Cartoon",
comfort_character: str = "Koala"
) -> str:
"""
Adapts a story for an autistic child based on culture, age, gender, and comfort character.
Args:
story: The original story text to adapt
culture: Cultural context (e.g., 'Latino', 'Roma', 'Muslim', 'default')
age: Child's age (e.g., '7')
gender: Gender identity (e.g., 'boy', 'girl', 'non-binary')
vibe: Illustration style for the story
comfort_character: Supportive character/animal (e.g., 'Koala', 'Robot')
Returns:
The adapted story in English
"""
return _adapt_story_impl(story, culture, age, gender, vibe, comfort_character)
@mcp.tool()
def translate_story(
story: str,
language: str = "en",
gender: str = "female"
) -> str:
"""
Translates a story to the selected language with proper grammatical gender.
Args:
story: The story text to translate
language: Target language (e.g., 'Spanish from Spain', 'en', 'fr')
gender: Gender for grammatical agreement (e.g., 'boy', 'girl', 'non-binary')
Returns:
The translated story
"""
return _translate_story_impl(story, language, gender)
# Helper function to list available scenarios
@mcp.tool()
def list_scenarios() -> list[str]:
"""
Lists all available scenario templates.
Returns:
List of scenario names
"""
return [p.stem.replace("_", " ") for p in TEMPLATES_DIR.glob("*.json")]