mathmethods-mcp
# Mathematical/Numerical Methods - MCP Server
[](https://modelcontextprotocol.io/introduction)
[](LICENSE)
[](https://github.com/agmonetti/mathmethods-mcp/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@agmonetti/mathmethods-mcp)
[](https://pypi.org/project/mathmethods-mcp/)
[](https://m8ven.ai/mcp/agmonetti-mathmethods-mcp-1l7999)
[](https://aiagentslisting.com/mcp/mathmethods-mcp)
A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes a
numerical-methods core as tools an LLM agent can call directly from a chat
(VS Code, Zed, Claude, opencode, etc.). It is built on top of the
numerical-methods engine of the academic project `modeladoYsimulacion-web`
(UADE); the math core is **vendored** into this repository so the server is
fully self-contained.
## Installation and Usage
### 1. Run with NPX (Recommended)
Runs on-demand without any global installation:
#### Claude Code (One-liner CLI)
```bash
claude mcp add mathmethods npx -y @agmonetti/mathmethods-mcp
```
#### Claude Desktop & Cursor (JSON Configuration)
Add to your `claude_desktop_config.json` or `.cursor/mcp.json`:
```json
{
"mcpServers": {
"mathmethods": {
"command": "npx",
"args": ["-y", "@agmonetti/mathmethods-mcp"]
}
}
}
```
---
### 2. Install Globally from NPM
Ideal for instant startup without network latency on every invocation:
```bash
npm install -g @agmonetti/mathmethods-mcp
```
```json
{
"mcpServers": {
"mathmethods": {
"command": "mathmethods-mcp"
}
}
}
```
---
### 3. Run with UVX (Direct Python)
Any MCP client can also run the Python package directly with Astral's `uvx`:
```bash
claude mcp add mathmethods-mcp -- uvx mathmethods-mcp
```
```json
{
"mcpServers": {
"mathmethods": {
"command": "uvx",
"args": ["mathmethods-mcp"]
}
}
}
```
<details>
<summary>Run from a checkout instead (for development)</summary>
```bash
git clone https://github.com/agmonetti/mathmethods-mcp.git
cd mathmethods-mcp
uv sync --extra dev
uv run server.py
```
Every client config above also works with
`uv run --frozen --project <checkout> python <checkout>/server.py` in place of
`npx -y @agmonetti/mathmethods-mcp` or `uvx mathmethods-mcp`.
</details>
## Tools
### Root finding
| Tool | What it does |
| ----------------------- | --------------------------------------------------- |
| `root_bisection` | Bisection on `[a, b]` (sign change or endpoint root) |
| `root_newton_raphson` | Newton–Raphson with numeric derivative |
| `root_punto_fijo` | Fixed-point iteration `x = g(x)` |
| `root_aitken` | Aitken Δ² acceleration of fixed point |
| `root_comparar` | All four methods compared on the same problem |
### Numerical integration
| Tool | What it does |
| ----------------------- | --------------------------------------------------- |
| `integral_rectangulo` | Composite midpoint rule |
| `integral_trapecio` | Composite trapezoidal rule |
| `integral_simpson13` | Composite Simpson 1/3 (n even) |
| `integral_simpson38` | Composite Simpson 3/8 (n multiple of 3) |
| `integral_comparar` | All four rules compared (n multiple of 6) |
### Differentiation
| Tool | What it does |
| ----------------------- | --------------------------------------------------- |
| `finite_differences` | Forward/backward/central 1st & 2nd derivatives |
### ODE and interpolation
| Tool | What it does |
| ------------------------- | ------------------------------------------------------- |
| `ode_rk4` | Runge–Kutta 4 (4th order) |
| `ode_heun` | Heun predictor–corrector (2nd order) |
| `ode_euler` | Explicit Euler (1st order) |
| `interpolation_lagrange` | Lagrange interpolating polynomial |
### Monte Carlo
| Tool | What it does |
| ----------------------- | ------------------------------------------------------- |
| `mc_hit_or_miss_1d` | Hit-or-miss estimator (correct for sign-changing f) |
| `mc_valor_promedio_1d` | Mean-value estimate of `∫ₐᵇ f(x) dx` |
| `mc_valor_promedio_2d` | Mean-value estimate of a double integral |
| `mc_valor_promedio_3d` | Mean-value estimate of a triple integral |
| `mc_estadistico_1d` | M×N replicated experiment with statistical analysis |
| `mc_convergencia_1d` | Running average showing the estimate converging |
### Dynamic systems
| Tool | What it does |
| ----------------------------- | --------------------------------------------------------- |
| `dynamic_1d_solve` | Equilibria, stability, phase portrait and time series |
| `dynamic_1d_equilibria` | Find and classify the equilibria of `x' = f(x)` |
| `dynamic_1d_bifurcation` | Equilibria vs parameter (bifurcation diagram) |
| `dynamic_2d_linear_solve` | Linear `X' = A·X + B`: classification, eigenvalues, analytic solution |
| `dynamic_2d_nonlinear_solve` | Nonlinear `x' = f(x,y)`: equilibria, Jacobian, nullclines |
| `dynamic_2d_conservative_solve` | Divergence-free check, Hamiltonian/energy, closed orbits |
| `dynamic_2d_lanchester_solve` | Lanchester combat model with analytic time-to-annihilation |
| `dynamic_2d_nonhomogeneous_solve` | Non-homogeneous `X' = A·X + B(t)` with time-varying forcing |
Math expressions use Python/SymPy syntax: `x**2`, `sin(x)`, `exp(x)`,
`sqrt(x)`, `log(x)`. Common shorthand is accepted too: `e^x`, `sen(x)`, `ln(x)`
and the caret `^` for powers. The Greek combat parameters of Lanchester use the
Unicode symbols `α β γ ε μ δ`.
## Plots (optional)
Every tool accepts a `plot=False | True` flag. With `plot=True` the response
contains the usual JSON **plus** a rendered PNG (an MCP image content block):
phase portraits, solution curves, bifurcation diagrams, Monte Carlo
convergence, and so on.
```text
"Solve y' = y, y(0)=1 on [0,1] with RK4 and show me the plot."
```
Plotting needs the optional `viz` extra (Matplotlib), which is **not** part of
the default install so the stdio server startup stays light:
```bash
pip install "mathmethods-mcp[viz]" # pip
uvx --from "mathmethods-mcp[viz]" mathmethods-mcp # uv
uv sync --extra viz # from a checkout
```
If `plot=True` is used without the extra, the tool returns a clear error telling
you how to install it. Clients that do not render images still receive the JSON
result alongside the image, so nothing is lost.
## Project layout
```
mathmethods-mcp/
├── server.py # FastMCP app + all tools
├── mathmethods/
│ ├── compiler.py # hardened expression validation (whitelist, caps)
│ ├── plots.py # optional PNG rendering (plot=True), lazy matplotlib
│ ├── server.py # FastMCP app and tool definitions
│ └── core/ # vendored math core (from modeladoYsimulacion-web)
│ ├── root_finding.py ├── integration.py
│ ├── ode.py ├── interpolation.py
│ ├── differentiation.py├── monte_carlo.py
│ ├── dynamic_1d.py ├── dynamic_2d_linear.py
│ ├── dynamic_2d_non_homogeneous.py ├── dynamic_2d_nonlinear.py
│ ├── dynamic_2d_conservative.py ├── dynamic_2d_lanchester.py
│ └── utils.py
├── tests/ # test_tools.py + test_dynamic_tools.py + test_plots.py
├── mcp.example.json # server registration template (copy to .vscode/mcp.json)
├── requirements.txt
└── pyproject.toml
```
## Install
```bash
cd mathmethods-mcp
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
> After creating the venv, verify it is isolated (`venv/bin/python -c "import sys; print(sys.prefix)"`
> should print the venv path, not `/usr`). If your system Python produces a broken venv, try
> `python3 -m venv --copies venv`.
## Run
**Local (STDIO)** — default transport, used by VS Code / Claude Desktop:
```bash
uv run python server.py
```
**Remote (Streamable HTTP)** — the server prints a URL such as `http://127.0.0.1:8000/mcp`:
```bash
MCP_TRANSPORT=streamable-http uv run python server.py
```
The transport can also be chosen with the `MCP_TRANSPORT` environment variable
(`stdio` | `streamable-http` | `sse`), and the HTTP host/port with
`MCP_HTTP_HOST` / `MCP_HTTP_PORT` (defaults `127.0.0.1:8000`).
## Connect from a client
Every client registers the **same command**, `uvx mathmethods-mcp` (no paths, no
venv). If the server is not published yet or you work from a checkout, use
`uv run --frozen --project <PROJ> python <PROJ>/server.py` instead.
**Remote (Streamable HTTP)** — optional; start it once in a terminal, then
point the client at `http://127.0.0.1:8000/mcp`:
```bash
MCP_TRANSPORT=streamable-http uvx mathmethods-mcp
```
<details>
<summary><b>VS Code</b></summary>
Create `.vscode/mcp.json` (git-ignored) — or copy `mcp.example.json`:
```json
{
"servers": {
"mathmethods-stdio": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@agmonetti/mathmethods-mcp"]
},
"mathmethods-http": {
"type": "http",
"url": "http://127.0.0.1:8000/mcp"
}
}
}
```
Open the file and press **Start** next to the server you want; reload the
window if it doesn't appear (`Developer: Reload Window`).
</details>
<details>
<summary><b>Zed</b></summary>
Add the entry under `context_servers` (note: **not** `mcp_servers`) in
`~/.config/zed/settings.json` or the project-level `.zed/settings.json`:
```json
{
"context_servers": {
"mathmethods": {
"command": "npx",
"args": ["-y", "@agmonetti/mathmethods-mcp"]
}
}
}
```
You can also manage them via **Settings → AI → MCP Servers**.
</details>
<details>
<summary><b>opencode / OpenChamber</b></summary>
Both opencode and the OpenChamber desktop app share the same configuration
format. Add the entry under `mcp` in `opencode.json` (project root) or in the
global `~/.config/opencode/opencode.jsonc`:
```json
{
"mcp": {
"mathmethods": {
"type": "local",
"command": ["npx", "-y", "@agmonetti/mathmethods-mcp"],
"enabled": true
}
}
}
```
Or register it with the CLI (equivalent):
```bash
opencode mcp add mathmethods -- npx -y @agmonetti/mathmethods-mcp
```
For a remote server running on `http://127.0.0.1:8000/mcp`:
```json
{
"mcp": {
"mathmethods": {
"type": "remote",
"url": "http://127.0.0.1:8000/mcp",
"enabled": true
}
}
}
```
Verify with `opencode mcp list`.
</details>
<details>
<summary><b>Antigravity</b></summary>
Add the entry under `mcpServers` in the Antigravity config file, typically
`~/.gemini/antigravity/mcp_config.json`:
```json
{
"mcpServers": {
"mathmethods": {
"command": "npx",
"args": ["-y", "@agmonetti/mathmethods-mcp"]
}
}
}
```
If the file path differs on your install, use the in-IDE **Settings →
Integrations → MCP Servers** panel instead, which writes the same format.
</details>
<details>
<summary><b>GitHub Copilot CLI</b></summary>
The GitHub Copilot CLI (`copilot`) lets you add a server interactively:
```bash
copilot
```
then inside the session:
```text
/mcp add
Server name: mathmethods
Server type: 1 (Local/STDIO)
Command: npx -y @agmonetti/mathmethods-mcp
```
Press `Ctrl+S` to save. The settings are stored in
`~/.copilot/mcp-config.json` (top-level `mcpServers`); check the connection
with `/mcp show`.
</details>
<details>
<summary><b>Claude Desktop / Claude Code</b></summary>
Both use the `mcpServers` format. In Claude Desktop, edit
`claude_desktop_config.json`; in Claude Code:
```bash
claude mcp add mathmethods npx -y @agmonetti/mathmethods-mcp
```
```json
{
"mcpServers": {
"mathmethods": {
"command": "npx",
"args": ["-y", "@agmonetti/mathmethods-mcp"]
}
}
}
```
</details>
### Verify with the MCP Inspector
```bash
npx @modelcontextprotocol/inspector node server.py # or
npx @modelcontextprotocol/inspector --transport http http://127.0.0.1:8000/mcp
```
## Example usage
Ask your agent things like:
- "Find the root of `x^3 - 3x + 1` in `[0, 1]`."
- "Integrate `sin(x)/x` from 0 to 1 using Simpson with n=10."
- "Solve `y' = y` with y(0)=1 from x=0 to x=1 with step 0.1 (RK4)."
- "Build the Lagrange polynomial through (0,1), (1,3), (2,7) and evaluate at 1.5."
- "Estimate the integral of `sin(x)` over `[0, 2pi]` with Monte Carlo hit-or-miss."
- "Find the equilibria of the logistic model `x' = mu*x*(1 - x/K)` with K=2, mu=1."
- "Classify the 2D system `x' = 2x - y`, `y' = x + 2y` and sketch its trajectories."
- "Simulate a Lanchester battle x'=-αy, y'=-βx with α=1, β=2, 100 vs 80 soldiers."
## Security
The server is **read-only**: the tools only compute numbers, they never touch
the filesystem, the network or any destructive operation. Still, the inputs are
driven by an LLM, so defense in depth is applied:
- **Expression hardening** (`mathmethods/compiler.py` + `mathmethods/core/utils.py`):
length cap, symbol whitelist, function whitelist, and a lexical gate that
rejects attribute access (`.`/`__`) and unknown tokens BEFORE SymPy parses.
SymPy's `sympify`/`parse_expr` can execute arbitrary Python (verified RCE),
so every parse site — in this project and in the upstream backend — routes
through the gate.
- **Input caps**: iteration/subinterval/step/point counts are bounded to avoid
pathological CPU/RAM usage.
- **Exact tool descriptions**: the LLM picks tools by their metadata, so
descriptions stay accurate (guards against tool-poisoning attacks).
- **Prompt injection**: even if the model is tricked, the worst it can do is ask
for another computation. There are no privileged side channels.
## Known limitations
- The vendored core is inherited from the upstream project and kept as-is
(Spanish identifiers, etc.).
- `dynamic_2d_nonhomogeneous_solve` with **time-varying forcing on a
non-diagonal matrix A** shows the homogeneous solution only (the particular
term is computed for diagonal systems); the numeric RK4 trajectory is always
correct.
- The 1D bifurcation table is downsampled to 300 rows for readability.
TDQS
Scored across 29 tools
Most tools target a distinct numerical method, but several pairs overlap heavily: dynamic_1d_solve already returns equilibria, stability, phase portrait and time series, which is nearly what dynamic_1d_equilibria does, and dynamic_2d_linear_solve (X'=A·X+B with constant B) is a special case of dynamic_2d_nonhomogeneous_solve, making selection guesswork. The Monte Carlo family (valor_promedio, estadistico, convergencia, hit_or_miss) is distinguishable but requires reading descriptions closely, and individual rule tools versus the two *_comparar tools also invite misselection.
A domain-prefix convention exists (integral_, root_, ode_, mc_, dynamic_1d_, dynamic_2d_) and is mostly snake_case, but it is broken by bare names like finite_differences and interpolation_lagrange. Spanish and English are mixed within the same pattern (integral_comparar vs integral_trapecio vs root_newton_raphson; mc_valor_promedio_1d vs mc_hit_or_miss_1d), and suffixes mix verbs (solve, comparar) with nouns, so the scheme is readable but not predictable.
At 29 tools this is well past a comfortable scope for one server. The surface could be consolidated substantially: the four quadrature rules could be a single tool with a 'method' parameter (the comparison tool already does this), as could the three ODE solvers and several of the 2D dynamical-system variants.
Core numerical analysis areas are well covered — root finding, quadrature, ODE IVPs, Monte Carlo, and dynamical systems each have multiple methods plus comparison tools. However, there are notable gaps: interpolation has only Lagrange (no Newton/divided differences or splines), and there are no direct linear-system solvers (Gauss elimination, LU, iterative methods) or least-squares/curve-fitting tools, which are standard in this domain.