* feat: add Horizon authentication client and state
* fix: apply Windows state ACLs to existing descriptors
* fix: distinguish public route authorization failures
* fix: harden Horizon state boundaries
* Separate proxy protocol policy from client construction
🤖 Generated with OpenAI Codex
* Strip connection-owned request metadata at the proxy backend boundary
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Sanitize forwarded request metadata where the proxy copies it
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Forward hop-safe request metadata for proxied resources, templates, and prompts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Fix upgrade static analysis
Generated with Codex
* Preserve concrete transport return types
Generated with Codex
* Avoid widening transport return types
Generated with Codex
* Model transforming transport return types
Generated with Codex
* Exclude standalone screenshot examples from ty
Generated with Codex
* Always emit a tool title, derived from name when unset
Some MCP clients (e.g. ChatGPT) drop tools with no `title` instead of
falling back to `name` for display as the spec allows. Deriving a
default title in Tool.to_mcp_tool() fixes this for every tool built on
top of it, including the search-transform, code-mode, and session
proxy tools that never set one explicitly.
Fixes#4414
* Derive fallback title from the overridden name, document it
Addresses Codex review on #4694.
* Resolve title precedence from effective overrides
* Normalize mapping annotations before deriving the title
* Flatten OpenAPI discriminator subtypes into request bodies
* Resolve schema-name discriminator mappings and union conflicting variant fields
* Advertise discriminator values for propertyless variants and document the behavior
* Remove 3.x-era compatibility shims
* Require response_type in ctx.elicit()
* Name the utilities path for the two non-re-exported auth helpers
* Point sampling handler migration at its submodule
* Add require_roles auth check
* Make role docs runnable standalone and fully annotated
* Treat a scalar role claim as one role; correct step-up docs
* Add v4 version badge to require_roles docs
* Use issuer_url for OAuth issuer identity, not base_url
* Apply ruff format to issuer identity tests
* Align ID-JAG audience docstring with issuer_url
* Make InMemoryOAuthProvider keyword-only like its parent
* Keep ID-JAG audience on base_url, out of scope for issuer identity
* Remove stray scratch script
* Make AuthorizationHandler keyword-only
* Bind ID-JAG audience to the issuer identifier
* Fix double slash in issuer_url well-known log hint
A proxy has no back-channel to the real user, so driving a backend ask inside
it failed outright. Surface it as a result for the parent, as ProxyTool does.
Partial fulfillment means two in-flight updates can carry different answers,
so acknowledging the one that loses the update lock stranded the task on a key
the client had already sent.