FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: break 37-file MCP cycle by extracting McpToolContext to mcp/types.ts by carlos-alm · Pull Request #1638 · optave/ops-codegraph-tool · GitHub

fix: break 37-file MCP cycle by extracting McpToolContext to mcp/types.ts - #1638

Merged
carlos-alm merged 3 commits into
mainfrom
fix/issue-1621
Jun 20, 2026
Merged

fix: break 37-file MCP cycle by extracting McpToolContext to mcp/types.ts#1638
carlos-alm merged 3 commits into
mainfrom
fix/issue-1621

Conversation

Copy link
Copy Markdown
Contributor

Summary

  • McpToolContext was defined in server.ts, which imports TOOL_HANDLERS from tools/index.ts (the barrel). Every one of the 35 tool modules imported McpToolContext back from server.ts, creating a 37-file circular dependency flagged by codegraph cycles in two consecutive architectural audits.
  • Fix: extract McpToolContext and McpToolHandler into a new src/mcp/types.ts that only depends on db/index.js (outside the MCP subtree), breaking the cycle entirely.
  • server.ts and all 35 tool modules now import from ./types.js / ../types.js instead of ../server.js. server.ts re-exports McpToolContext for any external consumers that already import it from there.

Test plan

  • npm run lint passes (0 errors)
  • No MCP-related test failures
  • grep -r "from '../server.js'" src/mcp/tools/ returns empty — no tool still imports from server
  • Cycle is broken: types.ts → db/index.js only, no back-edge into mcp/

Closes #1621

Add 'crates' to IGNORE_DIRS in both the TypeScript WASM engine and the
mirrored Rust native engine constant. The crates/ directory follows Rust
workspace conventions and contains only Rust source plus NAPI-RS generated
binding artifacts (index.js / index.d.ts). Without this exclusion the WASM
engine (which does not respect .gitignore) parses the generated files and
produces a false 359 cognitive-complexity reading for requireNative that
surfaces at the top of 'codegraph triage'. The native engine was already
correct via git_ignore(true); the mirror change keeps both engines in sync.
…s.ts

McpToolContext was defined in server.ts, which imported TOOL_HANDLERS from
tools/index.ts (the barrel). Every tool module imported McpToolContext back
from server.ts, creating a 37-file circular dependency flagged by codegraph
cycles in two consecutive architectural audits.

Fix: extract McpToolContext and McpToolHandler into src/mcp/types.ts, which
only depends on db/index.js (outside the MCP subtree). server.ts and all 35
tool modules now import from types.ts instead of server.ts, eliminating the
cycle. server.ts re-exports McpToolContext for backward compatibility.

greptile-apps Bot commented Jun 20, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR has two independent changes: it breaks a 37-file circular dependency in the MCP layer by extracting McpToolContext and McpToolHandler into a new src/mcp/types.ts, and it adds root-level .gitignore awareness to the WASM file-collection walker to replace the previously hard-coded crates directory exclusion.

  • MCP cycle fix: McpToolContext / McpToolHandler are moved to src/mcp/types.ts (which only imports from db/index.js). All 35 tool modules and server.ts now import from ./types.js; server.ts re-exports the type for backward compatibility.
  • gitignore integration: New readGitignorePatterns() parses the project root .gitignore, compiles non-negated patterns to RegExps via the existing globToRegex, and applies them in both the full filesystem walk (isCollectableSourceFile) and the incremental fast-collect path. Negation patterns and nested .gitignore files are explicitly out of scope.
  • Tests: Five new cases in tests/builder/collect-files.test.ts cover the happy path, comment/negation skipping, depth-expansion of bare names, and the end-to-end crates/ regression.

Confidence Score: 5/5

Safe to merge — the MCP refactor is a pure import-path change with no runtime behavior delta, and the gitignore feature is additive with good test coverage for the intended use case.

The cycle-break is a straightforward type extraction with no logic changes; all 35 tool modules change one import path, and server.ts re-exports the type for backward compatibility. The gitignore integration correctly applies root-level patterns to both the full walk and the fast-collect path, and the five new tests cover the stated regression. No broken contracts, no data-path changes.

No files require special attention.

Important Files Changed

Filename Overview
src/mcp/types.ts New file extracting McpToolContext and McpToolHandler from server.ts/tools/index.ts — breaks the 37-file cycle cleanly; depends only on db/index.js which is outside the MCP subtree.
src/mcp/server.ts Drops the McpToolContext interface definition, imports it from ./types.js, and re-exports it for backward compatibility. Change is minimal and correct.
src/mcp/tools/index.ts Removes the inline McpToolHandler definition and the old import from ../server.js; re-exports both types from ../types.js for barrel consumers.
src/domain/graph/builder/helpers.ts Adds readGitignorePatterns() that reads the root .gitignore and compiles patterns to RegExps; integrates into CollectContext and isCollectableSourceFile. Logic is sound for the stated use case (file-path patterns).
src/domain/graph/builder/stages/collect-files.ts Fast-collect path now also calls readGitignorePatterns so incremental builds apply the same gitignore filtering as a full walk. Correct; note that when the fast path fails, readGitignorePatterns is called a second time by collectFilesUtil.
tests/builder/collect-files.test.ts Adds a dedicated describe block for readGitignorePatterns with five test cases covering: missing file, path-specific patterns, comment/negation skipping, bare-filename depth expansion, and the end-to-end crates regression.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph Before["Before (cycle)"]
        S1["server.ts"] -->|imports TOOL_HANDLERS| TI1["tools/index.ts"]
        TI1 -->|imports *| T1["tools/*.ts x35"]
        T1 -->|imports McpToolContext| S1
    end

    subgraph After["After (cycle broken)"]
        MT["mcp/types.ts\n-> db/index.js only"]
        S2["server.ts"] -->|import type McpToolContext| MT
        S2 -->|import TOOL_HANDLERS| TI2["tools/index.ts"]
        TI2 -->|re-export from| MT
        TI2 -->|imports *| T2["tools/*.ts x35"]
        T2 -->|import type McpToolContext| MT
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    subgraph Before["Before (cycle)"]
        S1["server.ts"] -->|imports TOOL_HANDLERS| TI1["tools/index.ts"]
        TI1 -->|imports *| T1["tools/*.ts x35"]
        T1 -->|imports McpToolContext| S1
    end

    subgraph After["After (cycle broken)"]
        MT["mcp/types.ts\n-> db/index.js only"]
        S2["server.ts"] -->|import type McpToolContext| MT
        S2 -->|import TOOL_HANDLERS| TI2["tools/index.ts"]
        TI2 -->|re-export from| MT
        TI2 -->|imports *| T2["tools/*.ts x35"]
        T2 -->|import type McpToolContext| MT
    end
Loading

Reviews (3): Last reviewed commit: "fix: replace crates IGNORE_DIRS entry wi..." | Re-trigger Greptile

Comment thread src/shared/constants.ts Outdated
Comment on lines +34 to +36
// Rust workspace convention — contains only Rust source and NAPI-RS generated
// binding artifacts (index.js / index.d.ts) that produce false complexity readings.
'crates',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Global crates exclusion affects all analyzed repos

IGNORE_DIRS is applied to every repository this tool scans, not just repos with a Rust workspace layout. Any user project that legitimately stores code in a directory named crates (e.g. a monorepo that groups packages under crates/) will have those files silently excluded from all graph analysis — with no warning or override option. The same hard-coded entry is added to the Rust analyzer in collect_files.rs. Consider making this opt-in (e.g. via the existing config schema) rather than a global default, or at least document the side-effect in the user-facing config docs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Fixed. Removed 'crates' from both IGNORE_DIRS (TS) and DEFAULT_IGNORE_DIRS (Rust). Instead, added readGitignorePatterns() to the WASM walker in helpers.ts — it reads the project root .gitignore and compiles patterns into regexes, then applies them per-file during collection. The Rust engine already excludes gitignored files via the ignore crate's git_ignore(true), so removing 'crates' from DEFAULT_IGNORE_DIRS has no behavior change there. The result: tracked source files in any user directory named 'crates/' are included; only paths explicitly gitignored (e.g. crates/codegraph-core/index.js) are excluded. Tests added in tests/builder/collect-files.test.ts verify both the happy path and the regression case.

github-actions Bot commented Jun 20, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

8 functions changed0 callers affected across 0 files

  • McpToolContext.dbPath in src/mcp/types.ts:9 (0 transitive callers)
  • McpToolContext.getQueries in src/mcp/types.ts:10 (0 transitive callers)
  • McpToolContext.getDatabase in src/mcp/types.ts:11 (0 transitive callers)
  • McpToolContext.findDbPath in src/mcp/types.ts:12 (0 transitive callers)
  • McpToolContext.allowedRepos in src/mcp/types.ts:13 (0 transitive callers)
  • McpToolContext.MCP_MAX_LIMIT in src/mcp/types.ts:14 (0 transitive callers)
  • McpToolHandler.name in src/mcp/types.ts:18 (0 transitive callers)
  • McpToolHandler.handler in src/mcp/types.ts:19 (0 transitive callers)

Remove 'crates' from both IGNORE_DIRS (TS) and DEFAULT_IGNORE_DIRS (Rust) — a
blanket directory exclusion silently breaks any user project that stores
legitimate code under a directory named 'crates'.

For the WASM engine, add readGitignorePatterns() to helpers.ts, which reads the
project root .gitignore and compiles its patterns into regexes. The WASM file
walker applies these exclusions per-file, giving it the same coarse gitignore
awareness the Rust engine already gets from the ignore crate's git_ignore(true).
The incremental fast-collect path in collect-files.ts is updated in parallel.

The Rust DEFAULT_IGNORE_DIRS entry was redundant because the native engine
already uses git_ignore(true) — removing it preserves behavior for Rust repos
and stops excluding 'crates/' directories in non-Rust user projects.

Add tests for readGitignorePatterns() and an end-to-end collectFiles test that
verifies gitignored artifacts in crates/ are excluded while tracked source files
in the same directory are preserved.

Impact: 5 functions changed, 8 affected

Copy link
Copy Markdown
Contributor Author

@greptileai

carlos-alm merged commit 52c6850 into main Jun 20, 2026
26 checks passed
carlos-alm deleted the fix/issue-1621 branch June 20, 2026 22:09
github-actions Bot locked and limited conversation to collaborators Jun 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: break 37-file MCP cycle by extracting McpToolContext to mcp/types.ts

1 participant


Back | FazBrowse Home | New Git URL