# MCP Server with EduChain Integration for Educational Content Generation
# Follows Model Context Protocol (MCP) standards to expose EduChain tools/resources
# Compatible with Claude Desktop for testing
# Citation: EduChain library (https://github.com/satvik314/educhain), MCP Python SDK (https://github.com/modelcontextprotocol/python-sdk)
import asyncio
from typing import List, Dict, Any
import httpx
from mcp.server.fastmcp import FastMCP
from pydantic import BaseModel, Field
from educhain import Educhain
# Initialize MCP server
mcp = FastMCP("EduChainServer")
# Initialize EduChain with default settings or environment variables for Grok
# Note: Assumes educhain uses environment variables or defaults to a free-tier LLM like Grok
# Citation: https://github.com/satvik314/educhain for configuration details
educhain = Educhain()
# Task 1: Define Pydantic models for structured outputs
class MultipleChoiceQuestion(BaseModel):
question: str = Field(description="The question text")
options: List[str] = Field(description="List of answer options")
correct_answer: str = Field(description="The correct answer")
explanation: str = Field(description="Explanation for the correct answer")
class LessonPlan(BaseModel):
title: str = Field(description="Title of the lesson plan")
objectives: List[str] = Field(description="Learning objectives")
activities: List[str] = Field(description="Classroom activities")
duration: str = Field(description="Estimated duration")
class Flashcard(BaseModel):
front: str = Field(description="Question or term on the front")
back: str = Field(description="Answer or definition on the back")
# Task 2: Define MCP tools for EduChain integration
@mcp.tool(title="GenerateMCQs")
async def generate_mcqs(topic: str, num_questions: int = 5) -> List[MultipleChoiceQuestion]:
"""
Generate multiple-choice questions for a given topic.
Args:
topic: The subject or topic for the questions (e.g., 'Python Programming Basics')
num_questions: Number of questions to generate (default: 5)
Returns:
List of MultipleChoiceQuestion objects
"""
try:
mcqs = educhain.generate_mcqs(
topic=topic,
num_questions=num_questions,
response_model=MultipleChoiceQuestion
)
return mcqs
except Exception as e:
return [MultipleChoiceQuestion(
question="Error",
options=["N/A"],
correct_answer="N/A",
explanation=f"Failed to generate MCQs: {str(e)}"
)]
@mcp.tool(title="GenerateLessonPlan")
async def generate_lesson_plan(subject: str) -> LessonPlan:
"""
Generate a lesson plan for a specified subject.
Args:
subject: The subject for the lesson plan (e.g., 'Algebra')
Returns:
LessonPlan object
"""
try:
lesson_plan = educhain.generate_lesson_plan(
subject=subject,
response_model=LessonPlan
)
return lesson_plan
except Exception as e:
return LessonPlan(
title="Error",
objectives=["N/A"],
activities=["N/A"],
duration=f"Failed to generate lesson plan: {str(e)}"
)
# Bonus: Flashcard generator tool
@mcp.tool(title="GenerateFlashcards")
async def generate_flashcards(topic: str, num_cards: int = 5) -> List[Flashcard]:
"""
Generate flashcards for a given topic.
Args:
topic: The topic for the flashcards (e.g., 'Python Programming Basics')
num_cards: Number of flashcards to generate (default: 5)
Returns:
List of Flashcard objects
"""
try:
flashcards = educhain.generate_flashcards(
topic=topic,
num_cards=num_cards,
response_model=Flashcard
)
return flashcards
except Exception as e:
return [Flashcard(
front="Error",
back=f"Failed to generate flashcards: {str(e)}"
)]
# Main execution block for running the MCP server
if __name__ == "__main__":
# Use stdio transport for local testing with Claude Desktop
mcp.run(transport="stdio")