Skip to main content
Glama
GaloisHLee
by GaloisHLee

sagemath_evaluate

Execute SageMath mathematical computations locally to solve equations, perform symbolic algebra, and analyze data using a configured SageMath installation.

Instructions

Evaluate SageMath code locally

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYes
timeoutMsNo

Implementation Reference

  • Core handler function that evaluates the provided SageMath code: writes code to a temporary .sage file, spawns the 'sage' process to execute it, handles timeout via runProcess helper, collects stdout/stderr/exitCode/duration/timedOut, cleans up temp dir, and returns the result.
    export async function evaluateSage(code: string, timeoutMs = 10000): Promise<SageRunResult & { tmpDir?: string }> {
      const sage = getSageExecutable();
      const tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'mcp-sage-'));
      const scriptPath = path.join(tmpRoot, 'script.sage');
      await fs.writeFile(scriptPath, code, 'utf8');
    
      const result = await runProcess(sage, [scriptPath], timeoutMs);
    
      // Attempt cleanup
      try { await fs.rm(tmpRoot, { recursive: true, force: true }); } catch {}
    
      return { ...result };
    }
  • Input/output schemas using Zod: input requires 'code' string and optional 'timeoutMs'; output matches SageRunResult structure (stdout, stderr, exitCode, durationMs, timedOut).
    {
      title: 'SageMath Evaluate',
      description: 'Evaluate SageMath code locally',
      inputSchema: {
        code: z.string(),
        timeoutMs: z.number().int().positive().optional(),
      },
      outputSchema: {
        stdout: z.string(),
        stderr: z.string(),
        exitCode: z.number().nullable(),
        durationMs: z.number(),
        timedOut: z.boolean(),
      },
    },
  • src/index.ts:41-69 (registration)
    Registers the 'sagemath_evaluate' tool on the MCP server, providing title/description/schemas and a thin async handler wrapper that calls evaluateSage and formats MCP response with text content and structured JSON.
    server.registerTool(
      'sagemath_evaluate',
      {
        title: 'SageMath Evaluate',
        description: 'Evaluate SageMath code locally',
        inputSchema: {
          code: z.string(),
          timeoutMs: z.number().int().positive().optional(),
        },
        outputSchema: {
          stdout: z.string(),
          stderr: z.string(),
          exitCode: z.number().nullable(),
          durationMs: z.number(),
          timedOut: z.boolean(),
        },
      },
      async ({ code, timeoutMs }) => {
        const result = await evaluateSage(code, timeoutMs ?? 10000);
        const structured = result as unknown as Record<string, unknown>;
        return {
          content: [{
            type: 'text',
            text: `SageMath evaluation response (structured JSON below)\n${JSON.stringify(structured)}`,
          }],
          structuredContent: structured,
        };
      }
    );
  • Key helper function to spawn a child process (sage), pipe stdout/stderr, enforce timeout with SIGKILL, handle errors/spawn failures, and resolve with SageRunResult including duration and timedOut flag. Used by both evaluateSage and getSageVersion.
    async function runProcess(cmd: string, args: string[], timeoutMs: number): Promise<SageRunResult> {
      const start = Date.now();
      let stdout = '';
      let stderr = '';
      let timedOut = false;
    
      return new Promise<SageRunResult>((resolve) => {
        let child: ReturnType<typeof spawn> | undefined;
        try {
          child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] });
        } catch (err: any) {
          resolve({
            stdout: '',
            stderr: `Failed to spawn process: ${err?.message || String(err)}`,
            exitCode: null,
            durationMs: Date.now() - start,
            timedOut: false,
          });
          return;
        }
    
        const t = setTimeout(() => {
          timedOut = true;
          try { child?.kill('SIGKILL'); } catch {}
        }, Math.max(1, timeoutMs));
    
        // Handle asynchronous spawn errors (e.g., command not found)
        child.on('error', (err) => {
          clearTimeout(t);
          resolve({
            stdout: '',
            stderr: `Process error: ${err?.message || String(err)}`,
            exitCode: null,
            durationMs: Date.now() - start,
            timedOut,
          });
        });
    
        child.stdout?.on('data', (d) => { stdout += d.toString(); });
        child.stderr?.on('data', (d) => { stderr += d.toString(); });
    
        child.on('close', (code) => {
          clearTimeout(t);
          resolve({
            stdout,
            stderr,
            exitCode: code,
            durationMs: Date.now() - start,
            timedOut,
          });
        });
      });
    }
  • TypeScript interface defining the structure of Sage execution results, matching the outputSchema in registration.
    export interface SageRunResult {
      stdout: string;
      stderr: string;
      exitCode: number | null;
      durationMs: number;
      timedOut: boolean;
    }

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/GaloisHLee/mcp-server-sagemath'

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