Skip to content

feat(mcp): observe file paths from MCP tools for glob rule matching - #93

Open
dzuyonak wants to merge 3 commits into
frap129:mainfrom
dzuyonak:feat/mcp-observations-and-fixes
Open

dzuyonak wants to merge 3 commits into
frap129:mainfrom
dzuyonak:feat/mcp-observations-and-fixes

Conversation

@dzuyonak

@dzuyonak dzuyonak commented Nov 4, 2026

Copy link
Copy Markdown

Summary

globs-based rules attach from FileObservation records. Today those records
are only produced by the native file-handling tools (read, write, edit,
apply_patch, lsp).

When an agent reads or searches the workspace through an MCP server (semantic
indexer, ripgrep wrapper, language server, filesystem or memory server), the
returned paths never become observations, so matching rules never attach.

This PR adds a language-agnostic observation normalizer for MCP tool results.
Native tool behavior is unchanged.

Implementation

  1. MCP tool detection

    • mcp__<server>__<tool>.
    • OpenCode's <server>_<tool> naming (for example 1c-index_read_method),
      matched by a whole segment from read, find, search, lookup,
      inspect, info, get, grep, list, scan, query, glob.
    • Native tools are explicitly excluded to avoid double observations.
  2. Path extraction

    • Key/value fields: path=, file=, file_path=, filePath=,
      relativePath=, module_path=, filename=; quoted values, spaces, and
      non-ASCII/Cyrillic paths.
    • Grep/ripgrep-style rows: - src/a.go:10, src/a.go:10:5, → path,
      -> path, and bare path lists.
    • JSON payloads: recursive walk for path-like keys, including arrays under
      results or items.
    • Tool arguments: when a server accepts a target path and returns only the
      file content.
  3. Normalization

    • Windows separators are normalized to /.
    • URLs, .git/, node_modules/, wildcard masks, and version-like tokens
      such as 1.2.3 are rejected.
    • Paths are deduplicated and capped at 5 per call.

Also in this PR

  • Windows: windowsHide: true when resolving the git branch, so the
    background service does not flash a console window on every dispatch.
  • Keywords: Unicode-aware leading boundary instead of ASCII \b, so
    Cyrillic and other non-ASCII keywords match.

Compatibility

  • Native read/write/edit/apply_patch/lsp observations are untouched.
  • No configuration changes and no new dependencies.
  • Only paths already present in model-visible tool output or arguments are
    parsed; no extra filesystem access.

Tests

Added coverage in src/session/file-observation.test.ts for TypeScript,
Python, Go, Rust, Vue, and 1C paths with spaces/Cyrillic names, plus
grep-style rows, JSON payloads, argument fallback, URL/noise rejection, and
the 5-path cap.

Targeted run:

npx tsc --noEmit
npx eslint src/session/file-observation.ts src/session/file-observation.test.ts src/rules/rule-filter.ts src/detection/git-branch.ts
npx prettier --check --end-of-line auto src/session/file-observation.ts src/session/file-observation.test.ts src/rules/rule-filter.ts src/detection/git-branch.ts src/index.rules.test.ts
npx vitest run src/session/file-observation.test.ts src/index.rules.test.ts src/detection/git-branch.test.ts

Result: 137 passed (16 file-observation, 110 index.rules, 11 git-branch).

The full suite still reports 5 pre-existing Windows-only failures in
src/config/plugin-options.test.ts, tui/data/rules.test.ts, and
src/index.runtime.test.ts (POSIX path expectations, file permissions, and a
shell side-effect marker). They are unrelated to this change.

Commits

  1. feat(mcp): observe file paths from MCP tool results — main change.
  2. fix(windows): hide git subprocess console window — no console flashes.
  3. fix(keywords): support non-ASCII keywords — Unicode keyword matching.

Parse workspace paths from MCP tool output and arguments so glob-based rules attach when code is inspected through an MCP server instead of the native read tool. Handles key/value fields, grep-style rows, JSON payloads, and tool arguments for any language.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant