pub struct Manifest {Show 13 fields
pub description: String,
pub version: String,
pub owner: String,
pub author: Option<String>,
pub homepage: Option<String>,
pub license: Option<String>,
pub exec: Exec,
pub cli_zip: Option<String>,
pub viewer_zip: Option<String>,
pub viewer_url: Option<String>,
pub viewer_routes: Vec<ViewerRoute>,
pub mobile_ready: bool,
pub mcp_servers: Vec<McpServer>,
}Expand description
Declarative metadata a plugin ships with itself. The wire shape is
JSON; the on-disk convention (sibling file, embedded resource,
--manifest flag, …) is deliberately out of scope of this struct
and will be settled in a follow-up.
Fields§
§description: StringOne-line description of what the plugin does. Surfaced in
listings and the plugin’s --help-equivalent UI.
version: StringVersion string. Semver convention is recommended but not enforced — the host just displays whatever’s here.
owner: StringGitHub <owner> segment of the source repo. Authors write
their canonical owner here; the installer overwrites this
field with whatever owner it was actually installed from (so
forks land on disk with the fork’s owner, not the upstream’s).
Author or authors of the plugin. Free-form string.
homepage: Option<String>Homepage or repository URL.
license: Option<String>SPDX license identifier (or any string).
exec: ExecPer-OS exec command for the plugin’s cli side — the same shape
tools use. The current platform’s vector is the program plus
its leading arguments; the run’s args are appended, and the
whole thing runs with CWD = <plugin dir>/cli/. Relative
program paths resolve against that folder; bare names keep
PATH-lookup semantics. Empty when the plugin is viewer-only.
cli_zip: Option<String>GitHub-release asset filename for the plugin’s cli bundle — a
.zip whose contents are extracted into <plugin dir>/cli/
at install time (the Self::exec working directory), the
same way Self::viewer_zip extracts to viewer/. Absent
when the exec needs nothing on disk (e.g. it invokes a
PATH-resolved program).
viewer_zip: Option<String>GitHub-release asset filename for the plugin’s viewer UI
bundle (a .zip whose root contains index.html plus
assets). When absent, the plugin has no viewer tab from this
source. Mutually exclusive with Self::viewer_url —
validated by Self::validate.
viewer_url: Option<String>Remote URL the viewer’s iframe loads directly, instead of an
on-disk bundle from Self::viewer_zip. The full URL is used
as the iframe src= verbatim — query string, path, port,
fragment all pass through. Must use https://, or http://
targeting localhost / 127.0.0.1 (development only).
Mutually exclusive with Self::viewer_zip. Self::viewer_routes
and Self::mobile_ready apply to remote-URL viewers the same
way they apply to zip-bundled viewers — the embedded axum
server still hosts the declared routes; the iframe still
receives the same postMessage protocol regardless of where
its HTML/JS loaded from.
viewer_routes: Vec<ViewerRoute>HTTP routes the viewer exposes on behalf of this plugin.
Each entry registers a handler at
/plugin/<repository>/<path> on the viewer’s embedded axum
server; a hit emits a PluginRequest { type, value } event
to the React frontend, which dispatches to the plugin’s
iframe via the postMessage bridge.
mobile_ready: boolPlugin author opts in to mobile viewer support by setting this. Mobile viewer builds only surface plugins with this flag true — mobile has no local backend binary, so plugin UIs that require a backend will misbehave unless their authors specifically design for “no-backend” mode. Defaults to false (desktop-only).
mcp_servers: Vec<McpServer>MCP servers the plugin wants the host to expose. Each entry
has a name (the identifier agents reference via
objectiveai_sdk::agent::ClientObjectiveaiMcpPluginEntry::mcp_servers)
plus the same url + authorization shape
objectiveai_sdk::agent::McpServer uses. Auth-requiring entries flag
authorization = true; credentials are resolved by the host
(env vars / config), not the manifest.
Implementations§
Source§impl Manifest
impl Manifest
Sourcepub fn has_viewer(&self) -> bool
pub fn has_viewer(&self) -> bool
Whether this plugin presents a viewer tab in the host. True
iff either viewer source field — Self::viewer_zip or
Self::viewer_url — is set.
Sourcepub fn tool_name(&self, name: &str) -> String
pub fn tool_name(&self, name: &str) -> String
LLM-visible tool name. See
objectiveai_sdk::agent::materialize_tool_name.
Sourcepub fn validate(&self) -> Result<(), &'static str>
pub fn validate(&self) -> Result<(), &'static str>
Validate fields that can’t be enforced by serde alone:
viewer_zip and viewer_url are mutually exclusive, and
viewer_url (when present) must be https:// or http://
targeting localhost / 127.0.0.1. Called at every parse
boundary (remote-fetched install, on-disk read) so a broken
manifest can’t sneak through.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Manifest
impl<'de> Deserialize<'de> for Manifest
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for Manifest
impl JsonSchema for Manifest
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreimpl StructuralPartialEq for Manifest
Auto Trait Implementations§
impl Freeze for Manifest
impl RefUnwindSafe for Manifest
impl Send for Manifest
impl Sync for Manifest
impl Unpin for Manifest
impl UnsafeUnpin for Manifest
impl UnwindSafe for Manifest
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more