# How OpenClaude Implements Feature-Gated and Conditional Tools

> Discover how OpenClaude uses compile-time flags, environment variables, and whitelists to implement feature-gated and conditional tools. Learn about its three-layer strategy.

- Repository: [Gitlawb/openclaude](https://github.com/Gitlawb/openclaude)
- Tags: internals
- Published: 2026-09-05

---

**OpenClaude controls tool availability through a three-layer strategy combining Bun’s compile-time feature flags, environment-variable mode switches, and curated whitelists defined in [`src/constants/tools.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/tools.ts).**

OpenClaude, the open-source Claude Code implementation, manages which AI tools are available at runtime using a sophisticated gating system. This architecture allows developers to ship lean binaries while optionally enabling heavy or experimental capabilities through **feature-gated and conditional tools**. The implementation leverages Bun's bundler features, runtime environment detection, and whitelist filtering to create a secure, modular tool pool.

## The Three-Layer Gating Architecture

OpenClaude’s tool gating operates at distinct stages: compilation, runtime initialization, and execution. This separation ensures that unused capabilities are eliminated from bundles entirely, while active modes can be toggled without redeployment.

### Compile-Time Feature Flags with Bun

At the bundling stage, OpenClaude uses Bun’s `feature` API to eliminate dead code before it reaches the final binary. When the bundler is invoked with a flag (e.g., `--feature COORDINATOR_MODE`), the `feature('COORDINATOR_MODE')` call resolves to `true`. If the flag is absent, the bundler optimizes away the gated code entirely.

```typescript
import { feature } from 'bun:bundle';

const isCoordinator = feature('COORDINATOR_MODE')
  ? isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
  : false;

```

Because the coordinator module imports heavy UI dependencies like React and Ink, this conditional compilation prevents bloating the default binary. The gated code simply does not exist in builds lacking the feature flag.

### Runtime Mode Activation via Environment Variables

When the coordinator feature is compiled in, activation is controlled at runtime by the `CLAUDE_CODE_COORDINATOR_MODE` environment variable. The helper `isEnvTruthy` treats any non-empty value as enabled, allowing administrators to switch modes without rebuilding:

```typescript
const coordinatorModeModule = feature('COORDINATOR_MODE')
  ? (require('../coordinator/coordinatorMode.js') as typeof import('../coordinator/coordinatorMode.js'))
  : null;

```

This pattern enables a single binary to operate in either normal or coordinator mode based solely on the execution environment.

### Tool Whitelisting for Coordinator Mode

When coordinator mode is active, OpenClaude restricts tool access to a vetted subset. The whitelist is defined as a constant `Set` in [`src/constants/tools.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/tools.ts):

```typescript
// https://github.com/Gitlawb/openclaude/blob/main/src/constants/tools.ts
export const COORDINATOR_MODE_ALLOWED_TOOLS = new Set([
  'list_files', 'read_file', /* …other safe tools… */
]);

```

This whitelist ensures that only safe, idempotent tools execute in coordinator environments, protecting the system from unintended side effects.

## Implementation in the Tool Pool

The core logic for merging built-in tools, MCP-provided tools, and applying feature gates resides in [`src/utils/toolPool.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/toolPool.ts).

### Merging and Filtering Tools in [`utils/toolPool.ts`](https://github.com/Gitlawb/openclaude/blob/main/utils/toolPool.ts)

All tools are consolidated in the `mergeAndFilterTools` function, which deduplicates entries and applies coordinator-mode filtering when appropriate:

```typescript
// https://github.com/Gitlawb/openclaude/blob/main/src/utils/toolPool.ts
export function mergeAndFilterTools(initialTools, assembled, mode) {
  const tools = …; // deduped & sorted list
  if (feature('COORDINATOR_MODE') && coordinatorModeModule) {
    if (coordinatorModeModule.isCoordinatorMode()) {
      return applyCoordinatorToolFilter(tools);
    }
  }
  return tools;
}

export function applyCoordinatorToolFilter(tools) {
  return tools.filter(
    t => COORDINATOR_MODE_ALLOWED_TOOLS.has(t.name) ||
         isPrActivitySubscriptionTool(t.name)   // PR-activity tools are always allowed
  );
}

```

The `applyCoordinatorToolFilter` function checks each tool against the whitelist, with special exceptions for PR-activity subscription tools that remain available regardless of coordinator status.

### GrowthBook Runtime Feature Flags

Beyond coordinator mode, OpenClaude supports dynamic feature gating through GrowthBook. Runtime flags like `feature('MEMORY')` or `feature('TOOL_SEARCH')` follow the same conditional import pattern:

```typescript
// src/utils/toolPool.ts (excerpt)
if (feature('TOOL_SEARCH')) {
  // Only import the heavy search implementation when the flag is present.
  const { searchTool } = require('../tools/SearchTool.js');
  assembled.push(searchTool);
}

```

These checks evaluate the flag first; if present, the runtime condition determines whether the tool proceeds to execution.

## Practical Implementation Examples

### Adding a Coordinator-Only Tool

To implement a tool restricted to coordinator mode, define the tool normally and add its name to the whitelist:

```typescript
// src/tools/MySpecialTool.ts
import { Tool } from '../Tool.js';
import { feature } from 'bun:bundle';

export const MySpecialTool: Tool = {
  name: 'my_special',
  async run(context) { … },
};

// src/constants/tools.ts – add to whitelist
export const COORDINATOR_MODE_ALLOWED_TOOLS = new Set([
  /* existing entries */ 'my_special',
]);

```

No changes to [`toolPool.ts`](https://github.com/Gitlawb/openclaude/blob/main/toolPool.ts) are required. The existing `mergeAndFilterTools` pipeline automatically hides the tool unless `COORDINATOR_MODE` is compiled in and the environment variable is set.

### Gating Tools with GrowthBook

For experimental tools controlled by feature flags:

```typescript
if (feature('MEMORY')) {
  const { memoryTool } = require('../tools/MemoryTool.js');
  assembled.push(memoryTool);
}

```

This ensures heavy dependencies load only when the organization explicitly enables the capability via GrowthBook.

### Building and Running with Feature Flags

Enable coordinator mode during bundling and execution:

```bash

# Build with the feature flag

bun build --feature COORDINATOR_MODE

# Run in normal mode

./openclaude

# Run in coordinator mode

CLAUDE_CODE_COORDINATOR_MODE=1 ./openclaude

```

## Summary

- **Compile-time gates** use Bun’s `feature` API to eliminate dead code and optional dependencies (like React-based coordinator UI) from the final bundle.
- **Runtime gates** rely on `CLAUDE_CODE_COORDINATOR_MODE` and GrowthBook flags to toggle capabilities without rebuilding the binary.
- **Whitelist filtering** in [`src/utils/toolPool.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/toolPool.ts) restricts coordinator mode to safe tools defined in [`src/constants/tools.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/tools.ts).
- **Conditional imports** prevent heavy modules from loading unless their corresponding feature flags are present, optimizing startup time and memory usage.

## Frequently Asked Questions

### What is the difference between compile-time and runtime feature gates in OpenClaude?

Compile-time gates use Bun’s bundler to completely remove code from the binary when flags like `COORDINATOR_MODE` are absent, ensuring zero runtime overhead. Runtime gates use environment variables (`CLAUDE_CODE_COORDINATOR_MODE`) and GrowthBook to toggle features dynamically, but require the code to be included in the build first.

### How do I add a new tool that only works in coordinator mode?

Create the tool implementation in `src/tools/`, then add its name to the `COORDINATOR_MODE_ALLOWED_TOOLS` Set in [`src/constants/tools.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/tools.ts). Ensure your build includes `--feature COORDINATOR_MODE`. The `mergeAndFilterTools` function in [`src/utils/toolPool.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/toolPool.ts) handles the rest automatically.

### Can I enable coordinator mode without rebuilding the binary?

No. Coordinator mode requires the React/Ink UI dependencies that are excluded from standard builds via Bun’s feature flag system. You must compile with `--feature COORDINATOR_MODE` to include the necessary code, after which you can toggle the mode on/off using the `CLAUDE_CODE_COORDINATOR_MODE` environment variable.

### How does OpenClaude prevent unauthorized tools from running in coordinator mode?

The `applyCoordinatorToolFilter` function in [`src/utils/toolPool.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/toolPool.ts) strictly validates every tool against the `COORDINATOR_MODE_ALLOWED_TOOLS` whitelist defined in [`src/constants/tools.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/tools.ts). Only tools explicitly listed in this Set (plus PR-activity subscriptions) execute when coordinator mode is active, preventing potentially destructive operations in restricted environments.