Skip to main content
Glama
Nighty3098

Mathcad 15 MCP Server

by Nighty3098

Mathcad 15 MCP Server

An MCP server (stdio transport) for driving Mathcad 15 from an LLM: set input variables, recalculate, read results, inspect regions, diagnose errors, save/export worksheets. Windows + Python 3.10+ (developed and verified on 64-bit Python 3.14.3).

Quick start (Windows)

cd C:\Users\Nighty\Desktop\MathCadMCP
.\.venv\Scripts\pip.exe install -r requirements.txt
.\.venv\Scripts\pip.exe install -e .
# Check without the MCP protocol (COM thread + live Mathcad):
.\.venv\Scripts\python.exe scripts\test_manager.py
# Unit + protocol:
.\.venv\Scripts\python.exe -m pytest tests\test_converters.py tests\test_schemas.py tests\test_protocol_smoke.py -q
# Live (requires a running Mathcad 15):
.\.venv\Scripts\python.exe -m pytest tests\test_live.py -q -m live

Manual server start: scripts\smoke.ps1 (it will hang waiting on stdio — that is expected).

Related MCP server: root-ext-cad

Client configuration

opencode (opencode.json, already in the repo root)

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "mathcad15": {
      "type": "local",
      "command": ["C:\\Users\\Nighty\\Desktop\\MathCadMCP\\.venv\\Scripts\\python.exe", "-m", "mathcad_mcp.server"],
      "cwd": "C:\\Users\\Nighty\\Desktop\\MathCadMCP",
      "environment": {
        "PYTHONPATH": "C:\\Users\\Nighty\\Desktop\\MathCadMCP\\src",
        "MATHCAD_ATTACH_ONLY": "1",
        "MATHCAD_MCP_LOG": "INFO"
      },
      "timeout": 310000,
      "enabled": true
    }
  }
}

Restart opencode after editing the config (it is loaded once at startup). timeout: 310000 matters: recalculate may run for up to 300 s.

Claude Desktop / other MCP clients (mcp.json)

{
  "mcpServers": {
    "mathcad15": {
      "command": "C:\\Users\\Nighty\\Desktop\\MathCadMCP\\.venv\\Scripts\\python.exe",
      "args": ["-m", "mathcad_mcp.server"],
      "cwd": "C:\\Users\\Nighty\\Desktop\\MathCadMCP",
      "env": {
        "PYTHONPATH": "C:\\Users\\Nighty\\Desktop\\MathCadMCP\\src",
        "MATHCAD_ATTACH_ONLY": "1",
        "MATHCAD_MCP_LOG": "INFO"
      }
    }
  }
}

Environment variables

Variable

Default

Description

MATHCAD_MCP_LOG

INFO

DEBUG|INFO|WARNING|ERROR; logs go to stderr only

MATHCAD_VISIBLE

(untouched)

1/0…; empty = do not change Visible

MATHCAD_ATTACH_ONLY

1

1 = attach only, otherwise try DispatchEx

MATHCAD_TIMEOUT_S

30

connect timeout

MATHCAD_DEFAULT_DIR

base for relative paths

MATHCAD_ALLOWED_DIRS

;-separated path jail; empty = no restriction

MATHCAD_MAX_MATRIX_ELEMENTS

10000

cap + truncated flag

MATHCAD_MAX_REGIONS

1000

scan cap

MATHCAD_AUTO_CONNECT

1

connect at server startup

MATHCAD_AUTOQUIT_ON_SHUTDOWN

0

(reserved; Quit still requires force)

MATHCAD_ALLOW_DESTRUCTIVE_NO_CONFIRM

0

dangerous: bypasses confirm_discard in tests

MATHCAD_READ_ONLY

0

1 disables all mutating tools (set/recalc/save/close/quit); reads still work

MATHCAD_BRIDGE_PYTHON

path to 32-bit Python for complex input (see below)

MATHCAD_BRIDGE_TIMEOUT_S

60

bridge call timeout

CLI flags (--attach-only/--no-attach-only, --visible/--no-visible, --timeout-s, --log-level, --auto-connect/--no-auto-connect) override the environment. Booleans accept 1/0, true/false, yes/no, on/off.

Example session

status()                                            -> connected, Mathcad 14.1.5.594
open_worksheet(path="C:/docs/calc.xmcd")            -> {name, fullname, ...}
set_value(name="F", value=10)                       -> {name: "F"}
recalculate()                                       -> {recalculated: ...}
get_value(name="Smax")                              -> {type: "real", real: 25.0, as_string: "25"}
batch_compute(inputs={"F": 15}, outputs=["Smax"])   -> {applied_inputs, outputs, recalculated}

