Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Web console

Rustybin ships a browser console at /ui, built for presenting: it shows what the upstream received, lets you send traffic directly or through your gateway, and drives every protocol without extra tools. The console is plain HTML, CSS and JavaScript modules embedded into the binary at build time (no Node build, no CDN), so it works offline and on air-gapped demo laptops.

GET /ui redirects (307) to /ui/ with a relative Location, so the console also works behind a gateway path prefix. Assets are served with a strong ETag and Cache-Control: no-cache, the page with a strict Content Security Policy (scripts and styles only from the console itself; requests may go to any origin, which is what "send through the gateway" needs). Like the control plane, /ui/* is never captured by the inspector and ignores fault injection headers.

GET {{base_url}}/ui
HTTP 307
[Asserts]
header "Location" == "ui/"
GET {{base_url}}/ui/
HTTP 200
[Asserts]
header "Content-Type" == "text/html; charset=utf-8"
header "Cache-Control" == "no-cache"
header "ETag" exists
header "Content-Security-Policy" contains "script-src 'self'"

When the instance protects its control plane (RUSTYBIN_CONTROL_AUTH=token or jwt), the console's files still load without credentials, but every call to /_rustybin/* carries a token. Open the console with the token in the URL fragment, /ui/#token=<token> (or /ui/#/traffic&token=<token>), or paste it on the sign-in screen. The console keeps it for the browser tab only, strips it from the address bar, sends it as Authorization: Bearer (the live traffic feed included), and shows the sign-in screen again when the token is refused or its exp passes. Console settings, Sign out forgets it. Details: Control-plane security.

RUSTYBIN_CONSOLE_TITLE (up to 80 characters) is shown as a badge in the header and in the browser tab title; RUSTYBIN_CONSOLE_BACKLINK (an http:// or https:// URL, anything else is ignored with a warning) adds a "Back to ..." link to the header and to the sign-in screen, for example back to the portal that launched the console. Both reach the page as HTML-escaped <meta> elements, so they are visible before sign-in.

Views

The views, in sidebar order (Alt+1 to Alt+9 switch to the first nine):

ViewWhat it does
OverviewWhich instance answers, whether it is healthy, uptime and inspector counters, and the base URLs (HTTP, HTTPS, gRPC, the AI providers, MCP, A2A, OIDC) to paste into a gateway configuration
Live trafficThe request inspector live over SSE: method, path, headers, body for every request Rustybin received, with filters, highlighting of headers gateways typically add or rewrite, copy as curl, and a compare mode that diffs two requests
Mock APIsOpenAPI mocks: create one from a spec, switch mocks on and off, edit responses, rules and security, try operations and watch their traffic (see below)
Request binsCreate a request bin with a configured response, send a test request, watch captures arrive live
API explorerThe route catalogue with search and category filters, and a "Try it" request builder prefilled from each endpoint's examples
AI playgroundChat with the mock LLM in OpenAI chat, OpenAI Responses, Anthropic, Gemini, Ollama (streaming) and Bedrock (non-streaming) wire formats, with modes, fault and latency injection, tool calling with a tool result round trip, the raw wire frames, and the AI request record of each call
MCP inspectorAn MCP client for 2026-07-28 (stateless) and 2025-11-25 (session): list and call tools with forms generated from their schemas, follow progress, read resources, get prompts, answer elicitation and sampling, a JSON-RPC message log, and the OAuth discovery steps of /mcp/protected
A2A clientAgent directory and cards, blocking or streaming sends over JSON-RPC in v1.0 or v0.3 (the HTTP+JSON binding is not used), a task timeline with artifacts, input-required and auth-required continuation, cancel, and the push notification sink
Chaos and healthThe health toggle, flaky endpoints with live counters, a fault injection header builder, and a load generator (at most 500 requests and 50 in flight) with a status histogram and latency percentiles, for rate limiting, retry and circuit breaker demos
Token labTokens from the identity provider (client credentials, password, authorization code + PKCE in a popup), a JWT decoder with an expiry countdown, introspection, UserInfo and JWKS, an HMAC request signer for /auth/hmac, and a Standard Webhooks signer and verifier

Mock APIs

The Mock APIs view (/ui/#/mocks) manages the instance's OpenAPI mocks:

  • List: every mock with its URL (copy button, plus the host-based URL when one is configured), title and version, operation count, an on/off switch, a security badge, calls in the last hour with the total and the last hit, stored items for stateful mocks, and a marker for undeployed draft changes. Select mocks with the checkboxes to switch them on or off or delete them in bulk. With no mocks yet, the page is a drop zone for a spec.
  • Create wizard: drop, browse or paste an OpenAPI 3.0 / 3.1 or Swagger 2.0 file (JSON or YAML; Swagger 2.0 is converted); the review step shows the operations, security schemes and warnings (POST /_rustybin/mocks/import) and a name with the resulting URL; the last step picks how responses are produced (spec examples, generated data, your own responses, or "Remember changes", the stateful mode), whether the mock is secured and how requests are validated, then creates and deploys it.
  • Header menu: Rename, Duplicate (a copy under a new name, deployed when the source is, with empty traffic), Export YAML, Download spec (as uploaded), Download collection (Postman, Hurl, curl, .http or k6, with an optional base URL such as a gateway route), Rollback, Clear traffic and Delete.
  • Operations and the operation editor: each operation with its hit count and last call; per documented status, the response source (spec example, generated data, stateful, or a custom body built in a form generated from the schema, with a JSON view validated as you type; "Edit as custom body" turns a generated preview into a fixed response), response headers, a delay, a public toggle, and rules ("when path parameter id equals 0, respond 404"), evaluated in order. Drag rules by their handle (or use the arrows) to reorder them. The Would match preview runs the unsaved rules against the latest captured call of the operation (or one you pick) and shows which rule would answer and the value each condition saw.
  • Try it: a request prefilled from a valid sample (parameters, body, demo credentials), sent to the mock, with the response, the response source and the validation result. A picker sets the Prefer header to ask for another status or example, and a button fetches a token from the built-in identity provider.
  • Security: the mocked security switch and mode, the demo credentials to copy, a way to get a token from the built-in identity provider, and which operations are public.
  • Data (stateful mocks only): the items the mock stored, per collection, with Refresh and Reset.
  • Traffic: the mock's captured calls, live, with the matched operation, status, validation and authentication result.
  • Deploy report: the deploy checks per operation, deploy, revisions and rollback, and export as rustybin.yaml.

Edits go to the mock's draft and reach the live mock when you press Deploy (the button shows the check results). The Security switch is the exception: it deploys at once, and asks first when other draft changes would go live with it. Every view has its own link: #/mocks/<name>/<tab>/<operationId>.

With a read-only control-plane token (console scope) the view shows everything but the controls that change mocks (bulk actions, Duplicate, Reset, Rename, Delete and the editors); downloads and the rule preview still work.

Settings

The settings dialog (gear icon) stores, in the browser:

SettingEffect
SessionThe X-Rustybin-Session the console sends: it tags the console's traffic and scopes per-client state (flaky counters, bins, A2A tasks). In public mode a random session is generated on first load, because the live traffic view needs one there.
Gateway base URLViews offer to send their requests through this URL instead of directly to Rustybin (the gateway must allow CORS for the console's origin)
Admin tokenSent for admin-guarded actions (health toggles, clearing all captured requests) when the instance has RUSTYBIN_ADMIN_TOKEN. Without it, the sign-in token is sent instead (useful with the admin token or a JWT with the admin scope).
ThemeFollow the system, light or dark

Control-plane endpoints used by the console

RouteReturns
GET /_rustybin/statusName, version, commit, instance id, hostname, uptime and start time, health, public mode, admin_token_configured, control_auth, hosted_mode, console title and back link, /identity request count, inspector counters (stored, capacity, total captured) and ports
GET /_rustybin/catalogThe route catalogue as JSON: categories with counts, and every endpoint with methods, category, summary, description and runnable examples
GET {{base_url}}/_rustybin/status
HTTP 200
[Asserts]
jsonpath "$.instance_id" == "docs-examples"
jsonpath "$.healthy" == true
jsonpath "$.admin_token_configured" == true
jsonpath "$.inspector.capacity" == 500
jsonpath "$.ports.grpc" exists
GET {{base_url}}/_rustybin/catalog
HTTP 200
[Asserts]
jsonpath "$.count" > 100
jsonpath "$.categories[0].name" == "Echo & Reflection"
jsonpath "$.endpoints[0].path" == "/echo"
jsonpath "$.endpoints[0].examples[0].method" == "GET"

conformance/ui/run.sh drives every view in a real Chromium (Playwright), in light and dark mode, and fails on any browser console error.