Skip to content

About

Token-efficient MCP server that answers .NET symbol questions with Roslyn instead of grep.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

RoslynGate

ci license: MIT

RoslynGate is a stdio MCP server that answers .NET symbol questions with Roslyn instead of text search. It returns compact, deterministic results so an agent can find a definition, reference, or hierarchy without dumping code into the context window.

It is built for medium and large .NET solutions. On a couple of projects, the MCP schema and the extra turns can cost more than the file reads they replace. Measure before expecting a win.

Tools

Tool Purpose
get_symbol_definition Resolve one symbol by qualified name or file + line.
find_symbol_references Find semantic references, paginated; includeDefinition=true also returns the resolved symbol.
get_type_hierarchy Base types, interfaces, derived types, implementations.
search_symbols Find symbols by name fragment before resolving.
reload_workspace Reload after project or structural changes.

Every response is JSON. detail=compact (default) keeps the wire small; detail=verbose adds namespace, container, column, and longer documentation.

When a page is truncated, find_symbol_references and search_symbols also return nextOffset and a hint:

{
  "total": 120,
  "offset": 0,
  "truncated": true,
  "nextOffset": 50,
  "hint": "Call find_symbol_references again with offset=50 and the same arguments."
}

Use parameterTypes to disambiguate overloads:

{
  "name": "SampleSdk.Widget.Open",
  "parameterTypes": ["string"]
}

With the default watcher, .cs edits are applied incrementally. Structural changes set stale: true; the agent should call reload_workspace before trusting an empty result. Disable the watcher with --no-watch.

Performance

Against rg on this repository, compact tool output used 76-92% fewer characters for definition, references, hierarchy, and search tasks. That is tool output, not session tokens. Warm queries took 4-11 ms; the first query includes MSBuild loading (~11 s on this repository). The MCP handshake takes ~0.33 s after the first run; the first run also extracts the single-file binary (~1.4 s). See docs/BENCHMARKS.md for methodology and caveats.

The OpenCode A/B on a two-project fixture was a token loss (232k against 81k), because the fixed MCP and skill overhead was larger than the saved reads. Use medium and large repositories for a meaningful token A/B; on small projects, judge RoslynGate by correctness and warm-query latency instead. Measure with the OpenCode or Claude A/B harness before promising a percentage.

TypeScript product (MVP)

A separate roslyngate-ts product lives under products/typescript. It uses the TypeScript compiler API (Program, TypeChecker, LanguageService) for .ts, .tsx, .js, and .jsx.

cd products/typescript
npm install
npm run build
node dist/cli.js --check --solution ../../fixtures/TsSample

The five MCP tools are the same contract as the .NET product. See docs/TODO-TS.md for the remaining release work.

Requirements

  • .NET SDK. RoslynGate does not install or bundle the SDK; it uses the one selected by the solution's global.json, or the latest installed SDK.
  • Linux x64, Windows x64, or macOS arm64 (Apple Silicon). Intel Macs are not supported.

The binary is self-contained, so the .NET runtime is included. The SDK is still required because MSBuildWorkspace uses MSBuild to evaluate projects, targets, references, and generated code.

--check shows the selected SDK:

roslyngate --solution . --check

If a global.json pins an SDK that is not installed, RoslynGate fails with the requested version and the list of installed SDKs instead of silently using another one.

Install

Install and configure Claude Code in one step:

npm install -g roslyngate
cd /path/to/repository
roslyngate setup claude

Or run it without installing:

npx -y roslyngate@0.2.2 setup claude
bunx roslyngate@0.2.2 setup claude

setup claude writes .mcp.json with the native binary path, solution path, and no npx or cmd /c indirection. Open Claude Code and approve roslyngate in /mcp.

For teams, add the opt-in project skill:

roslyngate setup claude --skill

That writes .claude/skills/roslyn-symbols/SKILL.md, which can be committed. An existing skill is left unchanged.

For OpenCode, use:

roslyngate setup opencode --solution . --skill

That writes or merges opencode.jsonc under mcp.servers.roslyngate, with codemode: false, the native binary path, and a strict OpenCode skill under .opencode/skills/roslyn-symbols/SKILL.md. The skill is also added to instructions so it is always active. Then open OpenCode and run /mcps.

