zuplo 7.6.9 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,9 @@ description:
6
6
  authenticated, metered, and routed by the gateway.
7
7
  ---
8
8
 
9
- The Zuplo AI Gateway supports the [Anthropic](https://docs.claude.com/en/home)
10
- `/v1/messages` API endpoint. This means that you can configure
11
- [Claude Code](https://www.claude.com/product/claude-code) to work seamlessly via
12
- the AI Gateway.
9
+ You can configure [Claude Code](https://www.claude.com/product/claude-code) to
10
+ send its model requests through the Zuplo AI Gateway, so the gateway
11
+ authenticates, meters, and routes every Claude Code session.
13
12
 
14
13
  ## Claude Code Setup
15
14
 
@@ -25,25 +24,37 @@ the AI Gateway.
25
24
 
26
25
  4. Copy the **API URL** and **API Key** shown at the top of the app page
27
26
 
28
- 5. Add the API key and gateway URL to your environment, or Claude Code settings,
29
- using either approach below
27
+ 5. Add the API key, gateway URL, and model mappings to `.claude/settings.json`
30
28
 
31
29
  </Stepper>
32
30
 
33
- ### Environment
31
+ ### Before copying: replace the provider name
34
32
 
35
- ```
36
- ANTHROPIC_AUTH_TOKEN=<your-ai-gateway-app-api-key>
37
- ANTHROPIC_BASE_URL=https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e
38
- ANTHROPIC_MODEL=anthropic/claude-sonnet-5
39
- ANTHROPIC_SMALL_FAST_MODEL=anthropic/claude-haiku-4-5
40
- ANTHROPIC_DEFAULT_OPUS_MODEL=anthropic/claude-opus-5
41
- ANTHROPIC_DEFAULT_SONNET_MODEL=anthropic/claude-sonnet-5
42
- ANTHROPIC_DEFAULT_HAIKU_MODEL=anthropic/claude-haiku-4-5
43
- ```
33
+ :::warning
34
+
35
+ The examples below assume your provider is named `anthropic`. Replace that
36
+ prefix with the name of **your** provider before copying the configuration. For
37
+ example, a provider named `my-anthropic` routes `my-anthropic/claude-sonnet-5`,
38
+ while a Bedrock provider named `bedrock` routes
39
+ `bedrock/anthropic.claude-sonnet-5`. The model part must be an id that provider
40
+ understands.
41
+
42
+ :::
43
+
44
+ The gateway routes every request using `providerName/model`. The provider prefix
45
+ picks which of your providers handles the request — a gateway can contain
46
+ several providers that serve Anthropic models.
44
47
 
45
48
  ### Using settings.json
46
49
 
50
+ You can configure Claude Code either globally or per project by editing the
51
+ settings file:
52
+
53
+ - **Global:** `~/.claude/settings.json`
54
+ - **Project-specific:** `.claude/settings.json` in your project directory
55
+
56
+ Add the following environment configuration to the settings file:
57
+
47
58
  ```json
48
59
  {
49
60
  "env": {
@@ -53,7 +64,8 @@ ANTHROPIC_DEFAULT_HAIKU_MODEL=anthropic/claude-haiku-4-5
53
64
  "ANTHROPIC_SMALL_FAST_MODEL": "anthropic/claude-haiku-4-5",
54
65
  "ANTHROPIC_DEFAULT_OPUS_MODEL": "anthropic/claude-opus-5",
55
66
  "ANTHROPIC_DEFAULT_SONNET_MODEL": "anthropic/claude-sonnet-5",
56
- "ANTHROPIC_DEFAULT_HAIKU_MODEL": "anthropic/claude-haiku-4-5"
67
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL": "anthropic/claude-haiku-4-5",
68
+ "ANTHROPIC_DEFAULT_FABLE_MODEL": "anthropic/claude-fable-5"
57
69
  }
58
70
  }
59
71
  ```
@@ -68,20 +80,7 @@ Claude Code appends `/v1/messages` to the base URL itself, so
68
80
  Restart Claude and it will switch to using your new AI Gateway configuration and
69
81
  all your Claude Code LLM requests will route through the AI Gateway.
70
82
 
71
- ### Model names include your provider's name
72
-
73
- The gateway routes every request by a model reference of the form
74
- `providerName/model`, where `providerName` is the name of the provider **you
75
- configured** in your gateway — not a fixed vendor id. A single gateway can
76
- contain several providers that serve Anthropic models — Anthropic itself, Google
77
- Vertex AI, AWS Bedrock, or multiple keyed instances of the same vendor — so the
78
- gateway never guesses a provider for a bare model name like `claude-sonnet-5`.
79
-
80
- The examples on this page assume the provider is named `anthropic`. Use the name
81
- of your own provider: a provider named `my-anthropic` routes
82
- `my-anthropic/claude-sonnet-5`, and a Bedrock provider named `bedrock` routes
83
- `bedrock/anthropic.claude-sonnet-5` (the model part is always the id the
84
- provider itself understands).
83
+ ### Configure every Claude Code model variable
85
84
 
86
85
  The model ids in these examples reflect what was current when this page was
87
86
  written, and ids differ across providers — a Bedrock provider serves different
@@ -96,8 +95,10 @@ the model variables above must be set to a prefixed reference:
96
95
  built-in default model unprefixed and the first request fails.
97
96
  - `ANTHROPIC_SMALL_FAST_MODEL` — the model for background tasks.
98
97
  - `ANTHROPIC_DEFAULT_OPUS_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`,
99
- `ANTHROPIC_DEFAULT_HAIKU_MODEL` — what the `opus`/`sonnet`/`haiku` aliases
100
- resolve to, so `claude --model opus` and `/model sonnet` keep working.
98
+ `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_FABLE_MODEL` — what the
99
+ `opus`/`sonnet`/`haiku`/`fable` aliases resolve to, so `claude --model opus`
100
+ and `/model sonnet` keep working. In these examples,
101
+ `ANTHROPIC_DEFAULT_FABLE_MODEL` maps `fable` to `anthropic/claude-fable-5`.
101
102
 
102
103
  :::caution{title='HTTP 400: model must use "providerName/model"'}
103
104
 
@@ -0,0 +1,157 @@
1
+ ---
2
+ title: Claude Desktop
3
+ sidebar_label: Claude Desktop
4
+ description:
5
+ Point Claude Desktop at an AI Gateway app so every Chat, Cowork, and Code
6
+ session is authenticated, metered, and routed by the gateway.
7
+ ---
8
+
9
+ [Claude Desktop](https://claude.com/download) can use the Zuplo AI Gateway as
10
+ its inference provider, so the gateway authenticates, meters, and routes every
11
+ Chat, Cowork, and Code session started from the desktop app.
12
+
13
+ This page covers routing Claude Desktop's model requests through the AI Gateway.
14
+ To give Claude Desktop tools from a Zuplo MCP route instead, see
15
+ [Connect Claude Desktop and Claude.ai](../../mcp-gateway/connect-clients/claude-desktop.mdx).
16
+
17
+ ## Claude Desktop Setup
18
+
19
+ <Stepper>
20
+
21
+ 1. Create a [new provider](../managing-providers.mdx) in the AI Gateway for
22
+ Anthropic
23
+
24
+ 2. [Set up a new team](../managing-teams.mdx)
25
+
26
+ 3. Create a [new app](../managing-apps.mdx) to use with Claude Desktop and
27
+ assign it to the team you created
28
+
29
+ 4. Copy the **API URL** and **API Key** shown at the top of the app page
30
+
31
+ 5. Enter the API URL, API key, and model list in Claude Desktop's third-party
32
+ inference settings
33
+
34
+ </Stepper>
35
+
36
+ ### Before copying: replace the provider name
37
+
38
+ :::warning
39
+
40
+ The examples below assume your provider is named `anthropic`. Replace that
41
+ prefix with the name of **your** provider before copying the configuration. For
42
+ example, a provider named `my-anthropic` routes `my-anthropic/claude-sonnet-5`,
43
+ while a Bedrock provider named `bedrock` routes
44
+ `bedrock/anthropic.claude-sonnet-5`. The model part must be an id that provider
45
+ understands.
46
+
47
+ :::
48
+
49
+ The gateway routes every request using `providerName/model`. The provider prefix
50
+ picks which of your providers handles the request — a gateway can contain
51
+ several providers that serve Anthropic models.
52
+
53
+ ### Configure third-party inference
54
+
55
+ Configure Claude Desktop's inference provider in its in-app configuration
56
+ window, available on macOS and Windows:
57
+
58
+ <Stepper>
59
+
60
+ 1. From the menu bar (macOS) or the application menu (Windows), select **Help →
61
+ Troubleshooting → Enable Developer Mode**.
62
+
63
+ 2. Open **Developer → Configure Third-Party Inference**.
64
+
65
+ 3. In the **Connection** section, set **Inference provider** to **Gateway**.
66
+
67
+ 4. In the **Gateway credentials** card, set **Gateway base URL** to the app's
68
+ API URL, for example
69
+ `https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e`,
70
+ and **Gateway API key** to the app's API key.
71
+
72
+ 5. Leave **Credential kind** set to **Static API key** and **Gateway auth
73
+ scheme** set to **Bearer**.
74
+
75
+ 6. In the **Models** section, add the models the app may use to the **Model
76
+ list**. See [Add models to the Model list](#add-models-to-the-model-list).
77
+
78
+ 7. Click **Apply locally**. Claude Desktop writes the configuration and
79
+ relaunches into it.
80
+
81
+ </Stepper>
82
+
83
+ :::note
84
+
85
+ Claude Desktop appends `/v1/messages` to the base URL itself, so **Gateway base
86
+ URL** is the app's URL _without_ the `/v1` suffix.
87
+
88
+ :::
89
+
90
+ :::caution{title="Keep the auth scheme set to Bearer"}
91
+
92
+ The gateway reads the API key from the `Authorization: Bearer` header, so keep
93
+ **Gateway auth scheme** set to **Bearer**. Likewise, keep **Credential kind**
94
+ set to **Static API key** — AI Gateway apps authenticate with their own API
95
+ keys, not identity-provider tokens.
96
+
97
+ :::
98
+
99
+ ### Add models to the Model list
100
+
101
+ The **Model list** in the **Models** section overrides the model list Claude
102
+ Desktop discovers on its own. Click **Add** once per model the app may use, and
103
+ fill in each entry:
104
+
105
+ - **Model ID** — the full `providerName/model` reference, for example
106
+ `anthropic/claude-sonnet-5`. A bare id such as `claude-sonnet-5` fails to
107
+ route through the gateway.
108
+ - **Display name** — the name shown in the model picker, for example
109
+ `Claude Sonnet 5`. Leave it blank and Claude Desktop formats a name from the
110
+ id.
111
+ - **Offer 1M-context variant** — leave this off unless your provider's
112
+ deployment accepts 1M-token context for the model.
113
+ - **Tier alias** — the Claude tier (Opus, Sonnet, Haiku, or Fable) this model
114
+ stands in for. Setting it pins what the bare alias (for example `opus`)
115
+ resolves to, so tier names route to your prefixed model reference.
116
+
117
+ The first entry is the default selection in the model picker. Include a
118
+ Haiku-tier model — Claude Desktop runs background and sub-agent tasks on a
119
+ small, fast model.
120
+
121
+ The model ids in these examples reflect what was current when this page was
122
+ written, and ids differ across providers — a Bedrock provider serves different
123
+ ids than Anthropic directly, and availability can vary by region. Check
124
+ [your provider's page](../managing-providers.mdx) in the portal for the models
125
+ it currently serves, and use those ids.
126
+
127
+ The app's
128
+ [Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
129
+ policy controls which models the app may use.
130
+
131
+ ### Verify the configuration
132
+
133
+ After Claude Desktop relaunches, send a message in a Chat conversation and start
134
+ a Cowork session. Both requests route through the gateway and count against the
135
+ [app](../managing-apps.mdx) in the Zuplo Portal, as do Code sessions started
136
+ from the desktop app. Terminal Claude Code sessions outside the desktop app use
137
+ a separate configuration — see [Claude Code](./claude-code.mdx).
138
+
139
+ :::caution{title='HTTP 400: model must use "providerName/model"'}
140
+
141
+ If a request fails with `The request body model must use "providerName/model"`,
142
+ the selected model reference is missing its provider prefix. Give every entry in
143
+ the model list a full `providerName/model` reference.
144
+
145
+ :::
146
+
147
+ ### Deploy to a fleet
148
+
149
+ To roll the configuration out to many devices, use the configuration window's
150
+ **Export** menu instead of **Apply locally**. It generates a `.mobileconfig`
151
+ profile for macOS MDM tools such as Jamf, a `.reg` policy file for Intune or
152
+ Group Policy, and related deployment artifacts. Managed configuration takes
153
+ precedence over local settings, so users can't point the app at a different
154
+ endpoint. For the deployment workflow and the full configuration key reference,
155
+ see Anthropic's
156
+ [Deploy Claude Desktop with an LLM gateway](https://claude.com/docs/third-party/claude-desktop/gateway)
157
+ and [Deploy with MDM](https://claude.com/docs/third-party/claude-desktop/mdm).
@@ -37,7 +37,7 @@ The following capabilities are supported across providers:
37
37
  | Mistral | ✅ | ✅ | ❌ | ❌ |
38
38
  | xAI | ✅ | ✅ | ❌ | ❌ |
39
39
  | Bedrock Mantle | ✅ | ❌ | ✅ | ✅ |
40
- | Vertex AI | ✅ | ✅ | ❌ | |
40
+ | Vertex AI | ✅ | ✅ | ❌ | |
41
41
  | Zuplo Demo | ✅ | ❌ | ❌ | ❌ |
42
42
  | OpenAI-compatible (Custom) | ✅ | ✅ | ❌ | ❌ |
43
43
 
@@ -97,11 +97,15 @@ Two things make its setup different from every other provider:
97
97
  asks for both.
98
98
 
99
99
  Every Vertex model ID is publisher-qualified, so a model reference has two
100
- slashes: a provider named `vertexai` serves `vertexai/google/gemini-3.7-flash`
101
- and `vertexai/qwen/qwen3-coder-480b-a35b-instruct-maas`. Model availability
102
- varies by location—most Model Garden models are served only from the `global`
103
- location. Vertex also hosts Anthropic's Claude models, but on a different API
104
- surface that the gateway doesn't route to.
100
+ slashes: a provider named `vertexai` serves `vertexai/google/gemini-3.7-flash`,
101
+ `vertexai/qwen/qwen3-coder-480b-a35b-instruct-maas`, and
102
+ `vertexai/anthropic/claude-haiku-4-5@20251001`. Model availability varies by
103
+ location—most Model Garden models are served only from the `global` location,
104
+ and Google's regional endpoints serve Claude Sonnet 4.6 and earlier only, so
105
+ `global` is the location that serves every Claude model. Vertex's Claude models
106
+ serve the native Anthropic Messages API (`/v1/messages`) and nothing else: they
107
+ aren't available on `/v1/chat/completions`, and each one must be enabled in
108
+ Model Garden for your Google Cloud project before it answers.
105
109
 
106
110
  For prerequisites, Google Cloud setup, provider steps, code examples, and
107
111
  troubleshooting, see [Using Vertex AI](./vertex-ai.mdx).
@@ -63,9 +63,9 @@ list—so clients that can't set a model still work.
63
63
 
64
64
  ## Supported endpoints
65
65
 
66
- | Endpoint | Notes |
67
- | ---------------------- | --------------------------------------------------------------------------------------------------------------- |
68
- | `/v1/chat/completions` | Chat completions for every provider |
69
- | `/v1/embeddings` | Embeddings for every provider except Anthropic |
70
- | `/v1/responses` | OpenAI Responses API: OpenAI, and [Bedrock Mantle](./bedrock-mantle.mdx) OpenAI-compatible models that serve it |
71
- | `/v1/messages` | Anthropic Messages API: Anthropic, and [Bedrock Mantle](./bedrock-mantle.mdx) Claude models |
66
+ | Endpoint | Notes |
67
+ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
68
+ | `/v1/chat/completions` | Chat completions for every provider |
69
+ | `/v1/embeddings` | Embeddings for every provider except Anthropic |
70
+ | `/v1/responses` | OpenAI Responses API: OpenAI, and [Bedrock Mantle](./bedrock-mantle.mdx) OpenAI-compatible models that serve it |
71
+ | `/v1/messages` | Anthropic Messages API: Anthropic, and the Claude models of [Bedrock Mantle](./bedrock-mantle.mdx) and [Vertex AI](./vertex-ai.mdx) |
@@ -9,16 +9,19 @@ description:
9
9
  ---
10
10
 
11
11
  **Vertex AI** is Google Cloud's managed model platform. Adding it as a provider
12
- serves both the Gemini family and Vertex's Model Garden partner models—DeepSeek,
13
- Qwen, GLM, Kimi, MiniMax, Gemma, and GPT-OSS—to your [apps](./apps.mdx) through
14
- the [Universal API](./universal-api.mdx), running on your Google Cloud project
15
- and your Google Cloud billing.
12
+ serves the Gemini family, Vertex's Model Garden partner models—DeepSeek, Qwen,
13
+ GLM, Kimi, MiniMax, Gemma, and GPT-OSS—and Anthropic's Claude models to your
14
+ [apps](./apps.mdx) through the [Universal API](./universal-api.mdx), running on
15
+ your Google Cloud project and your Google Cloud billing.
16
16
 
17
17
  Chat completions go to Vertex's **OpenAI-compatible endpoint**, so the gateway
18
18
  forwards OpenAI-shaped requests without translating them. Embeddings work too,
19
19
  though Vertex has no OpenAI-compatible embeddings endpoint—the gateway
20
20
  translates those onto Vertex's own embedding APIs, which is invisible from your
21
- app. What sets this provider apart is how you connect it: the endpoint is
21
+ app. Claude models are different again: Vertex serves them on the native
22
+ **Anthropic Messages API**, so they're available on `/v1/messages` only—see
23
+ [Call Claude models on the Messages API](#call-claude-models-on-the-messages-api).
24
+ What sets this provider apart is how you connect it: the endpoint is
22
25
  per-location, the Google Cloud project is a separate setting, and the credential
23
26
  is a **service account key file**—not an API key.
24
27
 
@@ -53,9 +56,11 @@ provider named `vertexai` serves all of these:
53
56
  - `vertexai/qwen/qwen3-coder-480b-a35b-instruct-maas`
54
57
  - `vertexai/deepseek-ai/deepseek-v3.2-maas`
55
58
  - `vertexai/zai-org/glm-5-maas`
59
+ - `vertexai/anthropic/claude-haiku-4-5@20251001`
56
60
 
57
- Copy model IDs from the model picker rather than typing them—the `-maas` suffix
58
- and the publisher prefix are both part of the ID.
61
+ Copy model IDs from the model picker rather than typing them—the `-maas` suffix,
62
+ the `@` version on the dated Claude models, and the publisher prefix are all
63
+ part of the ID.
59
64
 
60
65
  ## How the gateway calls Vertex AI
61
66
 
@@ -79,6 +84,9 @@ bearer credential.
79
84
  <DiagramNode id="embed" variant="green">
80
85
  Vertex embedding APIs
81
86
  </DiagramNode>
87
+ <DiagramNode id="messages" variant="blue">
88
+ Anthropic Messages API (Claude)
89
+ </DiagramNode>
82
90
  </DiagramGroup>
83
91
  <DiagramEdge from="app" to="gateway" label="Universal API" />
84
92
  <DiagramEdge
@@ -89,6 +97,7 @@ bearer credential.
89
97
  />
90
98
  <DiagramEdge from="gateway" to="compat" label="chat completions" />
91
99
  <DiagramEdge from="gateway" to="embed" label="embeddings" />
100
+ <DiagramEdge from="gateway" to="messages" label="/v1/messages" />
92
101
  </Diagram>
93
102
 
94
103
  The request URL the gateway builds combines both settings you enter:
@@ -98,6 +107,14 @@ https://us-central1-aiplatform.googleapis.com
98
107
  /v1/projects/my-project-123/locations/us-central1/endpoints/openapi/chat/completions
99
108
  ```
100
109
 
110
+ For a Claude model the gateway calls Vertex's Anthropic publisher surface
111
+ instead, with the model in the URL:
112
+
113
+ ```
114
+ https://aiplatform.googleapis.com
115
+ /v1/projects/my-project-123/locations/global/publishers/anthropic/models/claude-haiku-4-5@20251001:rawPredict
116
+ ```
117
+
101
118
  The **location** lives in the hostname, which is why the provider dialog asks
102
119
  for a location instead of an endpoint URL. The **project** doesn't appear in the
103
120
  hostname at all—it appears only in the path—so it can't be derived from the
@@ -107,25 +124,30 @@ send your traffic and your spend to someone else's Google Cloud project.
107
124
 
108
125
  ## Supported endpoints
109
126
 
110
- | Endpoint | Vertex AI models |
111
- | ---------------------- | ---------------- |
112
- | `/v1/chat/completions` | ✅ Forwarded |
113
- | `/v1/embeddings` | ✅ Translated |
114
- | `/v1/responses` | ❌ |
115
- | `/v1/messages` | ❌ |
127
+ | Endpoint | Gemini and Model Garden models | Claude models |
128
+ | ---------------------- | ------------------------------ | ------------- |
129
+ | `/v1/chat/completions` | ✅ Forwarded | ❌ |
130
+ | `/v1/embeddings` | ✅ Translated | ❌ |
131
+ | `/v1/responses` | ❌ | ❌ |
132
+ | `/v1/messages` | ❌ | ✅ Native |
116
133
 
117
- Streaming (`stream: true`) works on chat completions.
134
+ Streaming (`stream: true`) works on chat completions and on Messages.
118
135
 
119
- The gateway rejects `/v1/responses` and `/v1/messages` requests for Vertex
120
- models with a `400` error before any upstream call, because Vertex serves
121
- neither the OpenAI Responses API nor the Anthropic Messages API.
136
+ The gateway's model catalog records which API serves each model, and the gateway
137
+ routes every request accordingly. It rejects a request for a model on an
138
+ endpoint that doesn't serve it with a `400` before any upstream call:
139
+ `/v1/responses` for every Vertex model, `/v1/messages` for Gemini and Model
140
+ Garden models, and `/v1/chat/completions` or `/v1/embeddings` for Claude
141
+ models—that last error names `/v1/messages` as the endpoint to use.
122
142
 
123
- :::note{title="Anthropic models on Vertex aren't supported"}
143
+ :::note{title="Claude models are Messages-only on Vertex"}
124
144
 
125
- Vertex also hosts Anthropic's Claude models, but on a different API surface than
126
- the one this provider uses. The gateway can't route to them. To use Claude
127
- models, add the [Anthropic](./providers.mdx) provider or
128
- [Bedrock Mantle](./bedrock-mantle.mdx).
145
+ Vertex serves Anthropic's Claude models on the native Anthropic Messages API,
146
+ not on its OpenAI-compatible endpoint, so the gateway doesn't translate chat
147
+ completions for them the way it does for Claude models on
148
+ [Bedrock Mantle](./bedrock-mantle.mdx). Use an Anthropic client and
149
+ `/v1/messages`—see
150
+ [Call Claude models on the Messages API](#call-claude-models-on-the-messages-api).
129
151
 
130
152
  :::
131
153
 
@@ -145,7 +167,14 @@ is not available in region 'us-central1'
145
167
  ```
146
168
 
147
169
  Set the provider's **Location** to `global` if you plan to use Model Garden
148
- models, or add a second Vertex provider for a specific region and route to
170
+ models or Claude models. Google's regional endpoints serve Claude Sonnet 4.6 and
171
+ earlier, only in the regions listed on each model's Model Garden card, and only
172
+ where the model is enabled for your project. Claude models newer than Sonnet 4.6
173
+ are served by the `global` endpoint (and by Google's `us` and `eu` multi-region
174
+ endpoints, which the gateway doesn't accept as a location yet). For a Claude
175
+ model in a location that doesn't serve it, or where it isn't enabled for your
176
+ project, Vertex answers a `400` saying the model "is not servable in region".
177
+ Alternatively, add a second Vertex provider for a specific region and route to
149
178
  whichever one serves the model you want.
150
179
 
151
180
  ## Before you begin
@@ -179,6 +208,16 @@ what the provider dialog asks for.
179
208
  1. Enable the **Vertex AI API** on the project, under **APIs & Services →
180
209
  Library**. Confirm billing is enabled for the project as well.
181
210
 
211
+ 1. To use Claude models, enable each one in **Vertex AI → Model Garden**: search
212
+ for "Claude", open the model card, and click **Enable** for the locations
213
+ your providers use—a model enabled for `global` only answers a `400` saying
214
+ it "is not servable in region" from a regional provider. Until a model is
215
+ enabled, Vertex answers every request for it with a `404` saying the model
216
+ "was not found or your project does not have access to it"—the same message
217
+ it gives a misspelled model ID. Some Claude models also require the project
218
+ to turn on data sharing for the `anthropic` publisher; the `403` Vertex
219
+ returns in that case names the setting.
220
+
182
221
  1. Create a service account under **IAM & Admin → Service Accounts**.
183
222
 
184
223
  1. Grant that service account the **Vertex AI User** (`roles/aiplatform.user`)
@@ -335,6 +374,41 @@ than a partial charge:
335
374
  API also accepts—is rejected, because Vertex has no way to represent it. Send
336
375
  the original text.
337
376
 
377
+ ### Call Claude models on the Messages API
378
+
379
+ Claude models serve the native
380
+ [Anthropic Messages API](./universal-api.mdx#supported-endpoints) at
381
+ `/v1/messages`, including streaming and `/v1/messages/count_tokens`. With the
382
+ Anthropic SDK, set `baseURL` to the app's URL _without_ `/v1`—the SDK appends
383
+ `/v1/messages` itself—and pass the app's API key as `authToken`, not `apiKey`:
384
+
385
+ ```ts
386
+ import Anthropic from "@anthropic-ai/sdk";
387
+
388
+ const client = new Anthropic({
389
+ baseURL:
390
+ "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e",
391
+ authToken: process.env.ZUPLO_APP_API_KEY, // apiKey would send x-api-key, which the gateway ignores
392
+ });
393
+
394
+ const message = await client.messages.create({
395
+ model: "vertexai/anthropic/claude-haiku-4-5@20251001",
396
+ max_tokens: 1024,
397
+ messages: [{ role: "user", content: "Say hi" }],
398
+ });
399
+ ```
400
+
401
+ The gateway takes care of what Vertex does differently from Anthropic's own API:
402
+ it addresses the model in the request URL and drops it from the body, adds the
403
+ `anthropic_version` field Vertex requires, and authenticates with the access
404
+ token it minted from your service account. Your request body is otherwise
405
+ forwarded as-is, so system prompts, tool use, and streaming work as they do
406
+ against Anthropic directly. Client headers such as `anthropic-beta` pass
407
+ through, narrowed to the values Vertex accepts.
408
+
409
+ Claude models aren't available on `/v1/chat/completions`—a request there returns
410
+ a `400` that points at `/v1/messages`.
411
+
338
412
  ## Troubleshooting
339
413
 
340
414
  **The dialog rejects your credential.** Vertex uses a service account, not an
@@ -359,9 +433,11 @@ permissions, so it's easy to mistake for a credential problem.
359
433
  project than the one configured on the provider. Grant the role on the same
360
434
  project you entered as the **Google Cloud Project ID**.
361
435
 
362
- **A request fails with `400` saying the model isn't available in the region.**
363
- The model isn't served from your provider's location. Most Model Garden models
364
- are global-only—see
436
+ **A request fails with `400` saying the model isn't available in the region, or
437
+ that a Claude model "is not servable in region".** The model isn't served from
438
+ your provider's location, or isn't enabled for that location in your project.
439
+ Most Model Garden models are global-only, and Claude models are served from
440
+ `global` and the regions on each model's card—see
365
441
  [Model availability](#model-availability-depends-on-the-location). Set the
366
442
  provider's **Location** to `global`, or use a provider that points at a location
367
443
  serving that model.
@@ -370,10 +446,28 @@ serving that model.
370
446
  at most 250 inputs per request and text input only. See
371
447
  [Embeddings](#embeddings).
372
448
 
373
- **A `/v1/responses` or `/v1/messages` request fails with `400`.** Vertex's
374
- OpenAI-compatible endpoint serves neither API. Use `/v1/chat/completions`, or
375
- another provider for those endpoints—see
376
- [Supported endpoints](#supported-endpoints).
449
+ **A `/v1/responses` request fails with `400`.** Vertex serves the OpenAI
450
+ Responses API for none of its models. Use `/v1/chat/completions`, or another
451
+ provider—see [Supported endpoints](#supported-endpoints).
452
+
453
+ **A `/v1/messages` request for a Gemini or Model Garden model fails with
454
+ `400`.** Only Claude models serve the Messages API on Vertex. Use
455
+ `/v1/chat/completions` for the others.
456
+
457
+ **A Claude model fails with `400` on `/v1/chat/completions`.** Claude models are
458
+ Messages-only on Vertex. Send the request to `/v1/messages` with an Anthropic
459
+ client—see
460
+ [Call Claude models on the Messages API](#call-claude-models-on-the-messages-api).
461
+
462
+ **A Claude request fails with `404` saying the model "was not found or your
463
+ project does not have access to it".** Either the model isn't enabled in Model
464
+ Garden for your project (see [Set up Google Cloud](#set-up-google-cloud)) or the
465
+ model ID is wrong. Enabling a model applies to every location; a location that
466
+ doesn't serve the model is the separate `400` described above.
467
+
468
+ **A Claude request fails with `403` about data sharing.** Some Claude models
469
+ require the project to turn on data sharing for the `anthropic` publisher. The
470
+ error names the `setPublisherModelConfig` setting to change.
377
471
 
378
472
  ## Next steps
379
473
 
@@ -153,6 +153,8 @@ file-based configuration.
153
153
  ## Related
154
154
 
155
155
  - [Connect MCP clients overview](./overview.mdx)
156
+ - To route Claude Desktop's model requests through Zuplo instead, see the
157
+ [Claude Desktop AI Gateway integration](../../ai-gateway/integrations/claude-desktop.mdx)
156
158
  - Anthropic's official guide:
157
159
  [Connect to remote MCP servers](https://modelcontextprotocol.io/docs/develop/connect-remote-servers)
158
160
  - Anthropic's setup article:
@@ -160,7 +160,8 @@ served on the OpenAI API, and `/v1/messages` one served on the Anthropic API. A
160
160
  selection qualifies when its Provider Assignment is backed by that provider
161
161
  type, or when the provider catalog declares the selected model's dialect as that
162
162
  format — Bedrock Mantle serves its `openai`-dialect models on `/v1/responses`
163
- and its `anthropic`-dialect models on `/v1/messages`. Provider Names may be
163
+ and its `anthropic`-dialect models on `/v1/messages`, and Vertex AI serves its
164
+ `anthropic`-dialect Claude models on `/v1/messages`. Provider Names may be
164
165
  custom labels; validation never infers anything from the label or the model
165
166
  name, and a model the catalog does not declare is rejected.
166
167
 
@@ -121,5 +121,10 @@ When configured, this enables OAuth clients to find metadata information about
121
121
  how to interact with your OAuth 2.0 protected resources according to
122
122
  [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
123
123
 
124
+ When the plugin is configured with `scopesSupported`, the 401 response also
125
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
126
+ MCP clients request exactly the scopes your resource expects instead of every
127
+ scope the authorization server advertises.
128
+
124
129
  See [this document](/docs/articles/oauth-authentication) for more information
125
130
  about OAuth authorization in Zuplo.
@@ -56,7 +56,7 @@
56
56
  "type": "boolean",
57
57
  "default": false,
58
58
  "x-advanced": true,
59
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
59
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
60
60
  }
61
61
  }
62
62
  }
@@ -81,5 +81,10 @@ When configured, this enables OAuth clients to find metadata information about
81
81
  how to interact with your OAuth 2.0 protected resources according to
82
82
  [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
83
83
 
84
+ When the plugin is configured with `scopesSupported`, the 401 response also
85
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
86
+ MCP clients request exactly the scopes your resource expects instead of every
87
+ scope the authorization server advertises.
88
+
84
89
  See [this document](/docs/articles/oauth-authentication) for more information
85
90
  about OAuth authorization in Zuplo.
@@ -51,7 +51,7 @@
51
51
  "type": "boolean",
52
52
  "default": false,
53
53
  "x-advanced": true,
54
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
54
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
55
55
  }
56
56
  }
57
57
  }
@@ -0,0 +1,17 @@
1
+ ## OAuth 2.0 Protected Resource Metadata
2
+
3
+ The Cognito JWT Auth policy supports OAuth protected resource metadata
4
+ discovery. To enable this feature, set the `oAuthResourceMetadataEnabled` option
5
+ to `true` and add the
6
+ [`OAuthProtectedResourcePlugin` to `modules/zuplo.runtime.ts`](/docs/programmable-api/oauth-protected-resource-plugin).
7
+ When configured, this enables OAuth clients to find metadata information about
8
+ how to interact with your OAuth 2.0 protected resources according to
9
+ [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
10
+
11
+ When the plugin is configured with `scopesSupported`, the 401 response also
12
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
13
+ MCP clients request exactly the scopes your resource expects instead of every
14
+ scope the authorization server advertises.
15
+
16
+ See [this document](/docs/articles/oauth-authentication) for more information
17
+ about OAuth authorization in Zuplo.
@@ -56,7 +56,7 @@
56
56
  "type": "boolean",
57
57
  "default": false,
58
58
  "x-advanced": true,
59
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
59
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
60
60
  }
61
61
  }
62
62
  }
@@ -0,0 +1,17 @@
1
+ ## OAuth 2.0 Protected Resource Metadata
2
+
3
+ The Firebase JWT Auth policy supports OAuth protected resource metadata
4
+ discovery. To enable this feature, set the `oAuthResourceMetadataEnabled` option
5
+ to `true` and add the
6
+ [`OAuthProtectedResourcePlugin` to `modules/zuplo.runtime.ts`](/docs/programmable-api/oauth-protected-resource-plugin).
7
+ When configured, this enables OAuth clients to find metadata information about
8
+ how to interact with your OAuth 2.0 protected resources according to
9
+ [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
10
+
11
+ When the plugin is configured with `scopesSupported`, the 401 response also
12
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
13
+ MCP clients request exactly the scopes your resource expects instead of every
14
+ scope the authorization server advertises.
15
+
16
+ See [this document](/docs/articles/oauth-authentication) for more information
17
+ about OAuth authorization in Zuplo.
@@ -51,7 +51,7 @@
51
51
  "type": "boolean",
52
52
  "default": false,
53
53
  "x-advanced": true,
54
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
54
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
55
55
  }
56
56
  }
57
57
  }
@@ -0,0 +1,23 @@
1
+ ## OAuth 2.0 Protected Resource Metadata
2
+
3
+ The Okta JWT Auth policy supports OAuth protected resource metadata discovery.
4
+ To enable this feature, set the `oAuthResourceMetadataEnabled` option to `true`
5
+ and add the
6
+ [`OAuthProtectedResourcePlugin` to `modules/zuplo.runtime.ts`](/docs/programmable-api/oauth-protected-resource-plugin).
7
+ When configured, this enables OAuth clients to find metadata information about
8
+ how to interact with your OAuth 2.0 protected resources according to
9
+ [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
10
+
11
+ When the plugin is configured with `scopesSupported`, the 401 response also
12
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
13
+ MCP clients request exactly the scopes your resource expects instead of every
14
+ scope the authorization server advertises.
15
+
16
+ Okta custom authorization servers always advertise the `device_sso` and
17
+ `interclient_access` scopes in their own metadata and reject authorization
18
+ requests that combine them with your scopes (`illegal_scope_combination`). Set
19
+ `scopesSupported` on the plugin when this policy protects an MCP server, so
20
+ clients never fall back to that list.
21
+
22
+ See [this document](/docs/articles/oauth-authentication) for more information
23
+ about OAuth authorization in Zuplo.
@@ -56,7 +56,7 @@
56
56
  "type": "boolean",
57
57
  "default": false,
58
58
  "x-advanced": true,
59
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
59
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
60
60
  }
61
61
  }
62
62
  }
@@ -56,3 +56,21 @@ export async function myHandler(request: ZuploRequest, context: ZuploContext) {
56
56
  For a complete example of using the user object in a
57
57
  [RequestHandler](../handlers/custom-handler.md), see
58
58
  [Setting up JWT auth with Auth0](../policies/auth0-jwt-auth-inbound.md).
59
+
60
+ ## OAuth 2.0 Protected Resource Metadata
61
+
62
+ The OpenID JWT Auth policy supports OAuth protected resource metadata discovery.
63
+ To enable this feature, set the `oAuthResourceMetadataEnabled` option to `true`
64
+ and add the
65
+ [`OAuthProtectedResourcePlugin` to `modules/zuplo.runtime.ts`](/docs/programmable-api/oauth-protected-resource-plugin).
66
+ When configured, this enables OAuth clients to find metadata information about
67
+ how to interact with your OAuth 2.0 protected resources according to
68
+ [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
69
+
70
+ When the plugin is configured with `scopesSupported`, the 401 response also
71
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
72
+ MCP clients request exactly the scopes your resource expects instead of every
73
+ scope the authorization server advertises.
74
+
75
+ See [this document](/docs/articles/oauth-authentication) for more information
76
+ about OAuth authorization in Zuplo.
@@ -89,7 +89,7 @@
89
89
  "type": "boolean",
90
90
  "default": false,
91
91
  "x-advanced": true,
92
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
92
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
93
93
  }
94
94
  },
95
95
  "examples": [
@@ -84,5 +84,10 @@ When configured, this enables OAuth clients to find metadata information about
84
84
  how to interact with your OAuth 2.0 protected resources according to
85
85
  [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
86
86
 
87
+ When the plugin is configured with `scopesSupported`, the 401 response also
88
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
89
+ MCP clients request exactly the scopes your resource expects instead of every
90
+ scope the authorization server advertises.
91
+
87
92
  See [this document](/docs/articles/oauth-authentication) for more information
88
93
  about OAuth authorization in Zuplo.
@@ -56,7 +56,7 @@
56
56
  "type": "boolean",
57
57
  "default": false,
58
58
  "x-advanced": true,
59
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
59
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
60
60
  }
61
61
  }
62
62
  }
@@ -27,3 +27,8 @@ to `true` and add the
27
27
  When configured, this enables OAuth clients to find metadata information about
28
28
  how to interact with your OAuth 2.0 protected resources according to
29
29
  [`RFC 9728`](https://datatracker.ietf.org/doc/html/rfc9728).
30
+
31
+ When the plugin is configured with `scopesSupported`, the 401 response also
32
+ lists those scopes in the `scope` parameter of its `WWW-Authenticate` header, so
33
+ MCP clients request exactly the scopes your resource expects instead of every
34
+ scope the authorization server advertises.
@@ -66,7 +66,7 @@
66
66
  "type": "boolean",
67
67
  "default": false,
68
68
  "x-advanced": true,
69
- "description": "Flag that determines whether OAuth protected resource metadata is enabled."
69
+ "description": "Enables OAuth 2.0 Protected Resource Metadata discovery (RFC 9728). When `true`, requests without a bearer token receive a 401 whose `WWW-Authenticate` header points `resource_metadata` at the `/.well-known/oauth-protected-resource` document for the request path and, when the `OAuthProtectedResourcePlugin` declares `scopesSupported`, lists those scopes in `scope`. Requires the `OAuthProtectedResourcePlugin` in `zuplo.runtime.ts` or a user-defined route at that path."
70
70
  }
71
71
  }
72
72
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "7.6.9",
3
+ "version": "7.7.0",
4
4
  "type": "module",
5
5
  "description": "The official Zuplo CLI for local development and platform management",
6
6
  "homepage": "https://zuplo.com/docs/cli/overview",
@@ -32,9 +32,9 @@
32
32
  "zuplo": "zuplo.js"
33
33
  },
34
34
  "dependencies": {
35
- "@zuplo/cli": "7.6.9",
36
- "@zuplo/core": "7.6.9",
37
- "@zuplo/runtime": "7.6.9",
38
- "@zuplo/test": "7.6.9"
35
+ "@zuplo/cli": "7.7.0",
36
+ "@zuplo/core": "7.7.0",
37
+ "@zuplo/runtime": "7.7.0",
38
+ "@zuplo/test": "7.7.0"
39
39
  }
40
40
  }