# Opencodex

> Manage OpenCodex (Codex proxy fork): model catalog, provider routing, config.

- Skill: `wcpaka-lgtm/opencodex` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add wcpaka-lgtm/opencodex`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wcpaka-lgtm/opencodex/raw
- Safety review: pending (external: skill-scanner WARNING, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: wcpaka-lgtm (https://skillmd.com/u/wcpaka-lgtm)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/wcpaka-lgtm/opencodex

---


# OpenCodex Configuration

OpenCodex is a Codex fork/proxy that routes requests to multiple AI providers. It runs a local proxy and uses a JSON model catalog to define available models.

## Key File Locations (Windows)

| File | Purpose |
|------|---------|
| `~/.codex/opencodex-catalog.json` | Model catalog — defines all selectable models |
| `~/.codex/opencodex.config.toml` | Proxy config (base URL, catalog path, features) |
| `~/.codex/opencodex-journal.json` | Internal journal |
| `~/.opencodex/opencodex-service-task.xml` | Windows service definition |
| `~/.opencodex/opencodex-service.cmd` | Service start script |

## Model Catalog Structure

The catalog is a JSON file with a top-level `"models"` array. Each entry defines one selectable model.

### Required Fields for a Model Entry

```json
{
  "slug": "provider/model-name",
  "display_name": "provider/model-name",
  "description": "Routed via opencodex → provider (provider).",
  "default_reasoning_level": "medium",
  "supported_reasoning_levels": [
    {"effort": "low", "description": "Fast responses with lighter reasoning"},
    {"effort": "medium", "description": "Balances speed and reasoning depth for everyday tasks"},
    {"effort": "high", "description": "Greater reasoning depth for complex problems"},
    {"effort": "xhigh", "description": "Extra high reasoning depth for complex problems"},
    {"effort": "max", "description": "Maximum reasoning depth for the hardest problems"},
    {"effort": "ultra", "description": "Maximum reasoning with automatic task delegation"}
  ],
  "shell_type": "shell_command",
  "visibility": "list",
  "supported_in_api": true,
  "priority": 5,
  "upgrade": null,
  "base_instructions": "You are a coding agent powered by the MODEL_NAME model. Do not claim to be GPT-5 or made by OpenAI.",
  "supports_reasoning_summaries": true,
  "default_reasoning_summary": "none",
  "support_verbosity": true,
  "default_verbosity": "low",
  "apply_patch_tool_type": "freeform",
  "web_search_tool_type": "text_and_image",
  "truncation_policy": {"mode": "tokens", "limit": 10000},
  "supports_parallel_tool_calls": true,
  "supports_image_detail_original": true,
  "context_window": 272000,
  "max_context_window": 272000,
  "effective_context_window_percent": 95,
  "experimental_supported_tools": [],
  "input_modalities": ["text", "image"],
  "supports_search_tool": true,
  "comp_hash": "opencodex",
  "auto_compact_token_limit": 244800
}
```

### Critical Fields

| Field | Values | Effect |
|-------|--------|--------|
| `visibility` | `"list"` | Model appears in selector UI |
| `visibility` | `"hide"` | Model exists but is hidden from selector |
| `slug` | `provider/model-name` | Unique identifier, used for routing |
| `priority` | `5` (third-party), `103` (OpenAI native) | Sort order in UI |

## Adding a New Model (via Management API — REQUIRED)

**⚠️ DO NOT edit `opencodex-catalog.json` directly.** OpenCodex regenerates/overwrites the catalog file at runtime — manual edits are silently lost. Use the management API instead.

The management API runs on the **same port as the proxy** (default `127.0.0.1:10100`).

### Add a custom model

```bash
curl -s -X POST http://127.0.0.1:10100/api/custom-models \
  -H "Content-Type: application/json" \
  -d '{"provider":"alibaba","modelId":"qwen3.8","displayName":"qwen3.8","contextWindow":272000,"inputModalities":["text","image"]}'
```

- `provider` and `modelId` are required; the routing slug becomes `provider/modelId`.
- `displayName` must NOT contain `/` — use just the model name (e.g. `"qwen3.8"`, not `"alibaba/qwen3.8"`).
- Returns `{"id":"<uuid>","provider":"...","modelId":"...",...}` on success.
- **No restart needed** — the model appears in `/v1/models` and the UI immediately.

### Verify

```bash
curl -s http://127.0.0.1:10100/v1/models | python -c "import sys,json; d=json.load(sys.stdin); print([m['id'] for m in d['data'] if 'qwen3.8' in m['id']])"
```

### Management API endpoints

| Method | Path | Purpose |
|--------|------|---------|
| GET | `/api/models` | All models (routed + custom + native) with disabled state |
| GET | `/api/custom-models` | List custom-added models |
| POST | `/api/custom-models` | Add a custom model (see above) |
| PUT | `/api/custom-models/:id` | Update displayName/contextWindow/modelId |
| DELETE | `/api/custom-models/:id` | Remove a custom model |
| PUT | `/api/disabled-models` | Enable/disable models (body: `{"models":["slug1","slug2"]}`) |
| GET | `/api/selected-models` | Current selection + available models |

## Pitfalls

- **NEVER edit `opencodex-catalog.json` to add models.** OpenCodex overwrites it at runtime. Use `POST /api/custom-models` instead. The catalog is useful as read-only reference for understanding routing.
- `displayName` in the custom-models API must NOT contain `/` — pass just the model name, not the full slug.
- The `slug` format is `provider/model-name` — this is how OpenCodex routes to the correct backend.
- The `opencode` CLI (opencode.ai) is a DIFFERENT tool from OpenCodex. Don't confuse them. OpenCode config is at `~/.config/opencode/opencode.jsonc`.
- OpenCodex source lives at `~/AppData/Roaming/npm/node_modules/@bitkyc08/opencodex/` — check `src/server/management/model-routes.ts` for API details if endpoints change.

## Proxy Config (opencodex.config.toml)

```toml
openai_base_url = "http://127.0.0.1:10100/v1"
model_catalog_json = "C:\\Users\\<user>\\.codex\\opencodex-catalog.json"

[features]
fast_mode = true
```

## Verification

After adding a model via the API:
1. `curl -s http://127.0.0.1:10100/v1/models` — confirm the new slug appears in the list.
2. No restart needed — the model is immediately available in the UI model selector.
3. If the model doesn't appear, check `GET /api/custom-models` to confirm it was saved, and `GET /api/disabled-models` to ensure it isn't disabled.

