Skip to main content
Glama
math-tools.ts7.21 kB
import { z } from 'zod'; import { DiceEngine } from '../math/dice.js'; import { ProbabilityEngine } from '../math/probability.js'; import { AlgebraEngine } from '../math/algebra.js'; import { PhysicsEngine } from '../math/physics.js'; import { ExportEngine } from '../math/export.js'; import { CalculationRepository, StoredCalculation } from '../storage/repos/calculation.repo.js'; import { getDb } from '../storage/index.js'; import { ProbabilityQuerySchema, ExportFormatSchema, CalculationResult } from '../math/schemas.js'; import { randomUUID } from 'crypto'; function getRepo() { const db = getDb(process.env.NODE_ENV === 'test' ? ':memory:' : 'rpg.db'); return { repo: new CalculationRepository(db), db }; } function logCalculationEvent(db: any, calculationId: string, type: string, sessionId?: string) { db.prepare(` INSERT INTO event_logs (type, payload, timestamp) VALUES (?, ?, ?) `).run('calculation', JSON.stringify({ calculationId, calculationType: type, sessionId }), new Date().toISOString()); } // Tool Definitions export const MathTools = { DICE_ROLL: { name: 'dice_roll', description: 'Roll dice using standard notation. Supports: basic rolls (2d6+3), drop lowest (4d6dl1), drop highest (4d6dh1), keep lowest (2d20kl1), keep highest (2d20kh1), advantage/disadvantage, and exploding dice (2d6!).', inputSchema: z.object({ expression: z.string(), seed: z.string().optional(), exportFormat: ExportFormatSchema.optional().default('json') }) }, PROBABILITY_CALCULATE: { name: 'probability_calculate', description: 'Calculate probabilities for dice rolls, including distributions and expected values.', inputSchema: ProbabilityQuerySchema.extend({ exportFormat: ExportFormatSchema.optional().default('plaintext') }) }, ALGEBRA_SOLVE: { name: 'algebra_solve', description: 'Solve algebraic equations.', inputSchema: z.object({ equation: z.string(), variable: z.string().optional(), exportFormat: ExportFormatSchema.optional().default('plaintext') }) }, ALGEBRA_SIMPLIFY: { name: 'algebra_simplify', description: 'Simplify algebraic expressions.', inputSchema: z.object({ expression: z.string(), exportFormat: ExportFormatSchema.optional().default('plaintext') }) }, PHYSICS_PROJECTILE: { name: 'physics_projectile', description: 'Calculate projectile motion trajectory.', inputSchema: z.object({ velocity: z.number(), angle: z.number(), height: z.number().optional().default(0), gravity: z.number().optional().default(9.81), exportFormat: ExportFormatSchema.optional().default('plaintext') }) } }; // Handlers export async function handleDiceRoll(args: z.infer<typeof MathTools.DICE_ROLL.inputSchema> & { sessionId?: string }) { const { repo, db } = getRepo(); const engine = new DiceEngine(args.seed); const exporter = new ExportEngine(); const result = engine.roll(args.expression); const calculation: StoredCalculation = { id: randomUUID(), sessionId: args.sessionId, ...result, seed: args.seed || result.seed }; repo.create(calculation); logCalculationEvent(db, calculation.id, 'dice_roll', args.sessionId); return { content: [ { type: 'text', text: exporter.export(calculation, args.exportFormat) } ] }; } export async function handleProbabilityCalculate(args: z.infer<typeof MathTools.PROBABILITY_CALCULATE.inputSchema> & { sessionId?: string }) { const { repo, db } = getRepo(); const engine = new ProbabilityEngine(); const exporter = new ExportEngine(); // Calculate probability and EV const prob = engine.calculateProbability(args.expression, args.target, args.comparison); const ev = engine.expectedValue(args.expression); const result: CalculationResult = { input: JSON.stringify(args), result: prob, steps: [ `Probability (${args.comparison} ${args.target}): ${(prob * 100).toFixed(2)}%`, `Expected Value: ${ev.toFixed(2)}` ], timestamp: new Date().toISOString(), metadata: { type: 'probability', probability: prob, expectedValue: ev } }; const calculation: StoredCalculation = { id: randomUUID(), sessionId: args.sessionId, ...result }; repo.create(calculation); logCalculationEvent(db, calculation.id, 'probability', args.sessionId); return { content: [ { type: 'text', text: exporter.export(calculation, args.exportFormat) } ] }; } export async function handleAlgebraSolve(args: z.infer<typeof MathTools.ALGEBRA_SOLVE.inputSchema> & { sessionId?: string }) { const { repo, db } = getRepo(); const engine = new AlgebraEngine(); const exporter = new ExportEngine(); const result = engine.solve(args.equation, args.variable || 'x'); const calculation: StoredCalculation = { id: randomUUID(), sessionId: args.sessionId, ...result }; repo.create(calculation); logCalculationEvent(db, calculation.id, 'algebra_solve', args.sessionId); return { content: [ { type: 'text', text: exporter.export(calculation, args.exportFormat) } ] }; } export async function handleAlgebraSimplify(args: z.infer<typeof MathTools.ALGEBRA_SIMPLIFY.inputSchema> & { sessionId?: string }) { const { repo, db } = getRepo(); const engine = new AlgebraEngine(); const exporter = new ExportEngine(); const result = engine.simplify(args.expression); const calculation: StoredCalculation = { id: randomUUID(), sessionId: args.sessionId, ...result }; repo.create(calculation); logCalculationEvent(db, calculation.id, 'algebra_simplify', args.sessionId); return { content: [ { type: 'text', text: exporter.export(calculation, args.exportFormat) } ] }; } export async function handlePhysicsProjectile(args: z.infer<typeof MathTools.PHYSICS_PROJECTILE.inputSchema> & { sessionId?: string }) { const { repo, db } = getRepo(); const engine = new PhysicsEngine(); const exporter = new ExportEngine(); const result = engine.projectile(args.velocity, args.angle, args.gravity, 10, args.height); const calculation: StoredCalculation = { id: randomUUID(), sessionId: args.sessionId, ...result }; repo.create(calculation); logCalculationEvent(db, calculation.id, 'physics_projectile', args.sessionId); return { content: [ { type: 'text', text: exporter.export(calculation, args.exportFormat) } ] }; }

Latest Blog Posts

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/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server