Content
# Tool List
[](https://pypi.org/project/baltamatica-mcp/)
[](LICENSE)
[](https://modelcontextprotocol.io)
[](https://www.baltamatica.com)
> 🔗 Let AI agents (Claude Code / Cursor / Codex) directly drive the domestic scientific computing software **Baltamatica** for interactive numerical computing.
## 📖 Project Overview
**baltamatica.mcp** is an open-source service based on the [Model Context Protocol (MCP)](https://modelcontextprotocol.io), providing a two-way communication bridge between large language models and the Baltamatica scientific computing kernel.
Through this project, AI agents can:
- 🧮 **Execute code**: Run `.m` scripts or single-line expressions directly in Baltamatica and retrieve console output
- 📊 **Read variables**: Get the values of matrices, vectors, structures, and cell arrays in the workspace (BEX backend binary fidelity)
- ✍️ **Write variables**: Inject scalars/vectors/matrices into the workspace (`set_variable`)
- 🔍 **Query status**: List the names, types, and dimensions of all variables in the current workspace
- 📂 **Manage scripts**: Run local `.m` script files
- 🧹 **Clear workspace**: Reset the computing environment
**Current status**: Two backends are available.
- **CLI backend**: Execute code through the Baltamatica command-line entry, using `.mat` status files to maintain workspace variables between multiple MCP calls. Supports all 6 tools.
- **BEX backend**: A C bridge running in the Baltamatica GUI process (JSON-over-TCP), supporting `execute_code`, `run_script`, `list_variables`, `get_variable`, `set_variable`, and `clear_workspace`:
- `get_variable` uses base64 binary fidelity for numerical/logical arrays (real and complex numbers, arbitrary size) and structured JSON for characters/strings/structures/cell arrays
- `set_variable` uses `bxAddVariable` to inject scalars/vectors/matrices into the workspace
- `execute_code`/`run_script` use `evalc` to capture console output and parse `BALTAMATICA_ARTIFACT=` file products
- The bridge lifecycle is robust (reliable `stop`, Ctrl-C recovery, `background` mode) and can trigger GUI Figure pop-ups (but Baltamatica itself has no graphics export function, see below)
## 🏗️ System Architecture
The project provides two backends. The **CLI backend** executes code through the Baltamatica command-line entry, using `.mat` status files to maintain workspace variables, and does not require compilation. The **BEX backend** is a C bridge running in the Baltamatica GUI process, using **JSON-over-TCP**, providing low-latency long connections, binary variable transmission, and variable injection. Both expose the same MCP toolset.
```
┌──────────────────────────────────────────────────────────┐
│ AI Agent (Claude Code / Cursor / Codex) │
└─────────────────────────┬────────────────────────────────┘
│ MCP Protocol (stdio)
▼
┌──────────────────────────────────────────────────────────┐
│ Python MCP Server (baltamatica-mcp) │
│ execute_code / run_script / list_variables / │
│ get_variable / set_variable / clear_workspace │
│ Engine Dispatcher │
└───────────────┬──────────────────────────┬───────────────┘
│ (--backend cli) │ (--backend bex)
▼ ▼
┌────────────────────┐ ┌──────────────────────────┐
│ CLI Backend │ │ BEX Backend │
│ subprocess + .mat │ │ JSON-over-TCP client │
└─────────┬──────────┘ └────────────┬─────────────┘
▼ ▼
baltamatica -nodesktop -s "…" mcp_bridge (BEX in GUI, TCP 31415)
```
### Backend Status
| Feature | CLI backend | BEX backend |
|:---|:---:|:---:|
| `execute_code` | ✅ | ✅ `evalc` captures output |
| `run_script` | ✅ | ✅ `evalc` captures output |
| `list_variables` | ✅ `whos` parsing | ✅ SDK variable enumeration |
| `get_variable` | ✅ `disp()` text | ✅ Binary fidelity + structured JSON |
| `set_variable` | ✅ Literal code | ✅ `bxAddVariable` (integer/float/complex/bool) |
| `clear_workspace` | ✅ | ✅ `clear` |
| Workspace state maintenance | ✅ `.mat` status file | ✅ BEX process long connection |
| File product feedback | ✅ artifact marker | ✅ Parse marker from captured output |
## 🚀 Quick Start
### Prerequisites
- Python 3.10+
- [Baltamatica 2025](https://www.baltamatica.com/download.html) (community edition is sufficient)
- Baltamatica command-line entry (macOS is usually `/Applications/Baltamatica.app/Contents/MacOS/baltamatica`)
- C compiler (only required when using the BEX backend; Baltamatica's built-in `bex` compiler will call the system clang/gcc)
### Installation
Install from PyPI (recommended):
```bash
pip install baltamatica-mcp
```
Or install from source (for development):
```bash
git clone https://github.com/wzlwww/baltamatica.mcp.git
cd baltamatica.mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```
### BEX Plugin Status
The BEX JSON protocol is documented in [docs/bex-protocol.md](docs/bex-protocol.md), and the bridge usage and lifecycle are documented in [docs/bex-plugin.md](docs/bex-plugin.md) and [docs/bex-bridge.md](docs/bex-bridge.md). The current BEX bridge implements `execute_code`, `run_script`, `clear_workspace`, `list_variables`, and `get_variable`, returning structured success/error results.
**Obtain the bridge binary** - three ways, choose one:
- **One-command installation** (simplest):
```bash
baltamatica-mcp install-bridge
```
Automatically download the corresponding platform's `mcp_bridge.bex*` to `~/.baltamatica-mcp/`, and print the command to paste into Baltamatica's startup command.
- **Manual download**: Download the corresponding platform's file from [GitHub Releases](https://github.com/wzlwww/baltamatica.mcp/releases) (macOS arm64 `mcp_bridge.bexmaci64`, Linux x86-64 `mcp_bridge.bexa64`, Windows x64 `mcp_bridge.bexw64`).
- **Compile yourself**: `scripts/build_bex.sh` (automatically locate Baltamatica's `bex` compiler, fall back to interpreter compilation on Linux), or manually compile in Baltamatica's GUI command line:
```matlab
clear mcp_bridge
cd '/path/to/baltamatica.mcp/bex'
bex 'mcp_bridge.c' % Generate mcp_bridge.bexmaci64 / .bexa64 / .bexw64
```
**Load and maintain search path** (in Baltamatica's GUI command line):
```matlab
addpath('/path/to/mcp_bridge/ directory'); savepath % Make mcp_bridge a permanent search path
```
**Two operation modes**:
```matlab
mcp_bridge() % Foreground: block the command line until stopped
mcp_bridge('background') % Background: return immediately, command line free (recommended, can be controlled from the same GUI)
```
Start the Python MCP server to connect to the same port:
```bash
python -m baltamatica_mcp --backend bex --bex-host 127.0.0.1 --bex-port 31415
```
**Stop**:
```matlab
mcp_bridge('stop') % Reliable stop; can release port after Ctrl-C interruption
```
The bridge records the listening socket in the process global state: `stop` can directly close the socket and release the port after Ctrl-C interruption, and re-running `mcp_bridge()` will automatically recycle the leaked socket instead of binding failure. If `mcp_bridge` is not in the search path (e.g., after restart `addpath` is lost), use a pure TCP fallback tool to stop, completely independent of the path:
```bash
PYTHONPATH=src python -m baltamatica_mcp.bex_shutdown
```
**Known limitations**:
- `get_variable`: numerical/logical arrays (real and complex numbers, arbitrary size) use base64 binary fidelity; characters/strings/structures/cell arrays use structured JSON. Large structures/cell arrays will be truncated according to the limit (see the `truncated` field); structures/cell arrays with nested numbers are currently flattened arrays in column-major order.
- `set_variable`: supports integers (`int8`..`uint64`), floating-point numbers (`float32`/`float64`), complex numbers (`complex64`/`complex128`, `data={"real":...,"imag":...}`), and `bool`, up to two dimensions. The request uses buffered reading + heap allocation buffer, with a single request limit of about 16 MB (about 1 million doubles).
- Screen plotting is available (`figure`/`plot` will pop up in GUI), but **graphics export to file is not available** - after checking all 3736 documentation functions of Baltamatica, there are no `saveas`/`print`/`exportgraphics`/`getframe`/`imwrite` and other graphics export functions (this is a capability gap in Baltamatica itself). Alternative solutions: use `get_variable` to retrieve plotting data for AI-side rendering, or use `writematrix`/`writetable`/`save` to export data to files + `BALTAMATICA_ARTIFACT=` marker return (see below).
- CLI backend does not require compilation, cross-platform, suitable for quick start; BEX backend has more features (binary transmission, variable injection, output capture).
**File product feedback (BEX also supports)**: `execute_code` / `run_script` now capture console output, and files declared by scripts using `fprintf('BALTAMATICA_ARTIFACT=text/csv:/tmp/x.csv\n')` will be parsed into the returned `artifacts` list (path, MIME, existence, size).
### Configure in Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"baltamatica": {
"command": "/path/to/baltamatica.mcp/.venv/bin/python",
"args": ["-m", "baltamatica_mcp"]
}
}
}
```
### Configure in Claude Code
```bash
claude mcp add baltamatica -- /path/to/baltamatica.mcp/.venv/bin/python -m baltamatica_mcp
```
### CLI Fallback Mode (no compilation required)
The CLI backend will automatically detect the standard installation location (macOS `/Applications/Baltamatica.app/...`, Linux `/opt/Baltamatica/bin/baltamatica.sh`, Windows `C:\Program Files\Baltamatica\...`), and can be used with **zero configuration**:
```bash
baltamatica-mcp --backend cli
```
When installed in a non-standard location, use environment variables or parameters to specify:
```bash
BALTAMATICA_CLI=/path/to/baltamatica baltamatica-mcp --backend cli
```
The command-line entry for different platforms is different (the backend will automatically identify): macOS is `/Applications/Baltamatica.app/Contents/MacOS/baltamatica`, Linux is `baltamatica.sh` (will automatically set library path and pass `-s` parameter). On Linux without a display (SSH/server), the backend will automatically set `QT_QPA_PLATFORM=offscreen`.
You can also explicitly specify the entry and single execution timeout:
```bash
baltamatica-mcp --backend cli --cli-executable /path/to/baltamatica.sh --timeout 30
```
The CLI backend will use `.mat` status files to save workspace variables between multiple MCP calls. You can also explicitly specify:
```bash
python -m baltamatica_mcp --backend cli --state-file /tmp/baltamatica-mcp-state.mat
```
### Configure in Codex
```bash
codex mcp add baltamatica \
--env PYTHONPATH=/path/to/baltamatica.mcp/src \
--env BALTAMATICA_CLI=/Applications/Baltamatica.app/Contents/MacOS/baltamatica \
-- python3 -m baltamatica_mcp --backend cli --timeout 30
```
After configuration, you can call `execute_code`, `run_script`, `list_variables`, `get_variable`, `set_variable`, and `clear_workspace` through MCP tools.
### Development and Testing
Run unit tests without Baltamatica installation:
```bash
PYTHONPATH=src pytest -q -m "not integration"
PYTHONPATH=src python3 -m compileall -q src tests
```
If Baltamatica CLI is installed locally, enable real integration testing:
```bash
BALTAMATICA_CLI=/Applications/Baltamatica.app/Contents/MacOS/baltamatica \
PYTHONPATH=src pytest -q -m integration
```
## 📁 Project Structure
```
baltamatica.mcp/
├── README.md
├── LICENSE
├── pyproject.toml
├── .github/workflows/ci.yml
├── src/baltamatica_mcp/
│ ├── __init__.py
│ ├── __main__.py
│ ├── server.py # MCP Server & Tool Registration
│ ├── engine.py # Backend Protocol and Result Type
│ ├── backend_cli.py # CLI Backend: subprocess + .mat State File
│ ├── backend_bex.py # BEX JSON-over-TCP Client
│ ├── serializer.py # Variable Binary Decoding/Encoding and Structured Presentation
│ └── bex_shutdown.py # Pure TCP Shutdown for BEX Bridge
├── bex/
│ ├── CMakeLists.txt # BEX CMake Build Configuration
│ ├── mcp_protocol.h # BEX JSON Protocol Constants
│ ├── mcp_bridge.c # BEX TCP Bridge Source Code (Main Body)
│ └── bex_plot_probe.c # Plot Capability Probe
├── tests/
│ ├── test_backend_cli.py
│ ├── test_backend_bex.py
│ ├── test_serializer.py
│ ├── test_bex_sources.py
│ ├── test_bex_shutdown.py
│ ├── test_server.py
│ ├── test_integration_cli.py # Marked as Integration
│ ├── test_integration_bex.py # Marked as Integration
│ └── fixtures/sample_script.m
├── docs/
│ ├── contributing.md
│ ├── bex-protocol.md
│ ├── bex-plugin.md
│ ├── bex-bridge.md
│ ├── bex-plot-probe.md
│ ├── releasing.md
│ └── pr-plan.md
├── scripts/
│ └── build_bex.sh # Compile BEX Bridge Binary with bex Compiler
└── examples/
├── monte_carlo_pi.m
├── numerical_pipeline_demo.m
├── artifact_export_demo.m
└── bex_plot_probe_demo.m
```
---
## 🛠️ MCP Tools (Exposed Tool Interfaces to AI)
| Tool Name | Parameters | Description | CLI Backend | BEX Backend |
|:---|:---|:---|:---:|:---:|
| `execute_code` | `code: string` | Execute Code and Return Console Output | ✅ | ✅ `evalc` Captures Output |
| `run_script` | `file_path: string` | Run `.m` Script File | ✅ | ✅ `evalc` Captures Output |
| `list_variables` | — | List All Variables in Workspace (Name, Type, Dimension) | ✅ `whos` Parsing | ✅ SDK Variable Enumeration |
| `get_variable` | `name: string` | Get Variable Value | ✅ `disp()` Text | ✅ Binary Full Fidelity + Structured JSON |
| `set_variable` | `name, data, dtype?` | Create/Overwrite Workspace Variable | ✅ Literal Code | ✅ `bxAddVariable` (Integer/Floating Point/Complex/Boolean) |
| `clear_workspace` | — | Clear Workspace State | ✅ | ✅ `clear` |
### File Artifact Feedback
Scripts can declare generated file artifacts through standard output:
```matlab
fprintf('BALTAMATICA_ARTIFACT=text/csv:/tmp/result.csv\n');
```
MCP returns will include an `artifacts` list, recording file path, MIME type, existence, and file size. If MIME type is omitted:
```matlab
fprintf('BALTAMATICA_ARTIFACT=/tmp/plot.png\n');
```
The service will infer common types based on the extension, such as `image/png`, `application/pdf`, `text/csv`. See `examples/artifact_export_demo.m` for an example.
---
## 🗺️ Development Roadmap
Detailed PR split and implementation plan see [docs/pr-plan.md](docs/pr-plan.md).
### Completed
- [x] MCP Server Skeleton (`FastMCP`)
- [x] CLI Backend (`subprocess` + `baltamatica -nodesktop -s`)
- [x] `execute_code` / `run_script`
- [x] `.mat` State File Maintenance for CLI Workspace
- [x] `list_variables` / `get_variable` / `clear_workspace`
- [x] Optional Real Integration Tests and GitHub Actions CI
- [x] Numerical Computation Example: `examples/numerical_pipeline_demo.m`
- [x] File Artifact Feedback: `BALTAMATICA_ARTIFACT=...`
- [x] BEX JSON Protocol Design and Python TCP Client Skeleton
- [x] BEX Plugin Minimal Available Version
- [x] BEX `list_variables` / `get_variable` Text Variable Reading
- [x] BEX Small Real Number/Logical Array Structured JSON Reading
- [x] BEX Lifecycle Robustness: Reliable `stop` / Ctrl-C Recovery / Self-Healing Rebinding / `background` Mode / Status Return Value
- [x] BEX `get_variable` Existence Pre-Check (Avoid Non-Existent Variables in GUI Displaying `evalin` Error)
- [x] BEX Numerical/Logical Binary Full Fidelity Transmission (Including Complex Numbers) + Character/String/Structure/Cell Structured Serialization
- [x] BEX `set_variable`: Inject Workspace Variables from Scalar/Vector/Matrix (`bxAddVariable`)
- [x] BEX `execute_code` / `run_script` Console Output Capture (`evalc` + `try/catch`, Successful Return stdout, Failed Return Error Message)
- [x] BEX File Artifact Feedback: Parse `BALTAMATICA_ARTIFACT=` Marker from Captured Output
- [x] Plotting Export Investigation: Confirm bex Lacks `saveas`/`print`/`exportgraphics` Functions (3736 Functions Checked), Switch to Data Side Return
- [x] `background` Mode Thread Safety Assessment: Bridge Serialization of All Requests (800 Sequential + Concurrent Dual Connection Zero Errors); Unique Risk is Manual Simultaneous GUI Operation in Background Mode (See [docs/bex-bridge.md](docs/bex-bridge.md) Thread and Concurrency Section)
- [x] Automated BEX Integration Tests (`bex` Compilation Verification + Runtime Bridge Round-Trip, Marked as `integration`)
- [x] Release Experience: `baltamatica-mcp` Console Entry, Project URL, `set_variable` Tool and Documentation
- [x] BEX `set_variable` Extension: Integer (int8..uint64) / Floating Point (float32/64) / Complex (complex64/128) Type + Buffered Reading Large Payload (Upper Limit ≈ 16 MB)
- [x] Packaging Readiness: `python -m build` Produces sdist/wheel, Console Entry, `scripts/build_bex.sh` Compiles Bridge Binary, Release Process See [docs/releasing.md](docs/releasing.md)
- [x] Release **v0.2.0**: PyPI (`pip install baltamatica-mcp`) + GitHub Release (Including macOS/Linux/Windows Precompiled Binaries)
- [x] **v0.2.1** Installation Simplification: CLI Backend Zero-Configuration Automatic Detection of bex + `baltamatica-mcp install-bridge` One-Click Bridge Binary Download
- [x] **v0.2.2** Linux Fix: CLI Backend Switches to `baltamatica.sh` (`baltamaticaC.sh` Swallows `-s`) + No Display Auto `QT_QPA_PLATFORM=offscreen` (macOS/Linux Both Tested)
### Next
- [ ] BEX Graphics Export to File: Limited by bex Lacking `saveas`/`print`/`exportgraphics` Functions, Requires Vendor Support
---
## 🔧 Core Dependencies of bex SDK API
This project depends on the following key interfaces provided by the bex SDK (`bex.h`, API v3.9):
| API Function | Functionality |
|:---|:---|
| `bxEvalString(expr)` | Execute a String Command |
| `bxEvalIn(ws, expr, plhs)` | Execute Expression in Specified Workspace and Capture Return Value |
| `bxCallBaltamatica(...)` | Call bex Built-in/Custom Functions through Function Name |
| `bxGetVariableNames(result, num)` | Get All Variable Names in Current Workspace |
| `bxAddVariable(name, value, mode)` | Inject Variables into Workspace |
| `bxRemoveVariable(name)` | Delete Workspace Variables |
| `bxGetDoublesRO/bxGetComplexDoublesRO/...(ba)` | Read-Only Get Various Type Matrix Data Pointers (Binary Return) |
| `bxCreateDoubleMatrix/bxCreateLogicalMatrix(...)` | Create Matrix (`set_variable` Injection) |
| `bxGetDoublesRW/bxGetLogicalsRW(ba)` | Read-Write Data Pointers (Write Injection Data) |
| `bxGetString / bxGetFieldByNumberRO / bxGetCellRO` | Read String/Structure Field/Cell Element (Structured Serialization) |
| `bxGetDimensions(ba)` | Get Array Dimension Information |
| `bxGetClassID(ba)` | Get Variable Data Type |
| `bxArrayToCStr(ba, ...)` / `bxAsCStr(ba, ...)` | Format/Convert Variable to String |
| `bxPrintf(...)` | Output to Command Line Window (Bridge Status Information) |
`execute_code` / `run_script` call built-in `evalc` function through `bxCallBaltamatica` to capture console output.
---
## 🤝 Contribution Guidelines
Welcome to contribute code! Please refer to [CONTRIBUTING.md](docs/contributing.md).
### Branch Model
- `main`: Stable release branch, always available
- `develop`: Main development branch, all features merged here
- `feature/<name>`: Feature branch, pulled from `develop`
- `fix/<name>`: Bug fix branch
### Commit Specification
Use [Conventional Commits](https://www.conventionalcommits.org/) specification:
```
feat: Add execute_code tool implementation
fix: Fix console output truncation issue
docs: Update README installation instructions
refactor: Refactor engine communication module
test: Add variable serialization unit test
chore: Update CI configuration
```
---
## 📄 License
MIT License © 2026 [wzlwww](https://github.com/wzlwww)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available