pub struct ToolDescriptor {
pub id: String,
pub name: String,
pub description: String,
pub kind: ToolKind,
pub arg_names: Vec<String>,
pub arg_descriptions: Vec<String>,
pub score: Option<f32>,
pub meta: Option<Value>,
pub widget_accessible: bool,
pub output_template: Option<String>,
}Expand description
A ranked tool descriptor (Contract 1).
Fields§
§id: String<server>__<tool> | composio__<slug>.
name: String§description: StringNever null — "" when absent.
kind: ToolKind§arg_names: Vec<String>§arg_descriptions: Vec<String>§score: Option<f32>§meta: Option<Value>The tool’s _meta, verbatim (widget keys), when present.
widget_accessible: boolWhether a widget originating from this tool may callTool (companion).
output_template: Option<String>The ui://widget/<slug>.html template uri when this tool renders a widget.
Implementations§
Source§impl ToolDescriptor
impl ToolDescriptor
Sourcepub fn matches_allowlist(&self, allowlist: &[String]) -> bool
pub fn matches_allowlist(&self, allowlist: &[String]) -> bool
Whether this descriptor is reachable under an agent’s tool allowlist,
matching the execution gate ([super::tool_allowed]) so a ?agent=
search view does not under-report tools the agent can actually call:
for MCP/built-in/app tools an entry may be the fully-qualified id, the
bare tool name, or the server segment; for Composio it is matched on
the fully-qualified id only (Composio ids have no name/server grant form,
and id-only is the cross-plane-bypass guard on the call path).
§ToolKind::Skill: id or server segment, never the bare name
A skill row’s id is skills__<slug>, so its server segment is the skills
provider — the grant that lets an agent call skills__load at all. Matching
on id-or-server therefore mirrors the execution gate’s tool-allowlist half
exactly: an agent with no grant on the skills server cannot load any skill,
so surfacing skill rows to it would advertise nothing reachable.
The bare name is deliberately excluded. A skill’s name is human prose
(“Resolve merge conflicts”), and the default arm’s e == name would let an
allowlist entry written for a tool (search, meant for exa__search) match
a skill that happens to be called “search” — the same cross-plane
bare-name match the gateway’s is_allowed doc records as security fix #1.
What this does NOT check is the agent’s per-agent skill allowlist
(AgentRecord.skills), which is a different list this crate never sees; it
is what skills__search / skills__load scope on. So under a tool
allowlist that grants skills, this returns true for every enabled skill,
including ones outside that agent’s skill allowlist — which skills__load
will still refuse. See McpRegistry::search_scoped for where the skill
allowlist is applied and which plane still misses it.
Trait Implementations§
Source§impl Clone for ToolDescriptor
impl Clone for ToolDescriptor
Source§fn clone(&self) -> ToolDescriptor
fn clone(&self) -> ToolDescriptor
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more