---
title: Capability authoring
description: Define Request, Stream, and Event contracts and generate each language projection in its owning package.
---

A Capability is the contract between a consumer and a provider. Author it once;
each Rust or Bun distribution generates only the projection it owns.

The first `lenso plugin new` scaffold consumes the existing Agent Tool Provider
Capability. Defining a new cross-Plugin role remains an explicit contract-owner
workflow: author the Descriptor and schemas, generate each owned projection,
and publish them from the Capability package.

## Create a request Capability

This descriptor declares one `greet` Operation:

```json title="contract/greeting/capability.json"
{
  "id": "example.greeting@1",
  "version": "1.0.0",
  "portable": true,
  "cross_lane_transfer": true,
  "operations": [{
    "name": "greet",
    "interaction": "request",
    "request_schema": "schemas/greet-request.schema.json",
    "response_schema": "schemas/greet-response.schema.json",
    "domain_error_schema": "schemas/greet-error.schema.json"
  }]
}
```

The three referenced files are ordinary JSON Schema. Keep expected business
failures in the Domain Error schema rather than returning strings from runtime
exceptions:

```json title="contract/greeting/schemas/greet-error.schema.json"
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "string",
  "enum": ["empty_name"]
}
```

Install the generator and write the projection owned by this package. For a
native Rust Capability package:

```sh
cargo install lenso-contract-codegen --locked
lenso-contract-codegen generate \
  contract/greeting/capability.json \
  --rust \
  contract/greeting/src/generated.rs
```

For a custom Bun Capability package, use `--typescript` and keep only the
TypeScript output. Official Lenso Bun projections are published by
`@lenso/bun` from locked snapshots of their owner repositories.

```sh
bun add @lenso/bun
```

CI should reject generated drift and incompatible revisions:

```sh
lenso-contract-codegen check \
  contract/greeting/capability.json \
  --rust \
  contract/greeting/src/generated.rs

lenso-contract-codegen lint old/capability.json contract/greeting/capability.json
```

## Choose the interaction shape

| Shape | Descriptor value | Use it for | Current semantics |
| --- | --- | --- | --- |
| Request | `"request"` | commands and queries with one terminal result | bounded queue, concurrency, deadline, cancellation |
| Stream | `"stream"` | bidirectional conversations | bounded messages, independent half-close, explicit terminal result |
| Event | `"event"` | volatile fan-out | per-subscriber bounded admission and partial outcomes; no persistence or redelivery |

For Stream and Event, only the `interaction` value changes. The generator emits
the matching Provider/Client types for the selected language.

## Configure capacity in Composition

Capacity is App policy, not part of the portable Descriptor. The Plugin-owned
contract supplies safe defaults; the resolved App Plan records Request
admission, operation overrides, and Event mailbox bounds for the exact
Generation.

`event_capacity` matters only for Event Operations. A full queue rejects
admission; it does not silently become a durable Outbox.

## Keep package-owned projections current

Run `lenso-contract-codegen check` in each package that distributes a generated
projection. App authoring consumes the resulting Plugin Descriptor and Bundle;
it does not use a second `lenso.json` contract registry.

See the complete, maintained fixtures for
[Request](https://github.com/LioRael/lenso-cli/tree/main/crates/lenso-authoring/tests/fixtures/contracts/greeting),
[Stream](https://github.com/LioRael/lenso-protocols/tree/main/crates/lenso-contract-codegen/tests/fixtures/stream),
and [Event](https://github.com/LioRael/lenso-protocols/tree/main/crates/lenso-contract-codegen/tests/fixtures/event).
