@zuplo/runtime 7.12.7 → 7.13.2

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.
@@ -22,5 +22,5 @@
22
22
  * DEALINGS IN THE SOFTWARE.
23
23
  *--------------------------------------------------------------------------------------------*/
24
24
 
25
- import{F as p,K as c,N as u}from"../chunk-N2ZQITZD.js";import"../chunk-WIQFTAJL.js";import{a as d}from"../chunk-QGAJTUPE.js";import"../chunk-A3QGJZO7.js";import{aa as i}from"../chunk-RH345HSZ.js";import"../chunk-UKQQD2JN.js";import{a as o}from"../chunk-TYV53J3B.js";function w(l={request:new Request("https://api.example.com")}){let e=[];function t(s){e.push(Promise.resolve(s))}return o(t,"waitUntil"),{context:new a({event:{waitUntil:t},route:l.route,originalRequest:l.request}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(w,"createMockContext");var g={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},a=class extends EventTarget{static{o(this,"MockZuploContext")}#e;#t;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=g,parentContext:n,originalRequest:r}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:i.console.info,log:i.console.log,debug:i.console.debug,warn:i.console.warn,error:i.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=n,this.#e=e,this.#t=r,this.analyticsContext=new c(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,n){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addPreRequestHandler(e,t){let n;try{n=u.getContextExtensions(this)}catch{n=u.initialize(this,new d(this.#t??new Request("https://api.example.com")))}n.preRequestPhase??="active",p(this,n,e,t)}get preRequestHandlers(){let e;try{e=u.getContextExtensions(this)}catch{return[]}return(e.preRequestState?.entries??[]).map(t=>({policyName:t.policyName,name:t.name}))}addEventListener(e,t,n){let r=o(s=>{try{typeof t=="function"?t(s):t.handleEvent(s)}catch(m){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),m}},"wrapped");super.addEventListener(e,r,n)}};export{a as MockZuploContext,w as createMockContext};
25
+ import{G as p,L as c,O as u}from"../chunk-5VRGV7FV.js";import"../chunk-ZCJ5QBVD.js";import{a as d}from"../chunk-QGAJTUPE.js";import"../chunk-A3QGJZO7.js";import{aa as i}from"../chunk-FQIUJWH2.js";import"../chunk-UKQQD2JN.js";import{a as o}from"../chunk-TYV53J3B.js";function w(l={request:new Request("https://api.example.com")}){let e=[];function t(s){e.push(Promise.resolve(s))}return o(t,"waitUntil"),{context:new a({event:{waitUntil:t},route:l.route,originalRequest:l.request}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(w,"createMockContext");var g={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},a=class extends EventTarget{static{o(this,"MockZuploContext")}#e;#t;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=g,parentContext:n,originalRequest:r}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:i.console.info,log:i.console.log,debug:i.console.debug,warn:i.console.warn,error:i.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=n,this.#e=e,this.#t=r,this.analyticsContext=new c(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,n){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addPreRequestHandler(e,t){let n;try{n=u.getContextExtensions(this)}catch{n=u.initialize(this,new d(this.#t??new Request("https://api.example.com")))}n.preRequestPhase??="active",p(this,n,e,t)}get preRequestHandlers(){let e;try{e=u.getContextExtensions(this)}catch{return[]}return(e.preRequestState?.entries??[]).map(t=>({policyName:t.policyName,name:t.name}))}addEventListener(e,t,n){let r=o(s=>{try{typeof t=="function"?t(s):t.handleEvent(s)}catch(m){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),m}},"wrapped");super.addEventListener(e,r,n)}};export{a as MockZuploContext,w as createMockContext};
26
26
  //# sourceMappingURL=index.js.map
@@ -22,5 +22,5 @@
22
22
  * DEALINGS IN THE SOFTWARE.
23
23
  *--------------------------------------------------------------------------------------------*/
24
24
 
25
- import{Ia as a,Ja as l,Ka as c,La as o,Oa as p,Pa as y,Qa as m}from"../../chunk-RH345HSZ.js";import"../../chunk-UKQQD2JN.js";import{a as i}from"../../chunk-TYV53J3B.js";async function g(r,e){let t=typeof e.credentials=="function"?await e.credentials():e.credentials,n=r.method,d=n!=="GET"&&n!=="HEAD"&&r.body!=null?await r.arrayBuffer():null,s=await new o({method:n,url:r.url,headers:r.headers,body:d,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey,sessionToken:t.sessionToken,service:e.service,region:e.region,signQuery:e.signQuery}).sign();return new Request(s.url.toString(),{method:s.method,headers:s.headers,body:s.body})}i(g,"signRequest");export{c as AwsClient,o as AwsV4Signer,p as fromTemporaryCredentials,y as fromWebToken,m as fromZuploIdentity,l as getAwsCredentialProvider,a as setAwsCredentialProvider,g as signRequest};
25
+ import{Ia as a,Ja as l,Ka as c,La as o,Oa as p,Pa as y,Qa as m}from"../../chunk-FQIUJWH2.js";import"../../chunk-UKQQD2JN.js";import{a as i}from"../../chunk-TYV53J3B.js";async function g(r,e){let t=typeof e.credentials=="function"?await e.credentials():e.credentials,n=r.method,d=n!=="GET"&&n!=="HEAD"&&r.body!=null?await r.arrayBuffer():null,s=await new o({method:n,url:r.url,headers:r.headers,body:d,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey,sessionToken:t.sessionToken,service:e.service,region:e.region,signQuery:e.signQuery}).sign();return new Request(s.url.toString(),{method:s.method,headers:s.headers,body:s.body})}i(g,"signRequest");export{c as AwsClient,o as AwsV4Signer,p as fromTemporaryCredentials,y as fromWebToken,m as fromZuploIdentity,l as getAwsCredentialProvider,a as setAwsCredentialProvider,g as signRequest};
26
26
  //# sourceMappingURL=index.js.map
@@ -3331,7 +3331,7 @@ declare type BlockedModels1 = [ProviderAndModel_2, ...ProviderAndModel_2[]];
3331
3331
  export declare class BrownoutInboundPolicy extends InboundPolicy<BrownoutInboundPolicyOptions> {
3332
3332
  static readonly policyType = "brownout";
3333
3333
  crons: Cron[];
3334
- constructor(options: BrownoutInboundPolicyOptions, policyName: string);
3334
+ constructor(rawOptions: BrownoutInboundPolicyOptions, policyName: string);
3335
3335
  handler(
3336
3336
  request: ZuploRequest,
3337
3337
  context: ZuploContext
@@ -4302,40 +4302,40 @@ declare interface CompatibilityFlags {
4302
4302
  */
4303
4303
  return501ForUnsupportedHttpMethods: boolean;
4304
4304
  /**
4305
- * Retired: still accepted in `compatibilityFlags`, with no effect.
4305
+ * Whether OpenAPI schemas are validated by the specifications they declare:
4306
+ * the arguments of `mcpServerHandler`'s tools and prompts, and the requests
4307
+ * `request-validation-inbound` checks.
4306
4308
  *
4307
- * The MCP server handler's `initialize` returns `capabilities.tools: {}` for
4308
- * every project, without the non-standard `supported` and `available`
4309
- * fields this flag used to remove. Clients discover tools with
4310
- * `tools/list`. See `packages/runtime/specs/mcp-json-rpc.md`, MCPRPC-26 to
4311
- * MCPRPC-28.
4309
+ * Before this flag: `mcpServerHandler` builds tool and prompt validators at
4310
+ * runtime from `context.route.raw()` with Zod, exactly as before build-time
4311
+ * schemas (specs/mcp-tool-schemas-legacy.md); the build generates nothing
4312
+ * for MCP.
4312
4313
  *
4313
- * @deprecated The behavior is unconditional; listing the flag changes
4314
- * nothing.
4315
- */
4316
- removeMcpToolsCapabilityExtension: boolean;
4317
- /**
4318
- * Retired: still accepted in `compatibilityFlags`, with no effect.
4314
+ * After this flag: The build generates each tool's and prompt's schemas and
4315
+ * precompiled Ajv validators from the OpenAPI document, validated per the
4316
+ * dialect and OpenAPI version they declare (specs/mcp-tool-schemas.md), and
4317
+ * `prompts/list` also lists the arguments behind a prompt schema's `$ref`
4318
+ * and `allOf`. `request-validation-inbound` validates with the same dialect,
4319
+ * `format` and pattern rules, and keeps its parameter type coercion
4320
+ * (specs/compat-improved-schema-validation.md).
4321
+ */
4322
+ improvedSchemaValidation: boolean;
4323
+ /**
4324
+ * Whether the MCP server handler writes path, query and header tool
4325
+ * arguments into the route request by each OpenAPI parameter's `style`,
4326
+ * `explode`, `allowReserved` and `content`.
4319
4327
  *
4320
- * For every project, when the request's `MCP-Protocol-Version` header is
4321
- * `2025-11-25` or later, a `tools/call` whose arguments fail the tool's
4322
- * `inputSchema` returns a result with `isError: true` and the validation
4323
- * message as text content, and the tool is not called. Earlier or missing
4324
- * protocol versions return a JSON-RPC `-32602` error. See
4325
- * `packages/runtime/specs/mcp-json-rpc.md`, MCPRPC-19 to MCPRPC-25.
4328
+ * Before this flag: Query arrays repeat the name, query objects are JSON
4329
+ * text, path values are `String()` then `encodeURIComponent`, and header
4330
+ * values are stringified (an object becomes `[object Object]`). The
4331
+ * parameter's `style`, `explode`, `allowReserved` and `content` are ignored.
4326
4332
  *
4327
- * @deprecated The behavior is unconditional; listing the flag changes
4328
- * nothing.
4329
- */
4330
- returnMcpToolInputErrorsAsToolResults: boolean;
4331
- /**
4332
- * Before this flag: MCP input schemas are converted to Zod and back to JSON
4333
- * Schema, and Zod may insert defaults or discard undeclared properties.
4334
- * After this flag: the MCP SDK validates JSON Schema directly, preserving
4335
- * constraints and input values. Defaults remain annotations. HTTP validation is unchanged.
4336
- * Opt in only on the JavaScript runtimes (workerd and Zeno).
4333
+ * After this flag: Each parameter is serialized as the OpenAPI 3.1
4334
+ * Style Examples table says, for example `rgb[R]=100&rgb[G]=200` for a
4335
+ * `deepObject` and `.blue.black.brown` for a path `label`. Values are
4336
+ * percent-encoded as UTF-8 and a space is `%20`.
4337
4337
  */
4338
- useMcpDirectSchemaValidation: boolean;
4338
+ serializeMcpParametersByStyle: boolean;
4339
4339
  /**
4340
4340
  * Whether the MCP server handler rewrites tool names to follow the MCP tool
4341
4341
  * naming rule: 1 to 128 characters of `A-Z`, `a-z`, `0-9`, `_`, `-` and
@@ -4386,6 +4386,27 @@ declare interface CompatibilityFlags {
4386
4386
  * `_meta` is sent on every version.
4387
4387
  */
4388
4388
  omitMcpFieldsNewerThanNegotiatedVersion: boolean;
4389
+ /**
4390
+ * Whether built-in policies treat an empty or whitespace-only value for an
4391
+ * optional string option as if the option were left out.
4392
+ *
4393
+ * `$env(VAR)` with `VAR` defined but empty reaches a policy as `""`, so this
4394
+ * decides what an empty environment variable does to an optional option.
4395
+ *
4396
+ * Before this flag: Many policies reject `""`. Some fail every request with
4397
+ * a `ConfigurationError` (for example `http-deprecation-outbound` `link`,
4398
+ * `openmeter-inbound` `apiUrl`, `upstream-aws-service-auth-inbound`
4399
+ * `roleSessionName`). Others fail at request time (an `authHeader` of `""`
4400
+ * is not a valid header name). A few use a whitespace-only value as given
4401
+ * (a `" "` brownout `problem.title`).
4402
+ *
4403
+ * After this flag: Those options behave exactly as if they were left out,
4404
+ * and their default applies. Options where an empty value means something,
4405
+ * secrets, and options whose unset default grants more access keep their
4406
+ * current behavior. `BLANK_IS_NOT_UNSET` in
4407
+ * `policies/optional-string-options.spec.ts` lists them with the reason.
4408
+ */
4409
+ treatBlankOptionalStringOptionsAsUnset: boolean;
4389
4410
  }
4390
4411
 
4391
4412
  declare interface CompletionsFallbacks {
@@ -6239,7 +6260,12 @@ export declare class Handler {
6239
6260
  runtimeEnvironment: RuntimeEnvironment,
6240
6261
  event: ZuploEventContext
6241
6262
  ) => Promise<Response>;
6242
- handleError(err: Error, detail: string, request: Request): Response;
6263
+ handleError(
6264
+ err: Error,
6265
+ detail: string,
6266
+ request: Request,
6267
+ event: ZuploEventContext
6268
+ ): Response;
6243
6269
  }
6244
6270
 
6245
6271
  /**
@@ -15177,7 +15203,7 @@ export declare class UpstreamAwsFederatedAuthInboundPolicy extends InboundPolicy
15177
15203
  #private;
15178
15204
  static readonly policyType = "upstream-aws-federated-auth";
15179
15205
  constructor(
15180
- options: UpstreamAwsFederatedAuthInboundPolicyOptions,
15206
+ rawOptions: UpstreamAwsFederatedAuthInboundPolicyOptions,
15181
15207
  policyName: string
15182
15208
  );
15183
15209
  handler(
@@ -15246,7 +15272,7 @@ export declare class UpstreamAwsServiceAuthInboundPolicy extends InboundPolicy<U
15246
15272
  #private;
15247
15273
  static readonly policyType = "upstream-aws-service-auth";
15248
15274
  constructor(
15249
- options: UpstreamAwsServiceAuthInboundPolicyOptions,
15275
+ rawOptions: UpstreamAwsServiceAuthInboundPolicyOptions,
15250
15276
  policyName: string
15251
15277
  );
15252
15278
  handler(
@@ -15609,7 +15635,7 @@ export declare class UpstreamOAuthClientCredentialsInboundPolicy extends Inbound
15609
15635
  #private;
15610
15636
  static readonly policyType = "upstream-oauth-client-credentials";
15611
15637
  constructor(
15612
- options: UpstreamOAuthClientCredentialsInboundPolicyOptions,
15638
+ rawOptions: UpstreamOAuthClientCredentialsInboundPolicyOptions,
15613
15639
  policyName: string
15614
15640
  );
15615
15641
  handler(
@@ -15685,7 +15711,7 @@ export declare interface UpstreamOAuthClientCredentialsInboundPolicyOptions {
15685
15711
  export declare class UpstreamZuploJwtAuthInboundPolicy extends InboundPolicy<UpstreamZuploJwtAuthInboundPolicyOptions> {
15686
15712
  static readonly policyType = "upstream-zuplo-jwt";
15687
15713
  constructor(
15688
- options: UpstreamZuploJwtAuthInboundPolicyOptions,
15714
+ rawOptions: UpstreamZuploJwtAuthInboundPolicyOptions,
15689
15715
  policyName: string
15690
15716
  );
15691
15717
  /**
@@ -16278,7 +16304,7 @@ export declare class XmlToJsonOutboundPolicy extends OutboundPolicy<XmlToJsonPol
16278
16304
  static readonly policyType = "xml-to-json";
16279
16305
  private parser;
16280
16306
  private parseOnStatusCodes;
16281
- constructor(options: XmlToJsonPolicyOptions, policyName: string);
16307
+ constructor(rawOptions: XmlToJsonPolicyOptions, policyName: string);
16282
16308
  handler(
16283
16309
  response: Response,
16284
16310
  request: ZuploRequest,
@@ -4,6 +4,19 @@ export declare interface ApiRuntimeConfig {
4
4
  urls: UrlConfig | undefined;
5
5
  }
6
6
 
7
+ /** A generated schema as the assembler reads it. */
8
+ declare interface AssemblableSchema {
9
+ /** The schema root as JSON, referencing shared components with `$ref`. */
10
+ schema: string;
11
+ /** The key of the table the root's `#/$defs/<name>` references resolve in. */
12
+ defs?: string;
13
+ /**
14
+ * The `$schema` the advertised root carries, when the schema is not JSON
15
+ * Schema 2020-12 (MCPSCHEMA-2, MCPSCHEMA-23).
16
+ */
17
+ dialect?: string;
18
+ }
19
+
7
20
  /**
8
21
  * Assigns each tool a name that follows the MCP tool naming rule and is
9
22
  * unique among `names`, deterministically. `names` are the configured names
@@ -160,40 +173,40 @@ declare interface CompatibilityFlags {
160
173
  */
161
174
  return501ForUnsupportedHttpMethods: boolean;
162
175
  /**
163
- * Retired: still accepted in `compatibilityFlags`, with no effect.
176
+ * Whether OpenAPI schemas are validated by the specifications they declare:
177
+ * the arguments of `mcpServerHandler`'s tools and prompts, and the requests
178
+ * `request-validation-inbound` checks.
164
179
  *
165
- * The MCP server handler's `initialize` returns `capabilities.tools: {}` for
166
- * every project, without the non-standard `supported` and `available`
167
- * fields this flag used to remove. Clients discover tools with
168
- * `tools/list`. See `packages/runtime/specs/mcp-json-rpc.md`, MCPRPC-26 to
169
- * MCPRPC-28.
180
+ * Before this flag: `mcpServerHandler` builds tool and prompt validators at
181
+ * runtime from `context.route.raw()` with Zod, exactly as before build-time
182
+ * schemas (specs/mcp-tool-schemas-legacy.md); the build generates nothing
183
+ * for MCP.
170
184
  *
171
- * @deprecated The behavior is unconditional; listing the flag changes
172
- * nothing.
173
- */
174
- removeMcpToolsCapabilityExtension: boolean;
175
- /**
176
- * Retired: still accepted in `compatibilityFlags`, with no effect.
185
+ * After this flag: The build generates each tool's and prompt's schemas and
186
+ * precompiled Ajv validators from the OpenAPI document, validated per the
187
+ * dialect and OpenAPI version they declare (specs/mcp-tool-schemas.md), and
188
+ * `prompts/list` also lists the arguments behind a prompt schema's `$ref`
189
+ * and `allOf`. `request-validation-inbound` validates with the same dialect,
190
+ * `format` and pattern rules, and keeps its parameter type coercion
191
+ * (specs/compat-improved-schema-validation.md).
192
+ */
193
+ improvedSchemaValidation: boolean;
194
+ /**
195
+ * Whether the MCP server handler writes path, query and header tool
196
+ * arguments into the route request by each OpenAPI parameter's `style`,
197
+ * `explode`, `allowReserved` and `content`.
177
198
  *
178
- * For every project, when the request's `MCP-Protocol-Version` header is
179
- * `2025-11-25` or later, a `tools/call` whose arguments fail the tool's
180
- * `inputSchema` returns a result with `isError: true` and the validation
181
- * message as text content, and the tool is not called. Earlier or missing
182
- * protocol versions return a JSON-RPC `-32602` error. See
183
- * `packages/runtime/specs/mcp-json-rpc.md`, MCPRPC-19 to MCPRPC-25.
199
+ * Before this flag: Query arrays repeat the name, query objects are JSON
200
+ * text, path values are `String()` then `encodeURIComponent`, and header
201
+ * values are stringified (an object becomes `[object Object]`). The
202
+ * parameter's `style`, `explode`, `allowReserved` and `content` are ignored.
184
203
  *
185
- * @deprecated The behavior is unconditional; listing the flag changes
186
- * nothing.
204
+ * After this flag: Each parameter is serialized as the OpenAPI 3.1
205
+ * Style Examples table says, for example `rgb[R]=100&rgb[G]=200` for a
206
+ * `deepObject` and `.blue.black.brown` for a path `label`. Values are
207
+ * percent-encoded as UTF-8 and a space is `%20`.
187
208
  */
188
- returnMcpToolInputErrorsAsToolResults: boolean;
189
- /**
190
- * Before this flag: MCP input schemas are converted to Zod and back to JSON
191
- * Schema, and Zod may insert defaults or discard undeclared properties.
192
- * After this flag: the MCP SDK validates JSON Schema directly, preserving
193
- * constraints and input values. Defaults remain annotations. HTTP validation is unchanged.
194
- * Opt in only on the JavaScript runtimes (workerd and Zeno).
195
- */
196
- useMcpDirectSchemaValidation: boolean;
209
+ serializeMcpParametersByStyle: boolean;
197
210
  /**
198
211
  * Whether the MCP server handler rewrites tool names to follow the MCP tool
199
212
  * naming rule: 1 to 128 characters of `A-Z`, `a-z`, `0-9`, `_`, `-` and
@@ -244,6 +257,27 @@ declare interface CompatibilityFlags {
244
257
  * `_meta` is sent on every version.
245
258
  */
246
259
  omitMcpFieldsNewerThanNegotiatedVersion: boolean;
260
+ /**
261
+ * Whether built-in policies treat an empty or whitespace-only value for an
262
+ * optional string option as if the option were left out.
263
+ *
264
+ * `$env(VAR)` with `VAR` defined but empty reaches a policy as `""`, so this
265
+ * decides what an empty environment variable does to an optional option.
266
+ *
267
+ * Before this flag: Many policies reject `""`. Some fail every request with
268
+ * a `ConfigurationError` (for example `http-deprecation-outbound` `link`,
269
+ * `openmeter-inbound` `apiUrl`, `upstream-aws-service-auth-inbound`
270
+ * `roleSessionName`). Others fail at request time (an `authHeader` of `""`
271
+ * is not a valid header name). A few use a whitespace-only value as given
272
+ * (a `" "` brownout `problem.title`).
273
+ *
274
+ * After this flag: Those options behave exactly as if they were left out,
275
+ * and their default applies. Options where an empty value means something,
276
+ * secrets, and options whose unset default grants more access keep their
277
+ * current behavior. `BLANK_IS_NOT_UNSET` in
278
+ * `policies/optional-string-options.spec.ts` lists them with the reason.
279
+ */
280
+ treatBlankOptionalStringOptionsAsUnset: boolean;
247
281
  }
248
282
 
249
283
  /**
@@ -270,6 +304,12 @@ declare interface CorsPolicyConfiguration {
270
304
  exposeHeaders?: string[] | string;
271
305
  }
272
306
 
307
+ /** Shared components by name, each as JSON. */
308
+ declare type DefTable = Record<string, string>;
309
+
310
+ /** The tables of a generated module, by the key a schema names. */
311
+ declare type DefTables = Record<string, DefTable>;
312
+
273
313
  /**
274
314
  * Says how `name` breaks the MCP tool naming rule, or returns `undefined`
275
315
  * when it follows it. The reasons are customer-facing (build warnings).
@@ -324,6 +364,63 @@ declare const EventType: {
324
364
 
325
365
  declare type EventType = (typeof EventType)[keyof typeof EventType];
326
366
 
367
+ /** How one component's value is recovered from flat arguments. */
368
+ export declare interface FlatComponentPlan {
369
+ /** The component this plan assembles. */
370
+ component: InputComponentName;
371
+ /** How its value is recovered from the flat arguments. */
372
+ mode: InputComponentMode;
373
+ /**
374
+ * Top-level property names claimed by this component. Empty for a `spread`
375
+ * body that declares no properties of its own.
376
+ */
377
+ keys: string[];
378
+ }
379
+
380
+ /** A successfully computed flattening. */
381
+ declare interface FlatInputPlan {
382
+ /** The JSON Schema to advertise as the tool's `inputSchema`. */
383
+ schema: Record<string, unknown>;
384
+ /**
385
+ * Operator-facing notes about anything that stayed nested even though the
386
+ * plan succeeded — a request body that could not be hoisted while its
387
+ * operation's parameters could. Each names the cause and the fix.
388
+ */
389
+ warnings: string[];
390
+ /** Per-component assembly plans, in advertised property order. */
391
+ components: FlatComponentPlan[];
392
+ /** Every top-level property name mapped to its owning component. */
393
+ routes: Map<string, InputComponentName>;
394
+ /** The component that absorbs unclaimed properties, when there is one. */
395
+ spread?: InputComponentName;
396
+ /**
397
+ * True when the flat schema's body part is not a verbatim copy of the body's
398
+ * properties: a root `allOf` was merged, or a `dependentRequired` was hoisted.
399
+ * The validator then also checks the routed body against the body's own,
400
+ * unchanged schema, so a mistake in the merge can never accept more than the
401
+ * customer's OpenAPI does.
402
+ */
403
+ reshapedBody: boolean;
404
+ }
405
+
406
+ /** Why a composite schema could not be flattened. */
407
+ declare interface FlatInputRefusal {
408
+ /**
409
+ * Operator-facing explanation, including the fix. Logged at registration;
410
+ * never sent to an MCP client.
411
+ */
412
+ reason: string;
413
+ }
414
+
415
+ /** Result of {@link planFlatInput}: a plan, or the reason there isn't one. */
416
+ declare type FlatInputResult =
417
+ | ({
418
+ ok: true;
419
+ } & FlatInputPlan)
420
+ | ({
421
+ ok: false;
422
+ } & FlatInputRefusal);
423
+
327
424
  /* Excluded from this release type: getIdForParameterSchema */
328
425
 
329
426
  /* Excluded from this release type: getIdForRefSchema */
@@ -332,6 +429,18 @@ declare type EventType = (typeof EventType)[keyof typeof EventType];
332
429
 
333
430
  /* Excluded from this release type: getRawOperationDataIdentifierName */
334
431
 
432
+ /**
433
+ * The assembler of a generated module's tables for one `schemaRefs` setting.
434
+ * One per module and setting, so tools share parsed components.
435
+ *
436
+ * @param tables - the module's `defs`, or `undefined` when it has none
437
+ * @param mode - the handler's `schemaRefs`
438
+ */
439
+ export declare function getSchemaAssembler(
440
+ tables: DefTables | undefined,
441
+ mode: SchemaRefs
442
+ ): SchemaAssembler;
443
+
335
444
  /**
336
445
  * @public
337
446
  */
@@ -804,6 +913,67 @@ declare interface IncomingRequestProperties {
804
913
  /* Excluded from this release type: clientCertSubjectDn */
805
914
  }
806
915
 
916
+ /**
917
+ * How a component's value is assembled from the flat arguments.
918
+ *
919
+ * - `properties` — the component is an object whose declared property names
920
+ * appear at the top level (`pathParams`, `queryParams`, `headers`, and a
921
+ * flattened `body`).
922
+ * - `spread` — the component additionally absorbs every top-level property that
923
+ * no other component claims. Only a flattened `body` does this, and only when
924
+ * its own schema permits extra properties.
925
+ * - `wrapped` — the component is published as a single top-level property under
926
+ * its own name, exactly as in the nested shape. Used for a request body that
927
+ * cannot be flattened (an array, a string, a `oneOf`, ...).
928
+ */
929
+ declare type InputComponentMode = "properties" | "spread" | "wrapped";
930
+
931
+ /**
932
+ * Flattening of the composite tool input schema that `mcpServerHandler`
933
+ * generates for an OpenAPI operation.
934
+ *
935
+ * The generated validator models an operation's inputs as four components —
936
+ * `body`, `queryParams`, `pathParams`, `headers` (see `validator.ts`). Publishing
937
+ * that shape verbatim as a tool's `inputSchema` makes every argument nest one
938
+ * level deep, so a model has to send `{"body": {"query": "hoodie"}}` where both
939
+ * the MCP tool convention and Zuplo's own docs say `{"query": "hoodie"}`. Models
940
+ * send the flat form first, get a -32602, and retry — a wasted round trip on
941
+ * essentially every tool call.
942
+ *
943
+ * This module computes the *advertised* flat schema plus the routing table that
944
+ * maps each flat property back to the component it came from, so validation can
945
+ * still run each component's own schema unchanged. It works on the JSON Schema
946
+ * that `z.toJSONSchema` already produces for the composite, which keeps the
947
+ * published bytes for each leaf property identical to the nested shape.
948
+ *
949
+ * Nothing is flattened at all when it cannot be done without lying about what
950
+ * is accepted: a name collision between two components refuses the whole plan
951
+ * and the caller keeps the nested shape.
952
+ *
953
+ * A request body that is not a plain object (an array, a string, a `oneOf`) is
954
+ * NOT that case — it is a supported partial flattening. The parameters are
955
+ * hoisted and the body keeps its own `body` level, since there is nothing else
956
+ * that could honestly be done with it; the plan succeeds and carries a note
957
+ * saying why. Don't "fix" that into a full fallback.
958
+ *
959
+ * With `preserveJsonSchema` (the generated validators of
960
+ * `improvedSchemaValidation`) two body shapes that would otherwise stay
961
+ * nested are flattened, because the flat schema is then exactly what gets
962
+ * enforced: a root `allOf` of plain object schemas is merged into one object
963
+ * (FLAT-10, see `mergeAllOfBody`), and a `dependentRequired` over the body's
964
+ * own properties is copied to the flat root (FLAT-11). Both set
965
+ * `reshapedBody`, and the validator re-checks the routed body against its
966
+ * unchanged schema. A body whose root is the target of its own `$dynamicRef`
967
+ * (or 2019-09 `$recursiveRef`) recursion stays wrapped (see
968
+ * `dynamicRecursionProblem`).
969
+ */
970
+ /** One of the four input channels a generated tool can declare. */
971
+ export declare type InputComponentName =
972
+ | "body"
973
+ | "queryParams"
974
+ | "pathParams"
975
+ | "headers";
976
+
807
977
  /**
808
978
  * ISO 3166-1 Alpha-2 codes
809
979
  * @public
@@ -1077,6 +1247,21 @@ declare type JsonObject = {
1077
1247
 
1078
1248
  declare type JsonPrimitive = string | number | boolean | null;
1079
1249
 
1250
+ /**
1251
+ * Reads prompt metadata from direct properties and, with `resolveReferences`,
1252
+ * from unconditional `$ref` and `allOf` constraints.
1253
+ *
1254
+ * - With `improvedSchemaValidation`, the build runs it with
1255
+ * `resolveReferences` on a prompt's generated schema (mcp-tool-schemas
1256
+ * MCPSCHEMA-32, compat-improved-schema-validation SCHEMAVAL-2).
1257
+ * - Without it, the legacy path runs it without `resolveReferences` on the
1258
+ * prompt validator's Zod-derived schema (mcp-tool-schemas-legacy).
1259
+ */
1260
+ export declare function jsonSchemaToPromptArguments(
1261
+ schema: object,
1262
+ resolveReferences?: boolean
1263
+ ): PromptArgument[];
1264
+
1080
1265
  /**
1081
1266
  Matches any valid JSON value.
1082
1267
  @see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`.
@@ -1708,6 +1893,31 @@ declare interface ParameterDefinition extends ParameterBaseObject {
1708
1893
  in: string;
1709
1894
  }
1710
1895
 
1896
+ /**
1897
+ * Computes the flat `inputSchema` for a composite tool input schema.
1898
+ *
1899
+ * @param composite - the JSON Schema for the nested composite (the object whose
1900
+ * properties are `body` / `queryParams` / `pathParams` / `headers`)
1901
+ * @param present - the components this operation actually declares
1902
+ * @param preserveJsonSchema - the schemas are enforced as written by the
1903
+ * generated validators, so a body keyword that has no flat equivalent keeps it
1904
+ * wrapped, and FLAT-10 and FLAT-11 apply. `false` for the legacy Zod path.
1905
+ * @returns the flattening plan, or the reason flattening was refused
1906
+ *
1907
+ * @example
1908
+ * ```ts
1909
+ * const result = planFlatInput(z.toJSONSchema(composite), ["body"]);
1910
+ * if (result.ok) {
1911
+ * console.log(result.schema); // { type: "object", properties: { query: ... } }
1912
+ * }
1913
+ * ```
1914
+ */
1915
+ export declare const planFlatInput: (
1916
+ composite: Record<string, unknown>,
1917
+ present: InputComponentName[],
1918
+ preserveJsonSchema?: boolean
1919
+ ) => FlatInputResult;
1920
+
1711
1921
  /**
1712
1922
  * @public
1713
1923
  */
@@ -1760,6 +1970,13 @@ declare interface PreRequestHandlerApi {
1760
1970
  readonly signal: AbortSignal;
1761
1971
  }
1762
1972
 
1973
+ /** A named argument advertised by an MCP prompt. */
1974
+ export declare interface PromptArgument {
1975
+ name: string;
1976
+ description: string;
1977
+ required: boolean;
1978
+ }
1979
+
1763
1980
  /**
1764
1981
  * Generic type parameters for a request.
1765
1982
  * Extends RequestInitGeneric and adds query parameter typing.
@@ -1885,6 +2102,91 @@ export declare interface RouteData {
1885
2102
 
1886
2103
  /* Excluded from this release type: sanitizedIdentifierName */
1887
2104
 
2105
+ /** Builds the advertised schemas of one module, for one `schemaRefs` setting. */
2106
+ declare class SchemaAssembler {
2107
+ private readonly tables;
2108
+ readonly mode: SchemaRefs;
2109
+ private readonly parsed;
2110
+ private readonly refs;
2111
+ private readonly recursive;
2112
+ /** Per table: each component with its non-recursive references inlined. */
2113
+ private readonly bodies;
2114
+ /** Per table: the recursive components a body still references. */
2115
+ private readonly needs;
2116
+ private readonly assembled;
2117
+ constructor(tables: DefTables, mode: SchemaRefs);
2118
+ /**
2119
+ * The schema a tool advertises, assembled on first call and cached.
2120
+ *
2121
+ * @param schema - the generated schema
2122
+ * @param kind - the nested or flat `inputSchema`, or the `outputSchema`
2123
+ */
2124
+ assemble(schema: AssemblableSchema, kind: SchemaKind): object;
2125
+ /**
2126
+ * MCPSCHEMA-6: a `body` or output root that is only a `$ref` is replaced
2127
+ * by its target. The generated root keeps the reference, so a component
2128
+ * used as a body in many tools is not repeated in each.
2129
+ */
2130
+ private replaceRootRef;
2131
+ private memo;
2132
+ private parse;
2133
+ private refsOf;
2134
+ /**
2135
+ * `defs` mode: the root with the components it reaches under `$defs`,
2136
+ * sorted by name, as the build's own assembly wrote them before components
2137
+ * were shared.
2138
+ */
2139
+ private withDefs;
2140
+ /** Marks the components of `table` that sit on a reference cycle. */
2141
+ private markRecursion;
2142
+ private isRecursive;
2143
+ /**
2144
+ * `inline` mode: a reference to a component that does not reference itself
2145
+ * (directly or through others) becomes the component. References on a cycle
2146
+ * stay `$ref`s, with the cyclic components under `$defs`.
2147
+ */
2148
+ private inline;
2149
+ /** The component with its non-recursive references inlined, shared. */
2150
+ private body;
2151
+ private needsOf;
2152
+ /**
2153
+ * Rewrites one schema: inlines references to non-recursive components, and
2154
+ * writes the advertised form of `discriminator` (below). Subtrees that
2155
+ * change nothing are returned as they are, so components are shared.
2156
+ */
2157
+ private walk;
2158
+ private walkList;
2159
+ /** Walks the keywords of an object that is not (or no longer) a `$ref`. */
2160
+ private walkSiblings;
2161
+ /**
2162
+ * SV-15: a `discriminator.mapping` value names a component, which no longer
2163
+ * resolves once references are inlined. An input drops the whole
2164
+ * `discriminator`, as the Zod conversion of a union did; an output keeps
2165
+ * `propertyName` and drops `mapping`.
2166
+ */
2167
+ private discriminator;
2168
+ }
2169
+
2170
+ /**
2171
+ * What a generated schema is. A nested `input` has a `body` property, a
2172
+ * `flat` input has the body's properties in place of it, and an `output` is
2173
+ * the response schema.
2174
+ */
2175
+ declare type SchemaKind = "input" | "flat" | "output";
2176
+
2177
+ /**
2178
+ * Assembles the schemas `tools/list` advertises from the data the build
2179
+ * generates (packages/runtime/specs/mcp-tool-schemas.md MCPSCHEMA-6).
2180
+ *
2181
+ * The generated module holds each shared component once, as a JSON string in a
2182
+ * table, and every tool's schema as a root that points at the table with
2183
+ * `#/$defs/<name>` references. A source that repeated each component in each
2184
+ * tool grows with tools times components. Assembly happens on first use, per
2185
+ * tool, and is cached; a component is parsed once however many tools use it.
2186
+ */
2187
+ /** How an advertised schema carries shared components. */
2188
+ declare type SchemaRefs = "inline" | "defs";
2189
+
1888
2190
  export declare function setGlobalZuploEventContext(
1889
2191
  event: ZuploEventContext
1890
2192
  ): void;
@@ -1898,6 +2200,25 @@ declare interface UrlConfig {
1898
2200
 
1899
2201
  declare type UserDataDefault = any;
1900
2202
 
2203
+ /**
2204
+ * Whether a project's MCP tool schemas use the by-spec settings: validated per
2205
+ * the JSON Schema dialect and OpenAPI version they declare, instead of the
2206
+ * legacy Zod path built at runtime from `raw()` (mcp-tool-schemas-legacy).
2207
+ *
2208
+ * `improvedSchemaValidation` turns them on. This is the one place that
2209
+ * reads the flag for tool schemas: the build (`packages/codegen/src/mcp-tool-schemas/`) calls it with the project's
2210
+ * merged flags, and `mcpServerHandler` with
2211
+ * `Environment.instance.build.COMPATIBILITY_FLAGS`. Both come from the same
2212
+ * merged flags, so they always agree.
2213
+ *
2214
+ * @param flags - resolved compatibility flags (`COMPATIBILITY_FLAGS`, or the
2215
+ * build's merged flags by name)
2216
+ * @returns `true` when `improvedSchemaValidation` is `true`
2217
+ */
2218
+ export declare function usesImprovedSchemaValidation(flags: {
2219
+ readonly improvedSchemaValidation?: boolean;
2220
+ }): boolean;
2221
+
1901
2222
  /**
1902
2223
  * @public
1903
2224
  */