Custom plugin subagents never receive Grep/Glob in their tool schema

Resolved 💬 2 comments Opened Apr 22, 2026 by tmchow Closed Apr 22, 2026

Summary

Custom plugin subagents in Claude Code never receive Grep or Glob in their runtime function schema — regardless of whether the agent's frontmatter sets a tools: allowlist, omits it entirely, lists the tools explicitly, or uses array-form YAML.

Built-in subagents (Explore, Plan) do have Grep/Glob and they work there normally.

This contradicts the tools reference (which lists both as "Permission Required: No" and says "The tool names are the exact strings you use in subagent tool lists") and the subagents doc (which shows tools: Read, Grep, Glob, Bash as a canonical example and states "Inherits all tools if omitted").

Environment

  • Claude Code: 2.1.117
  • macOS 26.3 (build 25D125)
  • Plugin loaded via claude --plugin-dir <path>

Repro

  1. Install any plugin that declares a custom subagent. Spawn that subagent. Ask it to list its function schema.
  • Observed: Grep/Glob absent.
  1. Edit the agent frontmatter to include tools: Read, Grep, Glob, Bash. Restart and re-dispatch.
  • Observed: schema reports Read, Bash only. Grep/Glob still absent.
  1. Try YAML array form:

```yaml
tools:

  • Read
  • Grep
  • Glob

```

  • Observed: same — only Read in schema.
  1. Remove tools: entirely, relying on default inheritance.
  • Observed: schema contains Bash, Edit, Read, Skill, ToolSearch, Write. Grep/Glob still absent.
  1. In the same session, dispatch the built-in Explore subagent and ask it to call Glob.
  • Observed: works — Glob is in its schema and returns a file list.
  1. Emit a direct Glob call from a custom subagent:
  • Observed: Error: No such tool available: Glob

Expected

Custom plugin subagents should have Grep and Glob available in the same way built-in subagents do — either via default inheritance (per the docs' Inherits all tools if omitted) or via explicit tools: allowlist.

Evidence across multiple subagents

All from the compound-engineering plugin, same session:

| Subagent | tools: frontmatter | Actually registered |
|---------------------------------|----------------------------------------------------------|-------------------------------|
| ce-learnings-researcher | Read, Grep, Glob | Read |
| ce-learnings-researcher | (no tools: field) | Bash, Edit, Read, Skill, ToolSearch, Write |
| ce-git-history-analyzer | Read, Grep, Glob, Bash | Read, Bash |
| ce-issue-intelligence-analyst | Read, Grep, Glob, Bash, mcp__github__* | Read, Bash, mcp__github__* |
| ce-framework-docs-researcher | Read, Grep, Glob, Bash, WebFetch, WebSearch | Read, Bash, WebFetch, WebSearch |
| Explore (built-in) | (built-in default) | Includes Glob, Grep |

Consistent: every non-Grep/Glob entry registers. Grep/Glob never register for custom subagents. Built-ins unaffected.

Main-session note

In my parent (main) session, Grep and Glob are also absent from the function schema and do not appear in the deferred-tools list returned by ToolSearch. The only way I can reach Glob this session is by dispatching the built-in Explore subagent. Unclear whether this is the same underlying filter or a separate quirk — flagging it in case it's the same root cause.

Impact

Plugins whose subagents rely on native content search to implement their documented methodology (e.g. a knowledge-base researcher that greps frontmatter before reading) are effectively non-functional. The workaround — also granting Bash and falling back to rg/find via shell — defeats the security-narrowing intent of the tools: allowlist and reintroduces the permission-prompt churn that the allowlist was meant to avoid.

Notes

  • YAML format tested: both CSV (tools: Read, Grep, Glob) and array form exhibit the same behavior.
  • Frontmatter bytes verified clean ASCII (no hidden chars, no BOM).
  • User settings.json has no disabledTools, disallowedTools, or deny rule that would suppress Grep/Glob.
  • The compound-engineering plugin does not declare anything that would restrict tools globally.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