# flare-plugin-host
English · [中文](README.zh-CN.md)
Host-side library for Flare capability plugins: declare what your plugin can do,
register it with the platform, withdraw it on shutdown.
## Why a library instead of calling the RPC yourself
Not to save lines — to stop you from **under-calling**.
Registration accepts a partial declaration: leave `declared_operations` empty and
the platform accepts you anyway, marks the instance `unverified`, and the
declaration boundary silently stops applying to it. Nothing errors. Nothing logs
a problem. Your plugin just quietly loses its guarantees.
`PluginDeclaration` makes every one of those fields required, so an incomplete
declaration fails at compile time instead.
## Usage
```rust
use flare_plugin_host::{PluginDeclaration, PluginHost, SeatModel};
let declaration = PluginDeclaration {
tenant_id: "0".into(),
plugin_id: "vendorx-invoice".into(),
capability_id: "vendorx.invoice.create".into(),
grpc_authority: "10.0.0.7:9000".into(),
plugin_version: env!("CARGO_PKG_VERSION").into(),
api_version: "1".into(),
manifest_sha256: String::new(),
declared_operations: vec![
"vendorx.invoice.create".into(),
"vendorx.invoice.void".into(),
],
labels: Default::default(),
seat_model: SeatModel::Tenant,
};
PluginHost::connect("http://capability:50110")
.await?
.announce(&declaration)
.await?;
```
**One registration serves every declared operation.** The platform keys the route
book by `(tenant, plugin)` — your process holds a single record, and
`declared_operations` decides what it answers for. `capability_id` is just that
record's label; it does not narrow your reach.
## seat_model is a product decision
| `Tenant` | Installed by the tenant, usable by everyone in it | Most plugins |
| `PerUser` | Still needs a per-user grant | Marginal-cost (AI billed per token) or compliance-isolated capabilities |
There is no default. Selling a per-token capability per tenant loses more money
the more it is used, so the platform refuses to guess.
## License
Apache-2.0