# Understanding GroupModes in OpenHuman's Tool Registry: Advertised, Withheld, and Off Explained

> Learn about OpenHuman's Tool Registry GroupModes Advertised Withheld and Off. Understand how these settings control RPC schema exposure and tool callability for clients.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: deep-dive
- Published: 2026-08-29

---

**OpenHuman's Tool Registry uses a three-state `GroupMode` enum—`Advertised`, `Withheld`, and `Off`—to control whether tool groups expose their RPC schemas to clients and whether their tools are actually callable.**

The `tinyhumansai/openhuman` repository implements this visibility system in its core tooling layer to give developers granular control over which tool families are discoverable, hidden, or completely disabled in a given runtime deployment. The enum is defined in [`src/openhuman/tools/toolpacks/groups.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/toolpacks/groups.rs) at line 48 and drives the filtering logic throughout the application's tool registration pipeline.

## The Three GroupMode States

The `GroupMode` enum operates as a visibility gate with three distinct states. Each state determines two critical properties: whether the group's schemas appear on the wire and whether the tools are registered and callable.

### Advertised

When a group is set to **`Advertised`**, the system exposes the group's RPC schemas to the client and registers every tool in the group for immediate invocation. This is the default behavior for unknown groups and represents full visibility and functionality.

### Withheld

The **`Withheld`** state sends the group's schemas over the wire so the client knows the tools exist, but the tools are not advertised as usable by default. The harness can later load these tools on demand. In this state, tools are hidden from the default tool list and must be explicitly enabled to become callable.

### Off

Setting a group to **`Off`** completely removes it from the runtime. The group's schemas are omitted from the RPC schema list, and none of its tools are registered or callable. This state effectively disables the entire tool family.

## Implementing GroupModes with ToolGroups

The `ToolGroups` struct in [`src/openhuman/tools/toolpacks/groups.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/toolpacks/groups.rs) manages an array of `GroupMode` values—one entry per possible group—and provides a fluent builder API for configuration.

The struct exposes three key helper methods:

- **`with(&mut self, id: &str, mode: GroupMode) -> Self`** – Sets the mode for a specific group ID and returns self for chaining.
- **`mode(&self, id: &str) -> GroupMode`** – Reads a group's current mode, defaulting to `Advertised` for unknown groups.
- **`mode_for_tool(&self, tool: &str) -> GroupMode`** – Determines which mode owns a particular tool name, treating orphaned tools as `Advertised`.

The higher-level registration logic in [`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs) consults these modes when deciding whether to register a tool:

```rust
// Simplified logic from src/openhuman/tools/ops.rs
if groups.mode_for_tool(tool_name) != GroupMode::Off {
    // Register the tool – visible if Advertised or Withheld
}

```

## Preset Configurations

`ToolGroups` provides four factory presets that cover common deployment scenarios. These presets are utilized in [`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs) and [`src/embed/harness/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/embed/harness/builder.rs) to tailor tool availability for specific embedder configurations.

| Preset | Behavior |
|--------|----------|
| `ToolGroups::advertised()` | All groups set to `Advertised` (full visibility). |
| `ToolGroups::withheld()` | All groups set to `Withheld` (schemas visible, tools disabled by default). |
| `ToolGroups::none()` | All groups set to `Off` (complete disablement). |
| `ToolGroups::packed()` | "system" group is `Off`, all others are `Withheld` (minimal system exposure). |

## Practical Configuration Examples

You can instantiate these presets and customize them using the builder pattern. Here are three common patterns from the codebase:

```rust
use openhuman_core::openhuman::tools::toolpacks::{GroupMode, ToolGroups};

// Example 1: Advertise only the "documents" group, disable everything else
let groups = ToolGroups::none()
    .with("documents", GroupMode::Advertised);

// Example 2: Start with all groups withheld, then expose specific workflows
let groups = ToolGroups::withheld()
    .with("workflows", GroupMode::Advertised);

// Example 3: Use the packed preset (system off, others withheld)
let groups = ToolGroups::packed();

```

In Example 1, `groups.mode("documents")` returns `Advertised` while all other groups return `Off`. Example 2 keeps background utilities hidden while exposing workflow tools. Example 3 reflects the production configuration used when building embedder harnesses where system-level tools must remain inaccessible.

## Summary

- **`GroupMode`** is a three-state enum defined in [`src/openhuman/tools/toolpacks/groups.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/toolpacks/groups.rs) that controls both schema visibility and tool callability.
- **`Advertised`** exposes schemas and enables invocation; **`Withheld`** exposes schemas but disables invocation by default; **`Off`** hides schemas and disables invocation completely.
- The **`ToolGroups`** struct provides builder methods `with()`, `mode()`, and `mode_for_tool()` for programmatic configuration.
- Factory presets including `advertised()`, `withheld()`, `none()`, and `packed()` streamline configuration in runtime and harness builders.

## Frequently Asked Questions

### What is the difference between Withheld and Off in OpenHuman's GroupMode?

**Withheld** exposes the group's RPC schemas to the client so the tools are discoverable, but the tools are not callable until explicitly enabled. **Off** completely removes the group from the runtime—no schemas are sent, and the tools cannot be invoked under any circumstances.

### How do I configure a specific tool group mode in OpenHuman?

Instantiate a `ToolGroups` preset (like `ToolGroups::none()`) and chain the `.with("group_id", GroupMode::Advertised)` method to set specific modes. This pattern is used in both [`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs) and [`src/embed/harness/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/embed/harness/builder.rs) to configure runtime visibility.

### Where is the GroupMode enum defined in the OpenHuman source code?

The `GroupMode` enum is defined at line 48 in [`src/openhuman/tools/toolpacks/groups.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/toolpacks/groups.rs). The accompanying `ToolGroups` struct and its builder methods are implemented in the same file.

### What happens to tools when their group mode is set to Withheld?

Tools in a `Withheld` group have their schemas transmitted over the wire, allowing clients to know they exist, but they are filtered out of the default tool list. Operators can later enable these tools on demand, whereas `Off` tools are permanently excluded from registration logic in [`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs).