zuplo 7.8.6 → 7.8.8

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.
Files changed (63) hide show
  1. package/docs/ai-gateway/custom-policies.mdx +2 -1
  2. package/docs/ai-gateway/usage-limits.mdx +2 -2
  3. package/docs/api-management/overview.md +2 -2
  4. package/docs/articles/add-api-to-backstage.mdx +4 -3
  5. package/docs/articles/api-key-consumer-bucket-portal-ui.mdx +1 -1
  6. package/docs/articles/api-key-management.mdx +1 -1
  7. package/docs/articles/migrate-from-apigee.md +3 -3
  8. package/docs/articles/migrate-from-aws-api-gateway.md +3 -3
  9. package/docs/articles/migrate-from-azure-apim.md +3 -3
  10. package/docs/articles/migrate-from-kong.md +3 -3
  11. package/docs/articles/source-control-setup-github.mdx +2 -2
  12. package/docs/cli/create-zuplo-api.mdx +4 -4
  13. package/docs/cli/openapi-merge.mdx +1 -1
  14. package/docs/cli/openapi-merge.partial.mdx +1 -1
  15. package/docs/concepts/ai-gateway.mdx +1 -1
  16. package/docs/concepts/mcp.mdx +4 -4
  17. package/docs/dedicated/architecture.mdx +1 -1
  18. package/docs/errors/not-found.mdx +1 -1
  19. package/docs/getting-started/ai-gateway/portal.mdx +181 -0
  20. package/docs/getting-started/dev-portal/agent.mdx +148 -0
  21. package/docs/getting-started/dev-portal/index.mdx +26 -0
  22. package/docs/getting-started/dev-portal/local.mdx +213 -0
  23. package/docs/getting-started/dev-portal/portal.mdx +146 -0
  24. package/docs/{articles/step-3-add-api-key-auth.mdx → getting-started/gateway/add-api-key-auth/index.mdx} +30 -24
  25. package/docs/{articles/step-3-add-api-key-auth-local.mdx → getting-started/gateway/add-api-key-auth/local.mdx} +26 -21
  26. package/docs/{articles/step-2-add-rate-limiting.mdx → getting-started/gateway/add-rate-limiting/index.mdx} +20 -14
  27. package/docs/{articles/step-2-add-rate-limiting-local.mdx → getting-started/gateway/add-rate-limiting/local.mdx} +22 -15
  28. package/docs/getting-started/gateway/agent.mdx +198 -0
  29. package/docs/{articles/step-4-deploying-to-the-edge.mdx → getting-started/gateway/deploy-to-the-edge/index.mdx} +36 -27
  30. package/docs/{articles/step-4-deploying-to-the-edge-local.mdx → getting-started/gateway/deploy-to-the-edge/local.mdx} +46 -18
  31. package/docs/{articles/step-5-dynamic-rate-limiting.mdx → getting-started/gateway/dynamic-rate-limiting/index.mdx} +21 -12
  32. package/docs/{articles/step-5-dynamic-rate-limiting-local.mdx → getting-started/gateway/dynamic-rate-limiting/local.mdx} +21 -12
  33. package/docs/getting-started/gateway/index.mdx +24 -0
  34. package/docs/{articles/step-1-setup-basic-gateway.mdx → getting-started/gateway/setup-a-basic-gateway/index.mdx} +31 -22
  35. package/docs/{articles/step-1-setup-basic-gateway-local.mdx → getting-started/gateway/setup-a-basic-gateway/local.mdx} +22 -16
  36. package/docs/getting-started/index.mdx +25 -0
  37. package/docs/getting-started/mcp-gateway/agent.mdx +161 -0
  38. package/docs/getting-started/mcp-gateway/index.mdx +25 -0
  39. package/docs/{mcp-gateway/quickstart-local.mdx → getting-started/mcp-gateway/local.mdx} +35 -31
  40. package/docs/{mcp-gateway/quickstart.mdx → getting-started/mcp-gateway/portal.mdx} +64 -48
  41. package/docs/getting-started/mcp-server/agent.mdx +152 -0
  42. package/docs/getting-started/mcp-server/index.mdx +25 -0
  43. package/docs/{articles/mcp-quickstart-local.mdx → getting-started/mcp-server/local.mdx} +24 -13
  44. package/docs/{articles/mcp-quickstart.mdx → getting-started/mcp-server/portal.mdx} +35 -15
  45. package/docs/getting-started/migrate/agent.mdx +129 -0
  46. package/docs/getting-started/migrate/index.mdx +25 -0
  47. package/docs/getting-started/migrate/local.mdx +141 -0
  48. package/docs/getting-started/migrate/portal.mdx +129 -0
  49. package/docs/home.mdx +6 -0
  50. package/docs/mcp-gateway/connect-clients/chatgpt.mdx +2 -1
  51. package/docs/mcp-gateway/connect-clients/claude-code.mdx +2 -1
  52. package/docs/mcp-gateway/connect-clients/claude-desktop.mdx +2 -1
  53. package/docs/mcp-gateway/connect-clients/cursor.mdx +2 -1
  54. package/docs/mcp-gateway/connect-clients/vs-code.mdx +2 -1
  55. package/docs/mcp-gateway/how-it-works.mdx +2 -2
  56. package/docs/mcp-gateway/how-to/connect-upstream-api-key.mdx +4 -3
  57. package/docs/mcp-gateway/how-to/curate-tools.mdx +3 -2
  58. package/docs/mcp-gateway/overview.mdx +3 -3
  59. package/docs/policies/ai-gateway-smart-router-inbound/doc.md +14 -0
  60. package/docs/policies/akamai-ai-firewall-v2-inbound/doc.md +7 -0
  61. package/package.json +5 -5
  62. package/docs/ai-gateway/getting-started.mdx +0 -307
  63. package/docs/dev-portal/local-development.mdx +0 -72