See also examples/demo_script.py (cleans up after itself via VT_NULL).

Listing variables and units

list_variables() parses math-region XML (<define> per Math10.xsd) and returns defined names with kind (variable/function) and region index. get_value() additionally reports unit (e.g. "m*s^-1") rendered from the defining region's UnitsXML — null when the region has no interface or units (old/protected sheets).

Complex input via the 32-bit bridge (optional)

64-bit Python cannot construct Mathcad.NumericValue, so set_value(name="z", value={"real": 3, "imag": 4}) needs a helper:

  1. Install a 32-bit Python (e.g. 3.12 32-bit) and pywin32 into it.

  2. Set MATHCAD_BRIDGE_PYTHON=C:\Python312-32\python.exe.

  3. Complex scalars and complex matrices are then written through scripts/com_bridge_main.py (own process, same live Mathcad via GetActiveObject); results read back normally with Real/Imag.

Without the bridge, complex input returns UNSUPPORTED_OPERATION.

Demo sheet for full live checks (create manually, 2 minutes)

The Automation API cannot create math regions, so this file is created once by hand in Mathcad 15 and saved as examples\beamdef_demo.xmcd:

  1. F := 10

  2. Smax := F * 2.5

  3. M := [[1, 2], [3, 4]] (2×2 matrix via the matrix operator)

  4. Save as examples\beamdef_demo.xmcd.

Without it, live tests run in round-trip mode on a copy of the stock Handbook\datapack\basics.xmcd; with it, they additionally verify the computation F=10 → Smax=25.

Known limitations (empirically confirmed)

  1. Complex INPUT from 64-bit Python needs the bridge (UNSUPPORTED_OPERATION without it): Mathcad.NumericValue/MatrixValue/StringValue are 32-bit in-proc objects (automation.dllCLASS_E_CLASSNOTAVAILABLE). With MATHCAD_BRIDGE_PYTHON set, complex scalars/matrices work. Reading complex values (Real/Imag) always works.

  2. Top/bottom binding: SetValue binds at the top of the sheet, GetValue reads the bottommost definition; redefinitions in the sheet shadow the input.

  3. Units cannot be passed via Automation (per the VB sample notes in DevRef); AsString may carry units and locale formatting (, vs .) — it is never parsed as a number.

  4. Editing formulas/regions is impossible via the Automation API.

  5. Sheets with protected/scripted regions (e.g. DiffTool fixtures) may reject GetValue for SetValue bindings — use ordinary sheets.

  6. Variable listing (list_variables) only sees regions exposing MathInterface (fresh math regions); old/protected sheets yield [].

  7. Collections and matrices are 0-based (empirical + DevRef GetElement); the outer API is 0-based everywhere.

  8. No UI: format pickers (mcPromptUser=1 is forbidden), interactive handbooks, modal dialogs — the server never triggers them.

  9. MCP SDK: uses the installed mcp==2.2.0 (MCPServer, run_stdio_async). The separate PyPI package fastmcp is NOT required and NOT installed (different project, would conflict with mcp v2).

Safety

  • save_option only 0/2; 1 (prompt) is rejected by validation.

  • Closing an unsaved sheet without confirm_discard=true is refused; nothing is closed.

  • Quit() on a foreign process only with force=true.

  • Overwrite via save_as/export: existing file → .bak-<timestamp>, then size > 0 is verified.

  • Paths: absolute, ~ expanded, MATHCAD_ALLOWED_DIRS jail, open restricted to .xmcd/.mcd/.xmcdz/.xmct; handbooks are refused by Mathcad itself.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to automate SolidWorks (open/save parts, modify dimensions, export STEP) via COM, and optionally generate geometry using build123d code-CAD with PNG previews.
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    CAD-engineering MCP tool server for parametric modeling, DFM validation, mechanical calculations, and more. Enables code-CAD builds (build123d/CadQuery), model inspection, meshing, and mechanical calculators via MCP stdio.
    11
    -
  • A
    license
    A
    quality
    D
    maintenance
    A stdio MCP server that gives LLMs a safe scientific calculator with infix math, complex numbers, matrices, statistics, unit conversions, and more via tools that return JSON.
    33
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI hosts to interact with a browser CAD workbench through model-neutral local stdio or authenticated remote MCP tools, supporting command discovery, design-health analysis, and scoped previews while never reading local files or taking over open sessions.
    MIT