How OpenClaude Implements Feature-Gated and Conditional Tools

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.

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.

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:

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
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.

Merging and Filtering Tools in utils/toolPool.ts

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

// 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:

// 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:

// 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 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:

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:


# 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 restricts coordinator mode to safe tools defined in 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. Ensure your build includes --feature COORDINATOR_MODE. The mergeAndFilterTools function in 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 strictly validates every tool against the COORDINATOR_MODE_ALLOWED_TOOLS whitelist defined in 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →