Skip to main content

MCP server for Gauss automatic import workflows

Project description

gauss-mcp

一个基于 FastMCP 的 Python MCP server,用来把公开图片 URL 驱动到 Gauss 自动导入链路;配合 gauss-import skill 时,也支持先把本地图片上传到 OUS,再继续导入。

当前 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_furniturefloor_height_m 缺失时显式停下来等待用户输入
  • ImageType 失败时,skill 可以向用户确认是否为全景图,再通过人工覆盖继续推进
  • GaussImport 成功后会继续轮询 v2/gauss/info,直到展示信息可读
  • 如果本地等待窗口结束但展示信息仍在生成,run 会保持 running,后续继续 gauss_resume_run 即可

工作流 UML

下面这张状态图表达 run 从创建到展示信息就绪的主链路,以及 3 个显式人机 gate。

stateDiagram-v2
    [*] --> Created: gauss_create_run

    state "等待人工确认是否全景图" as ManualPanoramaConfirm
    state "全景图已就绪" as PanoramaReady
    state "等待 clear_furniture" as WaitClearFurniture
    state "等待 floor_height_m" as WaitFloorHeight
    state "展示信息仍在生成" as DisplayGenerating
    state imageTypeResult <<choice>>
    state clearDecision <<choice>>
    state floorDecision <<choice>>

    Created --> ImageType: gauss_run_image_type / gauss_resume_run
    ImageType --> imageTypeResult
    imageTypeResult --> PanoramaReady: is_pano=true\npanorama_url=source_url
    imageTypeResult --> Img2Pano: is_pano=false
    ImageType --> ManualPanoramaConfirm: 失败 / 疑似误判
    Img2Pano --> PanoramaReady: panorama_url ready
    Img2Pano --> ManualPanoramaConfirm: 异常且怀疑误判
    ManualPanoramaConfirm --> PanoramaReady: gauss_set_run_options(is_pano=true)
    ManualPanoramaConfirm --> Img2Pano: gauss_set_run_options(is_pano=false)

    PanoramaReady --> clearDecision
    clearDecision --> WaitClearFurniture: clear_furniture 缺失
    clearDecision --> PanoClear: clear_furniture=true
    clearDecision --> Pano2PointCloud: clear_furniture=false
    WaitClearFurniture --> clearDecision: gauss_set_run_options(clear_furniture)

    PanoClear --> Pano2PointCloud: cleared_panorama_url ready
    Pano2PointCloud --> SpatialTune: point cloud ready

    SpatialTune --> floorDecision
    floorDecision --> WaitFloorHeight: floor_height_m 缺失
    floorDecision --> GaussImport: floor_height_m ready
    WaitFloorHeight --> GaussImport: gauss_set_run_options(floor_height_m)

    GaussImport --> GaussInfo: result_url / ids ready
    GaussInfo --> DisplayGenerating: gauss_info_status=generating
    DisplayGenerating --> GaussInfo: gauss_resume_run
    GaussInfo --> Completed: gauss_info_status=ready\n返回 result_url / splat / drc
    Completed --> [*]

补充说明:

  • MCP 主链路当前仍消费公开图片 URL;gauss-import skill 已支持通过 gauss_get_ous_upload_token + /ous-upload 先上传本地图片,再继续导入。
  • clear_furniturefloor_height_mis_pano 人工覆盖都是显式 gate,不会在 MCP 内部静默填默认值。
  • rotation_z 未显式提供时,会默认复用 SpatialTune.rotate

环境要求

  • Python 3.11+
  • uv

安装

本地开发

uv sync

已发布包

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

uvx gauss-mcp

配置

必填鉴权配置

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

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

可选运行时配置

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_LOG_LEVEL=INFO
GAUSS_TRANSPORT=stdio
GAUSS_HOST=127.0.0.1
GAUSS_PORT=8000

全量参数说明

  • GAUSS_APPUID:OpenAPI 鉴权所需的 appuid。默认 None,调用真实接口时通常必填。
  • GAUSS_APPKEY:OpenAPI 鉴权所需的 appkey。默认 None
  • GAUSS_APPSECRET:OpenAPI 鉴权所需的 appsecret。默认 None
  • GAUSS_API_BASE_URL:OpenAPI 基础地址。默认 https://api-beta.kujiale.com/p/openapi/
  • GAUSS_WEB_BASE_URL:结果页基础地址,用于拼接 result_url。默认 https://www.kujiale.com
  • GAUSS_STATE_DIR:SQLite 状态目录。默认行为:
    • 从源码仓库直接运行时,使用 <repo>/data/state
    • 从已安装包或 uvx gauss-mcp 运行时,使用 ~/.gauss-mcp/state
  • GAUSS_RUNS_DIR:run artifact 目录。默认行为:
    • 从源码仓库直接运行时,使用 <repo>/data/runs
    • 从已安装包或 uvx gauss-mcp 运行时,使用 ~/.gauss-mcp/runs
  • GAUSS_TIMEOUT_S:单步远端轮询等待窗口,单位秒。默认 300
  • GAUSS_POLL_INTERVAL_S:轮询间隔,单位秒。默认 2
  • GAUSS_LOG_LEVEL:日志级别。默认 INFO
  • GAUSS_TRANSPORT:MCP 传输方式。默认 stdio。可选值:stdiossestreamable-http
  • GAUSS_HOST:HTTP 类传输绑定地址。默认 127.0.0.1;仅在 GAUSS_TRANSPORT=ssestreamable-http 时生效。
  • GAUSS_PORT:HTTP 类传输监听端口。默认 8000;仅在 GAUSS_TRANSPORT=ssestreamable-http 时生效。

补充说明:

  • database_pathGAUSS_STATE_DIR 派生,固定为 <state_dir>/gauss_mcp.sqlite3,不单独暴露环境变量。
  • 分发给其他人时,推荐显式配置 GAUSS_STATE_DIRGAUSS_RUNS_DIR,避免状态写入默认目录后不易排查。
  • 不要把真实密钥提交到仓库。

启动 MCP Server

默认使用 stdio 传输。

如果设置 GAUSS_TRANSPORT=sseGAUSS_TRANSPORT=streamable-http,进程会改为监听 GAUSS_HOST:GAUSS_PORT

从源码仓库启动

uv run gauss-mcp

或:

uv run python -m gauss_mcp

从已发布包启动

uvx gauss-mcp

打包与发布

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

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

典型发布流程:

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

添加到当前项目:

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

{
  "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,不要把真实密钥直接提交到仓库

主要工具

下面这张 UML 结构图按职责分层展示 MCP 暴露的 tool / resource 面。

classDiagram
    class RunManagement {
      +gauss_create_run()
      +gauss_get_run()
      +gauss_list_runs()
      +gauss_set_run_options()
      +gauss_resume_run()
      +gauss_create_variant()
    }

    class UploadSupport {
      +gauss_get_ous_upload_token()
    }

    class StepExecution {
      +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()
    }

    class DebugExport {
      +gauss_get_step()
      +gauss_retry_step()
      +gauss_export_run_report()
    }

    class ResourceView {
      +run_summary()
      +step_list()
      +step_detail()
      +run_report()
    }

    class WorkflowRun {
      +run_id
      +status
      +current_step
      +state
    }

    class StepSnapshot {
      +step_key
      +status
      +remote_task_id
      +request_path
      +submit_response_path
      +last_poll_response_path
      +output_path
      +error_path
    }

    RunManagement --> WorkflowRun : 创建 / 查询 / 推进
    StepExecution --> WorkflowRun : 推进状态机
    StepExecution --> StepSnapshot : 持久化单步快照
    DebugExport --> StepSnapshot : 调试 / 重试 / 导出
    ResourceView --> WorkflowRun : 只读访问
    ResourceView --> StepSnapshot : 只读访问

ResourceView 对应的实际 URI:

  • gauss://runs/{run_id}
  • gauss://runs/{run_id}/steps
  • gauss://runs/{run_id}/steps/{step_key}
  • gauss://runs/{run_id}/report

Run 管理

  • gauss_create_run
  • gauss_get_run
  • gauss_list_runs
  • gauss_set_run_options
  • gauss_resume_run
  • gauss_create_variant

上传辅助

  • gauss_get_ous_upload_token

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 会采用“逐步展示、逐步汇报”的策略,而不是一上来就用一次 gauss_resume_run(wait=true) 把多个步骤吞在一起。

本地图片输入时

如果用户给的是本地图片路径,skill 会先:

  1. 调用 gauss_get_ous_upload_token 获取 ousToken / globalDomain / blockSize
  2. 调用 /ous-upload skill 上传本地文件
  3. 如果 /ous-upload skill 不可用,提示用户到 https://coops.qunhequnhe.com/ai/skill#/detail?name=ous-upload&namespaceId=dev 安装
  4. 拿到上传后的公开 URL 后,再继续 gauss_create_run

OUS 上传前置条件与成功判定

本地图片链路依赖 gauss_get_ous_upload_token/ous-upload skill 配合完成。gauss_get_ous_upload_token 返回的 ousTokenglobalDomainblockSize 需要原样传给 /ous-upload skill;其中 ousToken 用于上传鉴权,blockSize 决定走单文件上传还是分片上传,bucketType 如果存在可以忽略。

/ous-upload skill 会按下面 3 个阶段执行:

  1. 准备阶段:确认本地文件存在且可读,计算文件大小和 MD5;当 file_size <= blockSize 时走单文件上传,否则按 ceil(file_size / blockSize) 拆分分片,分片序号从 1 开始。
  2. 上传阶段:单文件走 POST /ous/api/v2/single/upload;分片上传先走 POST /ous/api/v2/block/upload/init,再按需调用 POST /ous/api/v2/block/upload/part 上传缺失分片。
  3. 状态轮询阶段:只有在上传请求成功建立任务后,才调用 GET /ous/api/v2/upload/status 轮询结果。

成功与失败以终态 status 为准:

  • status = 5:上传成功,此时才返回最终 urluploadKey
  • status = 6status = 8:上传失败
  • 轮询间隔不要低于 200ms,总轮询时间不超过 2 分钟
  • 即使响应里提前出现 uploadKeyobsTaskId 或其他中间态字段,也不能视为上传成功

如果 /ous-upload skill 不可用,本地图片导入链路不会自动降级为 MCP 直接上传;需要先安装该 skill,拿到公开 URL 后再继续后续 Gauss 导入步骤。

新建导入任务时

skill 会按下面的顺序执行,并在每一步结束后明确展示结果:

  1. gauss_create_run
  2. gauss_run_image_type
  3. gauss_run_img2pano(仅 is_pano=false 时)
  4. gauss_run_pano_clear(按需)
  5. gauss_run_pano2pointcloud
  6. gauss_run_spatial_tune
  7. gauss_run_gauss_import
  8. gauss_run_gauss_info

展示时会尽量明确:

  • 当前 step 是否执行
  • 关键结果是什么
  • 哪些 step 被跳过
  • 跳过原因是什么
  • 下一步将做什么
  • 当首次拿到可用全景图时,当前回复里同时展示 markdown 图片 ![全景图](...) 和 URL 文本
  • 如果 PanoClear 产出了新的 cleared_panorama_url,会再次展示清家具后的全景图和 URL

例如:

  • ImageType 已执行,结果是全景图 → Img2Pano 会被明确标记为“已跳过,原因是当前图已可直接视为全景图”,并在当前回复里同时展示 ![全景图](<source_url>) 和原始 URL
  • ImageType 已执行,结果是普通图 → 下一步将显式执行 Img2Pano;一旦拿到 panorama_url,会立即展示全景图预览和 URL
  • 如果用户选择清家具,且 PanoClear 返回了新的 cleared_panorama_url → 会再次展示清家具后的全景图预览和 URL

已有 run 时

如果用户给的是 run_id,skill 会优先复用当前 run,而不是重建:

  1. 先调用 gauss_get_run(include_steps=true) 读取当前状态
  2. 明确展示 run 的 statuscurrent_step 和已完成步骤
  3. 需要继续时再调用 gauss_resume_run 或对应单步工具
  4. 失败时先读取失败 step 详情,再向用户解释原因和下一步建议

显式人机 gate

当前仍有 3 个显式的人机 gate:

  1. clear_furniture 未提供
  2. floor_height_m 未提供
  3. ImageType / Img2Pano 异常后,怀疑图片类型误判,需要人工确认是否为全景图

第 3 个 gate 的典型处理方式:

  • ImageType 失败 → 先读取 image_type step 详情,再询问用户这是不是全景图
  • Img2Pano 异常,且前面存在 is_pano=false 的判断 → 明确告诉用户 ImageType 这一步已经跑过了,但当前怀疑可能误判,再询问用户这张图其实是不是全景图
  • 用户回答“是全景图” → gauss_set_run_options(is_pano=true),再继续 gauss_resume_run(wait=true)
  • 用户回答“不是全景图” → gauss_set_run_options(is_pano=false),再继续 gauss_resume_run(wait=true)

开发与验证

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

真实环境 smoke test

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

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

项目结构

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。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gauss_mcp-0.1.3.tar.gz (26.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gauss_mcp-0.1.3-py3-none-any.whl (29.9 kB view details)

Uploaded Python 3

File details

Details for the file gauss_mcp-0.1.3.tar.gz.

File metadata

  • Download URL: gauss_mcp-0.1.3.tar.gz
  • Upload date:
  • Size: 26.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for gauss_mcp-0.1.3.tar.gz
Algorithm Hash digest
SHA256 5041fecfc0bdc04f08cdebeb4df8113cb967db136f8a0e77712915d0da6758a5
MD5 053fa84f8549fe306a32aa89e305dff9
BLAKE2b-256 c2f83602eb43ee0c93acf5b9e59b7cf765114218a3d61a9d9dc97955483cc055

See more details on using hashes here.

File details

Details for the file gauss_mcp-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: gauss_mcp-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 29.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for gauss_mcp-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 28a93c287645678a33593339b7486b6693daa49bc88975b0fe4d56c21fcc258f
MD5 a43fafb1bb2938db5ec00a5721a1fbd6
BLAKE2b-256 20bece8a314c0cb3741ebd708a60fc413ff826cb03c8b071533ae5771bcb8022

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page