内容
# shelx-mcp
一个 [MCP](https://modelcontextprotocol.io) 服务器,封装了 **SHELX** 控制台晶体学程序,以便LLM可以构建 `.ins` 指令文件,运行结构解决方案和精炼,并从聊天界面读取结果。
它附带了权威的 **SHELXL 指令参考** 和 **SHELXS / SHELXD / SHELXE 解决方案程序参考**,离线捆绑在一起,因此模型可以在不离开对话的情况下查找任何命令或解决方案关键词的作用。
---
## 功能
服务器暴露了 **11种工具**,分为两个覆盖区域:
- **精炼(SHELXL)** — 构建和精炼模型的卡片。
- **结构解决方案(SHELXS / SHELXD / SHELXE)** — 查找结构的关键词。
| 工具 | 覆盖范围 | 目的 |
|------|----------|---------|
| `run_shelx` | 两个 | 在提供的输入文件上执行任何允许的 SHELX 程序。 |
| `solve` | 解决方案 | 运行结构解决方案(SHELXS 直接方法或 SHELXT 双空间)。 |
| `refine` | 精炼 | 使用 SHELXL(或通过 SHELXT 使用 CGLS)运行最小二乘精炼。 |
| `list_commands` | 精炼 | 列出服务器理解的每个 SHELXL 指令。 |
| `command_help` | 精炼 | 一个指令的完整签名 + 描述(例如 `ANIS`,`L.S.`)。 |
| `search_commands` | 精炼 | 跨指令名称和描述的自由文本搜索。 |
| `list_solution_keywords` | 解决方案 | 列出 SHELXS/SHELXD `.ins` 卡片或 SHELXE 命令行选项。 |
| `solution_help` | 解决方案 | 一个解决方案关键词的完整签名 + 描述(例如 `TREF`,`-aN`)。 |
| `validate_ins` | 精炼 | 检查 `.ins` 文件是否包含所需的 SHELXL 头卡片。 |
| `analyze_results` | 两个 | 提取 R1,wR2,GooF(S),最大移位/esd,原子计数和警告。 |
| `shelx_info` | 两个 | 报告配置的 SHELX 目录和可用的程序。 |
> **精炼 vs. 解决方案覆盖**。SHELXL 精炼您已经拥有的模型;SHELXS/SHELXD/SHELXE 从衍射数据中找到模型。使用 `list_commands` / `command_help` / `search_commands` 进行精炼卡片,使用 `list_solution_keywords` / `solution_help` 进行解决方案关键词。SHELXT 和 SHELXC 作为教程提供,而不是关键词列表,因此它们不作为参考(但仍可以通过 `run_shelx` / `solve` 运行)。
### SHELX 如何驱动
SHELX 程序是由 **控制台工具通过 basename 驱动**:`shelxl name` 读取 `name.ins`(当存在 `HKLF` 指令时,还读取 `name.hkl`)并写入 `name.res`,`name.lst`,以及可选的 `name.cif` / `name.fcf`。该服务器将输入文件写入(临时)工作目录,运行可执行文件,并将生成的 文件作为文本返回。
---
## 要求
- **Python** >= 3.10(项目使用 `uv`,它在需要时获取自己的解释器)。
- 本地安装的 **SHELX 可执行文件**(从 https://shelx.uni-goettingen.de/ 或您的站点许可下载)。在作者的机器上,它们位于 `C:/Users/kuzmi/AppData/Local/shelx64/`。
- [`uv`](https://docs.astral.sh/uv/) 用于依赖项/环境管理。
---
## 安装
```bash
git clone https://github.com/stge4code/shelx-mcp.git
cd shelx-mcp
uv sync # 创建 .venv 并安装 mcp + python-dotenv
uv sync --extra test # 另外安装 pytest 用于测试套件
```
### 配置 SHELX 位置
复制模板并将 `SHELX_DIRECTORY` 指向包含 `*.exe` 文件的文件夹:
```bash
cp .env.example .env
# 然后编辑 .env:
# SHELX_DIRECTORY=C:/path/to/shelx64
```
> `.env` 被 git 忽略(它包含机器特定的路径)。只有 `.env.example` 被提交。
### 运行服务器
服务器通过 **stdio** 说 **MCP**,因此您通常不会手动启动它 — 您的代理会启动。要手动进行烟雾测试:
```bash
uv run shelx-mcp # 运行 stdio 服务器
uv run python -m shelx_mcp.server # 等价
```
在连接代理之前验证线路(并检查是否找到 SHELX):
```bash
uv run python -c "import shelx_mcp.server as s; print(s.shelx_info())"
```
---
## 连接代理
以下所有配置都使用以下命令启动服务器:
```
uv --directory <repo> run shelx-mcp
```
将 `<repo>` 替换为此检出的绝对路径(例如 `X:/DATA/Git/shelx-mcp`)。存储库内的 `.env` 文件在启动时自动被拾取。每个客户端都使用相同的 `command` / `args` 对;只有配置文件位置和密钥名称不同。
| 代理 | 配置文件 | 密钥 | 示例 |
|-------|-------------|-----|---------|
| **Crush** | `crush.json`(项目根目录或 `~/.config/crush/`) | `mcp`(`"type": "stdio"`) | [`examples/crush.json`](examples/crush.json) |
| **OpenCode** | `~/.config/opencode/opencode.jsonc` | `mcpServers` | [`examples/opencode.jsonc`](examples/opencode.jsonc) |
| **Claude Desktop** | `claude_desktop_config.json` | `mcpServers` | [`examples/claude_desktop.json`](examples/claude_desktop.json) |
| **VS Code / Copilot** | `.vscode/mcp.json` | `servers`(`"type": "stdio"`) | [`examples/vscode_mcp.json`](examples/vscode_mcp.json) |
| **Zed** | `~/.config/zed/settings.json` | `context_servers` | [`examples/zed.json`](examples/zed.json) |
| **Cursor** | `.cursor/mcp.json` | `mcpServers` | [`examples/cursor.json`](examples/cursor.json) |
| **Cline** | `cline_mcp_settings.json` | `mcpServers` | [`examples/cline.json`](examples/cline.json) |
复制匹配的示例到代理的配置文件位置(或将其服务器块合并到现有的配置中),然后重启代理。然后 `shelx` 服务器出现在 MCP 列表中,其 11 种工具在任何对话中都可用。
对于 Crush 来说,块看起来像这样(注意 `mcp` 密钥和所需的 `type` 字段,与 Claude/Cursor/Cline 使用的 `mcpServers` 密钥不同):
```json
{
"mcp": {
"shelx": {
"type": "stdio",
"command": "uv",
"args": ["--directory", "X:/DATA/Git/shelx-mcp", "run", "shelx-mcp"]
}
}
}
```
> `uv` 必须在代理的 `PATH` 中。如果它不在那里,请将 `"uv"` 替换为 `uv.exe` 的绝对路径(例如 `C:/Users/kuzmi/.local/bin/uv.exe`)。
### 技能
一个可重用的代理 **技能**,用于教授工作流程(查找指令,验证,解决,精炼,分析),位于 [`skills/shelx/SKILL.md`](skills/shelx/SKILL.md)。要为 Crush 安装它,请将文件夹复制到技能目录中:
```bash
mkdir -p ~/.config/crush/skills/shelx
cp -r skills/shelx/* ~/.config/crush/skills/shelx/
```
其他支持 markdown 技能的代理可以加载相同的文件。技能在会话中保持 SHELX 卡片顺序和解决→精炼→分析循环的一致性。
---
## 典型工作流程
1. **查找命令** — 精炼卡片:`command_help("ANIS")` 或 `search_commands("rigid group")`;解决方案关键词:`list_solution_keywords("shelxs")` 然后 `solution_help("shelxs", "TREF")`。
2. **构建模型** — 粘贴或生成 `.ins` 文件,然后 `validate_ins(...)` 以确认头卡片。
3. **解决/精炼** — 调用 `solve(ins, hkl)`(SHELXS/SHELXT)或 `refine(ins, hkl)`(SHELXL)。
4. **读取结果** — `analyze_results(lst=..., res=...)` 返回 R 因子,GooF 和任何警告;完整的 `.lst` / `.res` 通过运行工具内联返回,以进行更深入的检查。
---
## 工具参考
### `run_shelx(program, ins, hkl=None, basename="shelx_job", workdir=None, timeout=120, return_output=True)`
在提供的 `.ins`(和可选的 `.hkl`)文本上运行任何允许的 SHELX 程序。返回程序输出,返回代码,和(当 `return_output` 为真时)生成的 `.res` / `.lst` / `.cif` 文件。
### `solve(ins, hkl=None, program="shelxs", basename="solve", timeout=120)`
运行结构解决方案。`program` 是 `shelxs`(直接方法)或 `shelxt`(双空间)。需要为解决方案设置的 `.ins`(`TITL`,`CELL`,`ZERR`,`LATT`,`SYMM`,`SFAC`,`UNIT`,以及例如 `TREF`/`FMAP`,和 `HKLF`/`END`)和相应的 `.hkl` 数据。
### `refine(ins, hkl=None, program="shelxl", basename="refine", timeout=300)`
运行最小二乘精炼。需要一个完整的 `.ins`(带有 `L.S.`/`CGLS` 和 `HKLF`)和 `.hkl` 数据。返回 `.lst` 摘要和精炼的 `.res`。
### `list_commands()`
返回服务器已知的每个 SHELXL 指令名称(按字母顺序)。
### `command_help(name)`
返回一个 SHELXL 指令的签名和完整描述(例如 `command_help("ANIS")`,`command_help("L.S.")`)。
### `search_commands(query, limit=10)`
跨指令名称,签名,描述,相关卡片和示例行的自由文本搜索。
### `list_solution_keywords(program)`
列出 `program` ∈ {`shelxs`,`shelxd`,`shelxe`} 的 `.ins` 卡片(SHELXS/SHELXD)或命令行选项(SHELXE)。
### `solution_help(program, keyword)`
返回一个解决方案关键词的签名和完整描述。对于 SHELXS/SHELXD,使用卡片名称(例如 `solution_help("shelxs", "TREF")`);对于 SHELXE,使用带有破折号和占位符的选项(例如 `solution_help("shelxe", "-aN")`)。SHELXE 选项区分大小写。
### `validate_ins(ins)`
检查 `.ins` 文件是否包含所需的 SHELXL 头卡片(`TITL`,`CELL`,`ZERR`,`LATT`,`SYMM`,`SFAC`,`UNIT`,`HKLF`,`END`)和一些常见错误(例如 `SYMM` 对于 P1/P-1 不是必需的;`UNIT` 必须在 `HKLF` 之前)。
### `analyze_results(lst=None, res=None)`
总结精炼指标:R1,wR2,GooF(S),最大移位/esd,原子计数和任何警告行来自 `.lst` / `.res` 文本。
### `shelx_info()`
报告配置的 `SHELX_DIRECTORY` 和哪些 SHELX 程序存在。
---
## 捆绑的参考数据(离线)
服务器在运行时不调用网络。它在启动时解析这些捆绑的 HTML 文件(来自 https://shelx.uni-goettingen.de/):
| 文件 | 涵盖的程序 |
|------|------------------|
| `data/shelxl_reference.html` | SHELXL 精炼指令 |
| `data/shelxs_keywords.html` | SHELXS `.ins` 解决方案卡片 |
| `data/shelxd_sm_keywords.html` | SHELXD `.ins` 解决方案卡片 |
| `data/shelxe_keywords.html` | SHELXE 命令行选项 |
要刷新参考资料,请重新下载相应的页面并替换 `src/shelx_mcp/data/` 中的文件(它们通过 `pyproject.toml` 中的 `force-include` 被包含在轮中)。
---
## 项目布局
```
shelx-mcp/
├── .env.example # SHELX_DIRECTORY 的模板
├── pyproject.toml # uv / hatchling 项目元数据
├── examples/
│ ├── crush.json # Crush MCP 配置
│ ├── opencode.jsonc # OpenCode MCP 配置
│ ├── claude_desktop.json # Claude Desktop 配置
│ ├── vscode_mcp.json # VS Code / Copilot(.vscode/mcp.json)
│ ├── zed.json # Zed context_servers
│ ├── cursor.json # Cursor .cursor/mcp.json
│ └── cline.json # Cline 设置
├── skills/
│ └── shelx/
│ └── SKILL.md # 代理技能:SHELX 解决方案/精炼工作流程
├── src/shelx_mcp/
│ ├── server.py # FastMCP 服务器 + 工具
│ ├── runner.py # 安全的子进程执行 SHELX
│ ├── reference.py # 解析捆绑的 SHELXL 指令 HTML
│ ├── solution_ref.py # 解析捆绑的 SHELXS/SHELXD/SHELXE 参考
│ ├── analysis.py # 提取 R1/wR2/GooF/原子/警告
│ └── data/
│ ├── shelxl_reference.html # 捆绑的,离线的 SHELXL 手册
│ ├── shelxs_keywords.html # SHELXS .ins 卡片
│ ├── shelxd_sm_keywords.html # SHELXD .ins 卡片
│ └── shelxe_keywords.html # SHELXE 命令行选项
└── tests/
└── test_server.py
```
---
## 开发
```bash
uv sync --extra test
uv run pytest -q # 运行测试套件(不需要真正的 SHELX)
uvx ruff@0.11.0 check src tests # 整理
```
测试涵盖参考/解决方案解析,输出分析,`validate_ins`,服务器工具,以及(当配置了 `SHELX_DIRECTORY` 时)端到端的 SHELX 运行。
---
## 安全说明
- 只有 `ALLOWED_PROGRAMS`(`shelxs`,`shelxl`,`shelxt`,`shelxc`,`shelxd`,`shelxe`,`ciftab`)中的程序可以执行 — 不能滥用 `program` 参数来运行任意命令。
- `basename` 限制为 `[A-Za-z0-9_.-]`,并且拒绝 `.` / `..` 值,因此它不能逃离工作目录。
- 额外的输入文件必须是纯名称,没有目录组件。
- 输入文件被写入一个临时目录,该目录在运行后被删除(除非您显式传递 `workdir`),因此服务器永远不会写入您的存储库。