/** * Math teaching resource tools */ import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { mcpServer } from '../../server.js'; import { database, MathResource } from '../../storage/database.js'; import { randomUUID } from 'crypto'; export function registerMathTools(): void { // Search math resources mcpServer.registerTool( { name: 'math_resource_search', description: 'Search for math teaching resources (worksheets, problems, tools)', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query', }, grade: { type: 'string', description: 'Grade level (e.g., "1st", "2nd", "elementary", "middle", "high")', }, }, required: ['query'], }, }, async (args) => { const query = args.query as string; const grade = args.grade as string | undefined; const resources = database.searchMathResources(query, grade); if (resources.length === 0) { return { content: [ { type: 'text', text: `No math resources found matching "${query}"${grade ? ` for grade ${grade}` : ''}.\n\nYou can save resources using math_resource_save tool.`, }, ], }; } const results = resources .map( (r) => `Title: ${r.title}\nGrade: ${r.grade || 'N/A'}\nDifficulty: ${r.difficulty || 'N/A'}\nTags: ${r.tags.join(', ')}\n\nContent:\n${r.content}\n---` ) .join('\n\n'); return { content: [ { type: 'text', text: `Found ${resources.length} math resource(s):\n\n${results}`, }, ], }; } ); // Generate math problems mcpServer.registerTool( { name: 'math_problem_generate', description: 'Generate math problems by grade and difficulty', inputSchema: { type: 'object', properties: { grade: { type: 'string', description: 'Grade level (e.g., "1st", "2nd", "elementary", "middle", "high")', }, difficulty: { type: 'string', description: 'Difficulty level (easy, medium, hard)', default: 'medium', }, topic: { type: 'string', description: 'Math topic (e.g., "addition", "multiplication", "algebra", "geometry")', }, count: { type: 'number', description: 'Number of problems to generate', default: 5, }, }, required: ['grade'], }, }, async (args) => { const grade = args.grade as string; const difficulty = (args.difficulty as string) || 'medium'; const topic = args.topic as string | undefined; const count = (args.count as number) || 5; // Generate problems based on grade and difficulty const problems: string[] = []; if (grade.includes('1st') || grade.includes('2nd') || grade === 'elementary') { // Elementary level for (let i = 0; i < count; i++) { if (topic === 'addition' || !topic) { const a = Math.floor(Math.random() * 20) + 1; const b = Math.floor(Math.random() * 20) + 1; problems.push(`${a} + ${b} = ?`); } else if (topic === 'subtraction') { const a = Math.floor(Math.random() * 20) + 10; const b = Math.floor(Math.random() * a) + 1; problems.push(`${a} - ${b} = ?`); } else if (topic === 'multiplication') { const a = Math.floor(Math.random() * 10) + 1; const b = Math.floor(Math.random() * 10) + 1; problems.push(`${a} × ${b} = ?`); } } } else if (grade.includes('middle') || grade.includes('6th') || grade.includes('7th') || grade.includes('8th')) { // Middle school level for (let i = 0; i < count; i++) { if (topic === 'algebra' || !topic) { const a = Math.floor(Math.random() * 10) + 1; const b = Math.floor(Math.random() * 20) - 10; const c = Math.floor(Math.random() * 20) - 10; problems.push(`Solve for x: ${a}x + ${b} = ${c}`); } else if (topic === 'fractions') { const num1 = Math.floor(Math.random() * 10) + 1; const den1 = Math.floor(Math.random() * 10) + 1; const num2 = Math.floor(Math.random() * 10) + 1; const den2 = Math.floor(Math.random() * 10) + 1; problems.push(`Add: ${num1}/${den1} + ${num2}/${den2} = ?`); } else if (topic === 'geometry') { const side = Math.floor(Math.random() * 10) + 1; problems.push(`Find the area of a square with side length ${side}`); } } } else { // High school level for (let i = 0; i < count; i++) { if (topic === 'algebra' || !topic) { const a = Math.floor(Math.random() * 5) + 1; const b = Math.floor(Math.random() * 10) - 5; const c = Math.floor(Math.random() * 10) - 5; problems.push(`Solve: ${a}x² + ${b}x + ${c} = 0`); } else if (topic === 'geometry') { const r = Math.floor(Math.random() * 10) + 1; problems.push(`Find the area of a circle with radius ${r} (use π = 3.14)`); } else if (topic === 'trigonometry') { const angle = [30, 45, 60][Math.floor(Math.random() * 3)]; problems.push(`Find sin(${angle}°)`); } } } const problemsText = problems.map((p, i) => `${i + 1}. ${p}`).join('\n'); return { content: [ { type: 'text', text: `Generated ${count} math problem(s) for ${grade} grade (${difficulty} difficulty)${topic ? ` - Topic: ${topic}` : ''}:\n\n${problemsText}`, }, ], }; } ); // Save math resource mcpServer.registerTool( { name: 'math_resource_save', description: 'Save a math teaching resource', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'Title of the resource', }, content: { type: 'string', description: 'Content of the resource (worksheet, problem set, etc.)', }, grade: { type: 'string', description: 'Grade level', }, difficulty: { type: 'string', description: 'Difficulty level', }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags for categorization', }, id: { type: 'string', description: 'Optional ID for updating existing resource', }, }, required: ['title', 'content'], }, }, async (args) => { const now = new Date().toISOString(); const resource: MathResource = { id: (args.id as string) || randomUUID(), title: args.title as string, content: args.content as string, grade: args.grade as string | undefined, difficulty: args.difficulty as string | undefined, tags: (args.tags as string[]) || [], createdAt: now, }; database.saveMathResource(resource); return { content: [ { type: 'text', text: `Math resource "${resource.title}" saved successfully with ID: ${resource.id}`, }, ], }; } ); }