Skip to Content
How-To GuidesEffectEffect tools and middleware

Effect tools and middleware

Build a definition with Tool.toolDefinition(name).body(...). A provider finishes it with .implement({ camelCaseName: handler }); a caller uses Tool.client(definition). Handlers and clients return Effects and stream stdin/stdout/stderr with independent Effect Stream values. Drain both outputs concurrently when both are declared.

Use Middleware.typed({ name, parameters: Middleware.NoParameters, presented, handler }) when the presented tool shape is known. Use the universal middleware API for schema-agnostic, shape-preserving policy. Universal middleware can be installed environment-wide or on selected tool bindings; typed (monomorphic) middleware can only be installed on tool bindings. Per-tool merge modes never remove environment-wide middleware. Forward input, output, permission cards, and streams at most once; capability handles are affine.

The default world supports ordinary, standalone-middleware, and combined components. Standalone middleware can be attached and deployed independently; unused agent and tool discovery returns empty lists.