OAuth to OpenAI-compatible API router for Xiaomi MiMo Code Desktop. Bridge OAuth credentials into a universal API gateway to unlock Free Preview MiMo X models (MiMo-X-Pro-Preview & MiMo-X-Flash-Preview) across Claude Code, Codex, Antigravity, OpenCode and more.
Overview • Features • Quick Start • Models • Clients • Architecture • Guides • Disclaimer • License
- What is MiMo2API?
- Key Features
- Quick Start
- Model Catalog & Aliases
- Client Integration
- Architecture & Structure
- Advanced Guides
- Development & Testing
- Disclaimer & Legal Notice
- License
In September 2026, Xiaomi introduced the MiMo-X model family (MiMo-X-Pro-Preview and MiMo-X-Flash-Preview), offering advanced reasoning, multi-agent coordination, and coding capabilities through invitation-based beta testing in the Xiaomi MiMo Desktop application.
However, access to these free preview quotas is locked behind Xiaomi's OAuth authentication inside the desktop client. Developers could not consume these models as standard OpenAI-compatible endpoints (sk-...) in external coding agents, harnesses, or IDEs.
MiMo2API bridges this gap:
- It reads and manages Xiaomi OAuth tokens (
access_tokenandrefresh_token) from your local MiMo Desktop configuration (auth.json), proactively refreshing access tokens before expiration. - It serves a standard OpenAI-compatible endpoint (
/v1/chat/completions,/v1/models,/v1/health) with full Server-Sent Events (SSE) streaming andreasoning_contentdelta preservation. - It supports both a zero-dependency Local CLI Daemon (
localhost:20128) and a standalone Cloudflare Worker (worker/worker.js) with multi-account round-robin rotation and automatic 429 quota exhaustion fallback.
Disclaimer: This tool is provided strictly for personal educational and interoperability testing purposes. Extracting or reusing OAuth credentials outside official desktop clients carries the risk of account suspension or ban. See Disclaimer & Legal Notice.
- Unlock Free Preview Models: Access
MiMo-X-Pro-Preview,MiMo-X-Flash-Preview, andmimo-v2.5series models. - Dual Operational Modes:
- Local Daemon: Runs on
localhost:20128, auto-detecting desktop credentials with zero configuration. - Cloudflare Worker: Standalone 20 KB bundle ready for copy-paste into Cloudflare Workers or Vercel Edge.
- Local Daemon: Runs on
- Multi-Account Round-Robin: Pool multiple refresh tokens; requests distribute automatically across accounts.
- Intelligent 429 Failover: Automatically detects daily rate limits (
Daily free limit reached,Try again in...), parks the exhausted account in cooldown, and retries the request transparently with the next available account. - Streaming SSE with Reasoning Delta: Preserves thinking blocks in
delta.reasoning_contentfor real-time rendering in coding assistants. - Safe & Resource-Bounded:
- Client disconnect cancellation via
AbortSignal(prevents wasted quotas when cancelling prompts). - 120-second upstream timeout guards against stalled connections.
- 10MB request payload limit protects against buffer exhaustion attacks.
- Atomic token persistence using secure
0o600file permissions.
- Client disconnect cancellation via
Install and log into the Xiaomi MiMo Desktop application. This saves your OAuth session in auth.json.
Install globally via npm:
npm install -g mimo2apiOr run directly with npx without installation.
Test if your local credentials are detected:
mimo2api checkOr via npx:
npx mimo2api checkOr when running from a local clone:
npm run buildnode dist/cli.js checkExample output:
[MiMo2API] Checking local MiMo Desktop authentication...
Found configuration: C:\Users\<user>\AppData\Local\mimocode\data\auth.json
Found Xiaomi OAuth credentials:
- Access Token: eyJhbGci... (1024 chars)
- Refresh Token: dGhpcy1p... (256 chars)
- Expires: 2026-09-18T23:59:00.000Z
Local authentication check passed!
Run with default settings (port 20128, open access):
npx mimo2api startOr specify a custom port:
npx mimo2api start --port 20128Or enable optional API key authorization:
npx mimo2api start --port 20128 --key sk-my-secret-keyWhen running from source:
npm startYour local endpoint is available at http://localhost:20128/v1.
Deploy a 24/7 serverless gateway without keeping your computer running.
Open worker/worker.js and copy the entire file contents.
- Log into the Cloudflare Dashboard.
- Go to Workers & Pages -> Create application -> Create Worker.
- Set name to
mimo2apiand click Deploy. - Click Edit code, select all existing code, delete it, and paste the copied contents of
worker/worker.js. - Click Deploy in the top right.
In your Worker, go to Settings -> Variables and Secrets and add:
| Variable | Type | Required | Description |
|---|---|---|---|
MIMO_REFRESH_TOKEN |
Secret | Yes | Your MiMo refresh token. Multi-account supported: one token per line. |
API_KEY |
Secret | Optional | Client bearer key (e.g. sk-mimo-key). |
UPSTREAM_BASE_URL |
Text | Optional | Upstream URL (defaults to https://api.xiaomimimo.com/v1). |
Click Save and deploy.
Your Cloudflare Worker API URL:
https://mimo2api.<your-subdomain>.workers.dev/v1
MiMo2API automatically maps requested model aliases to canonical upstream models:
| Request Model Alias | Canonical Upstream Model | Description |
|---|---|---|
mimo-x-pro, mimo-x, gpt-4o |
MiMo-X-Pro-Preview |
Advanced reasoning model for complex architectural coding |
mimo-x-flash, mimo-flash |
MiMo-X-Flash-Preview |
Low-latency preview model for rapid edits and tool calls |
mimo-v2.5-pro, mimo-v2.5 |
mimo-v2.5-pro |
Xiaomi MiMo V2.5 base production model |
mimo-v2.5-flash |
mimo-v2.5-flash |
Xiaomi MiMo V2.5 high-throughput model |
9Router
Configuration file path:
~/.9router/db.json
Or configure via Web Dashboard under Providers -> Add Custom Provider:
- Provider Type:
openai
- Base URL:
http://localhost:20128/v1
- API Key:
sk-mimo
- Models:
mimo-x-pro, mimo-x-flash
Configuration entry for ~/.9router/db.json:
{
"providers": [
{
"id": "mimo2api",
"name": "MiMo2API",
"type": "openai",
"baseUrl": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"models": [
"mimo-x-pro",
"mimo-x-flash"
]
}
]
}Note: Both 9Router and MiMo2API default to port
20128. When running both locally on the same host, start MiMo2API on a different port (e.g.PORT=20129 npx mimo2api start) and point 9Router tohttp://localhost:20129/v1, or point 9Router to your Cloudflare Worker URL.
Aider
Configuration file path:
.aider.conf.yml
Add configuration:
openai-api-base: http://localhost:20128/v1
openai-api-key: sk-mimo
model: openai/mimo-x-proAntigravity (AGY)
Configuration file path:
~/.gemini/antigravity/antigravity.json
Add configuration:
{
"modelProviders": {
"mimo2api": {
"type": "openai",
"baseUrl": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"defaultModel": "mimo-x-pro"
}
}
}Cherry Studio
Configuration file path:
~/.cherry-studio/config.json
Or configure via UI in Settings -> Providers -> OpenAI:
- Custom Server Address:
http://localhost:20128/v1
- API Key:
sk-mimo
- Models:
mimo-x-pro
mimo-x-flash
Claude Code
Configuration file path (Global):
~/.claude/settings.json
Configuration file path (Project-level):
.claude/settings.json
Add configuration:
{
"env": {
"OPENAI_BASE_URL": "http://localhost:20128/v1",
"OPENAI_API_KEY": "sk-mimo",
"ANTHROPIC_MODEL": "mimo-x-pro"
}
}Then run:
claudeCline
Configuration file path:
.vscode/settings.json
Add configuration:
{
"cline.apiProvider": "openai-compatible",
"cline.openAiBaseUrl": "http://localhost:20128/v1",
"cline.openAiApiKey": "sk-mimo",
"cline.openAiModelId": "mimo-x-pro"
}Codex
Configuration file path:
~/.codex/config.toml
Add configuration:
[model]
provider = "openai"
base_url = "http://localhost:20128/v1"
api_key = "sk-mimo"
model_name = "mimo-x-pro"Continue.dev
Configuration file path:
~/.continue/config.json
Add configuration:
{
"models": [
{
"title": "MiMo-X Pro Preview",
"provider": "openai",
"model": "mimo-x-pro",
"apiBase": "http://localhost:20128/v1",
"apiKey": "sk-mimo"
}
]
}Cursor
Configuration file path (Global):
~/.cursor/User/settings.json
Configuration file path (Project-level):
.vscode/settings.json
Add configuration:
{
"cursor.openaiBaseUrl": "http://localhost:20128/v1",
"cursor.openaiApiKey": "sk-mimo",
"cursor.model": "mimo-x-pro"
}Or configure in Cursor Settings -> Models:
- Toggle Override OpenAI Base URL:
http://localhost:20128/v1 - Set OpenAI API Key:
sk-mimo - Add model:
mimo-x-pro
DeepSeek Harness
Configuration file path:
agent.yaml
Add configuration:
llm:
api_type: openai
base_url: "http://localhost:20128/v1"
api_key: "sk-mimo"
model: "mimo-x-pro"
temperature: 0.7Hermes
Configuration file path:
~/.hermes/config.json
Add configuration:
{
"llm": {
"provider": "openai",
"baseUrl": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"model": "mimo-x-pro"
}
}LibreChat
Configuration file path:
librechat.yaml
Add configuration:
endpoints:
custom:
- name: "MiMo2API"
apiKey: "sk-mimo"
baseURL: "http://localhost:20128/v1"
models:
default: ["mimo-x-pro", "mimo-x-flash"]
titleConvo: true
modelDisplayLabel: "MiMo"MiMo Code CLI
Configuration file path (Linux / macOS):
~/.local/share/mimocode/mimocode.jsonc
Configuration file path (Windows):
%LOCALAPPDATA%\mimocode\data\mimocode.jsonc
Add configuration:
NextChat (ChatGPT-Next-Web)
Configuration file path:
.env.local
Add configuration:
BASE_URL=http://localhost:20128
OPENAI_API_KEY=sk-mimo
CUSTOM_MODELS=-all,+mimo-x-pro,+mimo-x-flashOmniRoute
Configuration file path:
~/.omniroute/providers.json
Add configuration via CLI:
omniroute provider add --id mimo2api --type openai --base-url http://localhost:20128/v1 --api-key sk-mimo --models mimo-x-pro,mimo-x-flashOr add configuration to ~/.omniroute/providers.json:
{
"providers": [
{
"id": "mimo2api",
"name": "MiMo Preview Gateway",
"type": "openai-compatible",
"baseUrl": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"models": [
"mimo-x-pro",
"mimo-x-flash"
]
}
]
}OpenAI Compatible (Generic / SDKs)
Configuration file path:
.env
Add environment configuration:
OPENAI_BASE_URL="http://localhost:20128/v1"
OPENAI_API_KEY="sk-mimo"Python SDK example:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:20128/v1",
api_key="sk-mimo"
)
response = client.chat.completions.create(
model="mimo-x-pro",
messages=[{"role": "user", "content": "Write quicksort in Python."}],
stream=True
)
for chunk in response:
content = chunk.choices[0].delta.content or ""
print(content, end="", flush=True)Node.js SDK example:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://localhost:20128/v1",
apiKey: "sk-mimo",
});
const response = await client.chat.completions.create({
model: "mimo-x-pro",
messages: [{ role: "user", content: "Write quicksort in TypeScript." }],
});
console.log(response.choices[0].message.content);cURL command:
curl -X POST http://localhost:20128/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-mimo" \
-d '{"model":"mimo-x-pro","messages":[{"role":"user","content":"Hello!"}]}'OpenClaw
Configuration file path:
openclaw.json
Add configuration:
{
"providers": {
"mimo2api": {
"type": "openai-compatible",
"baseURL": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"models": [
"mimo-x-pro",
"mimo-x-flash",
"mimo-v2.5-pro"
]
}
}
}OpenCode
Configuration file path (Linux / macOS):
~/.local/share/opencode/opencode.jsonc
Configuration file path (Project-level):
opencode.jsonc
Add configuration:
{
"providers": {
"mimo2api": {
"type": "openai-compatible",
"baseUrl": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"models": [
"mimo-x-pro",
"mimo-x-flash"
]
}
},
"default_model": "mimo2api/mimo-x-pro"
}OpenHands (OpenDevin)
Configuration file path:
config.toml
Add configuration:
[llm]
model = "openai/mimo-x-pro"
base_url = "http://localhost:20128/v1"
api_key = "sk-mimo"Roo Code
Configuration file path:
.vscode/settings.json
Add configuration:
{
"roo-cline.apiProvider": "openai-compatible",
"roo-cline.openAiBaseUrl": "http://localhost:20128/v1",
"roo-cline.openAiApiKey": "sk-mimo",
"roo-cline.openAiModelId": "mimo-x-pro"
}Trae (ByteDance Agentic IDE)
Configuration file path:
~/.trae/config.json
Add configuration:
{
"modelProviders": [
{
"name": "MiMo2API",
"apiType": "openai",
"endpoint": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"models": [
"mimo-x-pro",
"mimo-x-flash"
]
}
]
}Windsurf
Configuration file path:
~/.codeium/windsurf/model_config.json
Add configuration:
{
"customOpenAI": {
"endpoint": "http://localhost:20128/v1",
"apiKey": "sk-mimo",
"model": "mimo-x-pro"
}
}MiMo2API/
├── src/
│ ├── types/
│ │ ├── auth.ts # OAuth credentials, pool states, refresh contracts
│ │ ├── openai.ts # OpenAI request/response/SSE schemas & chunk deltas
│ │ └── config.ts # Server and Cloudflare Worker runtime configuration
│ ├── auth/
│ │ ├── token-store.ts # Discovers and parses local auth.json with atomic writes
│ │ ├── oauth-client.ts # Xiaomi OAuth 2.0 exchange & proactive TTL refresh
│ │ └── pool-manager.ts # Multi-account round-robin pool with 429 cooldown backoff
│ ├── proxy/
│ │ ├── model-catalog.ts # Model list & alias normalizer (mimo-x-pro -> MiMo-X-Pro-Preview)
│ │ ├── stream-transformer.ts# Real-time SSE transformer with reasoning_content support
│ │ └── completion-handler.ts# Core completion proxy with cancellation & failover retry
│ ├── server/
│ │ ├── routes.ts # Route dispatcher (/v1/models, /v1/chat/completions, /v1/health)
│ │ └── http-server.ts # Native Node.js 22 HTTP server with graceful shutdown
│ ├── cli/
│ │ └── index.ts # CLI entrypoint (start, check)
│ └── worker/
│ └── index.ts # Cloudflare Workers / Vercel Edge fetch entrypoint
├── worker/
│ └── worker.js # Standalone zero-dependency Cloudflare Worker bundle (20 KB)
├── dist/
│ └── cli.js # Standalone Node.js CLI executable bundle (29 KB)
├── tests/ # 36 automated unit & integration tests
├── scripts/
│ └── build.ts # esbuild build pipeline
├── .github/
│ └── workflows/
│ └── test.yml # Automated CI workflow with skip test flags
├── package.json
└── tsconfig.json
If an account reaches its preview quota limit, MiMo2API automatically shifts traffic to the next account without interrupting your active session.
In Cloudflare Workers or your local environment, pass multiple refresh tokens separated by newlines in MIMO_REFRESH_TOKEN:
MIMO_REFRESH_TOKEN="token_account_1
token_account_2
token_account_3"Workflow:
- Round-Robin: Requests cycle across active accounts to distribute load.
- Quota Detection: When an account encounters HTTP 429 (
Daily free limit reachedorTry again in 2h 30m), the router parses the duration and parks that account in cooldown. - Transparent Retry: The current request is immediately retried using the next available account in the pool.
- Health Diagnostics: Query
/v1/healthto monitor active versus cooldown accounts.
| Variable | Mode | Default | Description |
|---|---|---|---|
PORT |
Local | 20128 |
Local HTTP daemon port |
HOST |
Local | 127.0.0.1 |
Local bind address |
API_KEY |
Both | (None) | Client authorization bearer token |
MIMO_REFRESH_TOKEN |
Both | (From auth.json) | Newline-separated list of refresh tokens |
MIMOCODE_HOME |
Local | (Auto) | Custom directory to look for auth.json |
UPSTREAM_BASE_URL |
Both | https://api.xiaomimimo.com/v1 |
Upstream MiMo inference endpoint |
OAUTH_TOKEN_URL |
Both | https://account.xiaomi.com/oauth2/token |
Upstream Xiaomi OAuth token endpoint |
Run typecheck:
npm run typecheckRun automated test suite:
npm testBuild standalone bundles:
npm run buildEvery commit and pull request runs automated verification through the Test & Verify GitHub Actions workflow (Node.js 22):
- Typecheck:
npm run typecheck - Unit & Integration Tests:
npm test - Bundle Verification:
npm run build
To skip the test suite on specific commits (e.g. for docs updates, asset additions, or fast iterations while still verifying types and builds), include any of the following tags in the commit message:
[skip test]or[skip tests][skip-test]or[skip-tests]
When triggered manually via Actions -> Run workflow, check the Skip running automated tests input option.
IMPORTANT: Please read this notice carefully before using or deploying MiMo2API.
- Educational & Research Purposes Only: This project is developed and distributed exclusively for personal educational, research, and non-commercial API interoperability testing purposes.
- Risk of Account Suspension or Ban: Extracting OAuth tokens, managing session credentials, or routing automated API requests outside the official Xiaomi MiMo Desktop client may violate Xiaomi's Terms of Service and End User License Agreements. Xiaomi may rate-limit, revoke tokens for, suspend, or permanently ban your Xiaomi account without prior warning.
- No Warranty & No Guarantee: The author and contributors make no claims, promises, or guarantees regarding the safety, status, or longevity of your Xiaomi account. This software is provided "AS IS", without warranty of any kind, express or implied.
- Assumption of Risk: You assume full and sole responsibility for any outcomes or damages resulting from using this software, including but not limited to account termination, loss of API access, or data loss. Use strictly at your own risk.
- Trademark Attribution: All product names, logos, and brands (such as "Xiaomi", "MiMo", "MiMo-Code") are trademarks or registered trademarks of their respective owners (Xiaomi Inc.). MiMo2API is an independent open-source project and is neither affiliated with, maintained by, nor endorsed by Xiaomi Inc.
This project is licensed under the GNU General Public License v3.0 (GPLv3). See the LICENSE file for details.
{ "providers": { "mimo2api": { "type": "openai-compatible", "baseUrl": "http://localhost:20128/v1", "apiKey": "sk-mimo", "models": [ "mimo-x-pro", "mimo-x-flash" ] } }, "default_model": "mimo2api/mimo-x-pro" }