Metadata-Version: 2.3
Name: gauss-mcp
Version: 0.1.0
Summary: MCP server for Gauss automatic import workflows
Requires-Dist: httpx>=0.28.1
Requires-Dist: mcp>=1.12.4
Requires-Dist: pydantic>=2.11.0
Requires-Dist: pydantic-settings>=2.10.1
Requires-Dist: tenacity>=9.1.2
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# gauss-mcp

一个基于 FastMCP 的 Python MCP server，用来把公开图片 URL 驱动到 Gauss 自动导入链路。

当前 v1 聚焦这条主链路：

1. `ImageType`
2. `Img2Pano`（仅普通图需要）
3. `PanoClear`（按需）
4. `Pano2PointCloud`
5. `SpatialTune`
6. `GaussImport`
7. `GaussInfo`（轮询 `v2/gauss/info` 直到展示信息就绪）
8. 返回 `design_id` / `plan_id` / `level_id` / `result_url` / `gauss_info_status` / `gauss_splat_url` / `gauss_drc_url`

不在本轮范围内：本地图片上传、渲染发布。

## 能力概览

- 运行状态持久化到 SQLite + artifact 文件
- 支持中断恢复，不依赖会话上下文
- 支持从中间步骤派生 variant run
- 支持导出单步调试信息和完整 run report
- `clear_furniture`、`floor_height_m` 缺失时显式停下来等待用户输入
- `ImageType` 失败时，skill 可以向用户确认是否为全景图，再通过人工覆盖继续推进
- `GaussImport` 成功后会继续轮询 `v2/gauss/info`，直到展示信息可读
- 如果本地等待窗口结束但展示信息仍在生成，run 会保持 `running`，后续继续 `gauss_resume_run` 即可

## 环境要求

- Python 3.11+
- `uv`

## 安装

### 本地开发

```bash
uv sync
```

### 已发布包

如果已经发布到 PyPI 或内网 Python 仓库，其他人可以直接运行：

```bash
uvx gauss-mcp
```

## 配置

### 必填鉴权配置

本地开发可以创建 `.env`，变量名必须使用 `GAUSS_*` 前缀：

```dotenv
GAUSS_APPUID=your_appuid
GAUSS_APPKEY=your_appkey
GAUSS_APPSECRET=your_appsecret
GAUSS_API_BASE_URL=https://api-beta.kujiale.com/p/openapi/
GAUSS_WEB_BASE_URL=https://www.kujiale.com
```

### 可选运行时配置

```dotenv
GAUSS_STATE_DIR=/absolute/path/to/gauss-mcp/state
GAUSS_RUNS_DIR=/absolute/path/to/gauss-mcp/runs
GAUSS_TIMEOUT_S=300
GAUSS_POLL_INTERVAL_S=2
```

说明：

- `GAUSS_APPUID`、`GAUSS_APPKEY`、`GAUSS_APPSECRET` 用于 OpenAPI 鉴权
- `GAUSS_API_BASE_URL` 当前测试环境默认是 `https://api-beta.kujiale.com/p/openapi/`
- `GAUSS_WEB_BASE_URL` 用于拼接最终结果链接
- `GAUSS_STATE_DIR`、`GAUSS_RUNS_DIR` 用于指定 SQLite 和 artifact 的持久化目录
- `GAUSS_TIMEOUT_S`、`GAUSS_POLL_INTERVAL_S` 用于控制轮询等待窗口
- 从源码仓库直接运行时，默认持久化到 `<repo>/data/state` 和 `<repo>/data/runs`
- 从已安装包或 `uvx gauss-mcp` 运行时，默认持久化到 `~/.gauss-mcp/state` 和 `~/.gauss-mcp/runs`
- 给其他人分发时，推荐显式配置 `GAUSS_STATE_DIR`、`GAUSS_RUNS_DIR`
- 不要把真实密钥提交到仓库

## 启动 MCP Server

默认使用 `stdio` 传输。

### 从源码仓库启动

```bash
uv run gauss-mcp
```

或：

```bash
uv run python -m gauss_mcp
```

### 从已发布包启动

```bash
uvx gauss-mcp
```

## 打包与发布

当前工程已经具备 Python 包分发能力：

- `pyproject.toml` 已声明 `uv_build` 构建后端
- 已提供 console script：`gauss-mcp`
- 可以构建 `sdist` / `wheel` 后上传到 PyPI 或内网仓库

