Watch
0
0
Fork
You've already forked hyperhive
0

hive-runtime, hive-agent: MCP permission only for kind other

A permission request counted as an MCP tool call whenever its title
looked like `<server>_<tool>`, whatever its kind, and acp_permits
allowed MCP calls before looking at the kind. So an `execute` request
titled e.g. `hyperhive_x`, or a `fetch` without web_tools, was allowed.

MCP tool calls come with kind `other` (opencode's toToolKind maps every
tool it doesn't name, MCP tools included, to "other"). The runtime now
sets PermissionAsk::mcp_server only for kind `other`, and acp_permits
allows an MCP server's tool only under the `other` arm.

Refs #4391
This commit is contained in:
atlas 2026-09-29 22:14:06 +02:00 • committed by mara
commit bed72ce280
3 changed files with 49 additions and 10 deletions

View file

@ -344,8 +344,9 @@ fn acp_permission_policy() -> PermissionPolicy {
/// Whether an ACP agent may run the tool call it asks about. Default-deny,
/// allowing what a claude agent has:
///
/// - tools of the MCP servers the session was handed — which of those an
/// agent gets is already decided by its tool groups (`mcp_config`);
/// - `other`-kind calls to tools of the MCP servers the session was handed
/// — which of those an agent gets is already decided by its tool groups
/// (`mcp_config`);
/// - the file tools, mirroring the claude built-ins
/// (`hive_sh4re::permissions`): `read`, `edit`, `search`;
/// - `fetch` with the `web_tools` group (`web`).
@ -353,10 +354,8 @@ fn acp_permission_policy() -> PermissionPolicy {
/// Everything else is refused, including a built-in shell (`execute`) —
/// shell goes through `mcp__bash__run` — and any kind this list doesn't name.
fn acp_permits(ask: &PermissionAsk<'_>, web: bool) -> bool {
if ask.mcp_server.is_some() {
return true;
}
match ask.kind {
"other" => ask.mcp_server.is_some(),
"read" | "edit" | "search" => true,
"fetch" => web,
_ => false,
@ -891,6 +890,20 @@ mod tests {
assert!(acp_permits(&mcp, false));
}
#[test]
fn an_mcp_looking_title_does_not_lift_execute_or_fetch() {
let execute = PermissionAsk {
kind: "execute",
mcp_server: Some("hyperhive"),
};
assert!(!acp_permits(&execute, true));
let fetch = PermissionAsk {
kind: "fetch",
mcp_server: Some("hyperhive"),
};
assert!(!acp_permits(&fetch, false));
}
#[test]
fn acp_fetch_follows_the_web_tools_group() {
assert!(acp_permits(&ask("fetch"), true));