Other MCP Server · MODEL CONTEXT PROTOCOL

cfrs2005 mcp gs robot

mcp-gs-robot gaussian bot

连接能力

cfrs2005 mcp gs robot 为 AI Agent 提供什么

  • **`list_robots`**: Lists robots accessible via the API key. (Based on: [List Robots API](https://developer.gs-robot.com/zh_CN/Robot%20Information%20Service/List%20Robots))
  • **`get_robot_status`**: Fetches the detailed status of a specific robot by its serial number. (Based on: [Get Robot Status API](https://developer.gs-robot.com/zh_CN/Robot%20Information%20Service/V1%20Get%20Robot%20Status))
  • **`list_robot_task_reports`**: Retrieves cleaning task reports for a specific robot, with optional time filtering. (Based on: [List Robot Task Reports API](https://developer.gs-robot.com/zh_CN/Robot%20Cleaning%20Data%20Service/V1%20List%20Robot%20Task%20Reports))
  • **`list_robot_maps`**: Lists the maps associated with a specific robot. (Based on: [List Robot Maps API](https://developer.gs-robot.com/zh_CN/Robot%20Map%20Service/V1%20List%20Robot%20Map))
  • **`src/gs_openapi/config.py`**: Contains base URLs, API paths, and environment variable names.
  • **`src/gs_openapi/auth/token_manager.py`**: Manages acquiring and refreshing OAuth tokens.
  • **`src/gs_openapi/api/`**: Contains modules (`robots.py`, `maps.py`) with functions that directly call the Gausium OpenAPI endpoints using `httpx`.
  • **`src/gs_openapi/mcp/gausium_mcp.py`**: Defines the `GausiumMCP` class which integrates the API calls and token management.
  • **`main.py`**: Initializes `GausiumMCP`, registers the API functionalities as MCP tools using `@mcp.tool()`, configures basic logging, and starts the server using `mcp.run()`.
  • **Clone the repository:**
  • **Create and activate a virtual environment using `uv`:**
  • **Install dependencies using `uv`:**
  • **Configure Credentials:**
  • `GS_CLIENT_ID`: Your Gausium Application Client ID.
  • `GS_CLIENT_SECRET`: Your Gausium Application Client Secret.
  • `GS_OPEN_ACCESS_KEY`: Your Gausium OpenAPI Access Key.
  • **Run the server:**

安全

MCP 收录不等于安全审核

MCP 服务器可能获得模型上下文、凭据、本地文件或调用外部系统的权限。连接 Agent 前,请检查代码、环境变量、网络行为、软件包来源与维护状态。

README

仓库文档

Saodi AI

An open-source ops agent for Gausium cleaning robots — MCP server, REST API, CLI and mobile web, on OpenAPI V3.

package mcp-gs-robot · pip install mcp-gs-robot

PyPI Python 3.12+ CI License: MIT

5-minute start · Let your AI agent set it up · Safety · Cognition & memory · Tools · HTTP API & H5 · Configuration · Troubleshooting · 中文文档

⚠️ Disclaimer — This is an unofficial, open-source project for personal research and learning. Not affiliated with, endorsed by, or supported by Gausium (高仙). Use at your own risk — robot commands move physical machines, so test on simulators or idle robots first. Built solely from the public Gausium OpenAPI V3 documentation.

H5 app: home with greeting, suggested questions and fleet overview; result cards (robot card, report KPIs, daily trend); execution pipeline (confirm → sent → delivered, nothing runs until approved); robot list (search, filters, online / offline / unreachable); current location (robot, heading and map points on the map)

The built-in H5 app, left to right: Home · Result cards · Execution pipeline · Robots · Current location. Running against a mock upstream with demo data.

What is this?

mcp-gs-robot wraps the Gausium OpenAPI V3 (robot status, maps, combined tasks, schedules, commands, reports) in a typed Python client, and exposes it through four entry points that share one tool registry:

Entry point Command Use it when…
MCP Server (stdio) mcp-gs-robot Claude Code, Claude Desktop, Cursor, Cherry Studio or any MCP client should operate robots
HTTP Server (FastAPI) gs-robot-server You want REST endpoints, Swagger and the built-in H5 mobile app
Saodi 扫地僧 (CLI + H5 chat) saodi You want a chat assistant that plans and runs robot operations behind confirmation gates, and remembers what it learns
Agent Skill skills/gs-robot/ You want to teach Claude Code / Codex / WorkBuddy the correct operating procedure

Architecture

  • 42 tools — all 36 V3 business endpoints, the legacy robot list, local lookups (describe_work_state, lookup_error_code), local memory (remember) and workflow helpers (run_cleaning_task, wait_for_command)
  • Typed & tested — pydantic v2 models, envelope unwrapping, upstream errors (6-digit platform codes, 10-digit robot task codes) surfaced as GausiumAPIError; offline test suite with a mock HTTP transport
  • Safety first — every tool that moves a robot or writes data is flagged dangerous and needs explicit approval in the Agent, CLI and H5
  • Gets smarter with use — sessions, tool calls and error threads are kept in a local SQLite file; verified lessons go into a private memory file that every new session loads
  • Provider-agnostic Agent — Anthropic (default, claude-opus-5) or any OpenAI-compatible endpoint (DeepSeek, vLLM, Ollama…); it answers in the language you write in
  • Built strictly on the official docs — docs/apis.md maps each endpoint to its official page; the full contract is docs/ARCHITECTURE_V3.md

5-minute quick start

Prerequisites: Python 3.12+, uv, and Gausium open-platform credentials (an application plus an AccessKey from the Gausium Developer Center). Node 18+ is only needed if you want to rebuild the H5 app — a production build is already committed.

1 · Install

git clone https://github.com/cfrs2005/mcp-gs-robot.git
cd mcp-gs-robot
uv sync --extra dev

(Or pip install mcp-gs-robot if you only need the commands; the wheel ships the H5 build and the skill.)

2 · Configure — cp .env.example .env, then fill in:

What Variables
Gausium credentials GS_CLIENT_ID, GS_CLIENT_SECRET, GS_OPEN_ACCESS_KEY (the AccessKeySecret, not the AccessKeyID)
Environment GS_BASE_URL — production https://openapi.gs-robot.com/, test https://openapi.dev.gs-robot.com/
HTTP server key GS_SERVER_API_KEY — any long random string; the H5 and REST clients send it as X-API-Key
LLM (pick one) Anthropic: SAODI_PROVIDER=anthropic + ANTHROPIC_API_KEY · OpenAI-compatible: SAODI_PROVIDER=openai + OPENAI_BASE_URL + OPENAI_API_KEY + SAODI_MODEL

.env is read from the current working directory by every entry point, is git-ignored, and must never be committed. Real environment variables take precedence over .env.

3 · Run an entry point (from the repository root)

Entry point Command Then
MCP (stdio) claude mcp add gs-robot -- uv --directory "$PWD" run mcp-gs-robot Ask your MCP client "List my robots and show battery and work state"
REST + H5 uv run gs-robot-server Open http://localhost:8000/ → Settings → paste GS_SERVER_API_KEY → Save. Swagger: http://localhost:8000/docs
Saodi CLI uv run saodi Chat in the terminal; dangerous steps ask [y/N]
Skill cp -r skills/gs-robot ~/.claude/skills/gs-robot Also mount the MCP server (row 1); the skill teaches the procedure

Check that the server is up: curl -s http://127.0.0.1:8000/api/v1/health → {"status":"ok", …, "auth_required":true}. auth_required: true means the H5 needs the key before anything else works.

uv run saodi --show-context prints Saodi's full system prompt without any key — a quick way to confirm the install.

Let your AI agent set it up

Paste this into Claude Code, Codex or Cursor (agent mode). It installs, configures, tests and smoke-tests the project with read-only calls only. The same prompt, with a Chinese version, is in docs/AGENT_SETUP_PROMPT.md.

Set up mcp-gs-robot (an unofficial MCP / REST / agent wrapper for the Gausium OpenAPI V3) on this
machine. Work step by step, show me each command's result, and stop at the first failure.

Hard rules
- Robots are physical machines. Call read-only tools only. Never call a tool marked dangerous
  (anything that creates, updates or deletes tasks or schedules, starts / pauses / resumes / stops /
  skips tasks, navigates, runs a cleaning workflow, or writes memory with `remember`).
- Never print, echo, log or commit credentials. Write them only into .env with your file-edit tool
  (not via shell echo), never paste them back to me, and confirm .env is git-ignored.

Steps
1. Prerequisites: `python3 --version` (3.12+) and `uv --version`. `node --version` (18+) only
   matters for step 5.
2. `git clone https://github.com/cfrs2005/mcp-gs-robot.git && cd mcp-gs-robot && uv sync --extra dev`
3. `cp .env.example .env`. Ask me for GS_CLIENT_ID, GS_CLIENT_SECRET and GS_OPEN_ACCESS_KEY (the
   AccessKeySecret, not the AccessKeyID), and whether to use production
   (https://openapi.gs-robot.com/) or test (https://openapi.dev.gs-robot.com/) for GS_BASE_URL.
   Ask which LLM provider I use: Anthropic (SAODI_PROVIDER=anthropic + ANTHROPIC_API_KEY) or an
   OpenAI-compatible endpoint (SAODI_PROVIDER=openai + OPENAI_BASE_URL + OPENAI_API_KEY +
   SAODI_MODEL). Generate GS_SERVER_API_KEY yourself with
   `python3 -c "import re,secrets,pathlib;p=pathlib.Path('.env');p.write_text(re.sub(r'(?m)^GS_SERVER_API_KEY=.*$','GS_SERVER_API_KEY='+secrets.token_urlsafe(32),p.read_text()))"` (it rewrites the line in .env in place and never prints the key; I will read it from .env myself).
   Then run `git check-ignore .env` (it must print .env) and `git status --short` (.env must not
   appear).
4. `uv run pytest -q` and `uv run ruff check src tests`; both must pass.
5. If Node 18+ is available: `cd h5 && npm ci && npm run build && cd ..`. Otherwise skip; a
   prebuilt H5 is already in src/gs_openapi/server/static/.
6. Start the server in the background with its output in a log file:
   `uv run gs-robot-server > server.log 2>&1 &`
7. `curl -s http://127.0.0.1:8000/api/v1/health` must return "status":"ok" and
   "auth_required":true.
8. Tell me to open http://localhost:8000/, go to Settings, paste the GS_SERVER_API_KEY value from
   .env and press Save (it should report the connection as OK). Do not show me the key yourself.
9. Read-only smoke test. Load the key without printing it:
   `KEY=$(grep '^GS_SERVER_API_KEY=' .env | cut -d= -f2-)`
   - `curl -s -X POST -H "X-API-Key: $KEY" -H 'Content-Type: application/json'
     -d '{"page":1,"page_size":5}' http://127.0.0.1:8000/api/v1/tools/list_robots`
   - pick one robot from that list with "online": true and call get_robot_status the same way
     with body {"robot_sn_list":["<that SN>"]}.
   Error meanings: 401 = wrong or missing X-API-Key; 110003 = these credentials are not bound to
   that robot (not "no data"); 230003 = robot offline; 100026 = rate limited, slow down.
10. Report: tool versions, pytest / ruff results, the health response, how many robots are
    online / offline, and any error as `<code> <msg>`. Leave out secrets and trace IDs.

Entry points in detail

MCP Server — Claude Code / Claude Desktop / Cursor

From a clone (reads .env in the repository):

claude mcp add gs-robot -- uv --directory /path/to/mcp-gs-robot run mcp-gs-robot

From pip install mcp-gs-robot, pass credentials explicitly — in claude_desktop_config.json / Cursor MCP settings:

{
  "mcpServers": {
    "gs-robot": {
      "command": "mcp-gs-robot",
      "env": { "GS_CLIENT_ID": "…", "GS_CLIENT_SECRET": "…", "GS_OPEN_ACCESS_KEY": "…" }
    }
  }
}

Transport is stdio. MCP hosts run tools directly, so keep your host's own tool-approval prompts on for dangerous tools. Set GS_ENABLE_LEGACY_TOOLS=1 to also expose the 0.1.x tools as legacy_*.

HTTP Server + H5 mobile app
uv run gs-robot-server              # http://0.0.0.0:8000 (GS_SERVER_HOST / GS_SERVER_PORT)
  • H5 app — open http://localhost:8000/ on your phone or in a browser, then fill in the API key under Settings
  • Swagger — http://localhost:8000/docs
  • Docker — cp .env.example .env && $EDITOR .env && docker compose up -d (serves on :8000)
Saodi (扫地僧) — chat in the terminal
uv run saodi                                   # provider and keys from .env
uv run saodi --robot <robot-sn>                # scope the session to one robot
uv run saodi --show-context                    # print the system prompt and exit (no key needed)
you> Is the lobby robot free? Enough battery for a full dust-push?
⚙ get_robot_status(robot_sn_list=["<robot-sn>"])
Online, 82% battery, IDLE on map "Lobby" — good to go.
you> Start the lobby dust-push task
⚙ list_task_definitions(...)
Approve start_task robot_sn=<robot-sn> fusion_task_id=…? [y/N] y
⚙ start_task(...)  ⚙ wait_for_command(...)
Command delivered (cmdStatus=6); it is not finished yet — I'll check workState again in ~30 s.

Other subcommands (no LLM key, no upstream calls):

uv run saodi memory                            # path and content of the local memory file
uv run saodi memory add "<lesson>" [--scope S] # add one lesson by hand
uv run saodi memory edit                       # open it in $VISUAL / $EDITOR
uv run saodi errors [--status open] [--json]   # error threads from the tool-call log
uv run saodi errors show <id>                  # one thread with its recent calls
uv run saodi errors promote <id>               # turn a thread into a memory lesson

Renamed after 0.2.0: the old pi-agent command and PI_AGENT_* variables still work for one release and print a deprecation warning.

Agent Skill — Claude Code / Codex / WorkBuddy
cp -r skills/gs-robot ~/.claude/skills/gs-robot     # Claude Code (user scope)
cp -r skills/gs-robot ~/.codex/skills/gs-robot      # Codex CLI

The skill encodes the safe operating procedure (status → capabilities → resources → task definition → start → poll) and ships reference tables for work states, command types and task-start error codes. See skills/gs-robot/README.md.

Safety model

Tools that move a robot or write data are registered with dangerous=True. Saodi never runs them on its own: it emits confirm_required and waits — [y/N] in the terminal, buttons in the H5, POST …/confirm over REST. A rejected call never reaches the robot (or the memory file).

Dangerous tool confirmation flow

Keep in mind:

  • Delivered is not finished. cmdStatus=6 means the robot received the command; follow up with get_robot_status or task reports.
  • REST executes directly. POST /api/v1/tools/{name} treats the caller as already having confirmed — gate it in your own client. SAODI_AUTO_APPROVE=1 disables the Agent gate (not recommended).

For the common "clean these areas" case, run_cleaning_task bundles the whole procedure into one confirmed call:

run_cleaning_task workflow

Saodi's cognition and memory

Every new session gets one system prompt, assembled in this order and fixed for the session (saodi --show-context prints it):

Layer Where Maintained by Shared?
Soul — identity, voice (answers in your language), safety rules, when to propose remember src/gs_openapi/agent/soul.md project maintainers open source
Knowledge — domain model, operating procedure, work-state table skills/gs-robot/ (references/domain.md, SKILL.md, references/work-states.md) — the same files the Agent Skill uses project maintainers open source
Memory — field-tested call experience skills/gs-robot/references/experience.md contributors, via pull requests open source
Local memory — lessons learned on your machine $SAODI_DATA_DIR/memory.md (default ~/.saodi/memory.md) you and Saodi (remember, saodi memory, saodi errors promote) private, never in git
Private context — notes you keep elsewhere $SAODI_CONTEXT_DIR/*.md (sorted by name) you private

The official error-code table (skills/gs-robot/references/error-codes.md, ~23 KB) is not loaded into every prompt: Saodi calls the read-only lookup_error_code tool when it meets a code it does not know, and is told not to guess. The whole prompt is capped by SAODI_CONTEXT_MAX_CHARS (default 60000); when it overflows, the oldest local memory entries are dropped first and a WARNING says how many.

Saodi memory loop: load stack and learning loop

How it gets smarter

  1. remember in chat. When Saodi learns something verified and reusable — what an error code means in practice, a robot's lasting quirk, your preferences — it proposes remember(lesson). That writes a file, so it asks for confirmation like any dangerous tool. On approval it appends - [YYYY-MM-DD] lesson to memory.md; duplicates are skipped and anything that looks like a credential (token / secret / Bearer / long random strings) is refused. It does not remember one-off data (today's battery, a single snapshot) or guesses. The next session loads the new line.
  2. From errors to lessons. Every tool call is logged locally; failures are folded into error threads. saodi errors lists them, PATCH /api/v1/errors/threads/{id} (try it in Swagger at /docs) lets you set the status, category and a note, and saodi errors promote <id> writes the note (or, if empty, the category and sample message) into memory.md and marks the thread as promoted.
  3. By hand. saodi memory add "…" or saodi memory edit.
  4. Back to everyone. If a lesson is general, propose it for experience.md in a pull request. Writing rule: general behaviour and how to handle it only — no robot SNs, trace IDs, request IDs, accounts, credentials, customer or site names.

Tools

All 42 tools are defined once in gs_openapi/tools/ and exposed identically to MCP, the Agent and REST (POST /api/v1/tools/{name}). Inputs are snake_case; the registry maps them to V3 camelCase. ⚠️ = dangerous.

Category Tools
Robots list_robots · get_robot_status · describe_work_state · get_robot_capabilities
Maps list_robot_maps · get_map_canvas · list_charging_positions · list_map_resources · list_task_resources
Tasks list_work_modes · list_task_definitions · get_task_definition · create_task_definition ⚠️ · update_task_definition ⚠️ · delete_task_definition ⚠️ · start_task ⚠️ · pause_task ⚠️ · resume_task ⚠️ · stop_task ⚠️ · skip_task_item ⚠️
Schedules list_schedules · get_schedule · get_schedule_calendar · list_schedule_pre_tasks · create_simple_schedule ⚠️ · update_simple_schedule ⚠️ · delete_simple_schedule ⚠️ · create_schedule ⚠️ · update_schedule ⚠️ · delete_schedule ⚠️
Commands get_command_status · list_command_history · navigate_home ⚠️ · pause_navigation ⚠️ · resume_navigation ⚠️ · stop_navigation ⚠️
Reports list_task_reports · get_task_report_map_images
Workflows wait_for_command · run_cleaning_task ⚠️
Reference lookup_error_code (local, read-only)
Memory remember ⚠️ (writes the local memory file)
Inputs for each tool

Robots & Maps

Tool Required Optional Notes
list_robots – page, page_size, relation Legacy v1alpha1/robots (V3 has no list endpoint)
get_robot_status robot_sn_list (≤100) Adds work_state_name / work_state_desc; snapshots lag ≤30 s
describe_work_state work_state Local lookup, no API call
get_robot_capabilities robot_sn Combined-task / schedule support flags
list_robot_maps robot_sn mapId, mapVersionId, displayName
get_map_canvas robot_sn, map_id Temporary PNG URL + grid metadata
list_charging_positions robot_sn, map_id
list_map_resources robot_sn, map_id_list include_paths/regions/positions Resources without work modes
list_task_resources robot_sn, map_id_list include_paths/regions/positions Query this before creating tasks/schedules

Tasks

Tool Required Optional
list_work_modes robot_sn
list_task_definitions robot_sn page, pagesize, site_id, task_name
get_task_definition robot_sn, fusion_task_id
create_task_definition robot_sn, task_name, work_mode, map_resource_list loop_count, site_id, task_advance_config ⚠️
update_task_definition robot_sn, fusion_task_id same as create ⚠️
delete_task_definition robot_sn, fusion_task_id ⚠️
start_task robot_sn, fusion_task_id loop_count ⚠️ returns requestId, taskInstanceId
pause_task / resume_task / stop_task / skip_task_item robot_sn ⚠️

Schedules

Tool Required
create_simple_schedule robot_sn, task_name, site_mode, work_mode, map_resource_list, plan_execute_type, plan_repeat_type, plan_start_date, plan_start_time ⚠️
update_simple_schedule / delete_simple_schedule robot_sn, plan_uuid, year, month, day_of_month, operation_type ⚠️
create_schedule / update_schedule / delete_schedule standard schedule fields (see docs) ⚠️
list_schedules robot_sn
get_schedule robot_sn, plan_uuid, year, month, day_of_month
get_schedule_calendar robot_sn, year_month
list_schedule_pre_tasks robot_sn, date

Commands, Reports, Workflows, Reference & Memory

Tool Required Optional
get_command_status robot_sn, request_id cmdStatus=6 = delivered, not finished
list_command_history robot_sn page, pagesize, cmd_status, command_type
navigate_home robot_sn, map_id map_resource_id ⚠️
pause_navigation / resume_navigation / stop_navigation robot_sn ⚠️
list_task_reports robot_sn page, pagesize, end_time_min, end_time_max
get_task_report_map_images task_report_id robot_sn
wait_for_command robot_sn, request_id timeout_seconds Polls until a terminal cmdStatus
run_cleaning_task robot_sn, task_name, map_id, resource_ids mode, strength, loop_count, wait_seconds ⚠️ capabilities → resources → create → start → poll
lookup_error_code code (3–10 digits) Matching rows from error-codes.md and entries from experience.md; found: false + a "do not guess" hint otherwise
remember lesson scope ⚠️ appends - [YYYY-MM-DD] lesson to $SAODI_DATA_DIR/memory.md; de-duplicated, credential-looking text refused

Regenerate the list from the registry:

uv run python -c "from gs_openapi.tools.registry import REGISTRY; [print(t.category, t.name, '⚠️' if t.dangerous else '') for t in REGISTRY.values()]"

HTTP API & H5

Base prefix /api/v1. GET /health is public; everything else requires X-API-Key when GS_SERVER_API_KEY is set. Errors share one envelope, {"error": {"code", "message", "trace_id"}}; upstream V3 errors become HTTP 502 carrying the business code.

Area Routes
Health & auth GET /health (public; auth_required tells clients a key is needed, never the key) · GET /auth/check (validates the key, no upstream call)
Tools POST /tools/{tool_name} — call any registry tool with its JSON input
Robots GET /robots · POST /robots/status · GET /robots/{sn}/status · /capabilities · /work-modes
Maps GET /robots/{sn}/maps · /maps/{map_id}/canvas · /maps/{map_id}/resources
Tasks GET/POST /robots/{sn}/task-definitions · GET/PUT/DELETE …/{fusion_task_id} · POST /robots/{sn}/tasks/{start|pause|resume|stop|skip}
Navigation POST /robots/{sn}/navigation/{go-home|pause|resume|stop}
Commands & reports GET /robots/{sn}/commands · …/commands/{request_id} · GET /robots/{sn}/reports
Schedules GET/POST /robots/{sn}/schedules · POST …/schedules/simple · GET/PUT/DELETE …/schedules/{plan_id}
Agent GET/POST /agent/sessions · GET/DELETE /agent/sessions/{id} · POST …/{id}/messages (SSE) · POST …/{id}/confirm
Error threads GET /errors/threads · GET/PATCH /errors/threads/{id}

SSE events from /messages: text_delta · tool_call · tool_result · confirm_required · done · error. Sessions are stored in SQLite, so a conversation survives a server restart.

KEY=$(grep '^GS_SERVER_API_KEY=' .env | cut -d= -f2-)
SID=$(curl -s -XPOST -H "X-API-Key: $KEY" localhost:8000/api/v1/agent/sessions | jq -r .session_id)
curl -N -XPOST -H "X-API-Key: $KEY" -H 'Content-Type: application/json' \
  -d '{"content":"List my robots and their battery"}' \
  localhost:8000/api/v1/agent/sessions/$SID/messages

H5 (h5/, Vue 3 + Vite + Vant): Chat (a home screen with greeting, suggested questions and a fleet overview; streaming Markdown, HTML preview and mermaid diagrams; a tool-call timeline with result cards for robots, report KPIs, daily trends and maps; an execution pipeline card for dangerous tools — confirm → sent → delivered, nothing runs until approved; and a history drawer), Robots (fleet list with search and filters, online / offline / unreachable states, battery and work state), Detail (current location — the robot, its heading and map points on the map — maps & canvas, task definitions, quick actions, reports; offline robots get a banner instead of errors) and Settings (API base, API key, language). When the server needs a key and none is saved, the H5 sends you to Settings. The production build is committed to src/gs_openapi/server/static/, so pip install ships it.

Languages

  • H5: English and 中文, switchable under Settings → Language (the first visit follows the browser language).
  • Saodi: replies in the language you write in; field names such as workState or cmdStatus stay in English.
  • Docs: English is the primary language; README_CN.md mirrors this file in Chinese. Tool descriptions are bilingual.

Configuration

Variable Default Description
GS_CLIENT_ID / GS_CLIENT_SECRET / GS_OPEN_ACCESS_KEY – Required. Gausium application + AccessKey credentials (GS_OPEN_ACCESS_KEY is the AccessKeySecret)
GS_BASE_URL https://openapi.gs-robot.com/ Upstream base URL; test environment https://openapi.dev.gs-robot.com/, or a mock
GS_HTTP_TIMEOUT 30 HTTP timeout, seconds
GS_ENABLE_LEGACY_TOOLS unset 1 also registers 0.1.x tools as legacy_* in the MCP server
GS_SERVER_HOST / GS_SERVER_PORT 0.0.0.0 / 8000 HTTP server bind
GS_SERVER_API_KEY unset When set, protected routes require X-API-Key
SAODI_PROVIDER anthropic anthropic or openai
SAODI_MODEL claude-opus-5 / deepseek-chat Model ID per provider
ANTHROPIC_API_KEY – Anthropic provider key
OPENAI_BASE_URL / OPENAI_API_KEY – OpenAI-compatible provider
SAODI_AUTO_APPROVE 0 1 skips dangerous-tool confirmation (including remember)
SAODI_MAX_TURNS 12 Max tool cycles per user message (tool results are truncated at 20k chars)
SAODI_DATA_DIR ~/.saodi Local data: saodi.sqlite (sessions, tool-call log, error threads) and memory.md (local memory)
SAODI_CONTEXT_DIR unset Directory of private *.md notes appended to the system prompt
SAODI_CONTEXT_MAX_CHARS 60000 System prompt length cap; oldest local memory entries go first, then truncation, with a WARNING

Deprecated names, read for one more release when the new name is unset (each prints one WARNING with the name only):

New Deprecated
SAODI_PROVIDER PI_AGENT_PROVIDER
SAODI_MODEL PI_AGENT_MODEL
SAODI_AUTO_APPROVE PI_AGENT_AUTO_APPROVE
SAODI_MAX_TURNS PI_AGENT_MAX_TURNS
saodi (command) pi-agent

Troubleshooting

Symptom Cause Fix
401 in the H5 or from curl GS_SERVER_API_KEY is set but the client sent no / a wrong X-API-Key H5: Settings → paste the key → Save (it checks /api/v1/auth/check). curl: add -H "X-API-Key: …". GET /api/v1/health shows auth_required
110003 Robot is not bound to the current user. Your open-platform application is not bound to this robot (or lacks permission for this data) This is not "no data". Check whether the SN appears in list_robots; if not, bind the robot to the application on the open platform. Report endpoints can say 110003 even when status works
230003 Robot … routing failed. Robot offline / long disconnected from the cloud Check onlineStatus / the online field of list_robots; retrying other endpoints will not help. One such robot fails a whole batch status call; the REST robot list already falls back to per-robot queries
100026 Rate limit (~20 calls/s) Slow down; avoid concurrent bursts
422 with correct parameters Possibly upstream field drift (the response no longer matches the local model) Run uv run saodi errors — a response_model / our_bug thread points at the model to fix; please open an issue
Credentials "missing" although .env exists .env is read from the current working directory; real environment variables win over it Run commands from the directory holding .env (for MCP: uv --directory <repo> run mcp-gs-robot), or pass the variables in the MCP env block; check for stale exported variables with env | grep '^GS_'
PI_AGENT_* is deprecated warnings Old variable names in .env Rename them to SAODI_*

Development

src/gs_openapi/
├── auth/token_manager.py      OAuth token (ms-epoch expiry, locked refresh)
├── core/                      HTTP client, V3 endpoint registry, errors
├── v3/                        GausiumV3 facade · pydantic models · reference tables
├── tools/                     Tool registry (single source for MCP / Agent / REST) + knowledge tools
├── mcp/                       FastMCP server (v3_server.py) + legacy_tools.py
├── agent/                     Saodi core, soul.md, prompt builder, providers, sessions, CLI
├── store/                     SQLite sessions / tool-call log / error threads, local memory.md
├── server/                    FastAPI app, routes, SSE, static H5 hosting
└── main.py                    `mcp-gs-robot` stdio entry
h5/                            Vue 3 mobile web app (builds into server/static)
skills/gs-robot/               Agent Skill + references (also Saodi's Knowledge / Memory)
docs/ARCHITECTURE_V3.md        The contract every module follows
tests/                         Offline tests (httpx.MockTransport, no network)
uv sync --extra dev
uv run pytest -q
uv run ruff check src tests
cd h5 && npm ci && npm run build    # rebuild the H5 into src/gs_openapi/server/static
uv build                            # wheel includes the H5 assets and the skill

To add a V3 tool, define the input model and handler in src/gs_openapi/tools/v3_tools.py with @tool(...); MCP, REST and the Agent pick it up automatically. Add a test and a row to the tool tables. Conventions are in CLAUDE.md; curl walkthroughs and MCP Inspector usage are in the Testing Guide.

Migrating from 0.1.x
0.1.x 0.2.0+
get_robot_status_smart, get_robot_status (v1/v2 routing by SN prefix) get_robot_status (V3 snapshot, any series, batch ≤100)
get_task_reports_smart, list_robot_task_reports list_task_reports
create_robot_command (start/pause/stop) start_task / pause_task / resume_task / stop_task, navigate_home
submit_temp_site_task, execute_*_workflow create_task_definition + start_task, or run_cleaning_task
list_robot_maps (openapi/v1) list_robot_maps (V3) + list_task_resources

Old tools remain available under legacy_* names with GS_ENABLE_LEGACY_TOOLS=1. The OAuth expires_in bug (a millisecond timestamp treated as seconds) is fixed, so remove any refresh workarounds.

Documentation

Document Purpose
Architecture contract Tool names, REST/SSE protocol, agent interface, cognition layers, local storage
Agent setup prompt Copy-paste prompt for Claude Code / Codex / Cursor (English + 中文)
V3 API index Every endpoint with method, path, supported firmware and a link to the official page
Claude Code integration MCP setup + Skill
Testing guide Unit tests, curl walkthrough, MCP Inspector
Skill README Installing the skill in Claude Code / Codex / WorkBuddy
Changelog Release notes

Contributing

Fork, create a feature branch, uv sync --extra dev, make your change with tests, run uv run pytest -q && uv run ruff check src tests, update the tool tables if you touched the registry, and open a pull request. Experience for experience.md is welcome — general behaviour only, with no SNs, trace IDs, accounts, credentials or customer / site names.

License

MIT — see LICENSE.

Disclaimer

This project is an unofficial, open-source effort for personal research and learning, built only from Gausium's public OpenAPI V3 documentation. It is not affiliated with, endorsed by, or supported by Gausium. No warranty of any kind; you are responsible for any robot you command. Always validate on simulators or idle machines first, keep credentials out of version control, and remember that a delivered command (cmdStatus=6) is not a completed task.

Made for people who would rather ask their robots than click through consoles.

在 GitHub 查看 README

社区

收藏、评分与讨论

正在载入社区数据…