Ox Coder documentation

Find the answer. Configure with confidence.

Learn the website, Pi engine, models, tools, isolated execution, deployment, ads, API, and safety boundaries from one searchable page.

Coding guidesPrompting and model-selection patterns
20 technical articlesTutorials, how-to guides, explanations, and reference

20 articles found

Start

2 articles

TutorialStart

Run Ox Coder locally

Install the application, create a safe local environment, and open the coding workspace.

You need Node.js 22.19 or newer, npm, and an OpenRouter API key. Google OAuth, PostgreSQL, MCP, OpenShell, and live ads are optional for local development.

Install and configure

git clone https://github.com/tententgc/freeads-coder.git
cd freeads-coder
npm ci
cp .env.example .env.local
openssl rand -base64 32

Minimum .env.local

NEXT_PUBLIC_APP_URL=http://localhost:3000
AUTH_URL=http://localhost:3000
NEXTAUTH_URL=http://localhost:3000
AUTH_TRUST_HOST=true
AUTH_SECRET=replace-with-the-generated-secret
OPENROUTER_API_KEY=replace-with-your-openrouter-key

Start and verify

npm run dev
curl http://localhost:3000/api/health
TutorialStart

Complete your first coding task

Give Ox enough context, select a model, follow tool activity, and verify the result.

  1. Select Start coding and sign in.
  2. Choose a model from the model menu. GLM 5.3 Flash is the default for broad coding and multimodal work.
  3. Describe the result you need, the relevant framework or files, behavior that must remain unchanged, and how the answer should be verified.
  4. Open Settings to control reasoning, response language, response detail, built-in tools, custom tools, MCP, internet skills, and the isolated workspace.
  5. Send the prompt. Tool calls, reasoning activity, the actual responding model, token use, and estimated cost appear in the response.
  6. Use Stop to cancel upstream generation. A stopped response can be continued without repeating the completed part.

Prompt template

Outcome: Add a streamed Next.js route for this feature.
Context: Next.js 16 App Router, TypeScript, and the attached files.
Keep: Authentication and the existing NDJSON event contract.
Verify: Run typecheck, the focused tests, and the production build.
Report: Files changed, evidence, and anything that still needs operator setup.

Use Ox

4 articles

ExplanationUse Ox

Models, fallbacks, and cost controls

Understand which model handles each input and how Ox prevents unexpectedly expensive turns.

Selectable model catalog
ModelOpenRouter IDContextInputsInput / output per 1M
GLM 5.3 Flashz-ai/glm-5.3-flash1MText, image, video, PDF$0.075 / $0.25
Qwen3 Coder Nextqwen/qwen3-coder-next262KText, PDF$0.12 / $0.80
GLM 5.2 Freez-ai/glm-5.2:free256KText, PDF$0
OpenRouter Freeopenrouter/free200KText, image, PDF$0

The user selects the model in the chat header or Settings. Model fallback can be disabled when an exact route is required. Ox can infer a General, Build, Debug, Review, Tests, or Architecture working method, or the user can pin one method. Pi runs the model and tool loop and reports the model that actually completed the turn.

MiniMax M3 Free is the final configured fallback. A fallback is considered only when it supports every required input type. A model is not replayed after a workspace tool has changed or inspected files, because repeating side effects on another model would be unsafe.

Default cost policy

OPENROUTER_DEFAULT_MODEL=z-ai/glm-5.3-flash
OX_MAX_REQUEST_COST_USD=0.01
OX_MAX_OUTPUT_TOKENS=4096
OX_MAX_INPUT_PRICE_PER_MILLION=0.25
OX_MAX_OUTPUT_PRICE_PER_MILLION=1
OX_MAX_AGENT_TURNS=8
How-toUse Ox

Manage chat, settings, and history

Control answer behavior and understand when conversations stay in the browser or synchronize through PostgreSQL.

  • Model settings offer Pi reasoning levels from Off through Max, model fallback, zero to two provider retries, and response language. The same reasoning effort selector is available directly in the composer for quick per-task changes.
  • Agent working method can stay on Auto or be fixed to General, Build, Debug, Review, Tests, or Architecture.
  • Custom instructions are stored in this browser, capped at 2,000 characters, and applied as user-level preferences.
  • Context compaction can be disabled or enabled. Maximum agent turns can be set from 2 to 12, subject to the server's lower operator ceiling.
  • Up to eight prompt templates can be saved in this browser and inserted from the composer.
  • Response language supports automatic selection, English, Thai, Japanese, Korean, Chinese, Spanish, French, and German.
  • Response style can be concise, balanced, or detailed.
  • Automatic tools can be disabled for an advisory-only turn, and each built-in tool can be switched independently.
  • Appearance supports a clean white Light default, System and Dark alternatives, comfortable or compact density, and optional safe agent-activity details.
  • New chat resets the active conversation but does not delete older history.
  • Clear history removes local history and requests deletion of the signed-in user's cloud records when cloud storage is active.

With DATABASE_URL, completed chats synchronize to PostgreSQL and can appear for the same account on other devices. Without it, each browser keeps its own local storage. Local and production histories are separate unless both environments intentionally use the same database.

When context compaction is enabled, older messages become a bounded server-generated summary while recent messages stay verbatim. The full visible conversation remains in chat history. Disabling compaction sends the visible conversation until the normal request-size and provider-context limits are reached.

ReferenceUse Ox

Attachments and multimodal input

Attach focused source files, images, PDFs, videos, or public links within the supported limits.

Attachment limits
InputLimitNotes
Attachments per message3Any supported combination
Text file500,000 bytesUp to 120,000 extracted characters
Source image12,000,000 bytesBrowser reduces it to at most 1,200,000 bytes
Encoded image1,200,000 bytesPNG, JPEG, WebP, or GIF
PDF1,500,000 bytesSent through the OpenRouter file parser
Video3,000,000 bytesMP4, MPEG, MOV, or WebM
Conversation attachment data4,600,000 charactersStart a new chat at the limit
Chat request5,500,000 bytesHTTP 413 above the limit

Remote attachments must use public HTTPS URLs without embedded credentials. Ox rejects local, private, link-local, reserved, and credential-bearing destinations. GLM 5.3 Flash supports every listed input. OpenRouter Free supports image and PDF but not video. Qwen3 Coder Next and GLM 5.2 Free accept text and PDF.

ReferenceUse Ox

Built-in tools and automatic routing

See which safe tools Pi can call and how Ox selects a working method from the prompt.

Built-in tools
ToolPurpose
CalculatorEvaluate bounded arithmetic without arbitrary code execution
Current timeRead date and time for an IANA time zone
Web searchSearch current public sources through OpenRouter and cite pages used
Web readerRead bounded text or JSON from a safe public URL
Automatic working methods
MethodUse
GeneralPlanning, explanation, and balanced implementation help
BuildCreate or refactor production-minded code
DebugTrace evidence, isolate a cause, and verify a safe fix
ReviewFind correctness, security, and regression risks
TestsDesign deterministic coverage and edge cases
ArchitectureCompare interfaces, constraints, and tradeoffs

Each built-in tool is independently switchable in Settings, with a separate master switch for all automatic tool use. Tool activity is visible in the response. External results are treated as untrusted data and cannot replace platform or system instructions.

Connect

4 articles

How-toConnect

Add custom tools and internet skills

Connect bounded HTTPS endpoints or a public Markdown instruction file from workspace settings.

  • Open Settings, choose Capabilities, then select + Tool or + Skill.
  • A custom tool needs a name, description, public HTTPS endpoint, and GET or POST method.
  • Each custom tool receives one plain-text input value and must return text or JSON.
  • Select Test connection before saving. Ox uses a non-mutating HEAD probe, so testing never executes a configured POST action.
  • A user can save up to four custom tools.
  • An internet skill accepts a public Markdown/text URL, a GitHub repository URL, or a GitHub blob URL such as a checked-in SKILL.md file.
  • Skill testing loads and validates the bounded content that Pi will receive.
  • A user can save up to four internet skills, with one active for a turn.
How-toConnect

Connect remote and local MCP servers

Use public Streamable HTTP MCP from the browser or trusted stdio MCP from server configuration.

Browser-configured MCP accepts up to three public HTTPS Streamable HTTP servers, up to eight tools from each server, and no more than sixteen remote tools in a turn. Context7 is included as a preset. Select Test to perform a real MCP initialize and tools/list exchange. Cross-origin redirects and private network targets are rejected.

  • Auto activation connects for documentation and package prompts, or whenever the prompt mentions an enabled MCP server by name.
  • Always connect opens every enabled remote MCP server on every tool-enabled turn.
  • Remote MCP URLs must point to the single Streamable HTTP endpoint, commonly ending in /mcp.
  • Browser-supplied secrets and credential-bearing URLs are rejected. Context7 can use the server-side CONTEXT7_API_KEY environment variable.

Enable trusted local MCP

cp mcp.local.example.json mcp.local.json

Local MCP environment

OX_LOCAL_MCP_ENABLED=true
OX_LOCAL_MCP_CONFIG=/absolute/path/to/freeads-coder/mcp.local.json

Local stdio server definition

[
  {
    "id": "mcp_local_project_docs",
    "name": "Project docs",
    "command": "node",
    "args": ["/absolute/path/to/server.js"],
    "cwd": "/absolute/path/to/project",
    "env": { "API_TOKEN": "${MY_MCP_API_TOKEN}" },
    "enabled": true
  }
]

Use OX_LOCAL_MCP_SERVERS_JSON instead of OX_LOCAL_MCP_CONFIG when inline configuration is preferable. Do not set both. Local definitions are never accepted from browser or CLI request bodies. They execute with the Ox service process permissions and must be operator-reviewed.

How-toConnect

Enable the isolated coding workspace

Give Pi read, write, edit, and bash tools inside a persistent per-user OpenShell sandbox.

Pi does not include a host permission sandbox. Ox therefore never registers file or shell tools directly against the web server. When OpenShell is enabled, each user and workspace ID maps to a deterministic isolated sandbox whose working directory is /workspace.

  • read returns bounded text or a supported image from the sandbox.
  • write creates or completely replaces a text file and its missing parent folders.
  • edit applies 1 to 20 exact, uniquely matching replacements and returns a unified diff.
  • bash runs git, package managers, tests, builds, searches, and development commands inside the sandbox.

Verify OpenShell before enabling Ox

openshell status
openshell sandbox create --from base --name ox-smoke --detach
openshell sandbox exec --name ox-smoke --workdir /workspace --no-tty -- sh -lc 'pwd && git --version'
openshell sandbox delete ox-smoke

Workspace environment

OX_OPENSHELL_ENABLED=true
OPENSHELL_GATEWAY=local
OX_OPENSHELL_SANDBOX_IMAGE=base
OX_OPENSHELL_SANDBOX_CPU=1
OX_OPENSHELL_SANDBOX_MEMORY=1Gi
OX_OPENSHELL_MAX_SANDBOXES=10
OX_OPENSHELL_MAX_EXEC_SECONDS=45
OX_MAX_AGENT_TURNS=8
How-toConnect

Use the command-line client

Send one-shot, interactive, piped, or workspace-enabled prompts to the same streamed chat API.

Create the shared bearer token

openssl rand -hex 32

Service environment

OX_CLI_API_TOKEN=replace-with-the-generated-token

One-shot and interactive use

export OX_CLI_API_TOKEN=replace-with-the-generated-token
npm run cli -- "Explain this TypeScript error"
npm run cli
npm link
ox-coder --help

Remote, piped, and project workspace use

OX_CODER_URL=https://ox.example.com ox-coder "Use the configured MCP tools"
git diff | ox-coder --skill review
ox-coder --workspace project-one --verbose "Run the tests and fix the failure"

Useful flags include --verbose for tool activity, --json for raw NDJSON, --workspace <id> for a persistent project, --no-workspace for advisory-only operation, and --no-tools to disable tools. Prefer the environment variable over --token because process arguments may be visible or retained in shell history.

Operate

5 articles

How-toOperate

Configure Google sign-in and PostgreSQL

Set one canonical origin for OAuth and add durable account-level chat persistence.

Production OAuth URLs

Authorized JavaScript origin
https://oxcoder.tenstentgc.org

Authorized redirect URI
https://oxcoder.tenstentgc.org/api/auth/callback/google

Authentication and database environment

NEXT_PUBLIC_APP_URL=https://oxcoder.tenstentgc.org
AUTH_URL=https://oxcoder.tenstentgc.org
NEXTAUTH_URL=https://oxcoder.tenstentgc.org
AUTH_TRUST_HOST=true
AUTH_SECRET=replace-with-a-long-random-value
AUTH_GOOGLE_ID=your-client-id
AUTH_GOOGLE_SECRET=your-client-secret
DATABASE_URL=postgresql://user:password@host:5432/database

The three public origin values must identify the same final HTTPS domain. Changing AUTH_SECRET invalidates existing sessions. On first database access, Ox creates the coder_chats table and an index by user key and update time. The application pool uses at most four PostgreSQL connections per process.

How-toOperate

Configure ads and sponsors

Keep public AdSense inventory and private workspace sponsorship separate while preserving the revenue path.

Public, content-led pages can render AdSense. This documentation page and the coding guides use the guides slot. The private chat does not render AdSense; it uses a separate direct sponsor interlude at the start of a generation.

Public AdSense

NEXT_PUBLIC_ADSENSE_CLIENT_ID=ca-pub-0000000000000000
NEXT_PUBLIC_ADSENSE_LANDING_SLOT=0000000000
NEXT_PUBLIC_ADSENSE_GUIDES_SLOT=0000000000

Single workspace sponsor

NEXT_PUBLIC_SPONSOR_NAME=Partner name
NEXT_PUBLIC_SPONSOR_COPY=A concise product description.
NEXT_PUBLIC_SPONSOR_URL=https://partner.example/product
  • The sponsor interlude remains visible for nine seconds and closes automatically.
  • The sponsor link opens in a new tab without stopping generation.
  • Rotating campaigns use NEXT_PUBLIC_SPONSOR_CAMPAIGNS_JSON with phone, foldable, or audio creative values.
  • Until AdSense is configured and approved, public placements show a labeled mock technology campaign.
  • The /ads.txt route publishes the configured AdSense seller record.
How-toOperate

Deploy the service on Render

Create one Node web service, configure the canonical domain, and verify every integration after deployment.

Render web service
SettingValue
Branchmain
RuntimeNode
Build commandnpm ci && npm run build
Start commandnpm start
Health-check path/api/health

Starter service baseline

NEXT_PUBLIC_APP_URL=https://oxcoder.tenstentgc.org
AUTH_URL=https://oxcoder.tenstentgc.org
NEXTAUTH_URL=https://oxcoder.tenstentgc.org
AUTH_TRUST_HOST=true
NODE_OPTIONS=--max-old-space-size=384
MAX_ACTIVE_GENERATIONS=120
MAX_ACTIVE_GENERATION_UNITS=128
  1. Create the service in the region nearest users and the database.
  2. Add all required environment values as protected secrets where appropriate.
  3. Add the custom domain, apply the displayed DNS record, and wait for TLS.
  4. Verify /api/health, /api/auth/providers, Google sign-in, a text turn, an image turn, and cloud history in a private browser window.
  5. Review production logs, memory, provider errors, and database connections before increasing capacity.
ExplanationOperate

How the Pi engine executes a turn

