mimo2codex-proxy

v2026.09.25

Local proxy that lets OpenAI Codex CLI/desktop talk to MiMo, DeepSeek, and other LLMs via Responses API translation

GitHub
Install command
npx skhub add reason-machines/mimo2codex-proxy
Markdown
SKILL.md

mimo2codex Proxy Skill

Skill by ara.so — Codex Skills collection.

Overview

mimo2codex is a local proxy server that translates between OpenAI Codex's Responses API (wire_api = "responses") and upstream LLM providers using Chat Completions API. It enables the latest Codex CLI and desktop app to work with:

  • Xiaomi MiMo (V2.5 Pro, V2 Flash, V2 Omni)
  • DeepSeek (V4 Pro, V4 Flash, Reasoner)
  • Generic OpenAI-compatible providers (Qwen, GLM, Kimi, Ollama, vLLM, LM Studio)

Key features:

  • Per-request model routing (send mimo-v2.5-pro → MiMo, deepseek-v4-pro → DeepSeek)
  • Automatic MiMo reasoning_content round-trip handling (v0.2.3+)
  • Built-in admin webui at http://127.0.0.1:8788/admin/
  • Tool calling, web search, vision (model-dependent)
  • sqlite persistence for logs and token stats

Installation

npm (recommended)

npm install -g mimo2codex

curl one-liner

# macOS/Linux
curl -fsSL https://raw.githubusercontent.com/7as0nch/mimo2codex/main/scripts/install.sh | bash

# Windows PowerShell
irm https://raw.githubusercontent.com/7as0nch/mimo2codex/main/scripts/install.ps1 | iex

Git clone (for development)

git clone https://github.com/7as0nch/mimo2codex
cd mimo2codex
npm install
npm run build
npm link  # registers `mimo2codex` globally

Requirements: Node.js ≥ 18

Quick Start

1. Get API Keys

2. Configure Environment Variables

Built-in loader (v0.2.8+, recommended):

# Initialize .env file in ~/.mimo2codex/
mimo2codex init

# Edit ~/.mimo2codex/.env and add your keys:
# MIMO_API_KEY=sk-your-mimo-key
# DS_API_KEY=sk-your-deepseek-key

# Start (auto-loads .env)
mimo2codex

Manual environment variables:

# MiMo only
export MIMO_API_KEY=sk-your-mimo-key
mimo2codex

# DeepSeek only
export DS_API_KEY=sk-your-deepseek-key
mimo2codex --model ds

# Both providers (per-request routing)
export MIMO_API_KEY=sk-your-mimo-key
export DS_API_KEY=sk-your-deepseek-key
mimo2codex

3. Configure Codex

The startup banner prints the required snippets. Copy them to:

macOS/Linux:

  • ~/.codex/auth.json
  • ~/.codex/config.toml

Windows:

  • %USERPROFILE%\.codex\auth.json
  • %USERPROFILE%\.codex\config.toml

Example auth.json:

{
  "base_url": "http://127.0.0.1:8788",
  "api_key": "fake_api_key"
}

Example config.toml:

wire_api = "responses"
model = "mimo-v2.5-pro"

4. Start Codex

codex

CLI Commands

Core Commands

# Start proxy (MiMo default)
mimo2codex

# Start with DeepSeek as default
mimo2codex --model ds

# Custom port
mimo2codex --port 9000

# Custom data directory
mimo2codex --data-dir /path/to/data

# Disable reasoning display (still round-trips for MiMo)
mimo2codex --no-reasoning

# Disable .env auto-loading
mimo2codex --no-load-env

Utility Commands

# Initialize .env file
mimo2codex init

# Print cc-switch snippets
mimo2codex print-cc-switch

# Show version
mimo2codex --version

# Show help
mimo2codex --help

Configuration

Environment Variables

VariableProviderRequired
MIMO_API_KEYMiMoFor MiMo models
DS_API_KEY or DEEPSEEK_API_KEYDeepSeekFor DeepSeek models
QWEN_API_KEYQwenFor Qwen models
GLM_API_KEYGLMFor GLM models
KIMI_API_KEYKimiFor Kimi models
OPENAI_API_KEYOpenAIFor OpenAI models
CODEX_HOME-Custom Codex config directory

CLI Flags

FlagDefaultDescription
--port8788Proxy server port
--host127.0.0.1Proxy server host
--modelmimoDefault provider (mimo or ds)
--data-dir~/.mimo2codexData/logs directory
--no-reasoningfalseHide reasoning from terminal
--no-load-envfalseDisable .env auto-loading
--log-levelinfoLog level (debug/info/warn/error)

