mathmethods-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. mathmethods_mcp-0.1.0/LICENSE +21 -0
  2. mathmethods_mcp-0.1.0/PKG-INFO +436 -0
  3. mathmethods_mcp-0.1.0/README.md +418 -0
  4. mathmethods_mcp-0.1.0/mathmethods/__init__.py +7 -0
  5. mathmethods_mcp-0.1.0/mathmethods/__main__.py +6 -0
  6. mathmethods_mcp-0.1.0/mathmethods/compiler.py +202 -0
  7. mathmethods_mcp-0.1.0/mathmethods/core/__init__.py +36 -0
  8. mathmethods_mcp-0.1.0/mathmethods/core/differentiation.py +122 -0
  9. mathmethods_mcp-0.1.0/mathmethods/core/dynamic_1d.py +567 -0
  10. mathmethods_mcp-0.1.0/mathmethods/core/dynamic_2d_conservative.py +283 -0
  11. mathmethods_mcp-0.1.0/mathmethods/core/dynamic_2d_lanchester.py +264 -0
  12. mathmethods_mcp-0.1.0/mathmethods/core/dynamic_2d_linear.py +269 -0
  13. mathmethods_mcp-0.1.0/mathmethods/core/dynamic_2d_non_homogeneous.py +710 -0
  14. mathmethods_mcp-0.1.0/mathmethods/core/dynamic_2d_nonlinear.py +298 -0
  15. mathmethods_mcp-0.1.0/mathmethods/core/integration.py +396 -0
  16. mathmethods_mcp-0.1.0/mathmethods/core/interpolation.py +126 -0
  17. mathmethods_mcp-0.1.0/mathmethods/core/monte_carlo.py +312 -0
  18. mathmethods_mcp-0.1.0/mathmethods/core/ode.py +154 -0
  19. mathmethods_mcp-0.1.0/mathmethods/core/root_finding.py +339 -0
  20. mathmethods_mcp-0.1.0/mathmethods/core/utils.py +226 -0
  21. mathmethods_mcp-0.1.0/mathmethods/server.py +1414 -0
  22. mathmethods_mcp-0.1.0/mathmethods_mcp.egg-info/PKG-INFO +436 -0
  23. mathmethods_mcp-0.1.0/mathmethods_mcp.egg-info/SOURCES.txt +30 -0
  24. mathmethods_mcp-0.1.0/mathmethods_mcp.egg-info/dependency_links.txt +1 -0
  25. mathmethods_mcp-0.1.0/mathmethods_mcp.egg-info/entry_points.txt +2 -0
  26. mathmethods_mcp-0.1.0/mathmethods_mcp.egg-info/requires.txt +8 -0
  27. mathmethods_mcp-0.1.0/mathmethods_mcp.egg-info/top_level.txt +1 -0
  28. mathmethods_mcp-0.1.0/pyproject.toml +44 -0
  29. mathmethods_mcp-0.1.0/setup.cfg +4 -0
  30. mathmethods_mcp-0.1.0/tests/test_dynamic_tools.py +167 -0
  31. mathmethods_mcp-0.1.0/tests/test_extended_tools.py +151 -0
  32. mathmethods_mcp-0.1.0/tests/test_tools.py +198 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Agustin Monetti
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,436 @@
1
+ Metadata-Version: 2.4
2
+ Name: mathmethods-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server exposing numerical-methods tools: bisection, Simpson 1/3, Runge-Kutta 4, Lagrange interpolation
5
+ License-Expression: MIT
6
+ Project-URL: Repository, https://github.com/agmonetti/mathmethods-mcp
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: mcp[cli]==1.14.1
11
+ Requires-Dist: numpy>=1.26.0
12
+ Requires-Dist: sympy>=1.12.0
13
+ Requires-Dist: scipy>=1.11.0
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
16
+ Requires-Dist: ruff>=0.8.0; extra == "dev"
17
+ Dynamic: license-file
18
+
19
+ # MathematicalMethods MCP Server
20
+
21
+ [![MCP Server](https://badge.mcpx.dev?type=server)](https://modelcontextprotocol.io/introduction)
22
+ [![License](https://img.shields.io/github/license/agmonetti/mathmethods-mcp)](LICENSE)
23
+ [![CI](https://github.com/agmonetti/mathmethods-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/agmonetti/mathmethods-mcp/actions/workflows/ci.yml)
24
+ [![PyPI](https://img.shields.io/pypi/v/mathmethods-mcp)](https://pypi.org/project/mathmethods-mcp/)
25
+
26
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes a
27
+ numerical-methods core as tools an LLM agent can call directly from a chat
28
+ (VS Code, Zed, Claude, opencode, etc.). It is built on top of the
29
+ numerical-methods engine of the academic project `modeladoYsimulacion-web`
30
+ (UADE); the math core is **vendored** into this repository so the server is
31
+ fully self-contained.
32
+
33
+ ## Quick start
34
+
35
+ ```bash
36
+ claude mcp add mathmethods-mcp -- uvx mathmethods-mcp
37
+ ```
38
+
39
+ Any MCP client registers the server with the same one-liner command —
40
+ `uvx mathmethods-mcp` (a Python package that needs no cloning, venv or paths):
41
+
42
+ ```json
43
+ { "command": "uvx", "args": ["mathmethods"] }
44
+ ```
45
+
46
+ <details>
47
+ <summary>Run from a checkout instead (for development)</summary>
48
+
49
+ ```bash
50
+ git clone https://github.com/agmonetti/mathmethods-mcp.git
51
+ cd mathmethods
52
+ uv sync --extra dev
53
+ uv run mathmethods
54
+ ```
55
+
56
+ Every client config below also works with
57
+ `uv run --frozen --project <checkout> python <checkout>/server.py` in place of
58
+ `uvx mathmethods-mcp`.
59
+ </details>
60
+
61
+ ## Tools
62
+
63
+ ### Root finding
64
+
65
+ | Tool | What it does |
66
+ | ----------------------- | --------------------------------------------------- |
67
+ | `root_bisection` | Bisection on `[a, b]` (requires a sign change) |
68
+ | `root_newton_raphson` | Newton–Raphson with numeric derivative |
69
+ | `root_punto_fijo` | Fixed-point iteration `x = g(x)` |
70
+ | `root_aitken` | Aitken Δ² acceleration of fixed point |
71
+ | `root_comparar` | All four methods compared on the same problem |
72
+
73
+ ### Numerical integration
74
+
75
+ | Tool | What it does |
76
+ | ----------------------- | --------------------------------------------------- |
77
+ | `integral_rectangulo` | Composite midpoint rule |
78
+ | `integral_trapecio` | Composite trapezoidal rule |
79
+ | `integral_simpson13` | Composite Simpson 1/3 (n even) |
80
+ | `integral_simpson38` | Composite Simpson 3/8 (n multiple of 3) |
81
+ | `integral_comparar` | All four rules compared on the same integral |
82
+
83
+ ### Differentiation
84
+
85
+ | Tool | What it does |
86
+ | ----------------------- | --------------------------------------------------- |
87
+ | `finite_differences` | Forward/backward/central 1st & 2nd derivatives |
88
+
89
+ ### ODE and interpolation
90
+
91
+ | Tool | What it does |
92
+ | ------------------------- | ------------------------------------------------------- |
93
+ | `ode_rk4` | Runge–Kutta 4 (4th order) |
94
+ | `ode_heun` | Heun predictor–corrector (2nd order) |
95
+ | `ode_euler` | Explicit Euler (1st order) |
96
+ | `interpolation_lagrange` | Lagrange interpolating polynomial |
97
+
98
+ ### Monte Carlo
99
+
100
+ | Tool | What it does |
101
+ | ----------------------- | ------------------------------------------------------- |
102
+ | `mc_hit_or_miss_1d` | Hit-or-miss estimator (correct for sign-changing f) |
103
+ | `mc_valor_promedio_1d` | Mean-value estimate of `∫ₐᵇ f(x) dx` |
104
+ | `mc_valor_promedio_2d` | Mean-value estimate of a double integral |
105
+ | `mc_valor_promedio_3d` | Mean-value estimate of a triple integral |
106
+ | `mc_estadistico_1d` | M×N replicated experiment with statistical analysis |
107
+ | `mc_convergencia_1d` | Running average showing the estimate converging |
108
+
109
+ ### Dynamic systems
110
+
111
+ | Tool | What it does |
112
+ | ----------------------------- | --------------------------------------------------------- |
113
+ | `dynamic_1d_solve` | Equilibria, stability, phase portrait and time series |
114
+ | `dynamic_1d_equilibria` | Find and classify the equilibria of `x' = f(x)` |
115
+ | `dynamic_1d_bifurcation` | Equilibria vs parameter (bifurcation diagram) |
116
+ | `dynamic_2d_linear_solve` | Linear `X' = A·X + B`: classification, eigenvalues, analytic solution |
117
+ | `dynamic_2d_nonlinear_solve` | Nonlinear `x' = f(x,y)`: equilibria, Jacobian, nullclines |
118
+ | `dynamic_2d_conservative_solve` | Divergence-free check, Hamiltonian/energy, closed orbits |
119
+ | `dynamic_2d_lanchester_solve` | Lanchester combat model with analytic time-to-annihilation |
120
+ | `dynamic_2d_nonhomogeneous_solve` | Non-homogeneous `X' = A·X + B(t)` with time-varying forcing |
121
+
122
+ Math expressions use Python/SymPy syntax: `x**2`, `sin(x)`, `exp(x)`,
123
+ `sqrt(x)`, `log(x)`. Common shorthand is accepted too: `e^x`, `sen(x)`, `ln(x)`
124
+ and the caret `^` for powers. The Greek combat parameters of Lanchester use the
125
+ Unicode symbols `α β γ ε μ δ`.
126
+
127
+ ## Project layout
128
+
129
+ ```
130
+ modelo-mat-mcp/
131
+ ├── server.py # FastMCP app + all tools
132
+ ├── mathmethods/
133
+ │ ├── compiler.py # hardened expression validation (whitelist, caps)
134
+ │ ├── server.py # FastMCP app and tool definitions
135
+ │ └── core/ # vendored math core (from modeladoYsimulacion-web)
136
+ │ ├── root_finding.py ├── integration.py
137
+ │ ├── ode.py ├── interpolation.py
138
+ │ ├── differentiation.py├── monte_carlo.py
139
+ │ ├── dynamic_1d.py ├── dynamic_2d_linear.py
140
+ │ ├── dynamic_2d_non_homogeneous.py ├── dynamic_2d_nonlinear.py
141
+ │ ├── dynamic_2d_conservative.py ├── dynamic_2d_lanchester.py
142
+ │ └── utils.py
143
+ ├── tests/ # test_tools.py + test_dynamic_tools.py
144
+ ├── mcp.example.json # server registration template (copy to .vscode/mcp.json)
145
+ ├── requirements.txt
146
+ └── pyproject.toml
147
+ ```
148
+
149
+ ## Install
150
+
151
+ ```bash
152
+ cd modelo-mat-mcp
153
+ python3 -m venv venv
154
+ source venv/bin/activate
155
+ pip install -r requirements.txt
156
+ ```
157
+
158
+ > After creating the venv, verify it is isolated (`venv/bin/python -c "import sys; print(sys.prefix)"`
159
+ > should print the venv path, not `/usr`). If your system Python produces a broken venv, try
160
+ > `python3 -m venv --copies venv`.
161
+
162
+ ## Run
163
+
164
+ **Local (STDIO)** — default transport, used by VS Code / Claude Desktop:
165
+
166
+ ```bash
167
+ uv run python server.py
168
+ ```
169
+
170
+ **Remote (Streamable HTTP)** — the server prints a URL such as `http://127.0.0.1:8000/mcp`:
171
+
172
+ ```bash
173
+ MCP_TRANSPORT=streamable-http uv run python server.py
174
+ ```
175
+
176
+ The transport can also be chosen with the `MCP_TRANSPORT` environment variable
177
+ (`stdio` | `streamable-http` | `sse`), and the HTTP host/port with
178
+ `MCP_HTTP_HOST` / `MCP_HTTP_PORT` (defaults `127.0.0.1:8000`).
179
+
180
+ ## Connect from a client
181
+
182
+ Every client registers the **same command**, `uvx mathmethods-mcp` (no paths, no
183
+ venv). If the server is not published yet or you work from a checkout, use
184
+ `uv run --frozen --project <PROJ> python <PROJ>/server.py` instead.
185
+
186
+ **Remote (Streamable HTTP)** — optional; start it once in a terminal, then
187
+ point the client at `http://127.0.0.1:8000/mcp`:
188
+
189
+ ```bash
190
+ MCP_TRANSPORT=streamable-http uvx mathmethods-mcp
191
+ ```
192
+
193
+ <details>
194
+ <summary><b>VS Code</b></summary>
195
+
196
+ Create `.vscode/mcp.json` (git-ignored) — or copy `mcp.example.json`:
197
+
198
+ ```json
199
+ {
200
+ "servers": {
201
+ "modelo-mat-stdio": {
202
+ "type": "stdio",
203
+ "command": "uvx",
204
+ "args": ["mathmethods"]
205
+ },
206
+ "modelo-mat-http": {
207
+ "type": "http",
208
+ "url": "http://127.0.0.1:8000/mcp"
209
+ }
210
+ }
211
+ }
212
+ ```
213
+
214
+ Open the file and press **Start** next to the server you want; reload the
215
+ window if it doesn't appear (`Developer: Reload Window`).
216
+
217
+ </details>
218
+
219
+ <details>
220
+ <summary><b>Zed</b></summary>
221
+
222
+ Add the entry under `context_servers` (note: **not** `mcp_servers`) in
223
+ `~/.config/zed/settings.json` or the project-level `.zed/settings.json`:
224
+
225
+ ```json
226
+ {
227
+ "context_servers": {
228
+ "modelo-mat": {
229
+ "command": "uvx",
230
+ "args": ["mathmethods"]
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ You can also manage them via **Settings → AI → MCP Servers**.
237
+
238
+ </details>
239
+
240
+ <details>
241
+ <summary><b>opencode / OpenChamber</b></summary>
242
+
243
+ Both opencode and the OpenChamber desktop app share the same configuration
244
+ format. Add the entry under `mcp` in `opencode.json` (project root) or in the
245
+ global `~/.config/opencode/opencode.jsonc`:
246
+
247
+ ```json
248
+ {
249
+ "mcp": {
250
+ "modelo-mat": {
251
+ "type": "local",
252
+ "command": ["uvx", "mathmethods"],
253
+ "enabled": true
254
+ }
255
+ }
256
+ }
257
+ ```
258
+
259
+ Or register it with the CLI (equivalent):
260
+
261
+ ```bash
262
+ opencode mcp add modelo-mat -- uvx mathmethods-mcp
263
+ ```
264
+
265
+ For a remote server running on `http://127.0.0.1:8000/mcp`:
266
+
267
+ ```json
268
+ {
269
+ "mcp": {
270
+ "modelo-mat": {
271
+ "type": "remote",
272
+ "url": "http://127.0.0.1:8000/mcp",
273
+ "enabled": true
274
+ }
275
+ }
276
+ }
277
+ ```
278
+
279
+ Verify with `opencode mcp list`.
280
+
281
+ </details>
282
+
283
+ <details>
284
+ <summary><b>Antigravity</b></summary>
285
+
286
+ Add the entry under `mcpServers` in the Antigravity config file, typically
287
+ `~/.gemini/antigravity/mcp_config.json`:
288
+
289
+ ```json
290
+ {
291
+ "mcpServers": {
292
+ "modelo-mat": {
293
+ "command": "uvx",
294
+ "args": ["mathmethods"]
295
+ }
296
+ }
297
+ }
298
+ ```
299
+
300
+ If the file path differs on your install, use the in-IDE **Settings →
301
+ Integrations → MCP Servers** panel instead, which writes the same format.
302
+
303
+ </details>
304
+
305
+ <details>
306
+ <summary><b>GitHub Copilot CLI</b></summary>
307
+
308
+ The GitHub Copilot CLI (`copilot`) lets you add a server interactively:
309
+
310
+ ```bash
311
+ copilot
312
+ ```
313
+
314
+ then inside the session:
315
+
316
+ ```text
317
+ /mcp add
318
+ Server name: modelo-mat
319
+ Server type: 1 (Local/STDIO)
320
+ Command: uvx mathmethods-mcp
321
+ ```
322
+
323
+ Press `Ctrl+S` to save. The settings are stored in
324
+ `~/.copilot/mcp-config.json` (top-level `mcpServers`); check the connection
325
+ with `/mcp show`.
326
+
327
+ </details>
328
+
329
+ <details>
330
+ <summary><b>Claude Desktop / Claude Code</b></summary>
331
+
332
+ Both use the `mcpServers` format. In Claude Desktop, edit
333
+ `claude_desktop_config.json`; in Claude Code:
334
+
335
+ ```bash
336
+ claude mcp add mathmethods-mcp -- uvx mathmethods-mcp
337
+ ```
338
+
339
+ ```json
340
+ {
341
+ "mcpServers": {
342
+ "modelo-mat": {
343
+ "command": "uvx",
344
+ "args": ["mathmethods"]
345
+ }
346
+ }
347
+ }
348
+ ```
349
+ </details>
350
+
351
+ ### Verify with the MCP Inspector
352
+
353
+ ```bash
354
+ npx @modelcontextprotocol/inspector node server.py # or
355
+ npx @modelcontextprotocol/inspector --transport http http://127.0.0.1:8000/mcp
356
+ ```
357
+
358
+ ## Example usage
359
+
360
+ Ask your agent things like:
361
+
362
+ - "Find the root of `x^3 - 3x + 1` in `[0, 1]`."
363
+ - "Integrate `sin(x)/x` from 0 to 1 using Simpson with n=10."
364
+ - "Solve `y' = y` with y(0)=1 from x=0 to x=1 with step 0.1 (RK4)."
365
+ - "Build the Lagrange polynomial through (0,1), (1,3), (2,7) and evaluate at 1.5."
366
+ - "Estimate the integral of `sin(x)` over `[0, 2pi]` with Monte Carlo hit-or-miss."
367
+ - "Find the equilibria of the logistic model `x' = mu*x*(1 - x/K)` with K=2, mu=1."
368
+ - "Classify the 2D system `x' = 2x - y`, `y' = x + 2y` and sketch its trajectories."
369
+ - "Simulate a Lanchester battle x'=-αy, y'=-βx with α=1, β=2, 100 vs 80 soldiers."
370
+
371
+ ## Security
372
+
373
+ The server is **read-only**: the tools only compute numbers, they never touch
374
+ the filesystem, the network or any destructive operation. Still, the inputs are
375
+ driven by an LLM, so defense in depth is applied:
376
+
377
+ - **Expression hardening** (`mathmethods/compiler.py` + `mathmethods/core/utils.py`):
378
+ length cap, symbol whitelist, function whitelist, and a lexical gate that
379
+ rejects attribute access (`.`/`__`) and unknown tokens BEFORE SymPy parses.
380
+ SymPy's `sympify`/`parse_expr` can execute arbitrary Python (verified RCE),
381
+ so every parse site — in this project and in the upstream backend — routes
382
+ through the gate.
383
+ - **Input caps**: iteration/subinterval/step/point counts are bounded to avoid
384
+ pathological CPU/RAM usage.
385
+ - **Exact tool descriptions**: the LLM picks tools by their metadata, so
386
+ descriptions stay accurate (guards against tool-poisoning attacks).
387
+ - **Prompt injection**: even if the model is tricked, the worst it can do is ask
388
+ for another computation. There are no privileged side channels.
389
+
390
+ ## Known limitations
391
+
392
+ - The vendored core is inherited from the upstream project and kept as-is
393
+ (Spanish identifiers, etc.).
394
+ - `dynamic_2d_nonhomogeneous_solve` with **time-varying forcing on a
395
+ non-diagonal matrix A** shows the homogeneous solution only (the particular
396
+ term is computed for diagonal systems); the numeric RK4 trajectory is always
397
+ correct.
398
+ - The 1D bifurcation table is downsampled to 300 rows for readability.
399
+
400
+ ## Publishing to PyPI
401
+
402
+ The package is publish-ready (`uv build` succeeds and the wheel exposes all
403
+ tools). To release:
404
+
405
+ ```bash
406
+ uv build
407
+ uv publish # requires a PyPI token: `uv login` or UV_PUBLISH_TOKEN
408
+ ```
409
+
410
+ Once published, every client config just works with `uvx mathmethods-mcp` (no
411
+ paths, no venv). Bump `version` in `pyproject.toml` before each release.
412
+
413
+ ## Keeping the vendored core in sync
414
+
415
+ The math lives in `modeladoYsimulacion-web/backend/app/methods/`. When the
416
+ upstream code changes, copy the files here again:
417
+
418
+ ```bash
419
+ cp ../modeladoYsimulacion-web/backend/app/methods/{root_finding,integration,ode,interpolation,monte_carlo,dynamic_1d,dynamic_2d_linear,dynamic_2d_non_homogeneous,dynamic_2d_nonlinear,dynamic_2d_conservative,dynamic_2d_lanchester}.py mathmethods/core/
420
+ cp ../modeladoYsimulacion-web/backend/app/core/utils.py mathmethods/core/utils.py
421
+ ```
422
+
423
+ Then rewrite the `from app.core.utils import ...` imports to `from .utils
424
+ import ...` in the copied files.
425
+
426
+ ## Test
427
+
428
+ ```bash
429
+ uv run pytest
430
+ ```
431
+
432
+ ## Roadmap
433
+
434
+ - Translate the vendored core to English (manual, when time allows).
435
+ - Server-side CI is wired up (`.github/workflows/ci.yml`); coverage report next.
436
+ - Optional MCP resources/prompts (e.g. a theorem reference) on top of the tools.