zuplo 6.70.28 → 6.70.30

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.
@@ -17,6 +17,15 @@ authentication for your MCP Server.
17
17
 
18
18
  This guide will assume that you already have a working Auth0 account and tenant.
19
19
 
20
+ :::note
21
+
22
+ This guide is an example of how you can set up your Auth0 tenant for MCP OAuth
23
+ support. It is recommended that you consult the
24
+ [Auth0 documentation](https://auth0.com/ai/docs/mcp/guides/registering-your-mcp-client-application)
25
+ for more information.
26
+
27
+ :::
28
+
20
29
  ### Create an Auth0 API
21
30
 
22
31
  First, you will need to create an Auth0 API. This API will be used to represent
@@ -30,18 +39,6 @@ your MCP Server.
30
39
  `https://my-gateway.zuplo.dev/mcp`. **The trailing slash isn't required.**
31
40
  3. Leave the **Signing Algorithm** as `RS256` and click **Create**.
32
41
 
33
- ### Enable Dynamic Client Registration
34
-
35
- Next, you will need to enable Dynamic Client Registration for the API you just
36
- created.
37
-
38
- 1. In the Auth0 dashboard, navigate to the tenant settings in **Settings** on
39
- the left hand sidebar.
40
- 2. Navigate to the **Advanced** tab.
41
- 3. Scroll down to the **Settings** section and check the toggle for **OIDC
42
- Dynamic Application Registration**. Also ensure that the **Enable Application
43
- Connections** toggle is checked.
44
-
45
42
  ### Configure the Connection
46
43
 
47
44
  Next, you will need to configure an Auth0 Connection for your API.
@@ -80,12 +77,45 @@ Next, you will need to configure an Auth0 Connection for your API.
80
77
  --data '{ "is_domain_connection": true }'
81
78
  ```
82
79
 
83
- 5. Configure a Default Audience by clicking on Settings > General. Then in the
84
- API Authorization Settings, modify the Default Audience. See the Auth0 doc on
85
- [API Authorization Settings](https://auth0.com/docs/get-started/tenant-settings#api-authorization-settings)
86
- for more information on how to configure a default audience. The audience
87
- should be the identifier of the API you created in
88
- [Create an Auth0 API](#create-an-auth0-api).
80
+ 5. Enable Resource Parameter Compatibility Profile. See the
81
+ [Auth0 tenant settings docs](https://auth0.com/docs/get-started/tenant-settings)
82
+ for more information.
83
+
84
+ After completing these changes to your Auth0 tenant, you will need to enable
85
+ CIMD or DCR (or both) on your Auth0 tenant.
86
+
87
+ ### Enable CIMD for MCP OAuth
88
+
89
+ To use CIMD for MCP OAuth authentication, do the following:
90
+
91
+ 1. In the Auth0 dashboard, navigate to the tenant settings in **Settings** on
92
+ the left hand sidebar.
93
+ 2. Navigate to the **Advanced** tab.
94
+ 3. Scroll down to the **Settings** section and check the toggle for **Client ID
95
+ Metadata Document (CIMD) Registration**.
96
+ 4. Register the MCP clients via their public CIMD client data metadata URL by
97
+ clicking "Create Application" and then "Import from URL". Note that for all
98
+ the MCP clients you want to support, you will need to obtain the metadata URL
99
+ and register each application individually.
100
+
101
+ See the official
102
+ [Auth0 docs](https://auth0.com/ai/docs/mcp/guides/registering-your-mcp-client-application/manual-cimd-registration)
103
+ for more information.
104
+
105
+ ### Enabling DCR for MCP OAuth
106
+
107
+ To use DCR for MCP OAuth authentication, do the following:
108
+
109
+ 1. In the Auth0 dashboard, navigate to the tenant settings in **Settings** on
110
+ the left hand sidebar.
111
+ 2. Navigate to the **Advanced** tab.
112
+ 3. Scroll down to the **Settings** section and check the toggle for **Dynamic
113
+ Client Registration (DCR)**. Also ensure that the **Enable Application
114
+ Connections** toggle is checked.
115
+
116
+ See the official
117
+ [Auth0 docs](https://auth0.com/ai/docs/mcp/guides/registering-your-mcp-client-application/dynamic-client-registration)
118
+ for more information.
89
119
 
90
120
  ### Configure OAuth on Zuplo
91
121
 
@@ -184,3 +214,13 @@ open the OAuth settings. This will allow you to debug the flow step by step.
184
214
  You should be able to hit the **Continue** button in the Inspector UI at each
185
215
  step of the flow successfully. If you need more help debugging, see
186
216
  [Testing OAuth on Zuplo](../handlers/mcp-server.mdx#oauth-testing).
217
+
218
+ :::note
219
+
220
+ When testing CIMD authentication, you will need an MCP client with a CIMD
221
+ compatible client metadata URL. Currently, MCP Inspector does not have this, so
222
+ it is recommended that you test with another client like the Claude Code CLI
223
+ (Client Metadata URI as of May 2026 is
224
+ https://claude.ai/oauth/claude-code-client-metadata).
225
+
226
+ :::
@@ -0,0 +1,59 @@
1
+ ---
2
+ title: "Zuplo CLI: Project List"
3
+ sidebar_label: project list
4
+ ---
5
+
6
+ <CliCommand
7
+ command="project list"
8
+ description="Lists the projects in your account"
9
+ options={[
10
+ {
11
+ "name": "account",
12
+ "type": "string",
13
+ "description": "The account name",
14
+ "required": false,
15
+ "deprecated": false,
16
+ "hidden": false
17
+ },
18
+ {
19
+ "name": "output",
20
+ "type": "string",
21
+ "description": "Output format",
22
+ "default": "default",
23
+ "required": false,
24
+ "deprecated": false,
25
+ "hidden": false,
26
+ "alias": [
27
+ "o"
28
+ ],
29
+ "choices": [
30
+ "default",
31
+ "json"
32
+ ]
33
+ }
34
+ ]}
35
+ examples={[
36
+ [
37
+ "$0 project list",
38
+ "List all projects in your account"
39
+ ],
40
+ [
41
+ "$0 project list --output json",
42
+ "List all projects as JSON"
43
+ ],
44
+ [
45
+ "$0 project list --account my-account",
46
+ "Explicitly specify the account"
47
+ ]
48
+ ]}
49
+ usage="$0 project list [options]"
50
+ >
51
+
52
+ </CliCommand>
53
+
54
+ ## Global options
55
+
56
+ The following global options are available for all commands:
57
+
58
+ - [`--help`](./global-options.mdx#help)
59
+ - [`--api-key`](./global-options.mdx#api-key)
package/docs/cli/test.mdx CHANGED
@@ -32,6 +32,13 @@ sidebar_label: test
32
32
  "deprecated": false,
33
33
  "hidden": true,
34
34
  "normalize": true
35
+ },
36
+ {
37
+ "name": "test-concurrency",
38
+ "type": "number",
39
+ "required": false,
40
+ "deprecated": false,
41
+ "hidden": true
35
42
  }
36
43
  ]}
37
44
  examples={[
@@ -78,6 +78,7 @@
78
78
  | set-body-inbound | Set Body | Sets the body of the request in the inbound pipeline - make sure to convert a GET/HEAD request to another method when using this policy. | api-gateway |
79
79
  | set-headers-outbound | Set Headers | Adds or sets headers on the on the outgoing response. | api-gateway |
80
80
  | set-status-outbound | Set Status Code | Sets the status code on the on the outgoing response. | api-gateway |
81
+ | set-upstream-api-key-inbound | Set Upstream API Key | Sets a single header on the incoming request, typically used to attach an API key for the upstream service. A more directed version of the `SetHeadersInboundPolicy` that defaults the header name to `Authorization` and is intended to be used with an `$env()` reference for the value. | api-gateway |
81
82
  | sleep-inbound | Sleep / Delay | Add a delay to the incoming request. Useful for testing. | api-gateway |
82
83
  | stripe-webhook-verification-inbound | Stripe Webhook Auth | The Stripe Webhook policy validates the authenticity of an incoming Stripe webhook. | api-gateway |
83
84
  | supabase-jwt-auth-inbound | Supabase JWT Auth | The Supabase JWT Authentication policy supports user JWT tokens created by Supabase. | api-gateway |
@@ -33,6 +33,20 @@
33
33
  "description": "The options for the Akamai Firewall for AI inbound policy. Sends the incoming request to Akamai's Firewall for AI detect endpoint and blocks the request if any rule returns a 'deny' action.",
34
34
  "additionalProperties": false,
35
35
  "required": ["configurationId", "api-key"],
36
+ "examples": [
37
+ {
38
+ "configurationId": "$env(AKAMAI_FIREWALL_FOR_AI_CONFIGURATION_ID)",
39
+ "api-key": "$env(AKAMAI_FIREWALL_FOR_AI_API_KEY)",
40
+ "capture": {
41
+ "body": true,
42
+ "headers": false,
43
+ "url": false,
44
+ "queryString": false
45
+ },
46
+ "onWarn": "log",
47
+ "throwOnError": true
48
+ }
49
+ ],
36
50
  "properties": {
37
51
  "configurationId": {
38
52
  "type": "string",
@@ -108,14 +122,14 @@
108
122
  "export": "AkamaiFirewallForAiInboundPolicy",
109
123
  "module": "$import(@zuplo/runtime)",
110
124
  "options": {
125
+ "configurationId": "$env(AKAMAI_FIREWALL_FOR_AI_CONFIGURATION_ID)",
111
126
  "api-key": "$env(AKAMAI_FIREWALL_FOR_AI_API_KEY)",
112
127
  "capture": {
113
128
  "body": true,
114
129
  "headers": false,
115
- "queryString": false,
116
- "url": false
130
+ "url": false,
131
+ "queryString": false
117
132
  },
118
- "configurationId": "$env(AKAMAI_FIREWALL_FOR_AI_CONFIGURATION_ID)",
119
133
  "onWarn": "log",
120
134
  "throwOnError": true
121
135
  }
@@ -33,6 +33,20 @@
33
33
  "description": "The options for the Akamai Firewall for AI outbound policy. Sends the upstream response to Akamai's Firewall for AI detect endpoint and blocks the response if any rule returns a 'deny' action.",
34
34
  "additionalProperties": false,
35
35
  "required": ["configurationId", "api-key"],
36
+ "examples": [
37
+ {
38
+ "configurationId": "$env(AKAMAI_FIREWALL_FOR_AI_CONFIGURATION_ID)",
39
+ "api-key": "$env(AKAMAI_FIREWALL_FOR_AI_API_KEY)",
40
+ "capture": {
41
+ "body": true,
42
+ "headers": false,
43
+ "url": false,
44
+ "queryString": false
45
+ },
46
+ "onWarn": "log",
47
+ "throwOnError": true
48
+ }
49
+ ],
36
50
  "properties": {
37
51
  "configurationId": {
38
52
  "type": "string",
@@ -108,14 +122,14 @@
108
122
  "export": "AkamaiFirewallForAiOutboundPolicy",
109
123
  "module": "$import(@zuplo/runtime)",
110
124
  "options": {
125
+ "configurationId": "$env(AKAMAI_FIREWALL_FOR_AI_CONFIGURATION_ID)",
111
126
  "api-key": "$env(AKAMAI_FIREWALL_FOR_AI_API_KEY)",
112
127
  "capture": {
113
128
  "body": true,
114
129
  "headers": false,
115
- "queryString": false,
116
- "url": false
130
+ "url": false,
131
+ "queryString": false
117
132
  },
118
- "configurationId": "$env(AKAMAI_FIREWALL_FOR_AI_CONFIGURATION_ID)",
119
133
  "onWarn": "log",
120
134
  "throwOnError": true
121
135
  }
@@ -117,11 +117,11 @@
117
117
  "export": "ComplexRateLimitInboundPolicy",
118
118
  "module": "$import(@zuplo/runtime)",
119
119
  "options": {
120
+ "rateLimitBy": "ip",
120
121
  "limits": {
121
122
  "apples": 2,
122
123
  "bananas": 3
123
124
  },
124
- "rateLimitBy": "ip",
125
125
  "timeWindowMinutes": 0.6
126
126
  }
127
127
  },
@@ -129,11 +129,11 @@
129
129
  "export": "ComplexRateLimitInboundPolicy",
130
130
  "module": "$import(@zuplo/runtime)",
131
131
  "options": {
132
+ "rateLimitBy": "function",
132
133
  "identifier": {
133
134
  "export": "$import(./modules/my-module)",
134
135
  "module": "default"
135
- },
136
- "rateLimitBy": "function"
136
+ }
137
137
  }
138
138
  }
139
139
  ]
@@ -87,15 +87,11 @@
87
87
  },
88
88
  "examples": [
89
89
  {
90
- "x-example-name": "Public Key Validation with JWKS (Recommended)",
91
- "x-example-description": "This example shows how to configure the policy using a Public Key from an OpenID Connect provider.",
92
90
  "issuer": "$env(AUTH_ISSUER)",
93
91
  "audience": "$env(AUTH_AUDIENCE)",
94
92
  "jwkUrl": "https://zuplo-demo.us.auth0.com/.well-known/jwks.json"
95
93
  },
96
94
  {
97
- "x-example-name": "Client Secret Validation",
98
- "x-example-description": "This example shows how to configure the policy using a shared secret.",
99
95
  "issuer": "$env(AUTH_ISSUER)",
100
96
  "audience": "$env(AUTH_AUDIENCE)",
101
97
  "secret": "$env(AUTH_SECRET)"
@@ -108,8 +104,8 @@
108
104
  "export": "OpenIdJwtInboundPolicy",
109
105
  "module": "$import(@zuplo/runtime)",
110
106
  "options": {
111
- "audience": "$env(AUTH_AUDIENCE)",
112
107
  "issuer": "$env(AUTH_ISSUER)",
108
+ "audience": "$env(AUTH_AUDIENCE)",
113
109
  "jwkUrl": "https://zuplo-demo.us.auth0.com/.well-known/jwks.json"
114
110
  }
115
111
  },
@@ -117,8 +113,8 @@
117
113
  "export": "OpenIdJwtInboundPolicy",
118
114
  "module": "$import(@zuplo/runtime)",
119
115
  "options": {
120
- "audience": "$env(AUTH_AUDIENCE)",
121
116
  "issuer": "$env(AUTH_ISSUER)",
117
+ "audience": "$env(AUTH_AUDIENCE)",
122
118
  "secret": "$env(AUTH_SECRET)"
123
119
  }
124
120
  }
@@ -119,11 +119,11 @@
119
119
  "export": "QuotaInboundPolicy",
120
120
  "module": "$import(@zuplo/runtime)",
121
121
  "options": {
122
+ "period": "monthly",
123
+ "quotaBy": "user",
122
124
  "allowances": {
123
125
  "requests": 10
124
126
  },
125
- "period": "monthly",
126
- "quotaBy": "user",
127
127
  "quotaOnStatusCodes": "200-399"
128
128
  }
129
129
  }
@@ -121,11 +121,11 @@
121
121
  "export": "RateLimitInboundPolicy",
122
122
  "module": "$import(@zuplo/runtime)",
123
123
  "options": {
124
+ "rateLimitBy": "function",
124
125
  "identifier": {
125
126
  "export": "$import(./modules/my-module)",
126
127
  "module": "default"
127
- },
128
- "rateLimitBy": "function"
128
+ }
129
129
  }
130
130
  }
131
131
  ]
@@ -154,9 +154,9 @@
154
154
  "options": {
155
155
  "cacheBy": "propertyPath",
156
156
  "cacheByPropertyPath": ".userId",
157
+ "semanticTolerance": 0.8,
157
158
  "expirationSecondsTtl": 3600,
158
- "namespace": "user-cache",
159
- "semanticTolerance": 0.8
159
+ "namespace": "user-cache"
160
160
  }
161
161
  },
162
162
  {
@@ -168,9 +168,9 @@
168
168
  "export": "cacheKeyFunction",
169
169
  "module": "$import(./modules/cache-key)"
170
170
  },
171
+ "semanticTolerance": 0.9,
171
172
  "expirationSecondsTtl": 1800,
172
- "namespace": "api-cache",
173
- "semanticTolerance": 0.9
173
+ "namespace": "api-cache"
174
174
  }
175
175
  }
176
176
  ]
@@ -0,0 +1,43 @@
1
+ Many upstream APIs require an API key or bearer token to be passed in a header
2
+ on every request. This policy is a focused version of the
3
+ `SetHeadersInboundPolicy` that sets a single header (defaulting to
4
+ `Authorization`) and is designed to be paired with an environment variable so
5
+ the secret never lives in your `policies.json`.
6
+
7
+ The most common configuration sets a bearer token from an environment variable:
8
+
9
+ ```json
10
+ {
11
+ "name": "set-upstream-api-key-inbound-policy",
12
+ "policyType": "set-upstream-api-key-inbound",
13
+ "handler": {
14
+ "export": "SetUpstreamApiKeyInboundPolicy",
15
+ "module": "$import(@zuplo/runtime)",
16
+ "options": {
17
+ "value": "Bearer $env(UPSTREAM_API_KEY)"
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ You can also customize the header name. For example, if your upstream uses a
24
+ custom header rather than `Authorization`:
25
+
26
+ ```json
27
+ {
28
+ "name": "set-upstream-api-key-inbound-policy",
29
+ "policyType": "set-upstream-api-key-inbound",
30
+ "handler": {
31
+ "export": "SetUpstreamApiKeyInboundPolicy",
32
+ "module": "$import(@zuplo/runtime)",
33
+ "options": {
34
+ "header": "X-API-Key",
35
+ "value": "$env(UPSTREAM_API_KEY)"
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ By default the policy overwrites any header with the same name that was sent by
42
+ the client. Set `overwrite` to `false` to preserve the incoming value when one
43
+ is present.
@@ -0,0 +1,5 @@
1
+ The set upstream API key policy attaches a single header (by default
2
+ `Authorization`) to the incoming request so it can be forwarded to your
3
+ upstream service. It is a focused version of the set headers policy intended
4
+ for the common case of authenticating Zuplo to an upstream API using a secret
5
+ sourced from an environment variable.
@@ -0,0 +1,69 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema",
3
+ "$id": "http://zuplo.com/schemas/policies/auth0-jwt-auth-inbound.json",
4
+ "type": "object",
5
+ "title": "Set Upstream API Key",
6
+ "isDeprecated": false,
7
+ "isPaidAddOn": false,
8
+ "isEnterprise": false,
9
+ "isInternal": false,
10
+ "isBeta": false,
11
+ "isHidden": false,
12
+ "products": ["api-gateway"],
13
+ "description": "Sets a single header on the incoming request, typically used to attach an API key for the upstream service. A more directed version of the `SetHeadersInboundPolicy` that defaults the header name to `Authorization` and is intended to be used with an `$env()` reference for the value.",
14
+ "deprecatedMessage": "",
15
+ "required": ["handler"],
16
+ "properties": {
17
+ "handler": {
18
+ "type": "object",
19
+ "default": {},
20
+ "required": ["export", "module", "options"],
21
+ "properties": {
22
+ "export": {
23
+ "const": "SetUpstreamApiKeyInboundPolicy",
24
+ "description": "The name of the exported type"
25
+ },
26
+ "module": {
27
+ "const": "$import(@zuplo/runtime)",
28
+ "description": "The module containing the policy"
29
+ },
30
+ "options": {
31
+ "title": "SetUpstreamApiKeyInboundPolicyOptions",
32
+ "type": "object",
33
+ "description": "The options for this policy.",
34
+ "additionalProperties": false,
35
+ "required": ["value"],
36
+ "properties": {
37
+ "header": {
38
+ "type": "string",
39
+ "default": "Authorization",
40
+ "examples": ["Authorization"],
41
+ "description": "The name of the header to set on the request. Defaults to `Authorization`."
42
+ },
43
+ "value": {
44
+ "type": "string",
45
+ "examples": ["Bearer $env(UPSTREAM_API_KEY)"],
46
+ "description": "The value of the header. Most commonly an environment variable reference such as `Bearer $env(UPSTREAM_API_KEY)` so the secret is sourced from your environment."
47
+ },
48
+ "overwrite": {
49
+ "type": "boolean",
50
+ "x-show-example": false,
51
+ "default": true,
52
+ "description": "Overwrite the value if the header is already present in the request."
53
+ }
54
+ }
55
+ }
56
+ },
57
+ "examples": [
58
+ {
59
+ "export": "SetUpstreamApiKeyInboundPolicy",
60
+ "module": "$import(@zuplo/runtime)",
61
+ "options": {
62
+ "header": "Authorization",
63
+ "value": "Bearer $env(UPSTREAM_API_KEY)"
64
+ }
65
+ }
66
+ ]
67
+ }
68
+ }
69
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "6.70.28",
3
+ "version": "6.70.30",
4
4
  "type": "module",
5
5
  "description": "The programmable API Gateway",
6
6
  "author": "Zuplo, Inc.",
@@ -19,9 +19,9 @@
19
19
  "zuplo": "zuplo.js"
20
20
  },
21
21
  "dependencies": {
22
- "@zuplo/cli": "6.70.28",
23
- "@zuplo/core": "6.70.28",
24
- "@zuplo/runtime": "6.70.28",
22
+ "@zuplo/cli": "6.70.30",
23
+ "@zuplo/core": "6.70.30",
24
+ "@zuplo/runtime": "6.70.30",
25
25
  "@zuplo/test": "1.4.0"
26
26
  }
27
27
  }