# How Agent Tool Assignments Work in oh-my-claudecode: A Complete Customization Guide

> Learn how agent tool assignments work in oh-my-claudecode. Discover customization through disallowedTools and runtime overrides for tailored agent behavior.

- Repository: [Bellman/oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode)
- Tags: how-to-guide
- Published: 2026-03-27

---

**Agent tool assignments in oh-my-claudecode start with full access to all built-in tools, then apply restrictions through either front-matter `disallowedTools` declarations or explicit runtime `tools` overrides.**

Every agent in the oh-my-claudecode framework begins with unrestricted access to the complete toolkit, including **Read**, **Write**, **Edit**, **Glob**, **Grep**, **WebSearch**, and **WebFetch**. The system determines final agent tool assignments through a cascading restriction mechanism that combines static markdown configuration with dynamic runtime overrides. This architecture allows you to create specialized, read-only agents like `architect` while maintaining the flexibility to customize tool access for specific projects without touching core source code.

## The Two-Layer Agent Tool Assignment System

The framework implements a hierarchical approach to agent tool assignments where permissions flow from broad to specific:

| Restriction Source | Mechanism | Location |
|---|---|---|
| **`disallowedTools` front-matter** | Removes specific tools from the default full set (e.g., disabling `Write` and `Edit` for the architect agent) | [`agents/architect.md`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/agents/architect.md) (line 6) |
| **Explicit `tools` override** | Replaces the entire toolbox with a custom array or restriction map (`{tools:{read:true,…}}`) | Runtime via [`src/agents/definitions.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/definitions.ts) |

If neither restriction layer is present, the agent retains **all available tools**. This default-everything approach ensures agents are never accidentally crippled while still supporting precise capability limiting.

## Core Files Managing Tool Assignments

Understanding agent tool assignments requires familiarity with three critical files that handle parsing, transformation, and registry composition:

**[`src/agents/utils.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/utils.ts)** contains the parsing utilities. The `parseDisallowedTools(agentName: string)` function reads each agent's markdown front-matter and returns a string array of tool names to block. The companion `createAgentToolRestrictions(blockedTools: string[])` helper converts these block lists into the `{tools: {tool:false}}` shape required by the Claude Code SDK.

