Skip to main content
Glama

OpenEdu MCP Server

definition.pyโ€ข8.52 kB
""" Definition data model for OpenEdu MCP Server. This module defines the Definition model for representing word definitions from dictionary APIs. """ from dataclasses import dataclass, field from datetime import datetime from typing import Dict, Any, Optional, List import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent)) from models.base import BaseModel, EducationalMetadata @dataclass class Definition(BaseModel): """Model representing a word definition.""" word: str = "" definitions: List[str] = field(default_factory=list) part_of_speech: str = "" pronunciation: Optional[str] = None phonetic: Optional[str] = None etymology: Optional[str] = None examples: List[str] = field(default_factory=list) synonyms: List[str] = field(default_factory=list) antonyms: List[str] = field(default_factory=list) # Educational metadata educational_metadata: EducationalMetadata = field(default_factory=EducationalMetadata) subject_areas: List[str] = field(default_factory=list) # Source information source: str = "dictionary_api" source_url: Optional[str] = None def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for serialization.""" return { "word": self.word, "definitions": self.definitions, "part_of_speech": self.part_of_speech, "pronunciation": self.pronunciation, "phonetic": self.phonetic, "etymology": self.etymology, "examples": self.examples, "synonyms": self.synonyms, "antonyms": self.antonyms, "educational_metadata": self.educational_metadata.to_dict(), "subject_areas": self.subject_areas, "source": self.source, "source_url": self.source_url, "created_at": self.created_at.isoformat(), "updated_at": self.updated_at.isoformat() } @classmethod def from_dict(cls, data: Dict[str, Any]) -> 'Definition': """Create from dictionary.""" educational_metadata = EducationalMetadata.from_dict( data.get("educational_metadata", {}) ) return cls( word=data["word"], definitions=data.get("definitions", []), part_of_speech=data.get("part_of_speech", ""), pronunciation=data.get("pronunciation"), phonetic=data.get("phonetic"), etymology=data.get("etymology"), examples=data.get("examples", []), synonyms=data.get("synonyms", []), antonyms=data.get("antonyms", []), educational_metadata=educational_metadata, subject_areas=data.get("subject_areas", []), source=data.get("source", "dictionary_api"), source_url=data.get("source_url"), created_at=datetime.fromisoformat(data.get("created_at", datetime.now().isoformat())), updated_at=datetime.fromisoformat(data.get("updated_at", datetime.now().isoformat())) ) @classmethod def from_dictionary_api(cls, api_data: Dict[str, Any]) -> 'Definition': """Create Definition from Dictionary API response.""" word = api_data.get("word", "") # Extract meanings (definitions) definitions = [] part_of_speech = "" examples = [] synonyms = [] antonyms = [] meanings = api_data.get("meanings", []) if meanings: # Use the first meaning for primary part of speech first_meaning = meanings[0] part_of_speech = first_meaning.get("partOfSpeech", "") # Collect all definitions for meaning in meanings: for definition in meaning.get("definitions", []): definitions.append(definition.get("definition", "")) # Collect examples if definition.get("example"): examples.append(definition["example"]) # Collect synonyms and antonyms synonyms.extend(definition.get("synonyms", [])) antonyms.extend(definition.get("antonyms", [])) # Extract phonetics pronunciation = None phonetic = None phonetics = api_data.get("phonetics", []) if phonetics: for phonetic_entry in phonetics: if phonetic_entry.get("audio"): pronunciation = phonetic_entry["audio"] if phonetic_entry.get("text"): phonetic = phonetic_entry["text"] if pronunciation and phonetic: break # Create educational metadata educational_metadata = EducationalMetadata() # Etymology is not provided by Dictionary API etymology = "" # Determine difficulty level based on word characteristics word_length = len(word) definition_complexity = sum(len(d.split()) for d in definitions) / max(len(definitions), 1) if word_length <= 5 and definition_complexity <= 10: educational_metadata.difficulty_level = "Elementary" elif word_length <= 8 and definition_complexity <= 15: educational_metadata.difficulty_level = "Intermediate" else: educational_metadata.difficulty_level = "Advanced" # Set educational relevance based on presence of examples and complexity relevance_score = 0.5 # Base score if examples: relevance_score += 0.2 if synonyms or antonyms: relevance_score += 0.1 if etymology: relevance_score += 0.1 if phonetic: relevance_score += 0.1 educational_metadata.educational_relevance_score = min(relevance_score, 1.0) return cls( word=word, definitions=definitions, part_of_speech=part_of_speech, pronunciation=pronunciation, phonetic=phonetic, etymology=api_data.get("etymology"), examples=list(set(examples)), # Remove duplicates synonyms=list(set(synonyms)), # Remove duplicates antonyms=list(set(antonyms)), # Remove duplicates educational_metadata=educational_metadata, subject_areas=[], # Can be populated based on context source="dictionary_api", source_url=f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}" ) def get_primary_definition(self) -> str: """Get the primary (first) definition.""" return self.definitions[0] if self.definitions else "" def has_pronunciation(self) -> bool: """Check if pronunciation information is available.""" return bool(self.pronunciation or self.phonetic) def get_complexity_score(self) -> float: """Calculate word complexity score (0-1).""" score = 0.0 # Word length factor word_length = len(self.word) if word_length > 10: score += 0.3 elif word_length > 6: score += 0.2 else: score += 0.1 # Definition complexity avg_def_length = sum(len(d.split()) for d in self.definitions) / max(len(self.definitions), 1) if avg_def_length > 20: score += 0.3 elif avg_def_length > 10: score += 0.2 else: score += 0.1 # Multiple meanings increase complexity if len(self.definitions) > 3: score += 0.2 elif len(self.definitions) > 1: score += 0.1 # Etymology adds complexity if self.etymology: score += 0.2 return min(score, 1.0) def is_suitable_for_grade_level(self, grade_level: str) -> bool: """Check if word is suitable for a specific grade level.""" complexity = self.get_complexity_score() if grade_level in ["K-2"]: return complexity <= 0.3 elif grade_level in ["3-5"]: return complexity <= 0.5 elif grade_level in ["6-8"]: return complexity <= 0.7 else: # 9-12, College return True # All words suitable for higher grades

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