Kirnot.RoslynMcpServer 0.4.0

dotnet tool install --global Kirnot.RoslynMcpServer --version 0.4.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Kirnot.RoslynMcpServer --version 0.4.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Kirnot.RoslynMcpServer&version=0.4.0
                    
nuke :add-package Kirnot.RoslynMcpServer --version 0.4.0
                    

roslyn-mcp-server

roslyn-mcp-server is an unofficial C# MCP server that lets AI agents use Roslyn language features through roslyn-language-server.

The server is meant for Agent CLI-style tools working inside real C# repositories, including large mono-repos. It runs as an MCP stdio server, starts roslyn-language-server as a child LSP process after a solution or project is selected, then translates MCP tool calls into LSP requests.

The main goal is not to replace an IDE. The goal is to give an agent enough compiler-backed context to read, review, and navigate C# code without forcing the agent to parse a large repository by itself.

Why This Exists

AI agents can inspect files with normal filesystem tools, but C# code often needs semantic context:

  • where a symbol is defined
  • which overload or type a reference points to
  • where a symbol is referenced
  • what diagnostics Roslyn currently knows about
  • what symbols are present in a file or workspace

Roslyn already knows how to answer these questions. This project provides a thin MCP bridge so an agent can ask those questions while it works.

Large Repository Design

The project assumes large repositories from the beginning. A useful agent tool must stay predictable even when a repo has hundreds of projects, many solutions, slow restore state, or partial Roslyn indexing.

That leads to a few design choices:

  • By default the server does not load a solution at startup; --load-solution can opt into early solution loading.
  • Workspace discovery is bounded by scan depth, timeout, and candidate limits.
  • If multiple .sln, .slnx, or .csproj files exist, the agent must choose.
  • Roslyn LS is launched only after load_solution, load_project, or an unambiguous first read-tool auto-load.
  • Read tools do not block indefinitely while the language server is warming.
  • Large result sets are capped and report totalKnown, returned, and truncated metadata.
  • Warming or partially loaded workspaces return best-effort results with workspaceState, completeness, and retry metadata.
  • Diagnostics are based on textDocument/publishDiagnostics notifications already processed by the bounded background diagnostics queue; the server does not run an unbounded workspace-wide diagnostic computation. Queue capacity and pending/processed/dropped/stale counts are exposed through get_workspace_status.

In practice, WorkspaceWarming is a normal state for large repositories. Agents should use partial results when they are good enough and call get_workspace_status when they need to understand load warnings or failures.

Implemented Tools

Workspace tools:

  • list_workspaces - Discover .sln, .slnx, and .csproj candidates under the workspace root. Optional maxDepth skips git-based discovery and performs bounded filesystem BFS for near-root workspace files.
  • load_solution - Load a selected .sln or .slnx into Roslyn LS.
  • load_project - Load a selected .csproj into Roslyn LS.
  • get_workspace_status - Report the selected target, load state, warnings, open documents, and diagnostics queue/cache status.

Read-only Roslyn tools:

  • document_symbols - Return file-level types, members, and symbol ranges, optionally filtering returned symbols by kind while preserving ancestor context for matching descendants.
  • hover - Return Roslyn hover text for a source position.
  • go_to_definition - Return definition locations for a source position.
  • peek_definition - Return definition locations plus bounded source snippets.
  • find_references - Return references for a source position.
  • peek_references - Return reference locations plus bounded source snippets.
  • find_implementations - Return implementation locations from an interface, abstract member, or base contract position. Calling it on a concrete implementation may legitimately return only that implementation. Results can be narrowed with root-relative includePathPrefixes.
  • get_call_hierarchy - Return direct depth-1 incoming callers, outgoing callees, or both for a method, constructor, or property accessor position, optionally filtering returned edge counterparts by kind: method, constructor, property, event, operator, or field, and by root-relative includePathPrefixes.
  • get_type_hierarchy - Return base type, derived type, or interface implementation hierarchy edges for a type position, with bounded breadth-first traversal depth, result caps, and optional root-relative includePathPrefixes.
  • find_symbols - Search workspace symbols by name, optionally filtering returned results by kind such as class, interface, method, property, or field, and by symbol-name matchMode: default, exact, prefix, or contains. Default matching keeps Roslyn LS fuzzy candidates but ranks exact, prefix, and contains name matches before the result cap. It can also keep only symbols located under root-relative includePathPrefixes, which is useful in large repositories.
  • diagnostics - Return currently known file or workspace diagnostics.

Resources:

  • roslyn://server/guide - Short usage guidance for agents.
  • roslyn://server/capabilities - Short read-only capability summary.

This project is intentionally read-only. Rename, code actions, formatting, and apply/edit tools are outside the product direction; agents should make file changes with their normal workspace editing tools after using Roslyn context to understand the code.

Getting Started

Prerequisites:

  • .NET 10 SDK for installing .NET tools
  • roslyn-language-server

Install roslyn-language-server separately:

dotnet tool install --global roslyn-language-server --prerelease

roslyn-mcp-server does not bundle Roslyn LS. Starting with v0.4.0, the .NET tool package ID is Kirnot.RoslynMcpServer; the installed command remains roslyn-mcp-server.

.NET Tool

Install the MCP server as a .NET global tool:

dotnet tool install --global Kirnot.RoslynMcpServer

Run the installed command:

roslyn-mcp-server --help

If your MCP client does not inherit the .NET global tools directory on PATH, point it at the tool shim directly:

%USERPROFILE%\.dotnet\tools\roslyn-mcp-server.exe

On macOS or Linux:

$HOME/.dotnet/tools/roslyn-mcp-server

Release Artifacts

Alternatively, download the self-contained artifact for your OS from the v0.4.0 release or the latest release:

  • roslyn-mcp-server-v0.4.0-win-x64.zip
  • roslyn-mcp-server-v0.4.0-linux-x64.tar.gz
  • roslyn-mcp-server-v0.4.0-osx-x64.tar.gz
  • roslyn-mcp-server-v0.4.0-osx-arm64.tar.gz

The release artifacts are self-contained and single-file. The server executable does not require a separate .NET runtime installation, though roslyn-language-server and the target C# repository still need a compatible .NET SDK/runtime environment.

Point your MCP client at the extracted executable:

C:\Tools\roslyn-mcp-server\roslyn-mcp-server.exe

On macOS or Linux, extract the .tar.gz and use the roslyn-mcp-server executable from the extracted folder. If your archive tool does not preserve the executable bit, run chmod +x roslyn-mcp-server.

Build From Source

Use source builds for local development, unsupported platforms, or if you want to run the server directly from this repository. Source builds require Git and the .NET 10 SDK.

git clone https://github.com/kirnot92/roslyn-mcp-server.git
cd roslyn-mcp-server
dotnet build .\src\RoslynMcpServer\RoslynMcpServer.csproj -c Release

The built server executable will be under:

src/RoslynMcpServer/bin/Release/net10.0/

On Windows, the executable is typically:

src/RoslynMcpServer/bin/Release/net10.0/roslyn-mcp-server.exe

On macOS or Linux, the executable is typically:

src/RoslynMcpServer/bin/Release/net10.0/roslyn-mcp-server

After installing, downloading, or building the server, configure your MCP client to run roslyn-mcp-server or the server executable from the repository root you want to inspect.

If you prefer a self-built release-style layout, publish instead of building. Use the runtime identifier for your target platform, such as win-x64, linux-x64, osx-x64, or osx-arm64:

git clone https://github.com/kirnot92/roslyn-mcp-server.git
cd roslyn-mcp-server
dotnet publish .\src\RoslynMcpServer\RoslynMcpServer.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None -p:DebugSymbols=false -o .\publish\roslyn-mcp-server

With the default configuration, the current working directory becomes the workspace root. Use --root <path> only when your MCP client cannot set the working directory. Use --roslyn-language-server <path> only when roslyn-language-server is not on PATH.

--load-solution <path> is optional. When set, the server starts loading that .sln or .slnx as soon as the MCP server starts, so Roslyn LS can warm while the agent reads the repository. When it is omitted, the agent can still call load_solution or load_project when it needs Roslyn context.

Recommended tool flow:

  1. list_workspaces
  2. load_solution or load_project
  3. get_workspace_status
  4. read-only Roslyn tools

For code review workflows, start workspace loading early. A good pattern is to inspect the changed file list, load the intended solution or project, then read the diff while Roslyn LS warms in the background.

MCP Client Setup

Install, download, or build the server first, then point your MCP client at roslyn-mcp-server or the server executable. Use cwd or --root <repo-root> so the server knows which repository to inspect. Solution paths passed to --load-solution must be the exact root-relative path, such as Sources/Server.sln, or an absolute path inside the root. The server does not recursively search for a matching file name from this option.

1. Claude Code

Local setup with claude mcp add:

claude mcp add --transport stdio roslyn -- `
  roslyn-mcp-server `
  --root <repo-root> `
  --load-solution Server.sln

Project-scoped .mcp.json:

{
  "mcpServers": {
    "roslyn": {
      "command": "roslyn-mcp-server",
      "args": ["--root", ".", "--load-solution", "Server.sln"]
    }
  }
}

2. Gemini CLI

Project .gemini/settings.json:

{
  "mcpServers": {
    "roslyn": {
      "command": "roslyn-mcp-server",
      "args": ["--load-solution", "Server.sln"],
      "cwd": "<repo-root>",
      "timeout": 30000
    }
  }
}

3. Codex

Global ~/.codex/config.toml, or project-scoped .codex/config.toml in a trusted project:

[mcp_servers.roslyn]
command = "roslyn-mcp-server"
args = ["--root", "<repo-root>", "--load-solution", "Server.sln"]

If you keep a project-scoped .codex/config.toml in the repository root, --root can usually be .:

[mcp_servers.roslyn]
command = "roslyn-mcp-server"
args = ["--root", ".", "--load-solution", "Server.sln"]

Multiple Solutions

For repositories with separate solutions, run separate MCP server entries. For example, a Unity project can expose both server and client solutions:

{
  "mcpServers": {
    "roslyn-server": {
      "command": "roslyn-mcp-server",
      "args": ["--load-solution", "Server.sln"],
      "cwd": "<repo-root>"
    },
    "roslyn-unity": {
      "command": "roslyn-mcp-server",
      "args": ["--load-solution", "UnityClient.sln"],
      "cwd": "<repo-root>"
    }
  }
}

More setup and client examples are in docs/usage.md.

Current Status

The project is pre-release but usable for read-only C# navigation and diagnostics in agent workflows. It has been smoke-tested with real repositories including PowerShell, Semantic Kernel, and ASP.NET Core. Those tests are intentionally about responsiveness and usable metadata, not perfect semantic completeness for every large solution.

Known constraints:

  • roslyn-language-server is a prerelease dependency and may change behavior.
  • Large repositories may remain in WorkspaceWarming for a long time.
  • Project load errors usually reflect local SDK, workload, restore, or global.json environment problems and are surfaced through workspace warnings.
  • Diagnostics are current-known diagnostics from the last processed textDocument/publishDiagnostics notifications, not a guaranteed full build result.
  • Write/refactoring tools are not implemented.

Implementation notes for maintainers are in AGENTS.md and docs/implementation-notes.md.

License

This project is licensed under the MIT License. See LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.4.0 186 5/23/2026