phbeks.com MCP config api & claude code
// tools / configuring claude

Configuring Claude — the API & Claude Code

An interactive, opinionated walkthrough of how to wire up Claude — from the surface you touch (Claude Code: auth, model, settings.json) down to the Anthropic API it sits on (keys, request config, thinking, effort, caching). Builders generate copy-paste config; callouts flag the 400-errors before you hit them.

Two layers of auth, one precedence chain

Claude Code is a client for the Anthropic API. Authenticating Claude Code and authenticating a raw API call resolve credentials the same way — first match wins. Pick how you want to authenticate and the builder shows the setup and the precedence note.

Auth method picker
Precedence (both Claude Code and the SDKs) Explicit flag / constructor arg → ANTHROPIC_API_KEYANTHROPIC_AUTH_TOKENant auth login profile → cloud-provider credentials. A stale exported ANTHROPIC_API_KEY silently overrides an ant profile and your /login session — truly unset it (an empty "" still wins its slot). In Claude Code, run /status to see which method is active.
Don't commit keys Put keys in the environment or your OS keychain, never in code or in a tracked settings.json. Use .claude/settings.local.json (git-ignored) for anything machine-specific.

Pick a model — and use the exact ID

Default to Claude Opus 4.8 (claude-opus-4-8) unless you have a reason not to. Use the bare alias verbatim — never append a date suffix (e.g. claude-opus-4-8, not claude-opus-4-8-20251101); a wrong ID 404s.

ModelID (use this)ContextMax out$ / 1M in→outUse for
Claude Opus 4.8 ★ defaultclaude-opus-4-81M128K$5 → $25Most agentic / coding / hard reasoning
Claude Sonnet 4.6claude-sonnet-4-61M64K$3 → $15Best speed/intelligence balance
Claude Haiku 4.5claude-haiku-4-5200K64K$1 → $5Fast, cheap, simple tasks
Claude Opus 4.7claude-opus-4-71M128K$5 → $25Prev-gen Opus (pin if needed)
Claude Fable 5claude-fable-51M128K$10 → $50Most capable; hardest long-horizon work

Selecting the model in Claude Code

Live capability lookup Context window, output cap, and feature support (vision, thinking, effort) are queryable at runtime via the Models API: client.models.retrieve("claude-opus-4-8").max_input_tokens, .capabilities[...]. The table above is a snapshot.

Configure Claude Code with settings.json

Claude Code reads layered settings files, most-specific wins:

FileScopeCommit it?
~/.claude/settings.jsonUser — all your projectsn/a (personal)
.claude/settings.jsonProject — shared with the teamYes — check it in
.claude/settings.local.jsonProject — just you, this machineNo — git-ignored
Managed (enterprise)Org-deployed, highest precedenceAdmin-controlled
settings.json builder
Where it goes Save this as .claude/settings.json (team) or ~/.claude/settings.json (personal). permissions.allow/deny use tool-matcher syntax; deny always beats allow.
Automated behaviors need hooks, not settings "Run X every time Y happens" is a hooks entry in settings.json (the harness runs it), not a model instruction. Common events: PreToolUse, PostToolUse, Stop.

Configuring a request to /v1/messages

Everything Claude Code does is ultimately a call to the Messages API. Here's the client init and the knobs that matter, then a builder that assembles a real call.

Client init

# pip install anthropic — reads ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN / ant profile
from anthropic import Anthropic
client = Anthropic()  # no args: resolves credentials from the environment
// npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();  // resolves from env
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{ ... }'

The knobs that matter

Request builder

The config that 400s (Opus 4.7 / 4.8 / Fable 5)

budget_tokens is removed thinking: {type:"enabled", budget_tokens: N} returns 400. Use thinking: {type:"adaptive"} and control depth with output_config.effort.
No sampling params temperature, top_p, top_k all 400. Steer with the prompt instead.
No assistant prefill A trailing role:"assistant" turn 400s. Use output_config.format (structured outputs) or a system instruction to shape output.
Stream above ~16K max_tokens Non-streaming requests hit SDK HTTP timeouts at high max_tokens. Use .stream() + .get_final_message() / .finalMessage().
Fable 5 only An explicit thinking:{type:"disabled"} 400s (omit thinking entirely), and the org must allow 30-day data retention (ZDR orgs 400 on every request). Handle stop_reason:"refusal" before reading content.

Error codes (quick reference)

CodeTypeRetry?Usual cause
400invalid_request_errorNoBad params, removed field, non-alternating roles
401authentication_errorNoMissing/invalid key, or both API key + auth token set
404not_found_errorNoTypo'd / date-suffixed model ID
429rate_limit_errorYesRPM/TPM exceeded — SDK backs off automatically
529overloaded_errorYesTemporary capacity — retry with backoff

Next: configuring MCP