典型发布流程：

```bash
uv build
uv run twine check dist/*
uv run twine upload dist/*
```

说明：

- 发布前记得更新 `pyproject.toml` 中的 `project.version`
- 如果使用内网仓库，可按仓库要求补充 `twine upload` 参数
- 发布完成后，其他人可直接通过 `uvx gauss-mcp` 使用

## Claude Code / MCP 配置

推荐优先使用“已发布包 + `uvx`”的方式分发给其他人，不要求对方 clone 仓库。

### 方式一：用 CLI 添加到 Claude Code

添加到当前项目：

```bash
claude mcp add --scope project \
  --env GAUSS_APPUID=your_appuid \
  --env GAUSS_APPKEY=your_appkey \
  --env GAUSS_APPSECRET=your_appsecret \
  --env GAUSS_API_BASE_URL=https://api-beta.kujiale.com/p/openapi/ \
  --env GAUSS_WEB_BASE_URL=https://www.kujiale.com \
  gauss-mcp -- uvx gauss-mcp
```

如果想给自己全局使用，把 `--scope project` 改成 `--scope user`。

### 方式二：在项目根目录提供 `.mcp.json`

```json
{
  "mcpServers": {
    "gauss-mcp": {
      "command": "uvx",
      "args": ["gauss-mcp"],
      "env": {
        "GAUSS_APPUID": "your_appuid",
        "GAUSS_APPKEY": "your_appkey",
        "GAUSS_APPSECRET": "your_appsecret",
        "GAUSS_API_BASE_URL": "https://api-beta.kujiale.com/p/openapi/",
        "GAUSS_WEB_BASE_URL": "https://www.kujiale.com"
      }
    }
  }
}
```

配置建议：

- 本地开发继续用 `.env` + `uv run gauss-mcp` 即可
- 分发给其他人时，更推荐用 Claude Code 的 `env` 配置显式注入参数，不要假设对方工作目录里一定有 `.env`
- 如果团队要共享 `.mcp.json`，不要把真实密钥直接提交到仓库

## 主要工具

### Run 管理

- `gauss_create_run`
- `gauss_get_run`
- `gauss_list_runs`
- `gauss_set_run_options`
- `gauss_resume_run`
- `gauss_create_variant`

### Step 执行

- `gauss_run_image_type`
- `gauss_run_img2pano`
- `gauss_run_pano_clear`
- `gauss_run_pano2pointcloud`
- `gauss_run_spatial_tune`
- `gauss_run_gauss_import`
- `gauss_run_gauss_info`

### 调试与导出

- `gauss_get_step`
- `gauss_retry_step`
- `gauss_export_run_report`

### Resources

- `gauss://runs/{run_id}`
- `gauss://runs/{run_id}/steps`
- `gauss://runs/{run_id}/steps/{step_key}`
- `gauss://runs/{run_id}/report`

## Skill 交互约定

推荐配合 `.claude/skills/gauss-import/SKILL.md` 使用。

正常情况下，skill 会：

1. 创建 run
2. 调用 `gauss_resume_run(wait=true)` 持续推进
3. 在需要时向用户提问
4. 写回参数后继续推进

当前有 3 个显式的人机 gate：

1. `clear_furniture` 未提供
2. `floor_height_m` 未提供
3. `ImageType` 失败时，向用户确认这是不是全景图

第 3 个 gate 的处理方式是：

- 用户回答“是全景图” → `gauss_set_run_options(is_pano=true)`
- 用户回答“不是全景图” → `gauss_set_run_options(is_pano=false)`
- 然后再次 `gauss_resume_run(wait=true)`

## 开发与验证

```bash
uv run ruff check .
uv run mypy src
uv run pytest
uv build
uv run twine check dist/*
```

## 真实环境 smoke test

真实 smoke test 会在上游创建实际任务。执行前请确认：

- `.env` 中已配置有效鉴权信息
- 输入的是公开可访问的图片 URL
- 你接受在测试环境创建真实导入任务

## 项目结构

```text
src/gauss_mcp/
  __main__.py
  client.py
  config.py
  models.py
  server.py
  workflow.py
  persistence/
tests/
```

## 当前状态

本地质量门禁已打通：

- `ruff`
- `mypy`
- `pytest`
- `uv build`
- `twine check`

如果下一步要做真实链路验证，建议直接围绕 `gauss-import` skill 跑一次完整 smoke。
