openrewrite / openrewrite/rewrite

Moderne CLI mcp `grep`: brace-expansion glob silently returns "No matches found" instead of an error

Open
#8,856 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
3.7k
Forks
570
Avg merge
13h 12m
Merged PRs (30d)
261

Description

Component note, please redirect if wrong. This is about the grep tool exposed by
the Moderne CLI's MCP server (mod mcp, CLI 4.8.3), not an OpenRewrite recipe.
moderneinc/moderne-cli-releases has issues disabled and its README points at
support@moderne.io, so there is no public tracker for that component — I am filing
here because this repo is the closest public home and the report touches
org.openrewrite.text.FindAndReplace's filePattern semantics for comparison. Please
transfer or close-and-redirect as you see fit rather than spending triage time on it.

grep MCP tool: brace-expansion glob silently returns "No matches found" instead of an error

Summary

The grep tool exposed by mod mcp returns No matches found. when its glob
argument contains a brace alternation such as *.{md,sh}, in a repository where those
files do contain the pattern. It does not report that the glob is unsupported — it
reports that the code is clean.

A false negative from a search tool is probably worse than an error. An agent has no
way to tell "this pattern does not occur" from "your filter silently matched nothing",
so it proceeds on the assumption that there is nothing to fix. In my case the tool
reported no matches for a string that occurs 23 times across 11 files, and I only
caught it because I happened to re-run the same search with bash/rg for an unrelated
reason.

This is also inconsistent with run_recipe's org.openrewrite.text.FindAndReplace,
whose filePattern option documents multi-pattern support (;-separated). The grep
tool accepts neither form.

Environment

  • Moderne CLI 4.8.3 (mod mcp, stdio)
  • moderne Claude Code plugin 4.7.2
  • macOS 26.6.1, arm64
  • ripgrep 14.1.1 present on PATH
  • Repository: ~950 source files, LST state READY

Reproduction

In a repository where read-only appears in both *.md and *.sh files:

# grep arguments Result
1 {pattern: "read-only"} (no glob) ✅ 23 matches across 11 files
2 {pattern: "read-only", glob: "*.md"} ✅ matches in README.md, legacy/README.md, …
3 {pattern: "read-only", glob: "*.{md,sh}"} No matches found.
4 {pattern: "read-only", glob: "*.md;*.sh"} No matches found.
5 {pattern: "read-only", glob: "*.{md,sh,java,yaml}"} No matches found.

Cases 3–5 should each return at least everything case 2 returns, since *.md is one of
the alternates.

The same glob works in ripgrep

The tool documents itself as "Linear file-content search via ripgrep (with grep
fallback)", and ripgrep handles this glob natively:

$ rg --version
ripgrep 14.1.1 (rev fdb5e06cce)

$ rg -c --glob '*.{md,sh}' 'read-only'
legacy/README.md:1
README.md:4

So the alternation is valid ripgrep glob syntax and is being lost or mangled before it
reaches ripgrep, rather than being rejected by it.

Expected

Any one of these would be fine; the first is the least surprising:

  1. Support it. Pass the glob through to ripgrep's --glob, which already
    understands brace alternation. Optionally also accept the ;-separated form that
    FindAndReplace.filePattern documents, for consistency across the tool surface.
  2. Reject it. Return an explicit error naming the unsupported construct, e.g.
    glob "*.{md,sh}": brace alternation is not supported; pass a single pattern.

Actual

No matches found. — indistinguishable from a genuinely clean repository.

Minor, separate observation

Unlike rg, the grep tool appears to search hidden directories by default — case 2
above returned hits under .claude/, which bare rg skips. That is a defensible
choice, but it is undocumented and worth stating in the parameter description alongside
the glob semantics.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by confirming that this report concerns the Moderne CLI's MCP grep tool rather than code in openrewrite/rewrite; the report says the CLI releases repository has issues disabled and points to support@moderne.io. No source file or test is named here, so the next step is redirecting the report to the component owner and confirming whether the glob should be supported or explicitly rejected.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
cli, search
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
10/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.