Install
$ agentstack add mcp-xbp-europe-sagemath-mcp Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ● Network access Used
- ● Filesystem access Used
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
SageMath MCP Server
[](https://github.com/XBP-Europe/sagemath-mcp/actions/workflows/ci.yml) [](https://github.com/XBP-Europe/sagemath-mcp/releases/latest) [](https://pypi.org/project/sagemath-mcp/) [](https://github.com/XBP-Europe/sagemath-mcp/pkgs/container/sagemath-mcp) [](LICENSE) [](https://www.python.org/downloads/) [](https://modelcontextprotocol.io/) [](https://gofastmcp.com/) [](https://www.sagemath.org/) [](https://docs.astral.sh/ruff/) [](https://peps.python.org/pep-0561/)
A universal mathematics Model Context Protocol (MCP) server that gives LLM clients full access to SageMath --- one of the most comprehensive open-source mathematics systems available. Built on FastMCP 3.x, the server maintains a dedicated SageMath process for each MCP session so variables, functions, and assumptions persist across tool calls.
Whether the task is symbolic calculus, number theory, linear algebra, differential equations, plotting, combinatorics, graph theory, group theory, or basic arithmetic, the server provides 33 MCP tools --- all math tools backed by the full SageMath engine, plus evaluate_sage_streaming (streaming wrapper) and an HTTP /health endpoint.
Table of Contents
- [Features at a Glance](#features-at-a-glance)
- [Architecture Overview](#architecture-overview)
- [Quick Start](#quick-start)
- [Detailed Tool Reference](#detailed-tool-reference)
- [evaluatesage --- Open-Ended Execution](#evaluatesage----open-ended-sagemath-execution)
- [Calculus Tools](#calculus-tools)
- [Algebra & Simplification Tools](#algebra--simplification-tools)
- [Linear Algebra Tools](#linear-algebra-tools)
- [Differential Equations](#differential-equations)
- [Number Theory](#number-theory)
- [Statistics](#statistics)
- [Visualization](#visualization)
- [Session Management & Observability](#session-management--observability)
- [Security Sandbox](#security-sandbox)
- [LLM Client Configuration](#llm-client-configuration)
- [Deployment](#deployment)
- [Configuration Reference](#configuration-reference)
- [CLI Reference](#cli-reference)
- [Development](#development)
- [CLI Integration Testing](#cli-integration-testing)
- [Project Layout](#project-layout)
- [Technology Stack](#technology-stack)
- [Changelog](#changelog)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
Features at a Glance
| Category | Tools | Backend | Capabilities | |----------|-------|---------|-------------| | Core execution | evaluate_sage, evaluate_sage_streaming | Sage | Run any SageMath code with persistent state, LaTeX output, stdout capture, progress heartbeats, per-call timeouts, and line-by-line streaming | | Calculus | differentiate_expression, integrate_expression, limit_expression, series_expansion | Sage | Derivatives of any order, indefinite & definite integrals, one-sided limits, Taylor/Laurent series | | Algebra | solve_equation, simplify_expression, expand_expression, factor_expression, calculate_expression | Sage | Single equations & systems, symbolic simplification, expansion, factoring, numeric evaluation | | Symbolic sums | symbolic_sum | Sage | Symbolic summation and products (finite and infinite series) | | Linear algebra | matrix_multiply, matrix_operation | Sage | Matrix products, determinants, inverses, eigenvalues, rank, RREF, transpose | | Differential equations | solve_ode | Sage | First- and higher-order ODEs via Sage's desolve() | | Number theory | number_theory_operation | Sage | Primality testing, integer factorization, next prime, GCD, LCM | | Combinatorics | combinatorics_operation | Sage | Binomial, permutations, combinations, partitions, factorial, Catalan, Fibonacci, Bell numbers | | Graph theory | graph_operation | Sage | Named graphs and adjacency dicts; chromatic number, connectivity, planarity, diameter, shortest path | | Group theory | group_operation | Sage | Symmetric, dihedral, cyclic, alternating groups; order, abelian/cyclic test, center, exponent | | Elliptic curves | elliptic_curve_operation | Sage | Rank, torsion, discriminant, j-invariant, conductor, generators | | Coding theory | coding_theory_operation | Sage | Hamming, Reed-Solomon codes; length, dimension, minimum distance, generator matrix, rate | | Polynomial rings | polynomial_ring_operation | Sage | Groebner bases, ideal dimension/variety, reduction, Groebner test | | Boolean algebra | boolean_algebra_operation | Sage | Boolean polynomial ring; evaluate, variables, degree, zero/one test | | Geometry | geometry_operation | Sage | Distance, polygon area, polytope volume, convex hull, compactness via Polyhedron | | Statistics | statistics_summary | Sage | Mean, median, population & sample variance/std dev, min, max | | Probability | distribution_operation | Sage | Normal, exponential, Poisson, chi-squared, Student-t, uniform, beta, gamma; PDF, CDF, quantile, sampling | | Visualization | plot_expression, plot3d_expression, plot_multi_expression | Sage | 2D plots, 3D surface plots, multi-function overlays as base64-encoded PNG | | Numeric methods | find_root | Sage | Numeric root-finding in an interval via Sage's find_root() | | Vector calculus | vector_calculus_operation | Sage | Gradient, divergence, curl, Laplacian on scalar/vector fields | | Session control | reset_sage_session, cancel_sage_session | Worker | Clear state or abort long-running computations | | Infrastructure | /health endpoint, 3 MCP resources | Server | Health check, session snapshots, aggregated metrics, documentation links |
Architecture Overview
┌──────────────────────────────────────────────────────────────────┐
│ MCP Client (Claude Desktop, Gemini CLI, Codex CLI, etc.) │
└──────────────────────┬───────────────────────────────────────────┘
│ MCP protocol (stdio or HTTP)
▼
┌──────────────────────────────────────────────────────────────────┐
│ server.py --- FastMCP 3.x Application │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ 18 MCP Tools│ │ 3 Resources │ │ Middleware │ │
│ │ (evaluate, │ │ (session, │ │ - Request logging │ │
│ │ solve, │ │ monitoring, │ │ - Response caching │ │
│ │ diff, ...)│ │ docs) │ │ - Progress heartbeats │ │
│ └──────┬──────┘ └──────────────┘ └────────────────────────┘ │
│ │ │
│ ┌──────▼──────────────────────────────────────────────────────┐ │
│ │ session.py --- SageSessionManager │ │
│ │ Per-client session map with asyncio locks, idle culling │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Session A │ │ Session B │ │ Session C │ ... │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ └─────────┼───────────────┼───────────────┼──────────────────┘ │
└────────────┼───────────────┼───────────────┼────────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────┐
│ _sage_worker.py --- Subprocess Workers │
│ JSON stdin/stdout protocol │
│ │
│ ┌────────────┐ ┌──────────────────────┐ │
│ │ security.py│──▶│ AST validation │ │
│ │ │ │ before every exec() │ │
│ └────────────┘ └──────────────────────┘ │
│ │
│ Persistent namespace: vars, functions, │
│ classes survive across calls │
└────────────────────────────────────────────────┘
Request flow: MCP client → server.py tool → SageSessionManager.get_or_create() → SageSession.evaluate() → JSON request to _sage_worker.py subprocess → AST validation → exec() in persistent namespace → JSON response back.
Key design decisions:
- Process isolation: Each session runs SageMath in a separate subprocess. A crash or timeout in one session cannot affect others.
- Stateful sessions: Variables, functions, and assumptions persist across tool calls within the same MCP session, enabling multi-step mathematical workflows.
- Security by default: Every code snippet passes through an AST-based validator before execution, blocking dangerous operations regardless of the tool used.
- Progress heartbeats: Long-running computations emit periodic progress events (~1.5s) so clients can display activity indicators and detect stalls.
Quick Start
Install from PyPI
pip install sagemath-mcp
# Run the server over stdio (default)
sagemath-mcp
# Or expose an HTTP endpoint
sagemath-mcp --transport streamable-http --host 127.0.0.1 --port 8314
If the command is not on your PATH, run python -m sagemath_mcp.server --help.
Develop from source
git clone https://github.com/XBP-Europe/sagemath-mcp.git
cd sagemath-mcp
# Install dependencies (use uv or pip)
uv pip install -e .[dev]
# Run the server over stdio (default)
uv run sagemath-mcp
# Run with streaming-friendly HTTP transport
uv run sagemath-mcp --transport streamable-http --host 127.0.0.1 --port 8314
Optional: start a Sage container automatically
If you'd like a ready-to-use Sage runtime without installing it locally, run:
make sage-container # or ./scripts/setup_sage_container.sh
On Windows PowerShell:
pwsh -File scripts/setup_sage_container.ps1
Docker Image
Build a ready-to-run container with the MCP server baked in:
docker build -t sagemath-mcp:latest .
docker run -p 8314:8314 sagemath-mcp:latest --transport streamable-http
Released images are published to ghcr.io/xbp-europe/sagemath-mcp and signed with Cosign. Verify a downloaded artifact with:
cosign verify ghcr.io/xbp-europe/sagemath-mcp:latest \
--certificate-identity "https://github.com/XBP-Europe/sagemath-mcp/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
Docker Compose
docker compose up --build
The compose service exposes port 8314 on both host and container and mounts the repository at /workspace. Containers run as the non-root sage user (UID/GID 1000) to match the base image. Tweak runtime settings by editing the environment block (for example, increase SAGEMATH_MCP_EVAL_TIMEOUT or adjust SAGEMATH_MCP_MAX_STDOUT) before launch.
Detailed Tool Reference
evaluate_sage --- Open-Ended SageMath Execution
The primary tool. Executes arbitrary SageMath code inside a persistent worker process. Variables, functions, classes, and assumptions defined in one call survive into subsequent calls within the same MCP session.
| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | code | string | required | SageMath code to execute. Multi-line strings are supported. | | want_latex | bool | false | When true, the server generates a LaTeX representation of the final expression result (if one exists) via Sage's latex() function. Returned in the latex field. | | capture_stdout | bool | true | When true, any output from print() statements is captured and returned in the stdout field. Set to false for faster execution when stdout is not needed. | | timeout | float | null | Override the per-evaluation timeout in seconds. If omitted, the global default (SAGEMATH_MCP_EVAL_TIMEOUT, 30 s) applies. Must be > 0. |
Returns an EvaluateResult object:
| Field | Type | Description | |-------|------|-------------| | result_type | "expression" or "statement" | "expression" when the code ends with an expression whose value is captured; "statement" when it ends with an assignment or side effect. | | result | string or null | The repr() of the final expression value, or null for statement-type code. | | latex | string or null | LaTeX representation of the result (only when want_latex=true and the result is non-null). | | stdout | string | Captured stdout output (empty string if nothing was printed or capture_stdout=false). Truncated to SAGEMATH_MCP_MAX_STDOUT characters. | | elapsed_ms | float | Wall-clock execution time in milliseconds. |
Behavior details:
- While code is running, the server emits progress heartbeats roughly every 1.5 seconds so clients can display activity indicators.
- If the evaluation exceeds the timeout, the worker process is restarted and a
TimeoutErroris raised. All session state from prior calls is lost. - If the startup code (
from sage.all import *by default) failed when the worker launched, every subsequentevaluate_sagecall returns a clearStartupErrorinstead of a confusing NameError. - The AST security validator runs on every code snippet before execution (see [Security Sandbox](#security-sandbox)).
Domain-specific examples (these are included in the tool description LLMs see):
| Domain | Example Sage code | |--------|------------------| | Combinatorics | binomial(10, 3), Permutations(4).cardinality(), Combinations([1,2,3,4], 2).list() | | Graph theory | G = graphs.PetersenGraph(); G.chromatic_number() | | Number theory | prime_range(100), euler_phi(60), continued_fraction(pi, nterms=10) | | Geometry | polytopes.cube().volume(), EllipticCurve([0,0,1,-1,0]).rank() | | Probability | RealDistribution('gaussian', 1).cum_distribution_function(1.96) | | Group theory | SymmetricGroup(5).order(), AlternatingGroup(4).is_abelian() | | Polynomial rings | R. = PolynomialRing(QQ); (a+b)^3 | | Coding theory | codes.HammingCode(GF(2), 3).minimum_distance() |
Stateful multi-step workflow:
> evaluate_sage(code="var('a'); f = (a + 1)^5")
result_type: "statement", result: null
> evaluate_sage(code="expand(f)")
result_type: "expression", result: "a^5 + 5*a^4 + 10*a^3 + 10*a^2 + 5*a + 1"
> evaluate_sage(code="diff(f, a, 2)")
result_type: "expression", result: "20*(a + 1)^3"
Calculus Tools
differentiate_expression
Compute the symbolic derivative of an expression. Calls Sage's diff(expr, var, order) internally.
| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | expression | string | required | The expression to differentiate (e.g. "sin(x)*e^x", "x^3 + 2*x"). | | variable | string | "x" | The variable to differentiate with respect to. | | order | int (>= 1) | 1 | Differentiation order. 1 = first derivative, 2 = second derivative, etc. |
Returns: {"derivative": "...", "order": N}
> differentiate_expression(expression="x^5", variable="x", order=3)
{"derivative": "60*x^2", "order": 3}
> differentiate_expression(expression="sin(x)*cos(x)")
{"derivative": "cos(x)^2 - sin(x)^2", "order": 1}
integrate_expression
Compute indefinite or definite integrals. Calls Sage's integrate() function.
| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | expression | string | required | The expression to integrate. | | variable | string | "x" | The integration variable. | | lower_bound | string or null | null | Lower bound for definite integrals. Accepts symbolic values like "0", "-oo" (negative infinity), or expressions like "-pi". | | upper_bound | string or null | null | Upper bound for definite integrals. Accepts "1", "oo" (infinity), "pi/2", etc. |
Bot
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: XBP-Europe
- Source: XBP-Europe/sagemath-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.