Skip to main content
Glama

OpenEdu MCP Server

dictionary_tools.py44.5 kB
""" Dictionary tools for OpenEdu MCP Server. This module provides MCP tool implementations for Dictionary API integration, including educational filtering, vocabulary analysis, and word definition functionality. """ import logging import re from typing import Dict, Any, List, Optional, Union from datetime import datetime import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent)) from tools.base_tool import BaseTool from api.dictionary import DictionaryClient from models.definition import Definition from models.base import GradeLevel, EducationalMetadata, CurriculumStandard from config import Config from services.cache_service import CacheService from services.rate_limiting_service import RateLimitingService from services.usage_service import UsageService from exceptions import ToolError, ValidationError, APIError logger = logging.getLogger(__name__) class DictionaryTool(BaseTool): """Tool for Dictionary API integration with educational features.""" def __init__( self, config: Config, cache_service: CacheService, rate_limiting_service: RateLimitingService, usage_service: UsageService ): """ Initialize Dictionary tool. Args: config: Application configuration cache_service: Cache service instance rate_limiting_service: Rate limiting service instance usage_service: Usage tracking service instance """ super().__init__(config, cache_service, rate_limiting_service, usage_service) self.client = DictionaryClient(config) # Educational filtering configuration self.min_educational_relevance = config.education.content_filters.min_educational_relevance self.enable_age_appropriate = config.education.content_filters.enable_age_appropriate self.enable_curriculum_alignment = config.education.content_filters.enable_curriculum_alignment # Vocabulary complexity thresholds self.complexity_thresholds = { GradeLevel.K_2: 0.3, GradeLevel.GRADES_3_5: 0.5, GradeLevel.GRADES_6_8: 0.7, GradeLevel.GRADES_9_12: 0.85, GradeLevel.COLLEGE: 1.0 } # Subject-specific vocabulary indicators self.subject_indicators = { "science": ["biology", "chemistry", "physics", "scientific", "experiment", "hypothesis"], "mathematics": ["equation", "formula", "theorem", "geometric", "algebraic", "calculus"], "literature": ["narrative", "metaphor", "symbolism", "literary", "poetic", "prose"], "history": ["historical", "ancient", "medieval", "revolution", "civilization", "empire"], "geography": ["geographical", "climate", "terrain", "continental", "oceanic", "topographic"], "social_studies": ["society", "cultural", "political", "economic", "democratic", "citizenship"] } @property def api_name(self) -> str: """Name of the API this tool uses for rate limiting.""" return "dictionary" async def get_word_definition( self, word: str, grade_level: Optional[str] = None, include_pronunciation: bool = True, user_session: Optional[str] = None ) -> Dict[str, Any]: """ Get educational word definition with grade-level filtering. Args: word: Word to define grade_level: Target grade level for appropriate complexity include_pronunciation: Whether to include pronunciation information user_session: User session identifier Returns: Word definition with educational metadata Raises: ValidationError: If word is invalid ToolError: If definition retrieval fails """ async def _get_definition(): # Get comprehensive word data from Dictionary API word_data = await self.client.get_comprehensive_data(word) if not word_data: raise ToolError(f"Word not found: {word}", self.tool_name) # Convert to Definition model with educational enrichment definition = Definition.from_dictionary_api(word_data) # Enrich with educational metadata definition = await self._enrich_educational_metadata( definition, grade_level=grade_level ) # Apply grade-level filtering if specified if grade_level and not definition.is_suitable_for_grade_level(grade_level): # Simplify definitions for lower grade levels definition = self._simplify_for_grade_level(definition, grade_level) # Add pronunciation if requested if include_pronunciation and not definition.has_pronunciation(): try: phonetics = await self.client.get_phonetics(word) if phonetics: definition.phonetic = phonetics.get("text") definition.pronunciation = phonetics.get("audio") except Exception as e: logger.warning(f"Failed to get pronunciation for {word}: {e}") result = definition.to_dict() # Add educational analysis result["vocabulary_analysis"] = self._analyze_vocabulary_complexity(definition) result["educational_recommendations"] = self._generate_educational_recommendations(definition, grade_level) return result return await self.execute_with_monitoring( "get_word_definition", _get_definition, user_session=user_session ) async def get_vocabulary_analysis( self, word: str, context: Optional[str] = None, user_session: Optional[str] = None ) -> Dict[str, Any]: """ Analyze word complexity and educational value. Args: word: Word to analyze context: Optional context for better analysis user_session: User session identifier Returns: Vocabulary analysis with educational insights Raises: ValidationError: If word is invalid ToolError: If analysis fails """ async def _analyze_vocabulary(): # Get word definition word_data = await self.client.get_comprehensive_data(word) if not word_data: raise ToolError(f"Word not found: {word}", self.tool_name) definition = Definition.from_dictionary_api(word_data) definition = await self._enrich_educational_metadata(definition) # Perform comprehensive vocabulary analysis analysis = { "word": word, "complexity_score": definition.get_complexity_score(), "difficulty_level": definition.educational_metadata.difficulty_level, "grade_level_recommendations": [gl.value for gl in self._determine_appropriate_grade_levels(definition)], "subject_classifications": self._classify_by_subject(definition), "vocabulary_tier": self._determine_vocabulary_tier(definition), "learning_objectives": self._generate_learning_objectives(definition), "usage_frequency": self._estimate_usage_frequency(definition), "morphological_analysis": self._analyze_morphology(word), "semantic_relationships": { "synonyms": definition.synonyms[:5], # Limit to top 5 "antonyms": definition.antonyms[:5], "related_words": self._find_related_words(definition) }, "educational_value": self._assess_educational_value(definition, context) } return analysis return await self.execute_with_monitoring( "get_vocabulary_analysis", _analyze_vocabulary, user_session=user_session ) async def get_word_examples( self, word: str, grade_level: Optional[str] = None, subject: Optional[str] = None, user_session: Optional[str] = None ) -> Dict[str, Any]: """ Get educational examples and usage contexts. Args: word: Word to find examples for grade_level: Target grade level for appropriate examples subject: Subject area for context-specific examples user_session: User session identifier Returns: Educational examples with context Raises: ValidationError: If word is invalid ToolError: If example retrieval fails """ async def _get_examples(): # Get examples from Dictionary API examples = await self.client.get_word_examples(word) if not examples: # Generate educational examples if none available examples = self._generate_educational_examples(word, grade_level, subject) # Filter and enhance examples for educational use educational_examples = [] for example in examples: enhanced_example = self._enhance_example_for_education( example, word, grade_level, subject ) if enhanced_example: educational_examples.append(enhanced_example) # Add subject-specific examples if requested if subject: subject_examples = self._generate_subject_specific_examples(word, subject, grade_level) educational_examples.extend(subject_examples) return { "word": word, "examples": educational_examples[:10], # Limit to 10 examples "usage_tips": self._generate_usage_tips(word, grade_level), "common_mistakes": self._identify_common_mistakes(word), "grade_level": grade_level, "subject": subject } return await self.execute_with_monitoring( "get_word_examples", _get_examples, user_session=user_session ) async def get_pronunciation_guide( self, word: str, include_audio: bool = True, user_session: Optional[str] = None ) -> Dict[str, Any]: """ Get phonetic information for language learning. Args: word: Word to get pronunciation for include_audio: Whether to include audio URL user_session: User session identifier Returns: Pronunciation guide with phonetic information Raises: ValidationError: If word is invalid ToolError: If pronunciation retrieval fails """ async def _get_pronunciation(): # Get phonetics from Dictionary API phonetics = await self.client.get_phonetics(word) if not phonetics: raise ToolError(f"Pronunciation not available for: {word}", self.tool_name) # Enhance pronunciation guide for educational use guide = { "word": word, "phonetic_spelling": phonetics.get("text", ""), "audio_url": phonetics.get("audio", "") if include_audio else "", "pronunciation_tips": self._generate_pronunciation_tips(word, phonetics), "syllable_breakdown": self._break_into_syllables(word), "stress_pattern": self._identify_stress_pattern(word, phonetics), "rhyming_words": self._find_rhyming_words(word), "phonetic_rules": self._explain_phonetic_rules(word), "difficulty_level": self._assess_pronunciation_difficulty(word, phonetics) } return guide return await self.execute_with_monitoring( "get_pronunciation_guide", _get_pronunciation, user_session=user_session ) async def get_related_vocabulary( self, word: str, relationship_type: str = "all", grade_level: Optional[str] = None, limit: int = 10, user_session: Optional[str] = None ) -> Dict[str, Any]: """ Get synonyms, antonyms, and related educational terms. Args: word: Base word relationship_type: Type of relationship (synonyms, antonyms, related, all) grade_level: Target grade level for appropriate vocabulary limit: Maximum number of related words user_session: User session identifier Returns: Related vocabulary with educational context Raises: ValidationError: If parameters are invalid ToolError: If vocabulary retrieval fails """ async def _get_related(): # Validate relationship type valid_types = ["synonyms", "antonyms", "related", "all"] if relationship_type not in valid_types: raise ValidationError(f"Invalid relationship type. Must be one of: {valid_types}") # Get word data word_data = await self.client.get_comprehensive_data(word) if not word_data: raise ToolError(f"Word not found: {word}", self.tool_name) definition = Definition.from_dictionary_api(word_data) # Ensure we use the original word parameter, not the API response word related_vocab = { "word": word, # Always use the original query word "base_word": word, # Always use the original query word "api_word": definition.word, # Include the API response word for reference "relationships": {} } # Get synonyms if relationship_type in ["synonyms", "all"]: synonyms = await self._get_educational_synonyms(definition, grade_level, limit) related_vocab["relationships"]["synonyms"] = synonyms # Get antonyms if relationship_type in ["antonyms", "all"]: antonyms = await self._get_educational_antonyms(definition, grade_level, limit) related_vocab["relationships"]["antonyms"] = antonyms # Get related words if relationship_type in ["related", "all"]: related_words = await self._get_educational_related_words(definition, grade_level, limit) related_vocab["relationships"]["related"] = related_words # Add educational context related_vocab["educational_notes"] = self._generate_vocabulary_notes(definition, grade_level) related_vocab["learning_activities"] = self._suggest_vocabulary_activities(definition, grade_level) return related_vocab return await self.execute_with_monitoring( "get_related_vocabulary", _get_related, user_session=user_session ) async def _enrich_educational_metadata( self, definition: Definition, grade_level: Optional[str] = None ) -> Definition: """ Enrich definition with educational metadata. Args: definition: Definition instance to enrich grade_level: Target grade level for relevance scoring Returns: Enriched definition instance """ # Calculate educational relevance score relevance_score = self._calculate_educational_relevance(definition, grade_level) definition.educational_metadata.educational_relevance_score = relevance_score # Analyze vocabulary complexity complexity_analysis = self._analyze_vocabulary_complexity(definition) definition.educational_metadata.difficulty_level = complexity_analysis.get("difficulty_level") # Determine appropriate grade levels grade_levels = self._determine_appropriate_grade_levels(definition) definition.educational_metadata.grade_levels = grade_levels # Classify by subject areas subject_areas = self._classify_by_subject(definition) definition.subject_areas = subject_areas # Analyze curriculum alignment curriculum_alignment = self._analyze_curriculum_alignment(definition) definition.educational_metadata.curriculum_alignment = curriculum_alignment.get("standards", []) return definition def _calculate_educational_relevance( self, definition: Definition, target_grade_level: Optional[str] = None ) -> float: """Calculate educational relevance score for a word definition.""" score = 0.0 # Base score for having multiple definitions (indicates important word) if len(definition.definitions) > 1: score += 0.2 # Score for having examples (helps with understanding) if definition.examples: score += 0.2 # Score for having synonyms/antonyms (vocabulary building) if definition.synonyms or definition.antonyms: score += 0.1 # Score for pronunciation information (language learning) if definition.has_pronunciation(): score += 0.1 # Subject area relevance if definition.subject_areas: score += 0.2 # Grade level appropriateness if target_grade_level and definition.is_suitable_for_grade_level(target_grade_level): score += 0.2 return min(score, 1.0) def _analyze_vocabulary_complexity(self, definition: Definition) -> Dict[str, Any]: """Analyze vocabulary complexity and difficulty.""" word = definition.word complexity_score = definition.get_complexity_score() # Determine difficulty level if complexity_score <= 0.3: difficulty_level = "Elementary" elif complexity_score <= 0.5: difficulty_level = "Intermediate" elif complexity_score <= 0.7: difficulty_level = "Advanced" else: difficulty_level = "Expert" return { "complexity_score": complexity_score, "difficulty_level": difficulty_level, "word_length": len(word), "syllable_count": self._count_syllables(word), "definition_complexity": sum(len(d.split()) for d in definition.definitions) / max(len(definition.definitions), 1), "has_multiple_meanings": len(definition.definitions) > 1, "technical_indicators": self._count_technical_indicators(definition) } def _determine_appropriate_grade_levels(self, definition: Definition) -> List[GradeLevel]: """Determine appropriate grade levels for a word.""" complexity = definition.get_complexity_score() appropriate_levels = [] for grade_level, threshold in self.complexity_thresholds.items(): if complexity <= threshold: appropriate_levels.append(grade_level) # Ensure at least one grade level is included if not appropriate_levels: appropriate_levels = [GradeLevel.COLLEGE] return appropriate_levels def _classify_by_subject(self, definition: Definition) -> List[str]: """Classify word by academic subjects.""" subjects = [] content_text = f"{definition.word} {' '.join(definition.definitions)}".lower() for subject, indicators in self.subject_indicators.items(): if any(indicator in content_text for indicator in indicators): subjects.append(subject) return subjects def _analyze_curriculum_alignment(self, definition: Definition) -> Dict[str, Any]: """Analyze curriculum alignment for the word.""" # This is a simplified implementation # In a real system, this would align with specific curriculum standards subjects = self._classify_by_subject(definition) complexity = definition.get_complexity_score() # Determine relevant curriculum standards based on subjects and complexity standards = [] if any(subj in ["science", "mathematics"] for subj in subjects): standards.append(CurriculumStandard.NGSS) if complexity > 0.3: # Academic vocabulary standards.append(CurriculumStandard.COMMON_CORE) alignment = { "subjects": subjects, "standards": standards, "learning_objectives": self._generate_learning_objectives(definition), "assessment_potential": complexity > 0.3 # Words above basic complexity are good for assessment } return alignment def _simplify_for_grade_level(self, definition: Definition, grade_level: str) -> Definition: """Simplify definitions for lower grade levels.""" if grade_level in ["K-2", "3-5"]: # Keep only the simplest definitions simplified_definitions = [] for def_text in definition.definitions: if len(def_text.split()) <= 15: # Simple definitions only simplified_definitions.append(def_text) if simplified_definitions: definition.definitions = simplified_definitions[:2] # Max 2 definitions # Keep only simple examples simple_examples = [] for example in definition.examples: if len(example.split()) <= 10: # Simple examples only simple_examples.append(example) definition.examples = simple_examples[:3] # Max 3 examples return definition def _generate_educational_recommendations( self, definition: Definition, grade_level: Optional[str] ) -> Dict[str, Any]: """Generate educational recommendations for using the word.""" recommendations = { "teaching_strategies": [], "learning_activities": [], "assessment_ideas": [], "cross_curricular_connections": [] } complexity = definition.get_complexity_score() # Teaching strategies based on complexity if complexity <= 0.3: recommendations["teaching_strategies"].extend([ "Use visual aids and pictures", "Practice with simple sentences", "Connect to familiar concepts" ]) elif complexity <= 0.7: recommendations["teaching_strategies"].extend([ "Provide context and examples", "Break down into parts", "Use in multiple contexts" ]) else: recommendations["teaching_strategies"].extend([ "Explore etymology and word origins", "Analyze in academic contexts", "Compare with related terms" ]) # Learning activities if definition.synonyms: recommendations["learning_activities"].append("Synonym matching exercises") if definition.examples: recommendations["learning_activities"].append("Context clue practice") if definition.has_pronunciation(): recommendations["learning_activities"].append("Pronunciation practice") # Subject connections for subject in definition.subject_areas: recommendations["cross_curricular_connections"].append(f"Use in {subject} lessons") return recommendations def _count_syllables(self, word: str) -> int: """Estimate syllable count for a word.""" # Simple syllable counting heuristic word = word.lower() vowels = "aeiouy" syllable_count = 0 prev_was_vowel = False for char in word: is_vowel = char in vowels if is_vowel and not prev_was_vowel: syllable_count += 1 prev_was_vowel = is_vowel # Handle silent e if word.endswith('e') and syllable_count > 1: syllable_count -= 1 return max(syllable_count, 1) def _count_technical_indicators(self, definition: Definition) -> int: """Count technical/academic indicators in definitions.""" technical_terms = [ "technical", "scientific", "academic", "formal", "specialized", "professional", "medical", "legal", "mathematical", "theoretical" ] content = " ".join(definition.definitions).lower() return sum(1 for term in technical_terms if term in content) def _determine_vocabulary_tier(self, definition: Definition) -> str: """Determine vocabulary tier (Tier 1: Basic, Tier 2: Academic, Tier 3: Domain-specific).""" complexity = definition.get_complexity_score() has_subject_areas = bool(definition.subject_areas) if complexity <= 0.3 and not has_subject_areas: return "Tier 1 (Basic)" elif complexity <= 0.7 and not has_subject_areas: return "Tier 2 (Academic)" else: return "Tier 3 (Domain-specific)" def _generate_learning_objectives(self, definition: Definition) -> List[str]: """Generate learning objectives for the word.""" objectives = [] objectives.append(f"Students will understand the meaning of '{definition.word}'") if definition.examples: objectives.append(f"Students will use '{definition.word}' correctly in context") if definition.synonyms: objectives.append(f"Students will identify synonyms for '{definition.word}'") if definition.has_pronunciation(): objectives.append(f"Students will pronounce '{definition.word}' correctly") if definition.subject_areas: for subject in definition.subject_areas: objectives.append(f"Students will apply '{definition.word}' in {subject} contexts") return objectives def _estimate_usage_frequency(self, definition: Definition) -> str: """Estimate how frequently the word is used.""" # This is a simplified heuristic # In a real system, this would use actual frequency data complexity = definition.get_complexity_score() if complexity <= 0.3: return "High frequency (common word)" elif complexity <= 0.5: return "Medium frequency (academic word)" elif complexity <= 0.7: return "Low frequency (specialized word)" else: return "Very low frequency (technical/rare word)" def _analyze_morphology(self, word: str) -> Dict[str, Any]: """Analyze word structure and morphology.""" analysis = { "root": word, # Simplified - would need morphological analyzer "prefixes": [], "suffixes": [], "word_family": [] } # Simple suffix detection common_suffixes = ["-ing", "-ed", "-er", "-est", "-ly", "-tion", "-sion", "-ness", "-ment"] for suffix in common_suffixes: if word.endswith(suffix.replace("-", "")): analysis["suffixes"].append(suffix) analysis["root"] = word[:-len(suffix.replace("-", ""))] break # Simple prefix detection common_prefixes = ["un-", "re-", "pre-", "dis-", "mis-", "over-", "under-", "out-"] for prefix in common_prefixes: if word.startswith(prefix.replace("-", "")): analysis["prefixes"].append(prefix) analysis["root"] = word[len(prefix.replace("-", "")):] break return analysis def _find_related_words(self, definition: Definition) -> List[str]: """Find morphologically related words.""" # This is a simplified implementation # In a real system, this would use a morphological database word = definition.word related = [] # Add common variations if word.endswith("ing"): base = word[:-3] related.extend([base, base + "ed", base + "er"]) elif word.endswith("ed"): base = word[:-2] related.extend([base, base + "ing", base + "er"]) return related[:5] # Limit to 5 related words def _assess_educational_value(self, definition: Definition, context: Optional[str]) -> Dict[str, Any]: """Assess the educational value of the word.""" value = { "vocabulary_building": len(definition.synonyms) > 0, "concept_development": len(definition.definitions) > 1, "cross_curricular": len(definition.subject_areas) > 1, "language_development": definition.has_pronunciation(), "critical_thinking": definition.get_complexity_score() > 0.5, "overall_score": definition.educational_metadata.educational_relevance_score } return value def _generate_educational_examples( self, word: str, grade_level: Optional[str], subject: Optional[str] ) -> List[str]: """Generate educational examples when none are available from API.""" # This is a simplified implementation # In a real system, this would use a more sophisticated example generator examples = [] if grade_level in ["K-2"]: examples.append(f"The {word} is important.") examples.append(f"I can see the {word}.") elif grade_level in ["3-5"]: examples.append(f"Students should understand what {word} means.") examples.append(f"The teacher explained the {word} clearly.") else: examples.append(f"The concept of {word} is fundamental to understanding this topic.") examples.append(f"Researchers have studied {word} extensively.") return examples def _enhance_example_for_education( self, example: str, word: str, grade_level: Optional[str], subject: Optional[str] ) -> Optional[Dict[str, Any]]: """Enhance an example sentence for educational use.""" # Check if example is appropriate for grade level if grade_level in ["K-2", "3-5"] and len(example.split()) > 15: return None # Too complex for young learners enhanced = { "sentence": example, "target_word": word, "context_clues": self._identify_context_clues(example, word), "educational_focus": self._identify_educational_focus(example, subject), "difficulty_level": "appropriate" if len(example.split()) <= 20 else "challenging" } return enhanced def _identify_context_clues(self, example: str, word: str) -> List[str]: """Identify context clues in an example sentence.""" # Simplified implementation words = example.lower().split() word_index = -1 try: word_index = words.index(word.lower()) except ValueError: return [] clues = [] # Look for clues around the target word for i in range(max(0, word_index - 2), min(len(words), word_index + 3)): if i != word_index and len(words[i]) > 3: clues.append(words[i]) return clues[:3] # Limit to 3 clues def _identify_educational_focus(self, example: str, subject: Optional[str]) -> str: """Identify the educational focus of an example.""" if subject and subject in example.lower(): return f"{subject} context" # Look for educational indicators educational_words = ["learn", "study", "understand", "explain", "analyze", "compare"] for edu_word in educational_words: if edu_word in example.lower(): return f"Learning-focused ({edu_word})" return "General usage" def _generate_subject_specific_examples( self, word: str, subject: str, grade_level: Optional[str] ) -> List[Dict[str, Any]]: """Generate subject-specific examples.""" examples = [] # This is a simplified implementation # In a real system, this would have extensive subject-specific templates if subject == "science": examples.append({ "sentence": f"Scientists use the term {word} to describe this phenomenon.", "target_word": word, "context_clues": ["scientists", "phenomenon"], "educational_focus": "Science vocabulary", "difficulty_level": "appropriate" }) elif subject == "mathematics": examples.append({ "sentence": f"In mathematics, {word} represents an important concept.", "target_word": word, "context_clues": ["mathematics", "concept"], "educational_focus": "Math vocabulary", "difficulty_level": "appropriate" }) return examples def _generate_usage_tips(self, word: str, grade_level: Optional[str]) -> List[str]: """Generate usage tips for the word.""" tips = [] tips.append(f"Use '{word}' when you want to be specific and clear.") if grade_level in ["K-2", "3-5"]: tips.append("Practice saying the word out loud.") tips.append("Try using it in a simple sentence.") else: tips.append("Consider the context when using this word.") tips.append("Look for opportunities to use it in writing.") return tips def _identify_common_mistakes(self, word: str) -> List[str]: """Identify common mistakes with the word.""" mistakes = [] # This is a simplified implementation # In a real system, this would use error analysis data if len(word) > 8: mistakes.append("Watch out for spelling errors in longer words") if word.endswith("ly"): mistakes.append("Remember this is an adverb, not an adjective") return mistakes def _generate_pronunciation_tips(self, word: str, phonetics: Dict[str, Any]) -> List[str]: """Generate pronunciation tips.""" tips = [] syllable_count = self._count_syllables(word) if syllable_count > 2: tips.append(f"Break it down: {word} has {syllable_count} syllables") if phonetics.get("text"): tips.append(f"Phonetic spelling: {phonetics['text']}") return tips def _break_into_syllables(self, word: str) -> str: """Break word into syllables (simplified).""" # This is a very simplified syllable breaker # A real implementation would use a proper syllabification algorithm syllables = [] current_syllable = "" vowels = "aeiouy" for i, char in enumerate(word.lower()): current_syllable += char if char in vowels and i < len(word) - 1: if word[i + 1].lower() not in vowels: syllables.append(current_syllable) current_syllable = "" if current_syllable: syllables.append(current_syllable) return "-".join(syllables) if syllables else word def _identify_stress_pattern(self, word: str, phonetics: Dict[str, Any]) -> str: """Identify stress pattern (simplified).""" # This is a simplified implementation syllable_count = self._count_syllables(word) if syllable_count == 1: return "Single syllable (stressed)" elif syllable_count == 2: return "First syllable stressed (typical pattern)" else: return "Varies (check pronunciation guide)" def _find_rhyming_words(self, word: str) -> List[str]: """Find simple rhyming words.""" # This is a very simplified rhyme finder # A real implementation would use a phonetic dictionary rhymes = [] if word.endswith("ing"): rhymes.extend(["sing", "ring", "king", "wing"]) elif word.endswith("tion"): rhymes.extend(["nation", "station", "creation"]) elif word.endswith("ly"): rhymes.extend(["quickly", "slowly", "carefully"]) # Remove the original word if it appears rhymes = [r for r in rhymes if r != word] return rhymes[:5] # Limit to 5 rhymes def _explain_phonetic_rules(self, word: str) -> List[str]: """Explain relevant phonetic rules.""" rules = [] if word.endswith("e") and len(word) > 3: rules.append("Silent 'e' at the end makes the vowel say its name") if "ph" in word: rules.append("'ph' makes the 'f' sound") if "ough" in word: rules.append("'ough' can be pronounced different ways") return rules def _assess_pronunciation_difficulty(self, word: str, phonetics: Dict[str, Any]) -> str: """Assess pronunciation difficulty.""" difficulty_score = 0 # Length factor if len(word) > 8: difficulty_score += 1 # Syllable count syllables = self._count_syllables(word) if syllables > 3: difficulty_score += 1 # Complex letter combinations complex_patterns = ["ough", "augh", "eigh", "tion", "sion"] for pattern in complex_patterns: if pattern in word.lower(): difficulty_score += 1 break if difficulty_score == 0: return "Easy" elif difficulty_score == 1: return "Moderate" else: return "Challenging" async def _get_educational_synonyms( self, definition: Definition, grade_level: Optional[str], limit: int ) -> List[Dict[str, Any]]: """Get educationally appropriate synonyms.""" synonyms = [] for synonym in definition.synonyms[:limit]: # In a real implementation, we would check each synonym's complexity synonym_data = { "word": synonym, "appropriateness": "suitable", # Simplified "usage_note": f"Can be used instead of '{definition.word}'" } synonyms.append(synonym_data) return synonyms async def _get_educational_antonyms( self, definition: Definition, grade_level: Optional[str], limit: int ) -> List[Dict[str, Any]]: """Get educationally appropriate antonyms.""" antonyms = [] for antonym in definition.antonyms[:limit]: antonym_data = { "word": antonym, "appropriateness": "suitable", # Simplified "usage_note": f"Opposite meaning of '{definition.word}'" } antonyms.append(antonym_data) return antonyms async def _get_educational_related_words( self, definition: Definition, grade_level: Optional[str], limit: int ) -> List[Dict[str, Any]]: """Get educationally relevant related words.""" related_words = [] # Get morphologically related words morphological_related = self._find_related_words(definition) for word in morphological_related[:limit]: word_data = { "word": word, "relationship": "morphological", "usage_note": f"Related to '{definition.word}' by word structure" } related_words.append(word_data) return related_words def _generate_vocabulary_notes( self, definition: Definition, grade_level: Optional[str] ) -> List[str]: """Generate educational notes about vocabulary relationships.""" notes = [] if definition.synonyms: notes.append("Learning synonyms helps expand vocabulary and improve writing variety.") if definition.antonyms: notes.append("Understanding antonyms helps clarify meaning through contrast.") if grade_level in ["K-2", "3-5"]: notes.append("Start with simple word relationships and build complexity gradually.") return notes def _suggest_vocabulary_activities( self, definition: Definition, grade_level: Optional[str] ) -> List[str]: """Suggest vocabulary learning activities.""" activities = [] if definition.synonyms: activities.append("Create a synonym web or word map") activities.append("Practice replacing words in sentences with synonyms") if definition.antonyms: activities.append("Play antonym matching games") activities.append("Create opposite word pairs") if grade_level in ["K-2"]: activities.append("Draw pictures to show word meanings") activities.append("Act out words with body movements") elif grade_level in ["3-5"]: activities.append("Create vocabulary journals") activities.append("Write sentences using new words") else: activities.append("Analyze word usage in different contexts") activities.append("Create semantic maps showing word relationships") return activities async def health_check(self) -> Dict[str, Any]: """ Perform a health check for this tool. Returns: Dictionary with health status information """ try: # Test the Dictionary API client api_health = await self.client.health_check() return { "tool_name": self.tool_name, "status": "healthy" if api_health.get("status") == "healthy" else "degraded", "api_status": api_health, "features": [ "word_definitions", "vocabulary_analysis", "pronunciation_guides", "educational_examples", "related_vocabulary" ], "timestamp": datetime.now().isoformat() } except Exception as e: logger.error(f"Dictionary tool health check failed: {e}") return { "tool_name": self.tool_name, "status": "unhealthy", "error": str(e), "timestamp": datetime.now().isoformat() }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Cicatriiz/openedu-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server