feat(#1065): web_tools tool group gates WebFetch/WebSearch built-ins

Replaces the earlier capability-based approach (closed #1069) with a
ToolGroup — capabilities are for privileged system access, web egress is
a tool permission.

Add ToolGroup::WebTools to hive-sh4re:
- tools() returns &[] (no MCP tools gated)
- builtin_tools() returns &["WebFetch", "WebSearch"] — new method on ToolGroup
- Present in ALL and as_str() → "web_tools"

In hive-ag3nt/mcp.rs:
- allowed_tools_arg() now iterates group.builtin_tools() to prepend any
  group-gated built-ins alongside the base ALLOWED_BUILTIN_TOOLS set
- builtin_tools_arg_for_flavor(flavor) replaces builtin_tools_arg() so
  the flavor-correct effective groups are used when building --tools
- builtin_tools_arg() kept as a flavor=Agent convenience alias
- turn.rs updated to call builtin_tools_arg_for_flavor(files.flavor) so
  manager sessions also see web tools when web_tools is in their groups

The dashboard T00L GR0UPS table gains a web_tools column automatically
(ToolGroup::ALL drives the columns).
This commit is contained in:
iris 2026-06-02 11:23:39 +02:00
commit f6b80cf02e
3 changed files with 58 additions and 11 deletions

View file

@ -774,10 +774,18 @@ pub enum ToolGroup {
Diagnostics,
/// `bash_run`, `bash_status`
Execution,
/// Claude built-in web egress tools: `WebFetch` (retrieve a URL) and
/// `WebSearch` (search the web). Both are omitted from `--tools` by
/// default; adding this group to an agent enables them in the session
/// and in `--allowedTools` so they run without a confirmation prompt.
/// Does not gate any MCP tools — `tools()` returns `&[]`.
WebTools,
}
impl ToolGroup {
/// The MCP tool names (without the `mcp__hyperhive__` prefix) in this group.
/// Returns `&[]` for `WebTools` — it enables Claude built-in tools,
/// not MCP tools; see `builtin_tools()`.
#[must_use]
pub fn tools(self) -> &'static [&'static str] {
match self {
@ -804,6 +812,18 @@ impl ToolGroup {
],
Self::Diagnostics => &["get_logs"],
Self::Execution => &["bash_run", "bash_status"],
Self::WebTools => &[],
}
}
/// The Claude built-in tool names enabled by this group. Only
/// `WebTools` returns a non-empty slice; all other groups return `&[]`
/// (they control MCP tools via `tools()` instead).
#[must_use]
pub fn builtin_tools(self) -> &'static [&'static str] {
match self {
Self::WebTools => &["WebFetch", "WebSearch"],
_ => &[],
}
}
@ -837,6 +857,7 @@ impl ToolGroup {
Self::Scheduling,
Self::Diagnostics,
Self::Execution,
Self::WebTools,
];
/// The `snake_case` wire name for this group (matches `serde(rename_all =
@ -852,6 +873,7 @@ impl ToolGroup {
Self::Scheduling => "scheduling",
Self::Diagnostics => "diagnostics",
Self::Execution => "execution",
Self::WebTools => "web_tools",
}
}
}