soft-mcp-server
README.md
# 🛋️ soft-mcp-server
> 软装预算目录的 MCP Server —— 装修报价智能体的「软装确定性计算」独立进程
把软装预算所需的**唯一数据源**(54 项软装单价 × 3 档 + 5 风格系数 + 房间→区域映射)
从编排层(`interior-ai-agent`)内嵌 `SOFT_PRICES` 表中抽出,作为独立 MCP stdio 进程暴露,
编排层通过 `langchain-mcp-adapters` 跨进程调用 —— 与 `quote-mcp-server`(硬装引擎)完全对称。
## 为什么独立出来
- **单价表单一归属**:价格只存在于 `config/soft_catalog.json`,编排层零价格数据依赖,可独立更新、审计、复用于任意 MCP Host(Claude Desktop / Cursor)。
- **职责清晰**:确定性计算必须可复现、可审计;软装清单(LLM 生成)留在编排层,软装算价(确定性)落到本仓库。
- **环境解耦**:本服务仅需 `mcp`,与编排层(Python 3.14 + langgraph)互不影响。
## 工具
| 工具 | 说明 |
|---|---|
| `soft_catalog` | 返回全量软装目录(zones / 房间映射 / 风格系数 / 54 项单价) |
| `compute_soft_budget(style, rooms, tier)` | 按风格/房间/档位计算软装预算估算,返回 `{by_room, subtotal, total, style_mult, ...}` |
`total = round(subtotal × 风格系数)`,`rooms=None` 表示全屋满配(8 区域)。
## 运行(stdio 模式)
```bash
pip install "mcp>=1.0" # 唯一运行时依赖
python -m src.mcp_server.server # stdio 启动,供 MCP Host 接入
```
本服务**不监听任何网络端口**,必须由 MCP Host 以子进程方式拉起。
## 测试
```bash
pytest tests/test_catalog.py -q
```
测试直接读取同一份 `config/soft_catalog.json` 自算 expected,校验 `compute_soft_budget`
的 `subtotal` / `total` / `by_room` 严格一致,杜绝硬编码或漂移。
## 数据来源
用户提供的《软装报价清单》通用模板(2026-07-31)。`prices` 键对齐硬装档位词:
**最简=经济型 / 标准=中档 / 轻奢=高端**。模板单价不分风格,风格差异仅在总价层面以 `style_mult` 系数体现。
## 与 interior-ai-agent 的接线
编排层 `graph/mcp_client.py` 通过 `MultiServerMCPClient` 同时持有 `quote` 与 `soft` 两个 MCP 连接,
`graph/soft_agent.generate_soft_budget` 经 `call_soft_tool("compute_soft_budget", {...})` 获取数据,
返回结构与原内嵌版完全一致,前端无需改动。
---
## 单独部署
本服务是**无状态的 stdio MCP Server**,三种接入方式任选。
### 1. 本地直接运行(开发 / 调试)
```bash
cd soft-mcp-server
pip install "mcp>=1.0"
python -m src.mcp_server.server # 进程会阻塞等待 stdio JSON-RPC
```
### 2. 容器化运行(Docker)
```bash
docker build -t soft-mcp-server .
# 作为子进程由 Host 拉起,无需 -p 映射端口(stdio 走 stdin/stdout)
docker run --rm -i soft-mcp-server
```
也可注册进 `interior-ai-agent/docker-compose.yml`(当前 compose 已通过 `${SOFT_PATH:-../soft-mcp-server}:/app/soft` 挂载源码,复用编排层镜像内的 `mcp` venv,无需单独容器)。
### 3. 作为 MCP Host 的子进程接入
任何支持 MCP 的客户端只需在 `mcpServers` 配置里声明本服务的启动命令即可。
**Claude Desktop / Cursor(`claude_desktop_config.json` / MCP 设置)**
```json
{
"mcpServers": {
"soft-mcp-server": {
"command": "python",
"args": ["-m", "src.mcp_server.server"],
"cwd": "/abs/path/to/soft-mcp-server",
"env": {}
}
}
}
```
**interior-ai-agent(编排层,跨进程调用)**
编排层通过 `MultiServerMCPClient` 持有 `soft` 连接,由环境变量控制路径与 Python:
| 环境变量 | 默认值(本机) | 容器(compose)值 |
|---|---|---|
| `SOFT_MCP_PROJECT` | `C:\Users\Mayi\PycharmProjects\soft-mcp-server` | `/app/soft` |
| `SOFT_MCP_PYTHON` | 3.13 venv 的 `python.exe` | `/app/.venv/bin/python` |
编排层既可走确定性的 `call_soft_tool("compute_soft_budget", {...})`(图节点用),
也可把 `soft_catalog` / `compute_soft_budget` 转成 LangChain Tools 挂给任意 ReAct Agent 使用。
### 环境变量
| 变量 | 说明 |
|---|---|
| (无强制环境变量) | 单价表为静态 `config/soft_catalog.json`,运行时不依赖外部 API Key |
| `PYTHONPATH` | 已通过 `src/__init__.py` 与 `sys.path.insert` 自处理,无需额外设置 |
> 与硬装引擎 `quote-mcp-server` 不同,本服务**完全确定性、零外部 API 依赖**,
> 任何 MCP Host 接入后即可离线调用,单价表更新只需改 `config/soft_catalog.json` 并重启子进程。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues