Skip to content

Configuration

The VgiRpcServer constructor accepts an optional configuration object:

const server = new VgiRpcServer(protocol, {
enableDescribe: true,
serverId: "my-server-01",
});
Option Type Default Description
enableDescribe boolean true Host vgi_rpc.Reflection.v1, the introspection protocol
serverId string Random 12-char hex ID Server identifier included in response metadata
protocolVersion string "" Operator-supplied protocol-contract version label, surfaced on dispatch info / access-log records
dispatchHook DispatchHook — Observability hook invoked at the start and end of every dispatch (tracing, metrics)
externalLocation ExternalLocationConfig — External storage config for externalizing large response batches
onServeStart ServeStartHook — Lifecycle hook fired once before the first dispatched request (receives the TransportKind)

The createHttpHandler function accepts an optional HttpHandlerOptions object:

const handler = createHttpHandler(protocol, {
prefix: "/api",
tokenKey: myKey,
tokenTtl: 7200,
corsOrigins: "*",
maxRequestBytes: 10_000_000,
maxResponseBytes: 5_000_000,
serverId: "http-01",
stateSerializer: customSerializer,
});
  • Type: string
  • Default: "" (root)

URL path prefix for all endpoints. All method routes are mounted under this prefix. Pass e.g. "/vgi" to mount everything under /vgi.

  • Type: Uint8Array
  • Default: Random 32 bytes

XChaCha20-Poly1305 (AEAD) master key, 32 bytes, used to seal stream state tokens. Provide a stable key if you need tokens to survive a restart or load-balance across workers; if omitted, a random key is generated and tokens will not survive a restart.

  • Type: number
  • Default: 3600 (1 hour)

State token time-to-live in seconds. Set to 0 to disable TTL checks.

  • Type: StateSerializer
  • Default: jsonStateSerializer (JSON with BigInt support)

Custom serializer for stream state objects stored in state tokens.

interface StateSerializer {
serialize(state: any): Uint8Array;
deserialize(bytes: Uint8Array): any;
}

The default jsonStateSerializer uses JSON with special handling for BigInt values (prefixed with __bigint__:).

  • Type: number
  • Default: undefined (unlimited)

Maximum request body size in bytes. Requests exceeding this limit are rejected. The limit is also advertised via the VGI-Max-Request-Bytes header.

  • Type: number
  • Default: maxRequestBytes * 16 if set, otherwise unbounded

Cap on the post-decompression size of a Content-Encoding: zstd request body, in bytes. Defends against zstd decompression bombs where a tiny compressed frame declares a huge decompressed size.

  • Type: number
  • Default: undefined (unbounded)

Hard HTTP response-body cap for unary, exchange, and each producer turn. Values must be at least 64 KiB. Overshoot is replaced by an Arrow ResponseTooLargeError response with HTTP status 200; an oversized producer turn never returns a resumable cursor. Externalized payloads do not count toward this. The effective cap is the minimum of the application, hosting, and client-advertised limits and is advertised via VGI-Max-Response-Bytes.

  • Type: number
  • Default: undefined (unbounded)

For compatibility this value is treated as an application hard response cap when maxResponseBytes is not set. It does not change the one-request/one-invocation stream shape.

hostingMaxRequestBytes / hostingMaxResponseBytes

Section titled “hostingMaxRequestBytes / hostingMaxResponseBytes”

Optional hosting-platform limits. Each is combined with its application limit by taking the minimum, so capability discovery advertises the limit the worker can actually enforce.

Optional worker sizing target exposed off-wire as CallContext.preferredResponseBytes. It is clamped to the effective hard response limit. CallContext.responseLimitBytes exposes that effective hard limit.

  • Type: number
  • Default: undefined (unbounded)

Cap on bytes uploaded to external storage during one HTTP response. Always hard — externalized uploads have no escape valve. Advertised via VGI-Max-Externalized-Response-Bytes.

  • Type: number
  • Default: undefined

Optional advertised maximum upload size, surfaced via VGI-Max-Upload-Bytes.

  • Type: string
  • Default: undefined (no CORS headers)

CORS allowed origins. When set, Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers headers are added to all responses. OPTIONS preflight requests are handled automatically.

  • Type: number | null
  • Default: 300 (5 minutes)

Access-Control-Max-Age value in seconds for preflight OPTIONS responses. Set to null to omit the header.

  • Type: number | null
  • Default: 1 (response compression enabled)

zstd compression level (1–22) for responses. Responses are compressed by default: zstd where the runtime has an encoder (Bun, Node ≥ 22.15, Deno ≥ 2.6.9), gzip elsewhere (workerd, older Node). The level applies to zstd only — the Web CompressionStream gzip encoder exposes no level.

Level 1 rather than 3 because on Arrow IPC bodies it measured 4.7x faster and smaller; see the Compression guide.

Set to null to disable response compression entirely: VGI-Supported-Encodings then goes out present-but-empty and bodies travel uncompressed however the client asks.

  • Type: AuthenticateFn
  • Default: — (no authentication)

Optional authentication callback. Called for each request before dispatch.

  • Type: boolean
  • Default: false

Advertise VGI-Proxy-Proof-Required: true on every response, so a proxy or operator can confirm this worker rejects unproofed requests. Advertisement only — it enforces nothing. Set it alongside a requireProxyProof gate built with mode: "require"; that gate arrives as an opaque AuthenticateFn the handler cannot introspect, so the posture has to be stated. See Proxy proof.

  • Type: OAuthResourceMetadata
  • Default: —

Optional RFC 9728 OAuth Protected Resource Metadata. Served at the well-known endpoint.

  • Type: string
  • Default: "openid email"

OAuth scope for PKCE authorization requests.

  • Type: ReadonlySet<string>
  • Default: Set(["https://cupola.query-farm.services"])

Allowed return-to origins for external frontend redirects.

  • Type: boolean
  • Default: false

Enable opt-in sticky sessions. When enabled the server advertises VGI-Sticky-Enabled: true, honours VGI-Session / VGI-Session-Accept headers, and exposes a DELETE {prefix}/__session__ teardown endpoint.

  • Type: number
  • Default: 300

Default session TTL in seconds when ctx.openSession is called without an explicit ttl override.

  • Type: Record<string, string>
  • Default: —

Headers the server emits as VGI-Echo-<name>: <value> on the session-opening response. A conformant client captures them and replays them on every subsequent request in the session (used for client-driven routing, e.g. fly-force-instance-id on Fly.io).

  • Type: ExternalLocationConfig
  • Default: —

External storage config for externalizing large response batches.

  • Type: UploadUrlProvider
  • Default: —

Provider for vending pre-signed upload URLs to clients via {prefix}/__upload_url__/init.

  • Type: boolean
  • Default: true

Enable the HTML landing page at GET {prefix}/.

  • Type: boolean
  • Default: true

Enable the HTML describe / API reference page at GET {prefix}/describe.

  • Type: boolean
  • Default: true

Enable the HTML 404 page for unmatched GET routes.

  • Type: boolean
  • Default: true

Enable the JSON health endpoint at GET {prefix}/health.

  • Type: string
  • Default: the Protocol’s name

Protocol name shown in HTML pages.

  • Type: string
  • Default: —

URL to the service’s source repository, shown in the landing / describe pages.

  • Type: string
  • Default: Random ID

Server ID included in response metadata. Useful for identifying which server handled a request in multi-server deployments.

  • Type: string
  • Default: —

Operator-supplied protocol-contract version label, surfaced on every access-log record.

  • Type: DispatchHook
  • Default: —

Optional dispatch hook for observability (tracing, metrics).

  • Type: ServeStartHook
  • Default: —

Optional lifecycle hook fired once on the first dispatched request. Lazy-firing keeps it fork-safe for pre-fork servers.

The httpConnect function accepts an optional HttpConnectOptions object:

const client = httpConnect("http://localhost:8080", {
prefix: "/api",
compressionLevel: 3,
onLog: (msg) => console.log(`[${msg.level}] ${msg.message}`),
});
Option Type Default Description
prefix string "" (root) URL path prefix
onLog (msg: LogMessage) => void — Log message callback
compressionLevel number — zstd compression level (omit to disable)
authorization string — Authorization header value (e.g. "Bearer <token>") sent with every request
externalLocation ExternalLocationConfig — External storage config for resolving externalized batches
fetch typeof globalThis.fetch global fetch Request implementation for every SDK-owned HTTP operation. Prefer httpConnectSocks5h for the built-in strict SOCKS adapter.

The pipeConnect function accepts an optional PipeConnectOptions object:

Option Type Default Description
onLog (msg: LogMessage) => void — Log message callback
externalLocation ExternalLocationConfig — External storage config for resolving externalized batches

The subprocessConnect function accepts an optional SubprocessConnectOptions object (extends PipeConnectOptions):

const client = subprocessConnect(["bun", "run", "server.ts"], {
cwd: "./my-project",
env: { DEBUG: "1" },
stderr: "inherit",
onLog: (msg) => console.log(msg),
});
Option Type Default Description
cwd string — Working directory for subprocess
env Record<string, string> — Additional environment variables
stderr "inherit" | "pipe" | "ignore" "ignore" Subprocess stderr handling
onLog (msg: LogMessage) => void — Log message callback (inherited from PipeConnectOptions)
externalLocation ExternalLocationConfig — External storage config for resolving externalized batches (inherited from PipeConnectOptions)