**[`src/agents/definitions.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/definitions.ts)** serves as the central registry through `getAgentDefinitions()`. This function orchestrates the final toolset by merging static TypeScript configurations, markdown-based `disallowedTools` lists, and any runtime overrides supplied via `PluginConfig` or direct API calls.

**`agents/*.md` files** (such as [`agents/architect.md`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/agents/architect.md)) contain the authoritative per-agent configuration. The front-matter YAML declares which tools are explicitly forbidden for that specific agent personality.

## The Tool Assignment Pipeline

The framework applies agent tool assignments through a predictable five-step sequence:

### Step 1: Loading Static Definitions

Each agent (e.g., `architectAgent`, `executorAgent`) exports from its own TypeScript file (e.g., [`src/agents/architect.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/architect.ts)). At this stage, the `tools` property is intentionally *undefined*, signaling that the agent should inherit the full default toolkit.

### Step 2: Parsing Front-Matter Disallowed Tools

When `getAgentDefinitions()` executes, it invokes `parseDisallowedTools(name)` for each agent. This function opens `agents/<name>.md`, extracts the `disallowedTools:` line, splits the comma-separated values into an array, and returns the blocked tool list.

### Step 3: Creating Restriction Maps

If a disallowed list exists, the system prepares it for the SDK. While the framework handles this automatically during registry creation, the `createAgentToolRestrictions` helper allows manual construction of restriction objects when building custom plugins.

### Step 4: Applying Runtime Overrides

User-supplied configuration from `.omc/plans/*.md` or `~/.claude/settings.json` may contain a `tools` field under `config.agents.<name>`. These values, along with programmatic overrides passed to `getAgentDefinitions(options)`, *replace* any existing tool list—including the auto-generated block list from step 2.

### Step 5: Composing Final Definitions

The resulting agent object contains `description`, `prompt`, `model`, and either `tools` (an explicit allow list) or `disallowedTools` (a subtraction from the full set). This final configuration is returned to the Claude-Code orchestration layer.

## Customizing Agent Tool Assignments

You can customize agent tool assignments at three different integration points depending on your needs.

### Blocking Tools via Front-Matter

The simplest method uses YAML front-matter in the agent's markdown definition. This approach requires no code changes and persists across updates.

```yaml

# agents/architect.md

---
name: architect
description: Strategic Architecture & Debugging Advisor
model: claude-opus-4-6
level: 3
disallowedTools: Write, Edit   # ← architect becomes read-only

---

```

When `parseDisallowedTools('architect')` processes this file, it returns `['Write','Edit']`. The resulting agent can execute `Read`, `Glob`, and `Grep` operations but cannot modify files.

### Overriding Tools via Configuration

Project-specific customizations belong in your configuration files. This method completely replaces the default toolset rather than subtracting from it.

```json
// .omc/config.json
{
  "agents": {
    "architect": {
      "tools": ["Read", "Glob", "Grep", "lsp_diagnostics"]
    }
  }
}

```

When `loadConfig()` reads this file, the `override?.tools` branch in `getAgentDefinitions` replaces the architect's toolbox with exactly the four tools specified, ignoring any `disallowedTools` settings from the markdown.

### Programmatic Restrictions

For plugin developers or dynamic scenarios, use the utility functions to construct restriction maps manually.

```typescript
import { createAgentToolRestrictions } from './src/agents/utils.js';
import { getAgentDefinitions } from './src/agents/definitions.js';

const customDefs = getAgentDefinitions({
  overrides: {
    executor: {
      tools: createAgentToolRestrictions(['WebFetch', 'WebSearch']).tools
    },
  },
});

```

Here, the `executor` agent loses web-search capabilities while retaining all other tools. The `createAgentToolRestrictions` function generates the proper nested object structure that the SDK expects for capability limiting.

## Summary

- **Default posture**: Every agent begins with unrestricted access to all built-in tools when no `tools` or `disallowedTools` fields are present.
- **Subtractive restriction**: Use `disallowedTools` in an agent's markdown front-matter (e.g., [`agents/architect.md`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/agents/architect.md)) to remove specific capabilities while keeping the rest.
- **Additive replacement**: Supply a `tools` array via `PluginConfig` or runtime overrides to define an exact allow list, bypassing any markdown restrictions.
- **Implementation hub**: The `getAgentDefinitions` function in [`src/agents/definitions.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/definitions.ts) coordinates these layers, calling `parseDisallowedTools` from [`src/agents/utils.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/utils.ts) when needed.

## Frequently Asked Questions

### What is the default toolset for agents in oh-my-claudecode?

By default, every agent receives **all available tools** including Read, Write, Edit, Glob, Grep, WebSearch, and WebFetch. The TypeScript agent definitions (e.g., [`src/agents/architect.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/architect.ts)) leave the `tools` property undefined to signal this full-access mode. Restrictions are applied only when `disallowedTools` or explicit `tools` configurations are detected.

### How does the disallowedTools front-matter field work?

The `disallowedTools` field in an agent's markdown file (located in `agents/*.md`) contains a comma-separated list of tool names to remove from that agent's default toolbox. The `parseDisallowedTools` function in [`src/agents/utils.ts`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/src/agents/utils.ts) parses this line, splits it into an array, and passes it to the restriction logic. For example, `disallowedTools: Write, Edit` creates a read-only agent that can analyze code but cannot modify it.

### Can I add tools to an agent that are disabled by default?

Yes. Because the explicit `tools` override replaces the entire assignment rather than merging with restrictions, you can supply a complete array including any tools you need. Configure this in your [`.omc/config.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/.omc/config.json) or via the `overrides` parameter in `getAgentDefinitions`. This approach supersedes both the default full-access mode and any `disallowedTools` settings from the agent's markdown.

### Where should I define custom tool restrictions for my project?

Place project-specific agent tool assignments in [`.omc/config.json`](https://github.com/Yeachan-Heo/oh-my-claudecode/blob/main/.omc/config.json) or your plan files within the `.omc/plans/` directory. These user-provided configurations are loaded by the `loadConfig()` mechanism and passed to `getAgentDefinitions` as runtime overrides. This keeps your customizations separate from the core oh-my-claudecode source code and persists them across framework updates.