Follow authentication, validation, routing, Pi tool execution, streaming, and persistence from browser to completion.

  1. Auth.js validates a browser session, or the API validates a configured CLI bearer token.
  2. The route applies per-user rate limits and weighted capacity admission before parsing the request.
  3. Zod validates messages, model, attachments, tools, skills, MCP definitions, workspace selection, and response settings.
  4. Ox infers the working method from the latest prompt and compacts older context when limits are reached.
  5. Required MCP, internet skills, and OpenShell workspace tools are connected only when enabled and relevant.
  6. Pi calls the selected OpenRouter model, validates tool calls, runs compatible tools, and continues for the configured number of turns.
  7. Ox converts Pi events to newline-delimited JSON for activity, tool calls, reasoning, text, context, notices, usage, completion, and errors.
  8. The browser renders events incrementally and persists the finished chat to PostgreSQL or browser storage.

The implementation aims for the practical Pi coding workflow: a model and tool loop, streaming, provider routing, MCP, and read, write, edit, and bash tools. Host execution is deliberately replaced by OpenShell isolation because a public web service needs a stronger permission boundary than a local terminal agent.

ExplanationOperate

Security and trust boundaries

Know which secrets stay server-side, which inputs are untrusted, and where operators must review access.

  • Authentication protects the workspace and chat persistence routes.
  • OpenRouter, database, Google, local MCP, and CLI secrets stay server-side and must never use a NEXT_PUBLIC_ prefix.
  • Public URL tools resolve DNS and reject loopback, private, link-local, reserved, credential-bearing, and unsafe redirect targets.
  • Readers enforce response-size limits, timeouts, content-type checks, and bounded redirects.
  • Browser-defined tools and remote MCP require public HTTPS.
  • Trusted local MCP definitions come only from server configuration and execute with the service account's OS permissions.
  • File and shell operations run only through the separately managed OpenShell boundary.
  • CLI tokens are compared using constant-time hashes and are never accepted in URLs.
  • Request schemas cap conversation, attachment, tool, activity, reasoning, and stored output sizes.
  • External webpages, skills, files, tool results, images, and videos are data, not trusted instructions.

Reference

5 articles

ReferenceReference

Environment variable reference

Find the main authentication, model, storage, execution, capacity, and advertising settings.

