Skip to main content
skill CX Codex

platform-models-api-configure — Claude Code skill for Salesforce Models API

Points a coding agent at the Salesforce Models API with OrgJWT auth, checks the endpoint answers, and wires the credentials properly.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add forcedotcom/sf-skills --skill platform-models-api-configure -a claude-code
Open on GitHub

What platform-models-api-configure does

Use this skill when the agent has to talk to https://api.salesforce.com/ai/gpt/v1 instead of its usual endpoint. Every agent shares the same auth: a signed OrgJWT minted by scripts/get-orgjwt.sh through client_credentials with the sfap_api scope. After that the paths split. Claude and the Claude Agent SDK get Bedrock mode switched on, with environment variables, a fully qualified sfdc_ai__… model name and custom headers. Codex and other CLIs keep the token and URL but place the equivalent settings in their own config file.

It starts with .claude/.orgjwt.env, locked to chmod 600 and gitignored. Then a verification curl that has to return 200 before settings.json is touched at all. Skip that check and you will chase the same failure twice. The settings file gets an apiKeyHelper pointing at absolute paths plus an env block. Finish with a full restart, since the agent reads config only on startup.

You need a connected app in the org with the sfap_api scope, client_credentials enabled and a run-as user. Also curl, jq and sf. The empty "ANTHROPIC_AUTH_TOKEN": "" line is not decoration: that token outranks apiKeyHelper, so leaving it set sends the agent off with a stale key and straight into 401 or 404. Keep ANTHROPIC_BEDROCK_BASE_URL exact, no trailing slash.

The connected app itself is out of scope here and belongs to the connectivity skills.

What it helps with

  • route an agent through the Salesforce Models API endpoint
  • mint an OrgJWT with client_credentials and hand it to apiKeyHelper
  • confirm model access before touching the settings file
  • diagnose 401 or 404 responses from Models API
  • switch on Bedrock mode with the right environment variables

Example prompts for the agent

  • Point Claude at the Salesforce Models API with OrgJWT, credentials sit in .claude/.orgjwt.env
  • Check access to sfdc_ai__DefaultBedrockAnthropicClaude46Sonnet and print the HTTP status
  • The agent keeps getting 401 from Models API — find the cause and fix the config

How to install platform-models-api-configure

1Skills CLI (Vercel)

npx skills add forcedotcom/sf-skills --skill platform-models-api-configure -a claude-code

2Manually: put the files in place

~/.claude/skills/platform-models-api-configure/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/platform-models-api-configure/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about platform-models-api-configure

How do I install platform-models-api-configure in Claude Code?

Run npx skills add forcedotcom/sf-skills --skill platform-models-api-configure -a claude-code. The skill lands at ~/.claude/skills/platform-models-api-configure/SKILL.md.

What does platform-models-api-configure do?

It sets the Salesforce Models API URL, OrgJWT auth and Bedrock variables for Claude, and tells other CLIs where the matching client settings go. It also verifies the endpoint with a curl call and helps untangle 401 and 404 errors.

What has to be ready before running it?

A connected app with the sfap_api scope, client_credentials flow and a run-as user. On the machine you need curl, jq and sf.

Source text

SKILL.md · Apache-2.0
---
name: platform-models-api-configure
description: "Configure (or troubleshoot) an AI coding agent or CLI to route through the Salesforce Models API using a signed OrgJWT. Use this skill when pointing an agent at the Salesforce model endpoint (api.salesforce.com/ai/gpt/v1), setting up OrgJWT / Bedrock-mode auth, wiring the agent's settings, API-key helper, and credentials file for the Salesforce endpoint, or fixing Models API 401 / 404 / \"model not available\" errors. DO NOT TRIGGER when the user needs to create or configure the Salesforce Connected App itself (use integration-connectivity-connected-app-configure) or set up Named Credentials / callout auth (use integration-connectivity-generate)."
metadata:
  version: "1.0"
  domains: ["Platform", "Agentforce"]
  relatedSkills:
    - "integration-connectivity-connected-app-configure"
    - "integration-connectivity-generate"
  cliTools:
    - tool: ["curl"]
      semver: ">=7.29.0"
    - tool: ["jq"]
      semver: ">=1.6.0"
    - tool: ["sf"]
      semver: ">=2.0.0"
---

# Salesforce Models API setup for an AI coding agent

The Salesforce Models API (`https://api.salesforce.com/ai/gpt/v1`) is
authenticated with a signed **OrgJWT** (obtained via `client_credentials` with
the `sfap_api` scope — see `scripts/get-orgjwt.sh`; no proxy). That auth and the
base URL are the same for **any** agent. How each agent then talks to the
endpoint is agent-specific: Anthropic clients (**Claude Code** and the **Claude
Agent SDK**) route through **Bedrock mode** (the env vars in Step 3), whereas
other agents (e.g. Codex) use their own client config against the same endpoint
and token — Bedrock mode does **not** apply to them.

The steps below are the **Claude Code / Claude Agent SDK reference
implementation** (Bedrock mode + a JSON settings file + an API-key helper). For
a non-Bedrock agent, reuse the OrgJWT auth (Step 1) and the base URL, and apply
the equivalent client settings in that agent's own config location instead of
the Bedrock env vars.

Bundled scripts are in `scripts/`. Path placeholders below: `<SKILL>` = the
absolute path to **this skill's own directory** (the folder containing this
`SKILL.md`; resolve it from the skill path in context). `<ABS>` = the absolute
path to the user's project root. Always emit fully resolved absolute paths —
the API-key helper runs from an undefined working directory, so relative paths
break it.

## Prerequisite

A connected app in the org with the **`sfap_api`** OAuth scope and the
**client_credentials** flow enabled (consumer key/secret + a run-as user).
Setup steps: https://developer.salesforce.com/docs/ai/agentforce/guide/access-models-api-with-rest.html
`curl` + `jq` installed.

## Inputs to collect

- `SF_INSTANCE_URL` — org My Domain, e.g. `https://acme.my.salesforce.com`
- `SF_CLIENT_ID`, `SF_CLIENT_SECRET` — connected-app consumer key/secret
- Models API base URL: `https://api.salesforce.com/ai/gpt/v1`
- Model: a fully qualified `sfdc_ai__…` name, e.g.
  `sfdc_ai__DefaultBedrockAnthropicClaude46Sonnet`
  (full list: https://developer.salesforce.com/docs/ai/agentforce/guide/supported-models.html)
- Scope: project (`<cwd>/.claude/settings.json`, default) or user (`~/.claude/settings.json`) — reference-agent settings paths
- Headers — `<FEAT>` = `x-client-feature-id` (default `ai-platform-models-connected-app`),
  `<APP>` = `x-sfdc-app-context` (default `EinsteinGPT`). Used in the Step 2 verify curl
  and in `ANTHROPIC_CUSTOM_HEADERS`.

## Steps (reference implementation)

Concrete values for a JSON-settings + API-key-helper agent. Reuse the OrgJWT
auth, verify curl, and base URL verbatim for any agent; adapt the settings-file
location and env-var wiring to the target agent.

1. Write `<project>/.claude/.orgjwt.env` (chmod 600), gitignore it:
   ```ini
   SF_INSTANCE_URL="..."
   SF_CLIENT_ID="..."
   SF_CLIENT_SECRET="..."
   ```
2. Verify — must return `200` before writing settings:
   ```bash
   TOKEN=$(bash <SKILL>/scripts/get-orgjwt.sh <ABS>/.claude/.orgjwt.env)
   curl -s -o /dev/null -w '%{http_code}\n' \
     <MODELS_API_URL>/model/<MODEL>/invoke-with-response-stream \
     -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
     -H 'x-client-feature-id: <FEAT>' -H 'x-sfdc-app-context: <APP>' \
     --data '{"anthropic_version":"bedrock-2023-05-31","max_tokens":16,"messages":[{"role":"user","content":"hi"}]}'
   ```
3. Write `.claude/settings.json` (merge into existing; keep other keys):
   ```json
   {
     "apiKeyHelper": "bash <SKILL>/scripts/get-orgjwt.sh <ABS>/.claude/.orgjwt.env",
     "model": "<MODEL>",
     "env": {
       "ANTHROPIC_AUTH_TOKEN": "",
       "CLAUDE_CODE_USE_BEDROCK": "1",
       "CLAUDE_CODE_SKIP_BEDROCK_AUTH": "1",
       "ANTHROPIC_BEDROCK_BASE_URL": "<MODELS_API_URL>",
       "ANTHROPIC_SMALL_FAST_MODEL": "<MODEL>",
       "ANTHROPIC_DEFAULT_MODEL": "<MODEL>",
       "ANTHROPIC_CUSTOM_HEADERS": "x-client-feature-id: <FEAT>\nx-sfdc-app-context: <APP>"
     }
   }
   ```
   Use absolute paths in `apiKeyHelper`. (`<FEAT>` / `<APP>` defaults are in
   "Inputs to collect" above.)
4. Tell the admin to fully restart the agent (`claude` for the reference agent) —
   settings and the API-key helper load at startup only.

### Capturing as a runbook (when asked to document, not apply)

If the user wants the setup written up for review instead of applied to their
machine (e.g. "save it as a Markdown runbook"), write **all** of the above into
the requested file (e.g. `models-api-setup-runbook.md`), in order and self-contained:
the exact `.orgjwt.env` contents, the `chmod 600` + gitignore note, the
verification curl (with the "must be `200` before writing settings" note), the
full `settings.json` block with every key from Step 3, and the final
"fully restart `claude`" step. Don't omit any of the nine `settings.json` keys.

## Verify before finishing

- [ ] `.claude/.orgjwt.env` created, `chmod 600`, and gitignored
- [ ] Verification curl returned HTTP `200` before `settings.json` was written
- [ ] `ANTHROPIC_AUTH_TOKEN` set to `""` in `settings.json`
- [ ] `CLAUDE_CODE_USE_BEDROCK` set to `"1"`
- [ ] `CLAUDE_CODE_SKIP_BEDROCK_AUTH` set to `"1"`
- [ ] `ANTHROPIC_BEDROCK_BASE_URL` is exactly `https://api.salesforce.com/ai/gpt/v1` (no trailing slash/path)
- [ ] `model`, `ANTHROPIC_DEFAULT_MODEL`, and `ANTHROPIC_SMALL_FAST_MODEL` all use the fully qualified `sfdc_ai__…` alias
- [ ] `ANTHROPIC_CUSTOM_HEADERS` contains `x-client-feature-id` and `x-sfdc-app-context`
- [ ] `apiKeyHelper` uses absolute paths (`bash <SKILL>/scripts/get-orgjwt.sh <ABS>/.claude/.orgjwt.env`)
- [ ] User told to fully restart `claude`

## Must be exact (each prevents a specific failure)

- `"ANTHROPIC_AUTH_TOKEN": ""` — clears any global token that would otherwise
  outrank `apiKeyHelper` (precedence: `ANTHROPIC_AUTH_TOKEN` > `ANTHROPIC_API_KEY`
  > `apiKeyHelper`). Without it → wrong/old bearer → 401/404.
- `CLAUDE_CODE_USE_BEDROCK=1` — activates the Bedrock API client; without it
  Claude Code uses the standard Anthropic API protocol and ignores
  `ANTHROPIC_BEDROCK_BASE_URL` entirely, so every call bypasses the Models API.
- `CLAUDE_CODE_SKIP_BEDROCK_AUTH=1` — else Claude Code overwrites `Authorization`
  with AWS SigV4 and the OrgJWT never lands.
- `apiKeyHelper` must be invoked as `bash <path> <credsfile>` (avoids exit-126).
- Model must be a fully qualified `sfdc_ai__…` name (see supported models).
- Auth is the OrgJWT from `client_credentials` (a signed JWT, 2 dots, scope
  `sfap_api`) — NOT `sf org display` (unsigned session token → 404). `sf` CLI
  has no client_credentials command; the helper calls `/services/oauth2/token`.
- Only `ANTHROPIC_BEDROCK_BASE_URL` routes; no tenant-id header needed.

## Diagnose

| Error | Meaning | Check first |
|-------|---------|-------------|
| `401` | Token is not a valid OrgJWT | Connected App `sfap_api` scope, `client_credentials` flow enabled, consumer key/secret in `.orgjwt.env`; `ANTHROPIC_AUTH_TOKEN` not cleared to `""` |
| `404` | Token valid but model/env/org not routable | Fully qualified `sfdc_ai__…` model alias, `ANTHROPIC_BEDROCK_BASE_URL` exactly `https://api.salesforce.com/ai/gpt/v1`, org entitled for the Models API, `ANTHROPIC_AUTH_TOKEN` cleared |
| `model not available` | Non-alias model id | Replace with a fully qualified `sfdc_ai__…` alias (see supported models) |

© forcedotcom · Apache-2.0 · forcedotcom/sf-skills

Similar skills

All skills for Agent setup: memory, context, orchestration →

From the same set181

mobile-platform-offline-validate Audits Lightning Web Components for Komaci offline priming compatibility in Salesforce mobile apps and generates code-level fixes. CX Codex +1 4,700installs mobile-platform-native-capabilities-integrate Guides an agent through building Salesforce LWCs that use native mobile features such as scanning, location, NFC, and payments. Use it for lightning/mobileCapabilities work. CX Codex +1 4,700installs commerce-b2b-open-code-components-replace Replaces out-of-the-box B2B Commerce components with open source equivalents in site metadata content.json. Or just reports the mappings when you don't want files touched. CX Codex +1 4,600installs commerce-b2b-open-code-components-integrate Pulls Salesforce B2B Commerce open source components from GitHub into a store's site metadata so they show up in the Experience Builder palette. CX Codex +1 4,600installs platform-policy-rule-generate Writes PolicyRuleDefinition and PolicyRuleDefinitionSet metadata XML for Salesforce Data Cloud: schema, category tree and pre-deploy checks. CX Codex +1 4,100installs platform-custom-report-type-generate Guides the agent through authoring and validating Salesforce Custom Report Type metadata: base object, joins, exposed fields. Handy when a .reportType-meta.xml deploy fails. CX Codex +1 4,000installs platform-sharing-owd-configure Reads and changes Organization-Wide Defaults on Salesforce objects: shows current access levels and edits sharingModel in the object metadata. CX Codex +1 3,700installs platform-encryption-configure Skill for generating Salesforce Shield Platform Encryption metadata and evaluating key management architecture models. CX Codex +1 3,600installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor