baltamatica.mcp
by wzlwww
README.md
# baltamatica.mcp
[](https://pypi.org/project/baltamatica-mcp/)
[](LICENSE)
[](https://modelcontextprotocol.io)
[](https://www.baltamatica.com)
> 🔗 让 AI 代理(Claude Code / Cursor / Codex)直接驱动国产科学计算软件 **北太天元(Baltamatica)** 进行交互式数值计算。
---
## 📖 项目简介
**baltamatica.mcp** 是一个基于 [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 的开源服务,为大语言模型提供与北太天元科学计算内核之间的双向通信桥梁。
通过本项目,AI 代理可以:
- 🧮 **执行代码**:直接在北太天元中运行 `.m` 脚本或单行表达式,并取回控制台输出
- 📊 **读取变量**:获取工作区中矩阵、向量、结构体、元胞等变量的值(BEX 后端二进制全保真)
- ✍️ **写入变量**:把标量/向量/矩阵注入工作区(`set_variable`)
- 🔍 **查询状态**:列出当前工作区中所有变量的名称、类型和维度
- 📂 **管理脚本**:运行本地 `.m` 脚本文件
- 🧹 **清空工作区**:重置计算环境
**当前状态**:两套后端均可用。
- **CLI 后端**:通过北太天元命令行入口执行代码,用 `.mat` 状态文件在多次 MCP 调用之间保持工作区变量。支持全部 6 个工具。
- **BEX 后端**:在北太天元 GUI 进程内运行的 C 桥接(JSON-over-TCP),支持 `execute_code`、`run_script`、`list_variables`、`get_variable`、`set_variable`、`clear_workspace`:
- `get_variable` 对数值/逻辑数组(实数**和复数**、任意大小)走 base64 二进制全保真回传,对字符/字符串/结构体/元胞走结构化 JSON;
- `set_variable` 用 `bxAddVariable` 把标量/向量/矩阵注入工作区;
- `execute_code` / `run_script` 用 `evalc` 捕获控制台输出并解析 `BALTAMATICA_ARTIFACT=` 文件产物;
- 桥接生命周期健壮(可靠 `stop`、Ctrl-C 恢复、`background` 模式),并可触发 GUI Figure 弹窗(但北太天元本身无图形导出函数,见下)。
---
## 🏗️ 系统架构
项目提供两套后端。**CLI 后端**通过北太天元命令行入口执行代码,用 `.mat` 状态文件保持工作区变量,无需编译,适合快速上手。**BEX 后端**是一个在北太天元 GUI 进程内运行的 C 桥接,走 **JSON-over-TCP**,提供进程内低延迟长连接、二进制变量传输和变量注入。两者暴露相同的 MCP 工具集。
```
┌──────────────────────────────────────────────────────────┐
│ 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)
```
### 后端状态
| 特性 | CLI 后端 | BEX 后端 |
|:---|:---:|:---:|
| `execute_code` | ✅ | ✅ `evalc` 捕获输出 |
| `run_script` | ✅ | ✅ `evalc` 捕获输出 |
| `list_variables` | ✅ `whos` 解析 | ✅ SDK 变量枚举 |
| `get_variable` | ✅ `disp()` 文本 | ✅ 二进制全保真 + 结构化 JSON |
| `set_variable` | ✅ 字面量代码 | ✅ `bxAddVariable`(整数/浮点/复数/bool) |
| `clear_workspace` | ✅ | ✅ `clear` |
| 工作区状态保持 | ✅ `.mat` 状态文件 | ✅ BEX 进程长连接 |
| 文件产物反馈 | ✅ artifact marker | ✅ 从捕获输出解析 marker |
---
## 🚀 快速开始
### 前置条件
- Python 3.10+
- [北太天元 2025](https://www.baltamatica.com/download.html)(社区版即可)
- 北太天元命令行入口(macOS 通常是 `/Applications/Baltamatica.app/Contents/MacOS/baltamatica`)
- C 编译器(仅使用 BEX 后端时需要;北太天元自带 `bex` 编译器会调用系统 clang/gcc)
### 安装
从 PyPI 安装(推荐):
```bash
pip install baltamatica-mcp
```
或从源码安装(开发用):
```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 插件状态
BEX JSON 协议见 [docs/bex-protocol.md](docs/bex-protocol.md),桥接使用与生命周期见
[docs/bex-plugin.md](docs/bex-plugin.md) 与 [docs/bex-bridge.md](docs/bex-bridge.md)。
当前 BEX 桥接已实现 `execute_code`、`run_script`、`clear_workspace`、`list_variables`
和 `get_variable`,返回结构化成功/错误结果。
**获取桥接二进制** —— 三种方式,任选其一:
- **一条命令安装**(最简单):
```bash
baltamatica-mcp install-bridge
```
自动下载对应平台的 `mcp_bridge.bex*` 到 `~/.baltamatica-mcp/`,并打印要粘进北太天元的启动命令。
- **手动下载**:从 [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`)。
- **自行编译**:`scripts/build_bex.sh`(自动定位北太天元 `bex` 编译器,Linux 上会回退到解释器内编译),或在北太天元 GUI 命令行手动编译:
```matlab
clear mcp_bridge
cd '/path/to/baltamatica.mcp/bex'
bex 'mcp_bridge.c' % 生成 mcp_bridge.bexmaci64 / .bexa64 / .bexw64
```
**加载并常驻搜索路径**(在北太天元 GUI 命令行):
```matlab
addpath('/path/to/mcp_bridge/所在目录'); savepath % 让 mcp_bridge 常驻搜索路径
```
**两种运行模式**:
```matlab
mcp_bridge() % 前台:阻塞命令行,直到被停止
mcp_bridge('background') % 后台:立即返回,命令行空着(推荐,可从同一 GUI 控制)
```
启动后让 Python MCP server 连接同一端口:
```bash
python -m baltamatica_mcp --backend bex --bex-host 127.0.0.1 --bex-port 31415
```
**停止**:
```matlab
mcp_bridge('stop') % 可靠停止;前台被 Ctrl-C 打断后也能释放端口
```
桥接把监听 socket 记在进程全局态里:`stop` 能在前台被 Ctrl-C 打断后直接关闭 socket 释放端口,
重跑 `mcp_bridge()` 会自动回收泄漏的 socket 而不是 bind 失败。若 `mcp_bridge` 不在搜索路径上
(例如重启后 `addpath` 丢失),可用纯 TCP 的兜底工具停止,完全不依赖路径:
```bash
PYTHONPATH=src python -m baltamatica_mcp.bex_shutdown
```
**已知限制**:
- `get_variable`:数值/逻辑数组(实数**和复数**、任意大小)走 base64 二进制全保真回传;字符/字符串/结构体/元胞走结构化 JSON。极大的结构体/元胞会按上限截断(见 `truncated` 字段);结构体/元胞里嵌套的数值目前是列主序扁平数组。
- `set_variable`:支持整数(`int8`..`uint64`)、浮点(`float32`/`float64`)、复数(`complex64`/`complex128`,`data={"real":...,"imag":...}`)和 `bool`,二维以内。请求走缓冲读取 + 堆分配缓冲区,单条请求上限约 16 MB(约 100 万个 double)。
- 屏幕绘图可用(`figure`/`plot` 等会在 GUI 弹窗),但**图形导出到文件不可用**——遍查北太天元全部 3736 个文档函数,均无 `saveas`/`print`/`exportgraphics`/`getframe`/`imwrite` 等图形导出函数(这是北太天元本身的能力缺失)。替代方案:用 `get_variable` 取回绘图数据由 AI 端渲染,或用 `writematrix`/`writetable`/`save` 把数据导出成文件 + `BALTAMATICA_ARTIFACT=` 标记回传(见下)。
- CLI 后端无需编译、跨平台,适合快速上手;BEX 后端功能更全(二进制传输、变量注入、输出捕获)。
**文件产物反馈(BEX 也支持)**:`execute_code` / `run_script` 现在捕获控制台输出,脚本用
`fprintf('BALTAMATICA_ARTIFACT=text/csv:/tmp/x.csv\n')` 声明的文件会被解析进返回的
`artifacts` 列表(路径、MIME、是否存在、大小)。
### 在 Claude Desktop 中配置
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"baltamatica": {
"command": "/path/to/baltamatica.mcp/.venv/bin/python",
"args": ["-m", "baltamatica_mcp"]
}
}
}
```
### 在 Claude Code 中配置
```bash
claude mcp add baltamatica -- /path/to/baltamatica.mcp/.venv/bin/python -m baltamatica_mcp
```
### CLI Fallback 模式(无需编译)
CLI 后端会自动探测标准安装位置(macOS `/Applications/Baltamatica.app/...`、
Linux `/opt/Baltamatica/bin/baltamatica.sh`、Windows `C:\Program Files\Baltamatica\...`),
标准安装下**零配置**即可:
```bash
baltamatica-mcp --backend cli
```
装在非标准位置时,用环境变量或参数指定:
```bash
BALTAMATICA_CLI=/path/to/baltamatica baltamatica-mcp --backend cli
```
不同平台的命令行入口不一样(后端会自动识别):macOS 是 `/Applications/Baltamatica.app/Contents/MacOS/baltamatica`,Linux 是 `baltamatica.sh`(会自动设置库路径并透传 `-s` 参数)。在无显示器的 Linux(SSH/服务器)上,后端会自动设 `QT_QPA_PLATFORM=offscreen`。
也可以显式指定入口和单次执行超时:
```bash
baltamatica-mcp --backend cli --cli-executable /path/to/baltamatica.sh --timeout 30
```
CLI 后端会用 `.mat` 状态文件在多次 MCP 调用之间保存工作区变量。默认使用临时状态文件,
也可以显式指定:
```bash
python -m baltamatica_mcp --backend cli --state-file /tmp/baltamatica-mcp-state.mat
```
### 在 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
```
配置后可通过 MCP 工具调用 `execute_code`、`run_script`、`list_variables`、
`get_variable`、`set_variable` 和 `clear_workspace`。
### 开发测试
运行不依赖北太天元安装的单元测试:
```bash
PYTHONPATH=src pytest -q -m "not integration"
PYTHONPATH=src python3 -m compileall -q src tests
```
如果本机已安装北太天元 CLI,可以启用真实集成测试:
```bash
BALTAMATICA_CLI=/Applications/Baltamatica.app/Contents/MacOS/baltamatica \
PYTHONPATH=src pytest -q -m integration
```
---
## 📁 项目结构
```
baltamatica.mcp/
├── README.md
├── LICENSE
├── pyproject.toml
├── .github/workflows/ci.yml
├── src/baltamatica_mcp/
│ ├── __init__.py
│ ├── __main__.py
│ ├── server.py # MCP Server & Tool 注册
│ ├── engine.py # 后端协议与结果类型
│ ├── backend_cli.py # CLI 后端:subprocess + .mat 状态文件
│ ├── backend_bex.py # BEX JSON-over-TCP 客户端
│ ├── serializer.py # 变量二进制解码/编码与结构化呈现
│ └── bex_shutdown.py # 纯 TCP 关闭 BEX 桥接的兜底工具
├── bex/
│ ├── CMakeLists.txt # BEX CMake 构建配置
│ ├── mcp_protocol.h # BEX JSON 协议常量
│ ├── mcp_bridge.c # BEX TCP 桥接源码(主体)
│ └── bex_plot_probe.c # 绘图能力探针
├── 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 # 标记 integration
│ ├── test_integration_bex.py # 标记 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 # 用北太天元 bex 编译器编译本平台桥接二进制
└── examples/
├── monte_carlo_pi.m
├── numerical_pipeline_demo.m
├── artifact_export_demo.m
└── bex_plot_probe_demo.m
```
---
## 🛠️ MCP Tools(暴露给 AI 的工具接口)
| Tool 名称 | 参数 | 描述 | CLI 后端 | BEX 后端 |
|:---|:---|:---|:---:|:---:|
| `execute_code` | `code: string` | 执行代码并返回控制台输出 | ✅ | ✅ `evalc` 捕获输出 |
| `run_script` | `file_path: string` | 运行 `.m` 脚本文件 | ✅ | ✅ `evalc` 捕获输出 |
| `list_variables` | — | 列出工作区所有变量(名称、类型、维度) | ✅ `whos` 解析 | ✅ SDK 变量枚举 |
| `get_variable` | `name: string` | 获取变量值 | ✅ `disp()` 文本 | ✅ 二进制全保真 + 结构化 JSON |
| `set_variable` | `name, data, dtype?` | 创建/覆盖工作区变量 | ✅ 字面量代码 | ✅ `bxAddVariable`(整数/浮点/复数/bool) |
| `clear_workspace` | — | 清空工作区状态 | ✅ | ✅ `clear` |
### 文件产物反馈
脚本可以通过标准输出声明生成的文件产物:
```matlab
fprintf('BALTAMATICA_ARTIFACT=text/csv:/tmp/result.csv\n');
```
MCP 返回值会包含 `artifacts` 列表,记录文件路径、MIME 类型、是否存在和文件大小。若省略 MIME 类型:
```matlab
fprintf('BALTAMATICA_ARTIFACT=/tmp/plot.png\n');
```
服务会根据扩展名推断常见类型,例如 `image/png`、`application/pdf`、`text/csv`。示例见
`examples/artifact_export_demo.m`。
---
## 🗺️ 开发路线图 (Roadmap)
详细 PR 拆分和实现方案见 [docs/pr-plan.md](docs/pr-plan.md)。
### 已完成
- [x] MCP Server 骨架(`FastMCP`)
- [x] CLI 后端(`subprocess` + `baltamatica -nodesktop -s`)
- [x] `execute_code` / `run_script`
- [x] `.mat` 状态文件保持 CLI 工作区
- [x] `list_variables` / `get_variable` / `clear_workspace`
- [x] 可选真实集成测试与 GitHub Actions CI
- [x] 数值计算示例:`examples/numerical_pipeline_demo.m`
- [x] 文件产物反馈:`BALTAMATICA_ARTIFACT=...`
- [x] BEX JSON 协议设计与 Python TCP 客户端骨架
- [x] BEX 插件最小可用版
- [x] BEX `list_variables` / `get_variable` 文本变量读取
- [x] BEX 小型实数数值/逻辑数组结构化 JSON 读取
- [x] BEX 生命周期健壮化:可靠 `stop` / Ctrl-C 恢复 / 自愈重绑 / `background` 模式 / 状态返回值
- [x] BEX `get_variable` 存在性预检查(避免不存在变量在 GUI 里回显 `evalin` 错误)
- [x] BEX 数值/逻辑二进制全保真传输(含复数)+ 字符/字符串/结构体/元胞结构化序列化
- [x] BEX `set_variable`:从标量/向量/矩阵注入工作区变量(`bxAddVariable`)
- [x] BEX `execute_code` / `run_script` 控制台输出捕获(`evalc` + `try/catch`,成功返回 stdout、失败返回错误信息)
- [x] BEX 文件产物反馈:从捕获输出解析 `BALTAMATICA_ARTIFACT=` 标记
- [x] 绘图导出调研:确认北太天元无任何图形导出函数(3736 个函数全查),改走数据侧回传
- [x] `background` 模式线程安全评估:桥接串行化所有请求(800 顺序 + 并发双连接零错误);唯一风险是后台模式下手动同时操作 GUI(见 [docs/bex-bridge.md](docs/bex-bridge.md) 线程与并发一节)
- [x] 自动化 BEX 集成测试(`bex` 编译校验 + 运行中桥接往返,标记 `integration`)
- [x] 发布体验:`baltamatica-mcp` 控制台入口、项目 URL、`set_variable` 工具与文档
- [x] BEX `set_variable` 扩展:整数(int8..uint64)/浮点(float32/64)/复数(complex64/128)类型 + 缓冲读取大 payload(上限约 16 MB)
- [x] 打包就绪:`python -m build` 可出 sdist/wheel、控制台入口、`scripts/build_bex.sh` 编译桥接二进制、发布流程见 [docs/releasing.md](docs/releasing.md)
- [x] 发布 **v0.2.0**:PyPI(`pip install baltamatica-mcp`)+ GitHub Release(含 macOS/Linux/Windows 三平台预编译二进制)
- [x] **v0.2.1** 安装简化:CLI 后端零配置自动探测北太天元 + `baltamatica-mcp install-bridge` 一键下载桥接二进制
- [x] **v0.2.2** Linux 修复:CLI 后端改用 `baltamatica.sh`(`baltamaticaC.sh` 会吞掉 `-s`)+ 无显示器时自动 `QT_QPA_PLATFORM=offscreen`(mac/Linux 均实测通过)
### 下一步
- [ ] BEX 图形导出到文件:受限于北太天元本身缺少 `saveas`/`print`/`exportgraphics` 等函数,需厂商侧支持
---
## 🔧 核心依赖的北太天元 SDK API
本项目依赖北太天元 BEX SDK (`bex.h`, API v3.9) 提供的以下关键接口:
| API 函数 | 功能 |
|:---|:---|
| `bxEvalString(expr)` | 执行一条字符串命令 |
| `bxEvalIn(ws, expr, plhs)` | 在指定工作区执行表达式并捕获返回值 |
| `bxCallBaltamatica(...)` | 通过函数名调用北太天元内置/自定义函数 |
| `bxGetVariableNames(result, num)` | 获取当前工作区所有变量名 |
| `bxAddVariable(name, value, mode)` | 向工作区注入变量 |
| `bxRemoveVariable(name)` | 删除工作区变量 |
| `bxGetDoublesRO/bxGetComplexDoublesRO/...(ba)` | 只读获取各类型矩阵数据指针(二进制回传) |
| `bxCreateDoubleMatrix/bxCreateLogicalMatrix(...)` | 创建矩阵(`set_variable` 注入) |
| `bxGetDoublesRW/bxGetLogicalsRW(ba)` | 读写数据指针(写入注入的数据) |
| `bxGetString / bxGetFieldByNumberRO / bxGetCellRO` | 读取字符串/结构体字段/元胞元素(结构化序列化) |
| `bxGetDimensions(ba)` | 获取数组维度信息 |
| `bxGetClassID(ba)` | 获取变量的数据类型 |
| `bxArrayToCStr(ba, ...)` / `bxAsCStr(ba, ...)` | 将变量格式化/转换为字符串 |
| `bxPrintf(...)` | 向命令行窗口输出(桥接状态信息) |
`execute_code` / `run_script` 通过 `bxCallBaltamatica` 调用内置的 `evalc` 函数捕获控制台输出。
---
## 🤝 贡献指南
欢迎贡献代码!请参阅 [CONTRIBUTING.md](docs/contributing.md)。
### 分支模型
- `main`:稳定发布分支,始终保持可用
- `develop`:开发主分支,所有 feature 合入此处
- `feature/<name>`:功能分支,从 `develop` 拉出
- `fix/<name>`:Bug 修复分支
### 提交规范
使用 [Conventional Commits](https://www.conventionalcommits.org/) 规范:
```
feat: 添加 execute_code 工具实现
fix: 修复控制台输出截断问题
docs: 更新 README 安装说明
refactor: 重构引擎通信模块
test: 添加变量序列化单元测试
chore: 更新 CI 配置
```
---
## 📄 License
MIT License © 2026 [wzlwww](https://github.com/wzlwww)
TDQS
A3.7/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a distinct purpose: workspace management (clear, list, get, set) and code execution (snippet vs script). No overlap or ambiguity.
Naming Consistency5/5
All tools follow a consistent verb_noun pattern (e.g., clear_workspace, execute_code, set_variable). No deviations.
Tool Count5/5
6 tools is well-scoped for a MATLAB-like environment, covering workspace operations and code execution without unnecessary bloat.
Completeness4/5
Covers core workspace CRUD (create via set, read via get/list, delete via clear) and execution. Missing a per-variable delete, but overall sufficient for typical use.
Maintenance
ActivityInactive
ResponsivenessNo issues