Skip to main content
kRouter
All posts
How kRouter works

Xcode with any model: chat, Claude Agent and Codex

Xcode 26 and 27 can run chat, Claude Agent and Codex on other models, but each reads its own config. How to point all three at one local router.

Kodelyth · The team behind kRouter
· Updated
9 min read

You open Xcode > Settings > Intelligence, add a chat provider for GLM or another model, paste its URL and key, and Xcode refuses it:

Provider is not valid.
Models could not be fetched with the provided account details

Or the provider works in chat, and then you find that Claude Agent and Codex ignore it and still want a Claude.ai or ChatGPT login.

Both have the same cause. Chat, Claude Agent and Codex are three separate places a model plugs into Xcode, each speaking a different API and reading its configuration from a different place. Getting one right does nothing for the other two.

Three surfaces, three protocols

Surface in XcodeAPI it speaksWhere it is configured
Chat (any chat provider)OpenAI Chat Completions, plus GET /v1/modelsIntelligence settings, Chat section
Claude Agent (Xcode 26.3+)Anthropic Messagessettings.json in ~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig
Codex (Xcode 26.3+)OpenAI Responsesconfig.toml in ~/Library/Developer/Xcode/CodingAssistant/codex

Claude Agent runs on the Claude Agent SDK, the harness behind Claude Code, so it reads the same env block Claude Code does. Codex is OpenAI's Codex CLI, which has spoken only the Responses API since version 0.95; Xcode 26.3 already shipped 0.98. The two folders come from Apple's Extending and customizing agents page, which also says these files only affect agents launched inside Xcode. Xcode 26.6 added Google's Gemini as a third agent, plus support for agents that speak the Agent Client Protocol; they are set up separately and not covered here.

A router that answers all three protocols lets one set of provider accounts serve all three surfaces. kRouter serves /v1/chat/completions with /v1/models, /v1/messages and /v1/responses, and translates each to whatever the provider behind the chosen model speaks.

Why Xcode says "Provider is not valid"

Apple's setup guide spells out the contract: a chat provider must support the Chat Completions API and answer both {URL}/v1/models and {URL}/v1/chat/completions. Xcode fetches the model list when you add the provider and rejects it if that call fails. Four things make it fail:

  1. The provider has no /v1/models. Plenty of "OpenAI-compatible" APIs serve completions but no model list. A user on Apple's forums hit this message adding Z.ai's coding endpoint, and the reply that followed blamed exactly that.
  2. The URL already ends in /v1. Xcode adds /v1 itself, so https://host/v1 turns into https://host/v1/v1/models. The Xcode guides from OpenRouter and Vercel both tell you to leave the suffix off.
  3. The key is in the wrong header. If the API Key Header field does not match what the server expects, the server rejects the model-list request.
  4. Nothing is listening on the port. A Locally Hosted provider is just a port number. If the server behind it is not running when you add it, there is no model list to fetch.

Chat: add kRouter as a Locally Hosted provider

Xcode sends these requests from your Mac, not from a cloud service, so a server on localhost works. Cursor is the opposite case; see why Cursor ignores a localhost base URL.

npm install -g @sifxprime/krouter
krouter -t

Open http://localhost:20128/dashboard and connect at least one provider. Then, in Xcode:

  1. Open Xcode > Settings > Intelligence and click Add a Chat Provider under Chat. Some builds label it Add a Model Provider.
  2. Choose Locally Hosted, enter port 20128 and a description such as kRouter, and click Add.
  3. Open the new provider and star the models you use, so they sit at the top of the model picker.

kRouter's /v1/models lists every connected provider's models plus your combos, and requests from the same machine need no key. Model ids keep kRouter's provider/model form: ocg/glm-5.3, gh/claude-sonnet-4.6, kr/claude-haiku-4.5. A combo is listed under its own name. kRouter also answers /v1/v1/..., so a URL entered with a stray /v1 still works.

One catch: Locally Hosted has no field for a key. If you switch on Require API key on kRouter's Endpoint page (the Tunnel will not start without it), Xcode still adds the provider, because kRouter's model list does not ask for a key, but every chat comes back 401 "Missing API key". In that case add kRouter as an Internet Hosted provider with a key, as described for a remote kRouter below.

Claude Agent: Xcode's own settings.json

Two common attempts do nothing here.

  • Exporting ANTHROPIC_BASE_URL in ~/.zshrc. Xcode starts its agents in a restricted environment that does not inherit your shell, as fatbobman's write-up of 26.3 documents.
  • Editing ~/.claude/settings.json. Xcode's agent reads its own folder, not that file.

On Xcode 26.5 or later:

  1. Go to Settings > Intelligence > Claude Agent. The account row says "Not Signed In"; open its menu, choose Authenticate with configuration file…, and confirm.
  2. The row now reads "Configure in 'settings.json'". Click it, and Finder opens the file Xcode actually reads.
  3. Add the kRouter block, then relaunch Xcode:
{
  "env": {
    "ANTHROPIC_BASE_URL": "http://localhost:20128/v1",
    "ANTHROPIC_AUTH_TOKEN": "sk_krouter",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "gh/claude-opus-4.6",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "ocg/glm-5.3",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "kr/claude-haiku-4.5"
  }
}

The three model variables set what the Opus, Sonnet and Haiku tiers mean. The Haiku slot also runs background work, so give it something cheap. Leave Claude Agent's Model row on Default; that is how the forum user who got this working set it up. sk_krouter is a placeholder: on the same Mac, kRouter does not check keys unless Require API key is on.

You don't have to write this by hand. In kRouter's dashboard, open CLI Tools > Claude Code, pick a model for each slot, and click Manual Config to copy the JSON. Apply is the wrong button here: it writes your own ~/.claude/settings.json, not Xcode's file. Copy only the env block, not your whole personal settings file; hooks that call programs on your PATH may not find them in Xcode's restricted environment.

Xcode 26.3 and 26.4 have no configuration-file option. One forum user got it working by signing Claude Agent in with a real Anthropic API key, then copying settings.json into ClaudeAgentConfig and relaunching. The env block then redirected the traffic. Xcode 26.5 needs macOS Tahoe 26.2 or later, and with it you no longer need the Anthropic key.

Two things to watch:

  • The context window. Claude Code assumes 200K for any model name it does not recognise. For GLM, Kimi or DeepSeek, add CLAUDE_CODE_MAX_CONTEXT_TOKENS to the same env block; the Claude Code card's Max context picker puts it in the Manual Config JSON for you. Context windows for non-Claude models covers which value to pick.
  • Bare model names. If Claude Agent fails with "No active credentials for provider: anthropic", a name like claude-sonnet-4-6 arrived without a provider/ prefix, which means one of the three slots is unmapped. Unless a combo or model alias has that exact name, kRouter sends bare claude- names to the Anthropic API-key provider.

Codex: Xcode's own config.toml

The flow is the same. Go to Settings > Intelligence > Codex, choose Authenticate with configuration file…, then click "Configure in 'config.toml'" to open the file. Codex needs a Responses API endpoint, declared as its own provider:

model = "cx/gpt-5.5"
model_provider = "krouter"
 
[model_providers.krouter]
name = "kRouter"
base_url = "http://localhost:20128/v1"
wire_api = "responses"
 
[model_providers.krouter.http_headers]
Authorization = "Bearer sk_krouter"

kRouter's OpenAI Codex CLI / App card shows this block under Manual Config. The card also adds an [agents] line for the subagent model, which you can leave out. With a custom provider like this one, Codex sends the key from http_headers and needs no ChatGPT login.

For non-OpenAI models, Codex is the fussier of the two agents. Use GPT models through cx/, a ChatGPT plan signed in to kRouter; kRouter forwards those requests without translating them. On a translated route, some GPT model names make Codex send tools in a layout kRouter does not convert.

Tools from MCP servers are the bigger issue. Current Codex releases send MCP tools as namespace tools, a Responses-only shape that groups functions under the server's name, and kRouter 0.5.163 cannot unpack that group on a translated route: it becomes one function with no parameters. Xcode's build, test and preview tools are MCP tools. If the Codex that Xcode ships does the same, a Codex agent running on GLM or Claude can still answer you but cannot build or test. Codex CLI with any model covers the details.

Which surface for which model

You wantUseExample model value
Questions and quick edits, any modelChat, Locally HostedAny starred model, or a combo
An agent on Claude, through a Copilot or Kiro account you already haveClaude Agentgh/claude-sonnet-4.6, kr/claude-sonnet-4.5
An agent on GLM, Kimi, DeepSeek or MiniMaxClaude Agentocg/glm-5.3, ocg/kimi-k3
An agent on GPT modelsCodexcx/gpt-5.5
An agent that falls back to another provider when one runs outClaude AgentA combo name

Claude Agent is the better host for non-OpenAI models. Behind a gateway, Claude Code sends every tool, Xcode's MCP tools included, as an ordinary function definition, and kRouter converts those for each backend.

Xcode's agents can also capture SwiftUI preview snapshots, and in Xcode 27 simulator screenshots, to check their work. Those images come back inside tool results, which kRouter's vision adapter does not inspect, so it will not hand those turns to an image-capable model. A text-only model such as GLM-5.3 cannot read them. For UI work, run the agent itself on a model that reads images. Text-only models and screenshots covers the options.

Before you connect a Claude, Codex, GitHub Copilot or Kiro account, kRouter shows a risk notice. Those subscription sessions are not licensed for proxy use, and the account may be restricted.

kRouter on another Mac

If kRouter runs on a Mac mini or a VPS, the setup above still works with three changes:

  • An address Xcode can reach. The Tunnel and Tailscale rows on kRouter's Endpoint page each give you an HTTPS address. The dashboard will not start either one until you have set a password and login is on, and the Tunnel also needs Require API key. Setup is in the tunnel guide.
  • A real key. Create one on the same page. Without a key, kRouter answers 401 "API key required for remote API access".
  • Internet Hosted instead of Locally Hosted for chat. Enter that address (with or without the /v1 the Endpoint page shows; kRouter accepts both), your kRouter key, and x-api-key as the API Key Header, which kRouter reads as it is.

In the two agent files, replace http://localhost:20128 with the HTTPS address, keeping the /v1 at the end, and sk_krouter with the key.

Check kRouter before blaming Xcode

# With Require API key on, add -H "x-api-key: <your-krouter-key>" to both calls
 
# The call Xcode makes when it validates a chat provider
curl -s http://localhost:20128/v1/models | head -c 300
 
# The protocol Claude Agent speaks
curl -s http://localhost:20128/v1/messages \
  -H "Content-Type: application/json" \
  -d '{"model":"ocg/glm-5.3","max_tokens":64,"messages":[{"role":"user","content":"Reply with the word ok"}]}'

If the first returns your models and the second a reply, kRouter is working, and the problem is on the Xcode side: the wrong file, no relaunch, or an unmapped slot. The Codex post has the matching /v1/responses test.

Common questions

Can Xcode use models other than Claude and ChatGPT?

Yes, in all three places. Chat accepts any provider that serves Chat Completions and a model list. Claude Agent and Codex can be pointed elsewhere through their own configuration files, which Xcode 26.5 and later let you sign in with, as long as the endpoint speaks Anthropic Messages or the Responses API respectively.

Why does Xcode say "Models could not be fetched"?

Xcode validates a chat provider by appending /v1/models to the URL you entered and calling it. Either the provider has no model list, the URL already ends in /v1, or the key is in the wrong header. A router that serves /v1/models for every connected provider removes the first two causes.

Does adding a chat provider change Claude Agent or Codex?

No. Chat providers only power the chat. Claude Agent reads settings.json and Codex reads config.toml, both in Xcode's own CodingAssistant folder. Your shell environment does not reach either agent, and Claude Agent ignores the ~/.claude/settings.json you use in Terminal.

Do I need a kRouter API key in Xcode?

Not when kRouter runs on the same Mac, unless Require API key is on. Then the agent files need a real key, and chat needs an Internet Hosted provider, because Locally Hosted has no key field. From any other machine, every request needs a key from the Endpoint page.

Which Xcode version do I need?

Custom chat providers arrived with Xcode 26, and Claude Agent and Codex with 26.3. Signing the agents in through a configuration file, without a Claude.ai, ChatGPT, Anthropic or OpenAI account, needs 26.5 or later, which requires macOS Tahoe 26.2. Xcode 27 requires macOS Tahoe 26.6 or later.

Kodelyth · The team behind kRouter

Published by Kodelyth, the team that builds kRouter. Posts are drafted with AI assistance and reviewed by a person before they go out. kRouter is free and MIT licensed.

Install kRouter