feat: 初次提交
This commit is contained in:
234
src/tools/family/math.ts
Normal file
234
src/tools/family/math.ts
Normal 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}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user