Skip to main content

capability

Macro capability 

Source
macro_rules! capability {
    (
        id: $id:expr,
        kind: $kind:expr,
        title: $title:expr,
        description: $description:expr,
        input: $input:ty,
        output: $output:ty,
        stability: $stability:expr,
        exposure: $exposure:expr,
        tags: [$($tag:expr),* $(,)?],
        cache: $cache:expr,
        benchmark: $benchmark:expr,
        handler: $handler:expr $(,)?
    ) => { ... };
    ( id: $id:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], handler: $h:expr $(,)? ) => { ... };
    ( id: $id:expr, kind: $k:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], handler: $h:expr $(,)? ) => { ... };
    ( id: $id:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], cache: $c:expr, handler: $h:expr $(,)? ) => { ... };
    ( id: $id:expr, kind: $k:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], cache: $c:expr, handler: $h:expr $(,)? ) => { ... };
    ( id: $id:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], benchmark: $b:expr, handler: $h:expr $(,)? ) => { ... };
    ( id: $id:expr, kind: $k:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], benchmark: $b:expr, handler: $h:expr $(,)? ) => { ... };
    ( id: $id:expr, title: $title:expr, description: $d:expr, input: $i:ty, output: $o:ty, stability: $s:expr, exposure: $e:expr, tags: [$($t:expr),* $(,)?], cache: $c:expr, benchmark: $b:expr, handler: $h:expr $(,)? ) => { ... };
}
Expand description

The one canonical declaration of an executable capability. From it every projection is derived: the MCP tool and its schemas, the HTTP route and its OpenAPI operation, the Swagger UI entry, the command line’s introspection, the benchmark targets for every transport it is exposed on, the cache policy the executor applies, and the generated reference. Nothing is declared a second time anywhere.

Fields, in this order: id, an optional kind (a query by default; CapabilityKind::Command for one that changes this process’s memory), title, description, input, output, stability, exposure, tags, an optional cache (CachePolicy::Disabled by default), an optional benchmark (BenchmarkPolicy::Required by default), and handler. $input and $output derive schemars::JsonSchema (and serde), and $input implements super::benchmark::BenchmarkCases: their schemas become the canonical schemas, their doc comments the descriptions a client reads, and the input’s cases the benchmark inputs of every transport. The provenance is the Rust module the macro is expanded in; the capability’s module is stamped by crate::module!. Nothing here registers anything: the result is composed explicitly into a module.

use majordomus_cli::capability;
use majordomus_cli::capability::{BenchmarkCases, CachePolicy, CaseContext, Context, CapabilityError, Exposure, NamedCase, Stability};
#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
struct In {}
impl BenchmarkCases for In {
    fn benchmark_cases(_: &CaseContext<'_>) -> Vec<NamedCase<Self>> { vec![NamedCase::new("default", In {})] }
}
#[derive(serde::Serialize, schemars::JsonSchema)]
struct Out { ok: bool }
fn ping(_: &Context, _: In) -> Result<Out, CapabilityError> { Ok(Out { ok: true }) }
let e = capability! {
    id: "demo.ping", title: "Ping", description: "Answers.", input: In, output: Out,
    stability: Stability::Experimental, exposure: Exposure::default(), tags: ["demo"],
    cache: CachePolicy::Process { max_entries: 8, ttl_seconds: None },
    handler: ping,
};
assert_eq!(e.capability.id.as_str(), "demo.ping");
assert!(e.capability.cache.is_enabled());