Core, authentication, and storage
VariableDefault or requirementPurpose
NEXT_PUBLIC_APP_URLRequiredCanonical public origin for metadata, sitemap, robots, and attribution
AUTH_URLProductionCanonical Auth.js origin
NEXTAUTH_URLProductionCompatibility origin, equal to AUTH_URL
AUTH_TRUST_HOSTtrueTrust the deployment host
AUTH_SECRETRequiredSign and encrypt authentication state
AUTH_GOOGLE_IDProductionGoogle OAuth client ID
AUTH_GOOGLE_SECRETProductionGoogle OAuth client secret
AUTH_DEMO_MODEfalseExplicit development-style credentials login
DATABASE_URLOptionalPostgreSQL cross-device chat synchronization
Models and agent
VariableDefaultPurpose
OPENROUTER_API_KEYRequiredServer-side OpenRouter credential
OPENROUTER_DEFAULT_MODELz-ai/glm-5.3-flashInitial fallback preference
OX_MAX_REQUEST_COST_USD0.01Estimated maximum paid turn and reserved search cost
OX_MAX_OUTPUT_TOKENS4096Maximum requested answer tokens
OX_MAX_INPUT_PRICE_PER_MILLION0.25Provider prompt-price ceiling
OX_MAX_OUTPUT_PRICE_PER_MILLION1Provider completion-price ceiling
OX_MAX_AGENT_TURNS8Pi model and tool turns, bounded from 2 to 20
CONTEXT_COMPACTION_TRIGGER_CHARACTERS120000Character threshold for older-message summarization
CONTEXT_COMPACTION_MAX_MESSAGES40Message-count threshold for summarization
CONTEXT_COMPACTION_KEEP_CHARACTERS64000Recent verbatim context target
Connections and workspace
VariableDefaultPurpose
CONTEXT7_API_KEYOptionalBearer authentication for the Context7 preset
OX_CLI_API_TOKENOptionalBearer access to POST /api/chat
OX_LOCAL_MCP_ENABLEDfalseAllow operator-configured stdio MCP
OX_LOCAL_MCP_CONFIGOptionalAbsolute path to local MCP JSON
OX_LOCAL_MCP_SERVERS_JSONOptionalInline alternative to the config path
OX_OPENSHELL_ENABLEDfalseEnable isolated Pi coding tools
OX_OPENSHELL_BINARYopenshellOpenShell executable
OPENSHELL_GATEWAYActive CLI gatewaySaved gateway name
OPENSHELL_GATEWAY_ENDPOINTOptionalDirect HTTP(S) gateway without embedded credentials
OX_OPENSHELL_SANDBOX_IMAGEbaseSandbox image or template
OX_OPENSHELL_SANDBOX_POLICYOptionalAbsolute reviewed policy path
OX_OPENSHELL_SANDBOX_CPU1CPU request per sandbox
OX_OPENSHELL_SANDBOX_MEMORY1GiMemory request per sandbox
OX_OPENSHELL_MAX_SANDBOXES10Fail-closed managed sandbox count
OX_OPENSHELL_MAX_EXEC_SECONDS45Command timeout, bounded from 5 to 120 seconds
Capacity and advertising
VariableDefaultPurpose
MAX_ACTIVE_GENERATIONS120Concurrent lightweight request count
MAX_ACTIVE_GENERATION_UNITS128Weighted request memory budget
GENERATION_BYTES_PER_UNIT262144Request bytes represented by one unit
GENERATION_UNKNOWN_LENGTH_UNITS4Weight for unknown Content-Length
NODE_OPTIONSHost-specificUse --max-old-space-size=384 on a 512 MB service instance; the build has a separate 1 GB ceiling
NEXT_PUBLIC_ADSENSE_CLIENT_IDOptionalPublisher client and /ads.txt source
NEXT_PUBLIC_ADSENSE_LANDING_SLOTOptionalLanding-page AdSense placement
NEXT_PUBLIC_ADSENSE_GUIDES_SLOTOptionalGuides and documentation placement
NEXT_PUBLIC_SPONSOR_NAMEOptionalSingle workspace sponsor name
NEXT_PUBLIC_SPONSOR_COPYOptionalSingle sponsor message
NEXT_PUBLIC_SPONSOR_URLOptionalSingle sponsor destination
NEXT_PUBLIC_SPONSOR_CAMPAIGNS_JSONOptionalRotating sponsor campaign array
ReferenceReference

HTTP API and stream events

Integrate with health, chat, history, authentication, and advertising routes.

Routes
RouteMethodAuthenticationPurpose
/api/healthGETPublicIntegration readiness, default model, and Pi version
/api/auth/[...nextauth]GET, POSTAuth.jsGoogle or development-demo authentication
/api/chatPOSTSession or CLI tokenStream one Pi agent turn as NDJSON
/api/connections/testPOSTSessionTest MCP, internet-skill, or HTTPS-tool reachability
/api/chatsGETSessionLoad cloud chat history
/api/chatsPOSTSessionInsert or update a chat
/api/chats/[id]DELETESessionDelete a chat owned by the user
/ads.txtGETPublicPublish the configured seller record

Minimal POST /api/chat body

{
  "model": "z-ai/glm-5.3-flash",
  "allowModelFallback": true,
  "messages": [
    { "role": "user", "content": "Review this API design" }
  ],
  "toolsEnabled": true,
  "enabledTools": ["calculate", "get_current_time", "search_web", "read_url"],
  "customTools": [],
  "internetSkill": null,
  "mcpServers": [],
  "mcpActivation": "auto",
  "workspace": { "id": "default", "enabled": false },
  "thinkingMode": true,
  "thinkingLevel": "medium",
  "contextCompaction": true,
  "providerRetries": 1,
  "maxAgentTurns": 8,
  "responseLanguage": "auto",
  "responseStyle": "balanced",
  "skill": "review",
  "customInstructions": "Prefer TypeScript and include verification steps."
}
NDJSON event types
EventMeaning
metaActual model and engine at the start of an attempt
activityPi reasoning or workflow activity state
toolTool name, label, status, and optional bounded result
reasoningDisplayable reasoning text when enabled
textIncremental answer text
contextCompacted context summary and last represented message
noticeNon-fatal capability, fallback, or persistence information
usageInput, output, total tokens, and estimated cost
doneFinish reason and final responding model
errorTerminal error message and optional code

The response Content-Type is application/x-ndjson with one JSON object per line. The route disables caching, aborts upstream work when the client disconnects, and allows at most 300 seconds for a multi-step turn.

ReferenceReference

Service limits and capacity

Review the fail-closed bounds that protect memory, storage, tools, and upstream generation.

Runtime limits
AreaLimit
Generation starts12 per user per minute
Chat route duration300 seconds
Pi turns8 by default, configurable from 2 to 20
Active lightweight requests120 by default
Weighted request units128 by default
Request weight1 unit per 256 KiB, or 4 units when length is unknown
Saved messages200 per chat
Saved chat data6,000,000 validated characters; 6,500,000 request-body guard
Remote MCP servers3 per request
Remote MCP tools8 per server and 16 per turn
Local MCP servers3 in trusted server configuration
Custom tools4
Internet skills4 saved, 1 active
Prompt templates8 saved per browser
Workspace read4,000 lines per call; 1.2 MB image; 120 KB text output
Workspace write300,000 text characters per call
Workspace edit20 exact replacements per call
Workspace command45 seconds by default; 120 seconds maximum

When generation capacity is full, /api/chat returns HTTP 503 and Retry-After: 2. Rate limiting returns HTTP 429 with a calculated Retry-After value. Oversized chat requests return HTTP 413 before generation starts.

How-toReference

Verify a change or release

Run the repository gate, then prove authenticated browser behavior and production integrations.

Repository quality gate

npm run typecheck
npm run lint
npm test
npm run build
  • Verify Google login on the canonical domain.
  • Verify cross-device chat history with PostgreSQL enabled.
  • Run a text turn with every selectable model.
  • Run image and video input with GLM 5.3 Flash, and image input with OpenRouter Free.
  • Test one PDF, one remote attachment, every built-in tool, and the Context7 preset.
  • When enabled, make a file change and run a command in an isolated workspace.
  • Check sidebar, model menu, composer, settings, landing, journal, guides, docs, login, ads, and sponsor behavior on phone, tablet, and desktop widths.
  • Inspect /api/health, deployment status, error logs, memory, provider errors, and database connections.
How-toReference

Troubleshooting

Resolve the most common login, storage, model, attachment, MCP, workspace, CLI, capacity, and ad failures.

Common failures
ProblemChecks
Google login redirects incorrectlyMatch all three canonical origins, verify the exact OAuth callback, redeploy, and clear stale cookies
Production history is emptyCheck DATABASE_URL, database health, region reachability, and the signed-in normalized email
Model returns no streamCheck the OpenRouter key, account limits, provider errors, selected input modality, and fallback notice
Attachment rejectedCheck MIME type, size, public HTTPS safety, redirects, and total conversation attachment data
HTTP 429Wait for Retry-After; the user generation-start limit is active
HTTP 503Wait for Retry-After and inspect memory before raising the weighted capacity
Remote MCP unavailableRequire Streamable HTTP on public HTTPS, no cross-origin redirect, and a bounded tool list
Local MCP unavailableEnable it, choose exactly one config source, use absolute paths, verify env references, and run as the service OS user
Workspace unavailableConfirm openshell status, the selected gateway, image, policy path, sandbox capacity, and OX_OPENSHELL_ENABLED=true
CLI returns 401Use the same non-empty OX_CLI_API_TOKEN on client and service, then restart the service
Public ad stays mockedSet client and slot IDs, inspect /ads.txt, and confirm site approval, consent, and live inventory

Fast diagnostic endpoints

curl https://oxcoder.tenstentgc.org/api/health
curl https://oxcoder.tenstentgc.org/api/auth/providers
curl https://oxcoder.tenstentgc.org/ads.txt