{"id":50753259,"url":"https://github.com/jsungmin/rider-mcp-enforcer","last_synced_at":"2026-06-11T03:01:18.677Z","repository":{"id":362658649,"uuid":"1260186314","full_name":"JSungMin/rider-mcp-enforcer","owner":"JSungMin","description":"Claude Code plugin: force Rider's MCP symbol/reference/file index over Bash grep, with token-flood summarization. For large Unreal C++/.NET codebases.","archived":false,"fork":false,"pushed_at":"2026-06-05T09:08:45.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T12:09:48.555Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JSungMin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T08:31:28.000Z","updated_at":"2026-06-05T09:08:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/JSungMin/rider-mcp-enforcer","commit_stats":null,"previous_names":["jsungmin/rider-mcp-enforcer"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/JSungMin/rider-mcp-enforcer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSungMin%2Frider-mcp-enforcer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSungMin%2Frider-mcp-enforcer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSungMin%2Frider-mcp-enforcer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSungMin%2Frider-mcp-enforcer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JSungMin","download_url":"https://codeload.github.com/JSungMin/rider-mcp-enforcer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSungMin%2Frider-mcp-enforcer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34180147,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-11T03:00:27.881Z","updated_at":"2026-06-11T03:01:18.653Z","avatar_url":"https://github.com/JSungMin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rider-mcp-enforcer · gamedev-log-analyzer\n\n**English** · [한국어](README.ko.md)\n\n[![Claude Code](https://img.shields.io/badge/Claude%20Code-plugin-7C3AED)](https://code.claude.com/docs/en/plugins)\n[![MCP](https://img.shields.io/badge/MCP-server-1f6feb)](https://modelcontextprotocol.io)\n[![release](https://img.shields.io/github/v/release/JSungMin/rider-mcp-enforcer)](https://github.com/JSungMin/rider-mcp-enforcer/releases)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/JSungMin/rider-mcp-enforcer/pulls)\n[![Stars](https://img.shields.io/github/stars/JSungMin/rider-mcp-enforcer?style=social)](https://github.com/JSungMin/rider-mcp-enforcer/stargazers)\n\n\u003e Two Claude Code plugins for large Unreal C++, Unity, and .NET projects. Search the codebase through\n\u003e Rider's index instead of `grep`, and read tens-of-MB editor logs without dumping them into the\n\u003e conversation. Both cost about 99% fewer tokens than the naive approach.\n\n### Demo\n\n`gamedev-log-analyzer` turning a 6,000-line synthetic engine log into a few hundred tokens\n(`summary` / `search` / `locate` / `diff`):\n\n![gamedev-log-analyzer demo](demo/demo.svg)\n\n### What it looks like\n```text\n# Claude tries to grep code → the hook nudges it toward the Rider index (default `warn`):\n$ grep -rn \"AMyActor\" Source/**/*.cpp\n💡 [rider-mcp-enforcer] Heads-up: a code-symbol search via Bash. Prefer search_symbol / search_text\n   (or the `code-locator` subagent).   # RIDER_ENFORCE=block to hard-deny instead\n\n▶ search_symbol \"AMyActor\"\n  Source/Game/MyActor.h:42   class MYGAME_API AMyActor : public APawn   (+3 more)\n  → ~120 tokens   (grep would have dumped ~14,000)\n\n# A 52 MB editor log → parsed, deduped, classified:\n▶ /gamedev-log-analyzer:logs\n  41,233 lines · 7 errors · 312 warnings\n  ERROR   [LogStreaming] Failed to load asset \u003caddr\u003e         (×128)   @ AssetManager.cpp:210\n  WARNING [LogPhysics]   Penetration depth \u003cn\u003e exceeds limit (×4,051) @ MyComponent.cpp:88\n  → ~900 tokens   (raw log ≈ 1,300,000)\n```\n\u003csub\u003eIllustrative output with placeholder symbols.\u003c/sub\u003e\n\n### Sound familiar?\n- `grep` on a giant Unreal C++ repo floods the context. Searching through Rider's index instead stays token-capped, around 99% smaller ([benchmarks](#combined-token-savings-measured)).\n- A 50 MB editor log is unreadable as-is. Parsing, deduplicating, and classifying it brings it down to about 2,500 tokens.\n- Claude keeps reaching for `grep` on code. A hook catches that and points it at the Rider tools.\n\n### Contents\n- [Marketplace — two plugins](#marketplace--two-plugins) · [Combined savings](#combined-token-savings-measured) · [Using both together](#using-both-together)\n- [What it does](#what-it-does) · [Performance](#performance-measured) · [Editor log analysis](#editor-log-analysis)\n- [Prerequisites](#prerequisites) · [Install](#install) · [Setup](#setup--configuration-command) · [Updating](#updating-to-a-new-version)\n- [Configuration](#configuration-env) · [Troubleshooting](#troubleshooting) · [Contributing](#contributing) · [Releases](https://github.com/JSungMin/rider-mcp-enforcer/releases)\n\n---\n\nA Claude Code plugin that routes symbol search, find-usages, file search, function/variable navigation,\nand rename refactoring through JetBrains Rider's live index instead of Bash `grep` and text replace, and\ncaps the tokens a find-usages flood can spend. It's built for large Unreal C++ (Rider for Unreal) and\n.NET/C# codebases, where `grep` is slow and burns context.\n\nRenames go through Rider's `rename_refactoring`, which updates every reference across the project\nsemantically, so Claude never tries to `sed` a symbol name and break the build on a partial match. See\n[Refactoring](skills/rider-search/SKILL.md) in the routing skill.\n\n## Marketplace — two plugins\n\nThis repo is a Claude Code plugin marketplace. It holds two plugins built around the same goal: read\nbig things without paying for all of it in tokens.\n\n| Plugin | Does | Needs |\n| --- | --- | --- |\n| **rider-mcp-enforcer** (this page) | Steer code search to Rider's MCP symbol/reference/file tools over Bash grep (nudge by default, hard-block opt-in), token-capped | Rider running + MCP |\n| **[gamedev-log-analyzer](gamedev-log-analyzer/README.md)** | Parse/dedup/classify huge Unreal/Unity/Godot/MSVC-UBT-MSBuild logs (CLI-first), search + diff + locate + extract scalars | Node only (no IDE) |\n\nOne-step install: `rider-mcp-enforcer` declares `gamedev-log-analyzer` as a dependency, so installing it\npulls in both. Each server's `npm install` runs on the first session, so there's no manual setup:\n```bash\n/plugin marketplace add JSungMin/rider-mcp-enforcer\n/plugin install rider-mcp-enforcer@rider-mcp-enforcer   # also auto-installs gamedev-log-analyzer\n/reload-plugins                                          # first run auto-installs deps for both\n```\nWant only the log analyzer? Install it alone: `/plugin install gamedev-log-analyzer@rider-mcp-enforcer`.\n\n### Combined token savings (measured)\n| Task | Bash / raw | Plugin | Reduction |\n| --- | ---: | ---: | ---: |\n| Symbol search on a UE5 repo | ~195,600 tok | ~1,700 tok | **~99%** |\n| Read a 57 MB editor log | ~1,250,000 tok | ~2,500 tok | **~99.8%** |\n| Search one log trace tag (9,226 hits) | ~690,000 tok | ~1,700 tok | **~99.8%** |\n\n### Using both together\nThe log analyzer emits `file:line` for each entry; the Rider plugin turns a `file:line` into the\nactual symbol/source. A typical loop:\n1. `/gamedev-log-analyzer:logs` → find the error/warning and its `file:line`.\n2. Hand that location to rider-mcp-enforcer's `get_symbol_info` / `read_file` (or `search_symbol`) to\n   open and understand the code — without ever grepping or dumping the raw log.\n\nThe handoff also runs the other way: Rider's code index deliberately excludes `Saved/` (logs, build\noutput), so a search/read aimed at a log returns empty or \"not a directory\" here. When the proxy sees a\ncall targeting a log path — or an empty result that might live in the logs — it appends a one-line\npointer back to gamedev-log, so a log-analysis task doesn't get stuck retrying against the code index.\n\n## What it does\n\nRider 2025.2+ ships an MCP server that exposes (verified live) `search_symbol`, `search_file`,\n`search_text`, `search_regex`, `find_files_by_name_keyword`, `find_files_by_glob`, `get_symbol_info`,\n`rename_refactoring`, `read_file`, and ~20 more. This plugin adds the layer that makes Claude\nactually use them instead of grep:\n\n| Layer | File | Effect |\n| --- | --- | --- |\n| **Enforcement hook** | `hooks/block-code-grep.js` | Intercepts Bash `grep`/`rg`/`find -name` **and the built-in Grep tool** over C/C++/C# source, steering Claude to the Rider MCP tools. **Bash: default `warn`** — the command runs but a nudge is injected into the model's context; `RIDER_ENFORCE=block` hard-denies, `=0` disables. **Grep tool: warn-only, never blocks** — it's the right fallback on a just-edited/unindexed file Rider hasn't reindexed, so it's only nudged (on an explicit code glob/type/path); `=0` silences it. MCP search and the Read tool still bypass by design. Non-code text (logs, md, json) passes through. |\n| **`code-locator` subagent** | `agents/code-locator.md` | Delegate \"where is X / what calls Y / find file W\" to a context-isolated subagent that uses Rider's index internally and returns only a compact `file:line` table — the raw matches never enter your context. The accuracy + token win without any hook friction. |\n| **Routing skill** | `skills/rider-search/SKILL.md` | Karpathy-style rules: symbol/file/text lookups → Rider tools first; grep is last resort. |\n| **Summarizing proxy** | `proxy/` | An MCP server fronting Rider's MCP. Parses the JSON search responses (`{items:[{filePath,startLine,lineText}],more}`) into compact `path:line  text`, capped at `RIDER_MAX_RESULTS`, and injects a default `projectPath`. Stops large-codebase result floods from blowing up context. |\n\n\u003e To be clear about scope: Rider's MCP already does symbol and file search on its own. What this plugin\n\u003e adds on top is the enforcement, the token cap, and the projectPath handling.\n\n### Subagents\n\nEach plugin also ships a subagent you can hand a whole task to. It does the reading or searching in its\nown separate context and returns only the answer, so the raw log lines or source matches never land in\nyour main context. Since that context is separate rather than a gate the way the hook is, nothing slips\npast it, and a single-purpose agent usually beats the main session for accuracy.\n\n| Subagent | Use it for | Returns |\n| --- | --- | --- |\n| `gamedev-log-analyzer:log-analyst` | \"analyze this log\", \"what errors/warnings\", \"what changed\", \"track this scalar\", \"which warnings by code\" | A compact severity / dedup / code-rollup / `file:line` answer (no raw log lines) |\n| `rider-mcp-enforcer:code-locator` | \"where is X defined\", \"what calls Y\", \"all usages of Z\", \"find file W\" (C#/.NET or Unreal C++ in Rider) | A tight `kind name @ file:line` table (no source bodies) |\n\nYou don't invoke them by hand. Ask \"analyze `Editor.log`\" or \"find usages of `AMyActor`\" and Claude\npicks the right one from its description; naming it explicitly also works. A 3,000-line log comes back\nas roughly 300 tokens, a repo-wide search as a few dozen `file:line` rows. `code-locator` needs Rider's\nMCP connected; `log-analyst` runs on Node alone.\n\n### Commands \u0026 tools\n- `/rider-mcp-enforcer:setup` — configure the plugin (see [Setup](#setup--configuration-command)).\n- `/rider-mcp-enforcer:savings` — show cumulative token savings.\n- MCP tools (server `rider-search`): `rider_setup`, `rider_config`, `rider_detect`, `rider_savings`,\n  `rider_savings_reset`, the summarized Rider search tools (`search_symbol`, `search_text`, …), and the\n  Rider refactor tools (`rename_refactoring`, `move_type_to_namespace`, `reformat_file`).\n\u003e\n\u003e **Two real limitations of this Rider MCP build (verified live):**\n\u003e 1. **No semantic find-usages/find-references tool.** Reference-finding falls back to `search_text`/\n\u003e    `search_regex` (indexed string match, not semantic).\n\u003e 2. **`search_symbol` on Unreal C++ can be weak** — it may return filename/path matches (e.g. `.Build.cs`)\n\u003e    rather than the exact class. Verify results; fall back to `search_text` when a symbol hit looks off.\n\n## Performance (measured)\n\nReal A/B on a large UE5 project — finding one class name (~2,400 textual occurrences) via Bash grep\nvs this plugin. No project source is reproduced; see [BENCHMARK.md](BENCHMARK.md) for method.\n\n| | Bash grep (whole repo) | Bash grep (game dir) | **Plugin (Rider MCP, summarized)** |\n| --- | ---: | ---: | ---: |\n| Tokens to the model | ~195,600 | ~114,100 | **~1,700** |\n| Wall time | 55,006 ms | 382 ms | **~870 ms** |\n\n- Tokens: 98–99% fewer (67–115×), every time. About 87% of that comes from summarizing the response,\n  the rest from the cap.\n- Time: ~63× faster when grep would otherwise scan the whole repo, Engine included. It runs a little\n  slower than a grep you've already narrowed, since the MCP call carries a fixed SSE round-trip and\n  ripgrep is very fast on a small scope.\n\n### Accuracy difference (and why)\nThis is a precision/recall trade-off, not a case of one being more correct than the other:\n- **Recall:** the plugin returns the top `N` (cap), not all 2,400+ hits. The withheld ~98% are mostly\n  comments/includes/substring noise. Need an exhaustive list? Raise `RIDER_MAX_RESULTS` or use grep.\n- **Precision:** grep matches every substring (a `Foo` query also hits `FooBar`), over-reporting ~100×\n  here; the plugin's symbol search returned 25 distinct candidate files.\n- **Known weakness:** on Unreal C++, `search_symbol` may point at a file's line 1 rather than the exact\n  declaration (Rider indexing limit). `search_text` gives the real `file:line  code`; the skill tells\n  Claude to prefer it when a symbol hit looks off.\n\n\u003e So: for navigation (a definition plus representative usages) the plugin is both more accurate and far\n\u003e cheaper. For an exhaustive occurrence audit, raise the cap or fall back to grep on purpose.\n\n### Incomplete results (correctness guard)\nCapping saves tokens but it's dangerous for \"find ALL references\", where a missed call site means\nwrong code. So truncation is never silent:\n\n1. When the first fetch looks truncated, the proxy **auto-retries once** with a larger limit\n   (`RIDER_ESCALATE_LIMIT`) to learn the true count.\n2. If the set is still not exhaustive, the response carries a loud `⚠ INCOMPLETE RESULTS — showing X\n   of Y+` banner with three options: **raise the cap**, **narrow scope (`paths`)**, or **confirm a\n   partial set is acceptable**.\n3. The skill instructs Claude: for references/refactor/rename, **stop and ask the user** with those\n   options instead of acting on the partial list.\n\n## How much did it save? (token-savings command)\n\nEach summarized search also appends a per-call line — `✓ Saved ~N tokens here (Rider index, summarized\nvs raw response)` — whenever the win is non-trivial, so the payoff is visible in the moment (and its\nabsence is a hint the result was already small). The proxy records the same numbers cumulatively. Check\nthe running total any of these ways:\n\n- **In Claude Code:** run `/rider-mcp-enforcer:savings` (or just ask \"how much has the plugin saved?\").\n  It calls the `rider_savings` MCP tool.\n- **From a shell:** `node \u003cplugin-dir\u003e/proxy/stats.mjs`\n- **Reset:** call the `rider_savings_reset` tool.\n\nExample output:\n```\nrider-mcp-enforcer — cumulative token savings (vs forwarding Rider's raw responses)\n  summarized calls : 1\n  raw tokens       : ~30,398\n  sent tokens      : ~362\n  saved            : ~30,036 (99%)\n  noise items dropped (build artifacts): 78\n```\n\u003e \"Saved\" here is vs Rider's *raw* response. Savings vs **Bash grep** are typically far larger — see\n\u003e [BENCHMARK.md](BENCHMARK.md).\n\n## Prerequisites\n\n- **JetBrains Rider 2025.2+**, running, with the project open.\n- **Node.js ≥ 18** on PATH.\n- Rider MCP enabled: **Settings | Tools | MCP Server → Enable MCP Server**, then **Copy SSE Config**.\n\n## Install\n\n```bash\n# 1) Add the marketplace and install (also auto-installs gamedev-log-analyzer)\n/plugin marketplace add JSungMin/rider-mcp-enforcer\n/plugin install rider-mcp-enforcer@rider-mcp-enforcer\n/reload-plugins        # first run auto-installs the server deps (no manual npm)\n\n# 2) Configure it — from inside Claude Code, just run:\n/rider-mcp-enforcer:setup\n#   It detects Rider's SSE endpoint, asks for the project path, and writes the config.\n```\n\nVerify the `rider-search` MCP server and its tools appear, and that a `grep src/**/*.cpp` triggers a\nnudge toward the Rider tools (or is denied under `RIDER_ENFORCE=block`). (The `npm install` for each\nplugin's MCP server runs automatically on session start via a hook into `${CLAUDE_PLUGIN_DATA}`.)\n\n## Setup / configuration command\n\nYou don't edit OS environment variables. Settings live in a config file\n(`~/.rider-mcp-enforcer/config.json`) the proxy reads at startup. Configure it any of these ways:\n\n- **In Claude Code (recommended):** `/rider-mcp-enforcer:setup` — guided: it runs `rider_detect`,\n  asks for `projectPath`, and applies via the `rider_setup` tool. Then `/reload-plugins`.\n- **Ad-hoc via tools:** ask Claude to call `rider_setup { \"riderSseUrl\": \"...\", \"projectPath\": \"...\" }`,\n  `rider_config` (show current), or `rider_detect` (probe the port).\n- **From a shell:**\n  ```bash\n  node \u003cplugin-dir\u003e/proxy/setup.mjs --detect\n  node \u003cplugin-dir\u003e/proxy/setup.mjs riderSseUrl=http://127.0.0.1:\u003cport\u003e/sse projectPath=\"G:/Path/To/Project\"\n  node \u003cplugin-dir\u003e/proxy/setup.mjs --show\n  ```\n\nSettings are read at proxy startup → **run `/reload-plugins` after changing them**. Precedence:\n**environment variable \u003e config file \u003e built-in default** (so a same-named env var still wins).\n\n## Updating to a new version\n\nClaude Code caches the marketplace repo, so new commits are **not** auto-fetched. To pull a newer\nversion of this plugin:\n\n```bash\n# 1) Refresh the cached marketplace catalog\n/plugin marketplace update rider-mcp-enforcer\n\n# 2) Update the installed plugin (or uninstall + install to be sure)\n/plugin update rider-mcp-enforcer\n#   fallback: /plugin uninstall rider-mcp-enforcer  then  /plugin install rider-mcp-enforcer@rider-mcp-enforcer\n\n# 3) Reload so the new hook/command/MCP server take effect (deps auto-reinstall on session start)\n/reload-plugins        # or restart Claude Code\n```\n\nCheck what's installed with `/plugin` (it lists each plugin's version). If a command like\n`/rider-mcp-enforcer:setup` is missing, your installed copy predates it — update as above.\n\n\u003e Maintainer note: the `version` field in `.claude-plugin/plugin.json` gates updates — bump it when\n\u003e you want clients to pick up changes. Config keys/commands/tools must be updated in the same commit as\n\u003e any source change; version history lives in [Releases](https://github.com/JSungMin/rider-mcp-enforcer/releases)\n\u003e (auto-generated on each `v*` tag), not in this README.\n\u003e\n\u003e **Release/version sync:** the git tag equals the **headline plugin** version — every release bumps\n\u003e `rider-mcp-enforcer` (plugin.json + marketplace.json) to `X.Y.Z` and tags `vX.Y.Z` (identical), so\n\u003e `/plugin update rider-mcp-enforcer` always delivers the latest bundle. Because changes often land in\n\u003e the bundled `gamedev-log-analyzer` (which keeps its own independent semver), the headline plugin must\n\u003e still bump on those releases — otherwise clients see \"already at latest\" and never receive the update.\n\n## Configuration (env)\n\n| Var | Default | Meaning |\n| --- | --- | --- |\n| `RIDER_MCP_SSE_URL` | — (required) | Rider MCP SSE URL from \"Copy SSE Config\". Without it the proxy returns setup instructions and Claude falls back to grep. |\n| `RIDER_MAX_RESULTS` | `50` | Max `file:line` lines kept per summarized response. |\n| `RIDER_SUMMARIZE_TOOLS` | _(auto)_ | Optional **restrict** filter — comma list of tool names allowed to be summarized. By default the proxy summarizes **any list-shaped response** (decided by response shape, not name), so non-list tools like `read_file` are never touched and Rider tool renames need no config. |\n| `RIDER_PROJECT_PATH` | — | Default project path the proxy injects when a tool call omits `projectPath`. Set this when multiple projects are open in Rider (otherwise Rider errors \"Unable to determine the target project\"). Get it from the \"Currently open projects\" list in that error, or the project root. |\n| `RIDER_ESCALATE` | `1` | `0`/`false`/`off` disables auto-escalation (see below). |\n| `RIDER_ESCALATE_LIMIT` | `500` | When a result looks truncated, the proxy re-fetches once with this larger limit to learn the true count. |\n| `RIDER_MAX_LINE_CHARS` | `200` | Max chars of each match's code snippet (prevents one giant generated line from blowing the budget). |\n| `RIDER_EXCLUDE` | `/intermediate/,/binaries/,/build/,/saved/,/deriveddatacache/,/.vs/,/.idea/,/node_modules/,.vcxproj,.sln,.filters` | Comma list of case-insensitive path substrings dropped from results (build artifacts / generated noise). |\n| `RIDER_EXCLUDE_OFF` | `0` | `1`/`true`/`on` keeps the excluded paths in results. |\n| `RIDER_STATS_FILE` | `~/.rider-mcp-enforcer/stats.json` | Where the cumulative token-savings ledger is written. |\n| `RIDER_ENFORCE` | `warn` | `warn` (default) = run the command + inject a nudge; `block` = hard-deny (**Bash only** — the Grep tool is always warn-only, never blocked); `0`/`off` = disable the hook entirely. |\n\n## How enforcement works\n\n- The **hook** runs before every Bash call. If the command is a code-symbol search (grep/rg/ack/ag/\n  findstr or `find -name` targeting `*.cpp/.h/.cs/...` or `src|source|engine|plugins/`) and is *not*\n  aimed at a log/md/json/build path, it exits non-zero and Claude sees a message telling it to use\n  the Rider tool. Otherwise it allows the command.\n- The **skill** biases Claude toward the Rider tools proactively.\n- The **proxy** guarantees the token cap regardless of how Claude calls the tool.\n\n## Enable Rider MCP first (it's off until you turn it on)\n\nThe Rider MCP server isn't active by default in every build, and a lot of people have it disabled\nwithout realizing it, which makes the plugin look like it does nothing. Turn it on and find its URL:\n\n1. Rider → **Settings | Tools | MCP Server**.\n2. Tick **Enable MCP Server**. (If you don't see this page, update to Rider **2025.2+**.)\n3. In **Manual Client Configuration**, click **Copy SSE Config** (or Copy Stdio Config).\n4. From the copied config, take the SSE URL and set it:\n   ```bash\n   export RIDER_MCP_SSE_URL=\"http://localhost:\u003cport\u003e/sse\"   # macOS/Linux\n   $env:RIDER_MCP_SSE_URL = \"http://localhost:\u003cport\u003e/sse\"   # PowerShell\n   ```\n   The port is **per-instance** (often in the 63342/64342 range, but do not hardcode — copy it).\n5. Restart Claude Code (or `/reload-plugins`).\n\n### Verify it's actually on\n```bash\n# Is Rider serving the MCP SSE endpoint? 200/SSE = good, connection refused = disabled/wrong port.\ncurl -i -m 3 \"$RIDER_MCP_SSE_URL\"\n```\nIn Claude Code, the `rider-search` server should list real Rider tools (`find_symbol`,\n`find_references`, …). If it only lists a single `rider_status` tool, the proxy could **not** reach\nRider — MCP is off or the URL is wrong.\n\n## Troubleshooting\n\n| Symptom | Cause | Fix |\n| --- | --- | --- |\n| `rider-search` only shows a `rider_status` tool | Proxy can't reach Rider (MCP disabled or wrong URL) | Enable MCP (above), set/correct `RIDER_MCP_SSE_URL`, restart. |\n| Tool call returns \"rider-search-proxy is not connected to Rider\" | `RIDER_MCP_SSE_URL` unset/unreachable | Set it from **Copy SSE Config**; confirm with `curl`. |\n| Tool returns \"Unable to determine the target project\" | Multiple projects open in Rider, no `projectPath` | Set `RIDER_PROJECT_PATH` to the project root (the error lists open projects), or pass `projectPath` per call. |\n| Tool returns \"`projectPath`=… doesn't correspond to any open project\" | The project is **not open in Rider** | Rider MCP only searches projects open in the IDE. Open the project in Rider (it must finish indexing), then retry. The error lists the currently-open projects. |\n| Code search nudged when you wanted plain grep | The hook is steering you to Rider | Default `warn` still **runs** the command — just heed or ignore the nudge. To silence it entirely: `RIDER_ENFORCE=0`. |\n| `RIDER_ENFORCE=block` denies a search while Rider is unavailable | You opted into hard-block but MCP is off | Set `RIDER_ENFORCE=0` (or back to `warn`) until MCP is on. |\n| Wrong/empty summaries | Rider tool name differs from defaults, or unusual response shape | Set `RIDER_SUMMARIZE_TOOLS` to your build's tool names; tune `RIDER_MAX_RESULTS`. |\n| `curl` to the SSE URL refuses connection | Rider not running, MCP off, or wrong port | Start Rider, enable MCP, re-copy the SSE config. |\n| `Dependency \"gamedev-log-analyzer@rider-mcp-enforcer\" is not found in any configured marketplace` (Plugin Errors panel) | **Stale marketplace cache** after the `ue-log-analyzer`→`gamedev-log-analyzer` rename: the updated `plugin.json` names the new dependency, but your cached catalog still lists the old one | Refresh the catalog, then reload: `/plugin marketplace update rider-mcp-enforcer` → `/reload-plugins` (restart Claude Code if the panel still shows it). A leftover `ue-log-analyzer` install is harmless — remove it with `claude plugin prune`. |\n\n\u003e **MCP off?** No footgun by default — the hook's default `warn` always lets grep run, so Claude can\n\u003e still search even when Rider's MCP is unavailable. Only `RIDER_ENFORCE=block` would deny it; set\n\u003e `RIDER_ENFORCE=0` (or `warn`) in that case.\n\n## Status / caveats\n\n- **Live-verified against Rider 2025.2.3.** `search_text` and `search_symbol` are confirmed working on\n  a real Unreal Engine 5 project — the [benchmark](BENCHMARK.md) numbers were measured through them.\n  Tool names target Rider 2025.2+; if your build names a tool differently, check the `rider-search`\n  tool list and set `RIDER_SUMMARIZE_TOOLS`.\n- The summarizer is heuristic (keeps `path:line`-looking lines). Tune `RIDER_MAX_RESULTS` per repo.\n- Transport is SSE. If your Rider build only offers stdio, open an issue — a stdio client mode can be\n  added.\n\n## Permissions \u0026 safety\n\nEverything runs locally and nothing is uploaded:\n\n- The **hook** (`PreToolUse` on Bash) only inspects the command string to decide whether to redirect a\n  code-grep to Rider — it does not read file contents or run anything. It honors `RIDER_ENFORCE=0`.\n- The **proxy** connects only to Rider's MCP SSE endpoint on `localhost` and forwards/summarizes\n  search responses. It opens no outbound internet connections and writes only its config + a local\n  token-savings ledger under `~/.rider-mcp-enforcer/`.\n- **gamedev-log-analyzer** reads local log files you point it at and prints summaries.\n\nSee [SECURITY.md](SECURITY.md) and [PRIVACY.md](PRIVACY.md).\n\n## Version history\n\nSee the **[Releases](https://github.com/JSungMin/rider-mcp-enforcer/releases)** page — every version\ntag publishes categorized, PR-linked notes (🚀 Features / 🐛 Bug Fixes / 📝 Documentation / 🔧\nMaintenance), generated automatically. The badge at the top always points at the latest.\n\n## Contributing\n\nIssues and PRs welcome — bug reports, new log formats/engines, additional Rider tool mappings, or docs.\n\nThis repo is maintained with AI-assisted review, so PRs are judged from the diff, description, and\nevidence. Keep them small, clearly described, backed by evidence, and free of any proprietary data.\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a PR.\n\nIf this saved you tokens or debugging time, a star helps others find it. ⭐\n\n## Privacy\n\nThese plugins collect no personal data and process everything locally — see [PRIVACY.md](PRIVACY.md).\n\n## License\n\nMIT © 2026 JSungMin\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsungmin%2Frider-mcp-enforcer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsungmin%2Frider-mcp-enforcer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsungmin%2Frider-mcp-enforcer/lists"}