To use it as a plain CLI:

roslyngate --solution /path/to/repository

The first run downloads the self-contained binary for the current platform, verifies its SHA-256 checksum, and caches it. Supported platforms are Linux x64, Windows x64, and macOS arm64. Release binaries are available on the Releases page.

You can also download the binary for your platform from Releases and verify its .sha256 file.

Upgrade

roslyngate upgrade

This updates the global npm package, downloads the matching binary, and updates the roslyngate.command path in .mcp.json in the current directory when that command is a RoslynGate-managed cache path. It does not touch its args, timeout, or other MCP servers. Restart Claude Code or run /mcp afterwards.

If the command is portable (for example roslyngate or npx), the config is left unchanged. The upgrade detects whether the active command came from npm or Bun; use --manager npm|bun to override that detection. To update only npm and the binary:

roslyngate upgrade --no-config

Use --check to compare the installed and latest versions, or --dry-run to see the actions without installing or writing:

roslyngate upgrade --check
roslyngate upgrade --dry-run

Build

dotnet build RoslynGate.sln -warnaserror
dotnet test RoslynGate.sln

Run

dotnet run --project src/RoslynGate.Cli -- --solution fixtures/SampleSolution

The process speaks MCP over stdin/stdout. Diagnostics go to stderr. Close stdin to stop it.

Connect

{
  "mcpServers": {
    "roslyngate": {
      "command": "npx",
      "args": ["-y", "roslyngate", "--solution", "/path/to/repository"]
    }
  }
}

Test with OpenCode

The repository ships opencode.jsonc, a local stdio server entry.

  1. Run dotnet build.
  2. Start OpenCode in this repository and run /mcps.
  3. Confirm roslyngate connected.
  4. Ask the agent to use roslyngate to find a definition.

The command runs the built DLL, not dotnet run, so build output cannot corrupt the MCP stdout stream. For a published binary, replace command with the binary path and add --solution /path/to/repository.

See docs/CLIENTS.md for Claude Code, Cursor, VS Code, and the generic mcpServers shape.

Check

--check validates the configuration, locates the solution, and loads it with MSBuild without starting the protocol. It reports the project count and load time, and exits 0 when the workspace is usable and 1 otherwise.

roslyngate --solution . --check

Configuration

Flags override environment variables, which override defaults.

Flag Environment Default
-s, --solution ROSLYGATE_SOLUTION auto-detect
-l, --log-level ROSLYGATE_LOG_LEVEL error
--detail ROSLYGATE_DETAIL compact
--ref-limit ROSLYGATE_REF_LIMIT 50 (max 200)
--search-limit ROSLYGATE_SEARCH_LIMIT 20 (max 50)
--prewarm / --no-prewarm ROSLYGATE_PREWARM on
--watch / --no-watch ROSLYGATE_WATCH on
--check - -
-h, --help - -
-V, -v, --version - -

Exit codes: 0 normal end of input or successful check, 1 invalid configuration or solution, 2 fatal startup failure.

Errors

Failures are self-correcting. When a call returns isError: true, read error.hint and, if present, run error.try.

{
  "error": {
    "code": "symbol_not_found",
    "message": "No symbol matches 'Widget.Opn'.",
    "hint": "Names are case-sensitive. Search by fragment instead.",
    "try": {
      "tool": "search_symbols",
      "arguments": { "query": "Opn", "limit": 10 }
    }
  }
}

Development

dotnet restore --locked-mode
dotnet restore fixtures/SampleSolution/SampleSolution.sln
dotnet build RoslynGate.sln -warnaserror
dotnet test RoslynGate.sln
dotnet format RoslynGate.sln --verify-no-changes
npm test --prefix packaging/npm

See CONTRIBUTING.md for the trunk-based workflow, CHANGELOG.md for release history, and docs/BENCHMARKS.md for token and latency measurements.

License

MIT. See LICENSE.

About

Token-efficient MCP server that answers .NET symbol questions with Roslyn instead of grep.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages