feat: 初次提交

This commit is contained in:
ethan.chen
2026-01-06 17:35:52 +08:00
commit 372b52b214
24 changed files with 4645 additions and 0 deletions

234
src/tools/family/math.ts Normal file
View File

@@ -0,0 +1,234 @@
/**
* 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}`,
},
],
};
}
);
}