Model Routing

Built-in Model IDs

MiMo:

  • mimo-v2.5-pro (default)
  • mimo-v2-flash
  • mimo-v2.5 (vision)
  • mimo-v2-omni (vision)

DeepSeek:

  • deepseek-v4-pro (default)
  • deepseek-v4-flash
  • deepseek-chat
  • deepseek-reasoner

Routing Logic

  1. Explicit match: If client sends mimo-v2.5-pro, routes to MiMo (if key configured)
  2. Fallback: If client sends unknown model (e.g. gpt-4o), routes to --model provider's default
  3. Provider disabled: If client sends qwen3-max but no QWEN_API_KEY, falls back to --model provider

Example routing with both keys configured:

export MIMO_API_KEY=sk-mimo-key
export DS_API_KEY=sk-deepseek-key
mimo2codex  # default fallback: mimo

# In Codex config.toml:
# model = "deepseek-v4-pro"  → Routes to DeepSeek
# model = "mimo-v2.5-pro"    → Routes to MiMo
# model = "gpt-4o"           → Falls back to mimo-v2.5-pro

Admin Web UI

Access at http://127.0.0.1:8788/admin/ (port matches --port)

Features

  • Dashboard: Token usage charts, cache hit rates, request stats
  • Models: View all available models, test with ⚡Probe button
  • Providers: View/edit provider configs from providers.json
  • Logs: Browse chat logs with filtering
  • Settings: Configure Codex paths, manage aliases
  • Codex Enable: One-click write of auth.json and config.toml (replaces cc-switch)

Codex Enable (v0.2.6+)

  1. Open http://127.0.0.1:8788/admin/
  2. Click "Codex Enable" tab
  3. Select model and click "Apply"
  4. Automatically backs up existing configs (first OpenAI backup preserved permanently)

Runtime override mode: Switch models without restarting Codex (experimental)

Adding Custom Providers

Edit ~/.mimo2codex/providers.json (created after first run):

{
  "providers": [
    {
      "name": "qwen",
      "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
      "apiKeyEnvVar": "QWEN_API_KEY",
      "defaultModel": "qwen3-max",
      "models": ["qwen3-max", "qwen-turbo"],
      "aliases": {
        "qwen3": "qwen3-max"
      },
      "supportsWebSearch": true
    }
  ]
}

Provider schema:

FieldTypeDescription
namestringUnique provider identifier
baseUrlstringOpenAI-compatible base URL
apiKeyEnvVarstringEnvironment variable name
defaultModelstringModel ID for fallback
modelsstring[]Supported model IDs
aliasesobjectModel alias mappings
supportsWebSearchbooleanEnable web search tool

Example: Ollama

{
  "name": "ollama",
  "baseUrl": "http://localhost:11434/v1",
  "apiKeyEnvVar": "OLLAMA_API_KEY",
  "defaultModel": "llama3.2",
  "models": ["llama3.2", "qwen2.5-coder"],
  "aliases": {
    "llama": "llama3.2"
  },
  "supportsWebSearch": false
}
export OLLAMA_API_KEY=ollama  # Any non-empty value
mimo2codex

In Codex config.toml:

model = "llama3.2"

Tool Calling

Supported Tools

  • Function tools: Custom JSON schemas
  • local_shell: Execute shell commands
  • MCP tools: Via namespace parameter
  • web_search: MiMo native (auto-enabled for MiMo, skipped for DeepSeek)

Web Search

MiMo: Translates Codex's web_search tool to MiMo's native builtin. Requires plugin activation in MiMo console.

DeepSeek: Web search not supported — tool calls are stripped.

Example Tool Call

// Codex sends:
{
  "model": "mimo-v2.5-pro",
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "parameters": {
          "type": "object",
          "properties": {
            "location": { "type": "string" }
          }
        }
      }
    }
  ]
}

// mimo2codex translates to MiMo Chat Completions:
{
  "model": "mimo-v2.5-pro",
  "tools": [
    {
      "type": "function",
      "function": { ... }
    }
  ]
}

Vision Support

Supported models:

  • mimo-v2.5 (MiMo)
  • mimo-v2-omni (MiMo)

Non-vision models (mimo-v2.5-pro, mimo-v2-flash, DeepSeek models): Images are auto-stripped with placeholder text.

Example Vision Request

In Codex config.toml:

model = "mimo-v2.5"
codex
> Describe this image: /path/to/image.jpg

mimo2codex forwards the image URL/base64 to MiMo's vision model.

MiMo reasoning_content Round-Trip

Problem: MiMo requires every assistant message with tool_calls to echo back its reasoning_content on the next turn. Without this, MiMo returns 400 errors or hallucinates.

Solution: mimo2codex ≥ 0.2.3 automatically stores and re-inserts reasoning_content on subsequent turns.

Example

// Turn 1: MiMo returns
{
  "role": "assistant",
  "content": "",
  "tool_calls": [...],
  "reasoning_content": "I need to search the web"
}

// Turn 2: mimo2codex auto-injects reasoning_content
{
  "role": "assistant",
  "content": "",
  "tool_calls": [...],
  "reasoning_content": "I need to search the web"  // ← auto-added
}

Flag: --no-reasoning hides reasoning from terminal but preserves round-trip.

Common Patterns

Multi-Provider Setup

# .env file (~/.mimo2codex/.env)
MIMO_API_KEY=sk-mimo-key
DS_API_KEY=sk-deepseek-key
QWEN_API_KEY=sk-qwen-key

# Start proxy
mimo2codex

# Codex config.toml - switch models dynamically:
# model = "mimo-v2.5-pro"
# model = "deepseek-v4-pro"
# model = "qwen3-max"

Testing Model Connections

Use the admin UI's ⚡Probe button:

  1. Open http://127.0.0.1:8788/admin/
  2. Go to "Codex Enable" or "Models" tab
  3. Click ⚡Probe next to any model
  4. Validates key, baseUrl, and model ID end-to-end

Token Usage Tracking

# Start proxy
mimo2codex

# View stats at http://127.0.0.1:8788/admin/
# - Dashboard: Charts with cache hit overlay
# - Green bars: Cache hits
# - Gray ghosts: Prompt token totals
# - Window-wide hit rate summary

Custom Codex Directory

# Via environment variable
export CODEX_HOME=/custom/path
mimo2codex

# Via admin UI settings
# Navigate to Settings → Codex Path

Troubleshooting

400 Errors with MiMo (Tool Calls)

Symptom: MiMo returns 400 or agent rambles instead of calling tools.

Cause: Missing reasoning_content round-trip.

Fix: Upgrade to mimo2codex ≥ 0.2.3

npm update -g mimo2codex

Provider Not Routing

Check:

  1. API key is set: echo $MIMO_API_KEY
  2. Provider is enabled in startup banner
  3. Model ID matches provider's catalog (case-sensitive)
# Debug with log level
mimo2codex --log-level debug

Port Already in Use

# Change port
mimo2codex --port 9000

# Update auth.json:
# "base_url": "http://127.0.0.1:9000"

Web Search Not Working

MiMo: Activate the web search plugin in MiMo Console → Plugins.

DeepSeek: Not supported (tool calls are stripped).

Image Generation (/hatch)

Codex's /hatch command calls OpenAI's image_gen client-side — mimo2codex cannot intercept this. Workaround: Use mimoskill/ (see project README).

.env Not Loading

# Verify file location
ls ~/.mimo2codex/.env

# Check file syntax (no spaces around =)
cat ~/.mimo2codex/.env

# Disable auto-loading if needed
mimo2codex --no-load-env

Windows PowerShell Execution Policy

If irm | iex fails:

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

Integration with cc-switch

Generate cc-switch snippets:

mimo2codex print-cc-switch

Output example:

[mimo-v2.5-pro]
model = "mimo-v2.5-pro"
wire_api = "responses"
base_url = "http://127.0.0.1:8788"
api_key = "fake_api_key"

Copy to cc-switch config and use cc mimo-v2.5-pro to switch.

Data Persistence

Default location: ~/.mimo2codex/data.db (sqlite)

Stored data:

  • Chat logs (request/response pairs)
  • Token usage stats
  • Cache hit metrics
  • Model mappings

Custom location:

mimo2codex --data-dir /custom/path

TypeScript API (for embedding)

import { startServer } from 'mimo2codex';

const server = await startServer({
  port: 8788,
  host: '127.0.0.1',
  dataDir: '~/.mimo2codex',
  logLevel: 'info',
  noReasoning: false,
  loadEnv: true
});

// Server running at http://127.0.0.1:8788

Project Links

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.25

Published

Sep 25, 2026

Category

Uncategorized

License

NOASSERTION

Source path

skills/mimo2codex-proxy

Default branch

main

Latest commit

901a4e3

Tree SHA

faa2fa4