@@ -133,9 +133,9 @@ MCP client discovers and authenticates against it without custom configuration.
133
133
 
134
134
  ## Next steps
135
135
 
136
- - [Try the quickstart](./quickstart.mdx) — add the MCP Gateway plugin to a Zuplo
137
- project, configure Auth0, expose one upstream MCP server, and connect Claude
138
- Desktop.
136
+ - [Try the quickstart](../getting-started/mcp-gateway/portal.mdx) — add the MCP
137
+ Gateway plugin to a Zuplo project, configure Auth0, expose one upstream MCP
138
+ server, and connect Claude Desktop.
139
139
  - [Browse the how-to guides](./connect-clients/overview.mdx) — connect specific
140
140
  MCP clients, add more upstreams, curate tools, configure upstream OAuth.
141
141
  - [Read how it works](./how-it-works.mdx) — the request lifecycle, the two OAuth
@@ -35,6 +35,20 @@ callers with API keys. It is sent as `Authorization: Bearer`. If you leave it
35
35
  unset while the classifier app still checks keys, that app answers `401` and the
36
36
  gateway logs which policy to add.
37
37
 
38
+ `classifierAppID` must not be this app's own id, and the classifier application
39
+ must not run this policy itself. Both are rejected with a `ConfigurationError`
40
+ instead of silently skipping or failing open, so a misconfigured routing loop —
41
+ within one app, or between two — is never mistaken for smart routing that is
42
+ simply doing nothing.
43
+
44
+ The classifier application must not run
45
+ [Akamai AI Firewall](/docs/policies/akamai-ai-firewall-v2-inbound) either. That
46
+ firewall would inspect the internal classification call as if it were a
47
+ completion request — scanning the classifier's system prompt and JSON-only
48
+ response for injection/malicious-content patterns — and a resulting denial makes
49
+ Smart Router fail open, indistinguishable from smart routing quietly doing
50
+ nothing. This is rejected with a `ConfigurationError` for the same reason.
51
+
38
52
  ## Example
39
53
 
40
54
  ```json
@@ -34,6 +34,13 @@ When an application chain entry should inherit these credentials, omit the
34
34
  entry's `options`. Entry options replace the declaration's complete options
35
35
  object; they do not merge with it.
36
36
 
37
+ Do not add this policy to the inbound chain of an app used as a
38
+ [Smart Router](/docs/policies/ai-gateway-smart-router-inbound) classifier
39
+ (`classifierAppID`). The firewall would inspect Smart Router's internal
40
+ classification call as if it were a completion request, and Smart Router fails
41
+ open on a resulting denial — so this combination is rejected with a
42
+ `ConfigurationError` instead of silently degrading classification.
43
+
37
44
  ## Options
38
45
 
39
46
  | Option | Default | What it does |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "7.8.6",
3
+ "version": "7.8.8",
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.8.6",
36
- "@zuplo/core": "7.8.6",
37
- "@zuplo/runtime": "7.8.6",
38
- "@zuplo/test": "7.8.6"
35
+ "@zuplo/cli": "7.8.8",
36
+ "@zuplo/core": "7.8.8",
37
+ "@zuplo/runtime": "7.8.8",
38
+ "@zuplo/test": "7.8.8"
39
39
  }
40
40
  }
@@ -1,307 +0,0 @@
1
- ---
2
- title: Zuplo AI Gateway Getting Started
3
- sidebar_label: Getting Started
4
- description:
5
- Set up your first AI Gateway project. Configure an AI provider, create a team
6
- and an app, review the app's policy chain, and make your first LLM request
7
- through Zuplo.
8
- ---
9
-
10
- This guide walks you through setting up your first AI Gateway project, from
11
- creating the project to making your first LLM request through Zuplo.
12
-
13
- A Zuplo account contains your members and one or more projects. The AI Gateway
14
- you create in this guide is a Zuplo project; its providers, teams, and apps all
15
- belong to that project. See
16
- [Role Permissions](../articles/accounts/roles-and-permissions.mdx) for how Zuplo
17
- account, Zuplo project, and AI Gateway team roles control access.
18
-
19
- ## Prerequisites
20
-
21
- - A Zuplo account (sign up free at [zuplo.com](https://zuplo.com))
22
- - An API key for at least one LLM provider (OpenAI, Anthropic, Google, Mistral,
23
- xAI, etc.)—or none at all, if you start with the free
24
- [Zuplo Demo provider](./providers.mdx#zuplo-demo)
25
-
26
- <Stepper>
27
-
28
- 1. **Create an AI Gateway project**
29
-
30
- Sign in to the [Zuplo Portal](https://portal.zuplo.com), navigate to
31
- **Projects**, and click **New Project**. Choose **AI Gateway**, give your
32
- project a name (for example, "MyCompany AI Gateway"), and click **Create
33
- Project**.
34
-
35
- The portal shows **Setting up your gateway…** while it provisions the
36
- project. When that's done, the project homepage opens with a setup checklist
37
- for a provider, a team, and an app—the same path as this guide. Follow these
38
- steps; you can tick the checklist as you go or ignore it. The gateway is
39
- already deployed, so you can continue with this guide.
40
-
41
- :::note
42
-
43
- Connect a repository later if you want to write
44
- [custom policies](./custom-policies.mdx) or manage the gateway's source in
45
- Git. Open
46
- [**Settings → Source Control**](https://portal.zuplo.com/+/account/project/ai/settings/source-control).
47
- See [Source Control](./source-control.mdx).
48
-
49
- :::
50
-
51
- 2. **Configure a provider**
52
-
53
- Providers are the LLM services (such as OpenAI or Anthropic) that your apps
54
- use. You configure these once as an administrator, and your team members use
55
- them without needing direct access to provider API keys.
56
-
57
- Open
58
- [**Settings → AI Providers**](https://portal.zuplo.com/+/account/project/ai/settings/data-models)
59
- and click **Add Provider**. Select your AI provider (for example,
60
- **OpenAI**), paste your provider's API key, and select which models to make
61
- available. The **Provider Name** field fills in automatically based on the
62
- provider you selected—`openai`, for example. Click **Create**.
63
-
64
- :::caution{title="The provider name becomes the model prefix"}
65
-
66
- Apps reference this provider's models as `providerName/model`, so the
67
- provider name is the prefix in every model string—a provider named `openai`
68
- serves `openai/gpt-5-mini`. The pre-filled name is usually what you want. To
69
- use your own, set it now—the name is permanent after creation—and keep it
70
- short and lowercase.
71
-
72
- :::
73
-
74
- Repeat for additional providers. See [AI Providers](./providers.mdx) for the
75
- full list of supported providers, including OpenAI-compatible custom
76
- providers.
77
-
78
- 3. **Create a team**
79
-
80
- Teams organize users and carry their own budget rules and policy templates.
81
- Even if you're starting solo, you need at least one team.
82
-
83
- Open the **Apps & Teams** tab and click **New Team**. Name your team (for
84
- example, "Root" or your company name), choose an icon, and click **Create
85
- Team**. This is your first team, so there's no parent picker yet—it appears
86
- on later teams, letting you nest them.
87
-
88
- To set gateway-wide spending limits across this Zuplo project, open the
89
- gateway's **Settings → Usage Limits**. Team budgets—shared and
90
- per-expression—are set on the team's **Usage & Limits** tab. See
91
- [Usage Limits](./usage-limits.mdx). Gateway and team limits apply to every
92
- app regardless of its policy chain.
93
-
94
- 4. **Create an app**
95
-
96
- Apps represent individual software applications or services that call the AI
97
- Gateway. Each app gets its own unique URL and API key.
98
-
99
- In the **Apps & Teams** tab, select the team you just created and click
100
- **Create App** in the team's header. Give the app a descriptive name (for
101
- example, "Tennis Chat") and confirm the team that owns it. That's the whole
102
- dialog—models, app-specific budgets, and other behavior are configured on the
103
- app's policy chain in the next step.
104
-
105
- :::tip
106
-
107
- If the app's team has a policy template, the new app starts with the
108
- template's policy chain already in place. See
109
- [Policy Templates](./policy-templates.mdx).
110
-
111
- :::
112
-
113
- 5. **Review the app's policy chain**
114
-
115
- The portal opens the app's **Policies** tab, which shows the app's policy
116
- chain—the ordered list of policies that run on each request. No policy is
117
- required: an app with an empty chain works immediately, and each request
118
- picks its own model as `providerName/model`, from any model your providers
119
- expose.
120
-
121
- To restrict that, click **Add policy**, select **Model Filtering**, and give
122
- it an allow list of models you enabled in the provider step—for example
123
- `openai/gpt-5-mini` if you added OpenAI, or `zuplodemo/pirate` if you are
124
- using only Zuplo Demo. Requests may then use only listed models, and the
125
- first entry becomes the default when a request omits `model`.
126
-
127
- :::caution{title="An unrestricted app can reach every model you configured"}
128
-
129
- Without Model Filtering, an app may call any model available through the
130
- providers configured for this Zuplo project, including expensive ones. Add
131
- Model Filtering for any app that you want limited to a specific set.
132
-
133
- :::
134
-
135
- This is also where you add app-specific budgets, semantic caching,
136
- guardrails, and any custom policies. Changes to the chain apply within about
137
- a minute—no redeploy needed. See [Policy Chains](./policy-chains.mdx).
138
-
139
- 6. **Get the app's URL and API key**
140
-
141
- The app's **API URL** is shown in full at the top of the app page, and its
142
- key lives on the app's **API Key** tab. The API URL is the gateway's hostname
143
- plus the app's ID—for example
144
- `https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e`.
145
- Copy both rather than constructing them.
146
-
147
- Client libraries expect a base URL ending in `/v1`, so append it: the OpenAI
148
- SDK examples below use
149
- `https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1`
150
- as a stand-in, and requests land on paths like `/v1/chat/completions`.
151
-
152
- :::tip
153
-
154
- Expand the API URL to get the exact endpoint for each service the gateway
155
- mounts—**Chat Completions**, **Responses**, and **Messages**—and copy the one
156
- your client needs instead of assembling it by hand.
157
-
158
- :::
159
-
160
- :::note
161
-
162
- The gateway checks the key only after you add the
163
- [authentication policy](./policy-chains.mdx#authentication) to the app's
164
- chain. Until then the gateway identifies the app from the `{app_id}` segment
165
- of the URL and accepts the request without a key. The examples below send the
166
- key so they keep working once you add the policy.
167
-
168
- :::
169
-
170
- Export the key so the samples below can read it:
171
-
172
- ```bash
173
- export ZUPLO_APP_API_KEY="<the API key from the app page>"
174
- ```
175
-
176
- 7. **Send your first request from the Playground**
177
-
178
- Click **Playground** in the app's header to open it. It chats with the app's
179
- own gateway URL and API key, so it exercises the same policy chain your code
180
- hits—without wiring up a client first. The button sits on every app tab, so
181
- you can try a request while editing policies without losing your place.
182
-
183
- Pick a model from the selector, optionally set a system prompt, and send a
184
- message. The playground shows the cURL for the next request, and **Copy
185
- cURL** puts it on your clipboard to run in a terminal or adapt it for your
186
- client. Expand any reply to inspect the request and the raw response. Closing
187
- the playground keeps the conversation, so you can reopen it and carry on.
188
-
189
- </Stepper>
190
-
191
- You now have a working AI Gateway: a provider, a team, an app, and a chat
192
- completion through the app's URL.
193
-
194
- ## Integrate with your own code
195
-
196
- Once the Playground works, configure your own code with the same URL and key.
197
-
198
- These examples use the official
199
- [Node.js OpenAI SDK](https://platform.openai.com/docs/libraries/node-js-library);
200
- run `npm install openai` first. For other clients, see the integration guides
201
- for the [OpenAI SDK](./integrations/openai.mdx),
202
- [AI SDK](./integrations/ai-sdk.mdx), and
203
- [LangChain](./integrations/langchain.mdx).
204
-
205
- ### Before: direct provider integration (sample.mjs)
206
-
207
- ```javascript
208
- import OpenAI from "openai";
209
-
210
- // Direct OpenAI
211
- const openai = new OpenAI({
212
- apiKey: process.env.OPENAI_API_KEY,
213
- });
214
-
215
- const completion = await openai.chat.completions.create({
216
- model: "gpt-5-mini",
217
- messages: [{ role: "user", content: "Hello!" }],
218
- });
219
-
220
- console.log(completion.choices[0].message.content);
221
- ```
222
-
223
- ### After: using the Zuplo AI Gateway (sample.mjs)
224
-
225
- ```javascript
226
- import OpenAI from "openai";
227
-
228
- // Through the AI Gateway
229
- const openai = new OpenAI({
230
- apiKey: process.env.ZUPLO_APP_API_KEY,
231
- baseURL: process.env.ZUPLO_APP_BASE_URL,
232
- });
233
-
234
- const completion = await openai.chat.completions.create({
235
- model: "openai/gpt-5-mini",
236
- messages: [{ role: "user", content: "Hello!" }],
237
- });
238
-
239
- console.log(completion.choices[0].message.content);
240
- ```
241
-
242
- Run the example with `node sample.mjs`.
243
-
244
- ### Changes to make
245
-
246
- 1. **URL**: Replace your provider's URL with your app's gateway URL from the app
247
- page
248
- 2. **API Key**: Use your app's API key instead of the provider's key—the gateway
249
- checks it once the authentication policy applies
250
- 3. **Model**: Reference models as `providerName/model` so the gateway knows
251
- which provider to route to
252
- 4. **Everything else stays the same**: The request format remains compatible
253
- with OpenAI's API
254
-
255
- ## Verify your setup
256
-
257
- ### Make your first request
258
-
259
- Send a test request through your gateway, using your app's URL and API key:
260
-
261
- ```bash
262
- curl https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1/chat/completions \
263
- -H "Authorization: Bearer YOUR_APP_API_KEY" \
264
- -H "Content-Type: application/json" \
265
- -d '{
266
- "model": "openai/gpt-5-mini",
267
- "messages": [{"role": "user", "content": "Hello, world!"}]
268
- }'
269
- ```
270
-
271
- ### Check your usage
272
-
273
- 1. Open the
274
- [**Apps & Teams**](https://portal.zuplo.com/+/account/project/ai/apps) tab of
275
- your AI Gateway project
276
- 2. Click on your app
277
- 3. The app's **Overview** tab shows:
278
- - **Daily Usage** and **Monthly Usage**—spend, tokens, and requests, with
279
- progress against any configured limits
280
- - A **Metrics** frame with request count, token usage, and cost over time
281
- 4. Click **View in Analytics** on the Metrics frame for the full request-level
282
- breakdown, already filtered to this app.
283
-
284
- Your test request appears with token usage and performance metrics.
285
-
286
- ## Next steps
287
-
288
- - [Policy Chains](./policy-chains.mdx): add app-specific budgets, semantic
289
- caching, and guardrails to your app's chain
290
- - [Custom Policies](./custom-policies.mdx): write your own policy and add it to
291
- an app's chain
292
- - [Source Control](./source-control.mdx): connect a Git repository when you want
293
- to edit the gateway's source or write custom policies
294
- - [Policy Templates](./policy-templates.mdx): give every new app in a team a
295
- consistent starting chain
296
- - [Usage Limits](./usage-limits.mdx): set spending limits for the gateway,
297
- teams, and apps
298
-
299
- ## Common issues
300
-
301
- | Symptom | Fix |
302
- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
303
- | "Authentication failed" error | Verify you're using your app's API key, not your provider's key. This error appears only when the authentication policy applies |
304
- | 404 "Unsupported AI Gateway endpoint" | The path must end with a supported `/v1/...` operation—usually the URL is missing its `/v1` segment. Use the app's API URL plus `/v1/chat/completions`, for example |
305
- | 400 error asking for `providerName/model` | Prefix the model with the provider name configured in the portal—`openai/gpt-5-mini`, not `gpt-5-mini` |
306
- | 403 error listing the allowed models | The app's Model Filtering policy doesn't include the requested model; add it on the app's Policies tab or use a listed one |
307
- | Budget limit reached immediately | Check the gateway and team limits, which always apply, plus the app's Budgets and Costs policy; any level's limit can block the request |
@@ -1,72 +0,0 @@
1
- ---
2
- title: Local Development
3
- description:
4
- Learn how to work on the Dev Portal locally with live updates and hot
5
- reloading.
6
- ---
7
-
8
- Developing the Dev Portal locally is straightforward and provides a great
9
- developer experience with live updates and hot reloading. Follow these steps to
10
- get started.
11
-
12
- ## Prerequisites
13
-
14
- - [Node.js](https://nodejs.org) `>=v24.0.0`
15
- - [Git](https://git-scm.com)
16
-
17
- ## Getting Started
18
-
19
- <Stepper>
20
-
21
- 1. **Clone the Zuplo repository**
22
-
23
- ```bash
24
- git clone <repository-url>
25
- ```
26
-
27
- 1. **Install dependencies**
28
-
29
- ```bash
30
- npm install
31
- ```
32
-
33
- 1. **Navigate to the docs directory**
34
-
35
- ```bash
36
- cd docs
37
- ```
38
-
39
- 1. **Start the development server**
40
-
41
- ```bash
42
- npm run dev
43
- ```
44
-
45
- 1. **Open your browser**
46
-
47
- Navigate to [http://localhost:3000](http://localhost:3000) to see your Dev
48
- Portal.
49
-
50
- </Stepper>
51
-
52
- ## Development Workflow
53
-
54
- Once the development server is running, you can:
55
-
56
- - **Edit content**: Make changes to any Markdown, MDX, or configuration files
57
- - **Live updates**: Your browser will automatically refresh when you save
58
- changes
59
- - **Hot reloading**: Most changes will be reflected instantly without a full
60
- page reload
61
- - **Real-time feedback**: See your changes immediately as you develop
62
-
63
- The development server watches for file changes and automatically rebuilds the
64
- site, providing an excellent developer experience for creating and maintaining
65
- your documentation.
66
-
67
- ## What's Next?
68
-
69
- - Learn about [writing content](./zudoku/writing.mdx)
70
- - Check out [the configuration file](./zudoku/configuration/overview)
71
- - See how you can
72
- [customize the Dev Portal](./zudoku/customization/colors-theme)