Skip to content

Repository files navigation

title Reachy Mini API
emoji 🤖
colorFrom blue
colorTo purple
sdk docker
app_port 7860
pinned false
short_description Backend API for the Reachy Mini app store

Reachy Mini API

Backend service for the Reachy Mini app store. Split out of the showcase website so the mobile app's backend can be deployed independently of the marketing site.

Endpoints

Route Purpose Consumer
GET /api/js-apps JS app catalog (categorized + moderated) mobile app
GET /api/apps full catalog (Python + JS) website
GET /api/mcp-tools MCP tool catalog (Spaces tagged reachy-mini-tool, with resolved mcpUrl), moderated fail-closed mobile app
GET /api/moves community move catalog: one entry per recorded move across the HF datasets tagged reachy_mini_community_moves, plus per-dataset summaries gallery, clients
GET /api/{apps,js-apps,mcp-tools,moves}?q=&limit= semantic search: multilingual-embedding top-limit over that catalog (lexical fallback when the index is cold); response carries query + ranking all clients
GET /api/categories category taxonomy clients
POST /api/openai/ephemeral mint short-lived OpenAI Realtime keys mobile app
GET /api/oauth-config public OAuth client id website (fallback)
GET /api/health health probe monitoring
POST /api/refresh / refresh-categories / refresh-moderation admin triggers ops
POST /api/mcp-tools/refresh-moderation admin trigger for the tool sweep ops

Configuration

Set these in the Space's Settings -> Variables and secrets (see .env.example):

  • HF_TOKEN (required, write access to STORE_DATASET) - LLM categorization + moderation (and persisting their caches), plus the search embeddings via HF Inference.
  • OPENAI_API_KEY (required) - master key used server-side only to mint ephemeral Realtime session keys.
  • STORE_DATASET - single dataset holding app-list.json, block-list.json, categories.json, moderation.json. Defaults to pollen-robotics/reachy-mini-official-app-store.
  • EMBEDDING_MODEL - feature-extraction model powering catalog search. Defaults to intfloat/multilingual-e5-small.

Catalog search

The four catalog routes accept ?q=<free text>&limit=<n> and return the top limit entries by relevance instead of the full catalog. Ranking is multilingual (query in any language against English metadata): one embedding vector per entry (name + description + tags - deliberately not the README, which measurably diluted cross-lingual matching), computed at catalog refresh through the HF Inference router and cached by content hash, plus small popularity / exact-name boosts and a penalty for placeholder descriptions. Without HF_TOKEN, or while the index warms up, ranking degrades to lexical scoring (the response's ranking field says which one answered), and search is always applied after moderation filtering, so it can never surface a hidden Space.

Community moves

/api/moves indexes the recorded-move libraries shared on the Hub: HF datasets tagged reachy_mini_community_moves (the tag Marionette and the Blender add-on stamp on every share). The unit is the individual move, not the repo: each data/<stem>.json trajectory becomes one entry (fileUrl, optional audioUrl, its dataset attached), and its embedding passage is the stem words plus the library's display name, so ?q=un mouvement triste returns sad_nod-style moves directly. Trajectory files are never downloaded server-side; per-dataset file listings are cached on lastModified, so a steady-state refresh costs one hub call. The shared config/blocked-app-list.json killswitch applies (a dataset id there drops the whole library). There is no LLM moderation pass on this catalog: a move is trajectory data plus a slug, a much smaller blast radius than an app or an MCP tool.

Catalog moderation

/api/js-apps and /api/mcp-tools are both fail-closed: an entry is served only when it is on an official list or carries an explicit allow moderation verdict. A block, a review, a block-list hit or a missing verdict all keep it hidden (App Store guideline 1.2). Use ?includeHidden=true to inspect what is being filtered.

The block-list is deliberately shared between both catalogs, so blocking a Space in config/blocked-app-list.json is a global killswitch that needs no code deploy.

MCP tool Spaces get the same gate as apps because their descriptions are fed to the model and the tools can be invoked through the robot, which is a wider blast radius than a sandboxed app the user opens and watches.

To vouch for a first-party tool Space (skipping moderation, as for official apps), add its slug to config/official-tool-list.json:

[
  "pollen-robotics/reachy-mini-search-tool",
  "pollen-robotics/reachy-mini-weather-tool",
  "pollen-robotics/reachy-mini-time-tool"
]

That file is optional and unioned with official-app-list.json; a 404 simply means "no official tools", in which case first-party tools stay hidden until the LLM sweep clears them.

Stable hostname

The mobile app targets a frozen API base URL. In production this Space must answer on that stable host (pollen-robotics-reachy-mini.hf.space) via the existing redirect, so moving/rebuilding the backend never requires an App Store resubmission.

Local dev

npm install
HF_TOKEN=hf_xxx OPENAI_API_KEY=sk-xxx PORT=3001 npm start

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages