<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Prashant Patil</title>
    <description>The latest articles on DEV Community by Prashant Patil (@prashant_patil_9e62d3fa8a).</description>
    <link>https://dev.to/prashant_patil_9e62d3fa8a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3679473%2Fd1373e51-83e2-4971-a679-d2ee57a15999.png</url>
      <title>DEV Community: Prashant Patil</title>
      <link>https://dev.to/prashant_patil_9e62d3fa8a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prashant_patil_9e62d3fa8a"/>
    <language>en</language>
    <item>
      <title>Six Problems. Six Decisions. How sharp-mcp Actually Works Under the Hood.</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Sun, 21 Jun 2026 13:00:30 +0000</pubDate>
      <link>https://dev.to/prashant_patil_9e62d3fa8a/six-problems-six-decisions-how-sharp-mcp-actually-works-under-the-hood-1c9a</link>
      <guid>https://dev.to/prashant_patil_9e62d3fa8a/six-problems-six-decisions-how-sharp-mcp-actually-works-under-the-hood-1c9a</guid>
      <description>&lt;p&gt;Two months ago I published &lt;a href="https://dev.to/prashant_patil_9e62d3fa8a/i-just-wanted-claude-to-stop-hallucinating-my-nuget-apis-somehow-i-ended-up-building-a-full-c-dev-12om"&gt;my first article&lt;/a&gt; about sharp-mcp — a local MCP server that gives Claude real Roslyn-powered access to your C# codebase. That article introduced the &lt;em&gt;what&lt;/em&gt;. This one is the &lt;em&gt;why behind every decision&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I want to be direct about something first: I've been using sharp-mcp as my primary coding workflow for two months on real production work. Not demos, not toy projects — actual backend .NET development at my job. It has changed how I work completely. Every architectural decision I'm about to describe came from either hitting a real wall or refusing to accept a tradeoff I knew was wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/patilprashant6792-official/sharp-mcp" rel="noopener noreferrer"&gt;https://github.com/patilprashant6792-official/sharp-mcp&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  💬 Follow the build and share feedback in &lt;a href="https://github.com/patilprashant6792-official/sharp-mcp/discussions" rel="noopener noreferrer"&gt;GitHub Discussions&lt;/a&gt;
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The starting point: focus
&lt;/h2&gt;

&lt;p&gt;Claude Code, GitHub Copilot, Cursor — they're all built for every language, every ecosystem. That generality has a cost. When you're doing C# backend work, you're paying token overhead for abstractions built for Python, JavaScript, Ruby. I wanted something that only knows C#, only knows .NET, and uses that focus to do the job better than anything general-purpose ever could.&lt;/p&gt;

&lt;p&gt;That decision — narrow focus over broad compatibility — is what every other decision flows from.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 1: Direct file reading was the obvious first move — and it was broken
&lt;/h2&gt;

&lt;p&gt;I started where everyone starts: read the file, pass it to the model. It worked. It was also impractically slow for any real codebase. Search latency was high, large files burned context fast, and it touched the real filesystem on every single request.&lt;/p&gt;

&lt;p&gt;A 500-line service class costs ~2,000 tokens raw. Load ten files across a microservices solution and you've burned your entire context budget before writing a single line. That's not a tool, that's a handicap.&lt;/p&gt;

&lt;p&gt;Direct file reading wasn't viable at scale — and that failure made the solution obvious: parse the structure once, cache it, and serve from memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 2: Roslyn was the right answer, but it needed a home
&lt;/h2&gt;

&lt;p&gt;Roslyn gives you a full AST — classes, methods, line spans, dependencies, everything structured. Instead of handing Claude a 500-line file, you hand it the API surface: class name, constructor dependencies, method signatures with exact line numbers. The model gets exactly what it needs to reason and nothing it doesn't.&lt;/p&gt;

&lt;p&gt;But parsing on every request defeats the purpose entirely. The data needed to live somewhere fast.&lt;/p&gt;

&lt;p&gt;Redis was the obvious choice. If you're a .NET backend developer, you already have Redis. It's not an exotic dependency — it's infrastructure you trust in production. The decision was: parse once with Roslyn on startup, serialize the AST metadata into Redis, serve every subsequent call in milliseconds with zero disk I/O.&lt;/p&gt;

&lt;p&gt;Second call for any file: a Redis read. That's it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 3: NuGet hallucinations — the one nobody else is solving
&lt;/h2&gt;

&lt;p&gt;This was the most painful problem to hit and the most interesting one to solve.&lt;/p&gt;

&lt;p&gt;AI models generate correct-looking C# that doesn't compile because they don't know what's actually inside the NuGet packages you're using. &lt;code&gt;System.Text.Json&lt;/code&gt; changed nullable handling between 6.0 and 8.0. EF Core changed &lt;code&gt;DbContext&lt;/code&gt; configuration between 7.0 and 8.0. &lt;code&gt;IgnoreNullValues&lt;/code&gt; was deprecated mid-lifecycle. The model confidently generates code against APIs that no longer exist in your version.&lt;/p&gt;

&lt;p&gt;Documentation is incomplete. Training data is stale. The model guesses — and guesses wrong.&lt;/p&gt;

&lt;p&gt;The fix: stop guessing entirely. Decode the binary.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MetadataLoadContext&lt;/code&gt; downloads the real &lt;code&gt;.nupkg&lt;/code&gt;, resolves transitive dependencies, loads the DLL into an isolated context, reads the actual IL, and returns real signatures — real method names, real parameter types, real generics. No docs. No training data. The model gets the same ground truth the compiler uses.&lt;/p&gt;

&lt;p&gt;Frontier LLMs can web search documentation for behavioral context whenever they need it. What they cannot do is know the exact method signatures in your specific package version. That's the gap. That's what this closes.&lt;/p&gt;

&lt;p&gt;Token cost difference in practice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you're doing&lt;/th&gt;
&lt;th&gt;Raw docs dump&lt;/th&gt;
&lt;th&gt;sharp-mcp&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Explore a namespace&lt;/td&gt;
&lt;td&gt;~6,000 tokens&lt;/td&gt;
&lt;td&gt;~250 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Explore a class&lt;/td&gt;
&lt;td&gt;~2,000 tokens&lt;/td&gt;
&lt;td&gt;~400 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fetch one method&lt;/td&gt;
&lt;td&gt;~2,000 tokens&lt;/td&gt;
&lt;td&gt;~120 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Over a full implementation session this compounds into hours of additional useful context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 4: The cache needs to stay warm
&lt;/h2&gt;

&lt;p&gt;A cached Roslyn analysis is only useful if it reflects the current state of the file. This is the consistency problem that kills most caching approaches — you get speed, but you trade accuracy.&lt;/p&gt;

&lt;p&gt;The solution: a &lt;code&gt;FileSystemWatcher&lt;/code&gt; architecture that listens for file changes and automatically invalidates or updates the relevant cache entries. Every &lt;code&gt;.cs&lt;/code&gt; file edit you make in Visual Studio propagates to the cache within 300ms — a debounce window that handles the burst of events VS fires on a single save.&lt;/p&gt;

&lt;p&gt;Delete events evict the key. Rename events evict the old key and index the new path. A background indexer runs on startup and every 60 minutes to catch anything the watcher missed.&lt;/p&gt;

&lt;p&gt;The result: global code search runs against warm cache data within seconds, without touching the real codebase. Claude always sees your code as it exists on disk right now — never stale. This is what makes long feature implementation sessions practical.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 5: Claude.ai needs a bridge to localhost
&lt;/h2&gt;

&lt;p&gt;An LLM running over the web can't reach your local machine directly. ngrok provides the SSE tunnel — one command, one URL, paste it into Claude.ai Settings → Connectors, and Claude discovers all 23 tools automatically.&lt;/p&gt;

&lt;p&gt;It's a real dependency and I won't dress it up. A VS Code extension is on the roadmap to eliminate it. But for now it's one command and the rest of the setup is &lt;code&gt;dotnet run&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 6: The UI that removes the last friction point
&lt;/h2&gt;

&lt;p&gt;One thing I refused to build was a tool that required editing JSON config files or restarting a server every time you added a project.&lt;/p&gt;

&lt;p&gt;There's a built-in project management UI at &lt;code&gt;/config.html&lt;/code&gt;. You point it at a solution folder. That's it. sharp-mcp indexes everything — classes, methods, dependencies, file sizes — and the LLM immediately has full structural awareness of that codebase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg2674p2cuu77h8u4nr2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg2674p2cuu77h8u4nr2g.png" alt="Configuration UI of sharp-mcp" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You point it at a solution folder. That's it. sharp-mcp indexes everything — classes, methods, dependencies, file sizes — and the LLM immediately has full structural awareness of that codebase. Each project is independently enabled, re-indexable on demand, and deletable without touching any config file. And yes — sharp-mcp manages its own source code through the same UI. The tool is its own first user.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three principles everything was built around
&lt;/h2&gt;

&lt;p&gt;Looking back at all six decisions, they all trace back to three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt; — Redis cache + file watcher keeping it warm. No cold starts after the first indexing pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token efficiency&lt;/strong&gt; — every tool description tells the model when &lt;em&gt;not&lt;/em&gt; to call it. Batch modes, size hints, "last resort" labels — that's not documentation, it's prompt engineering baked into the architecture. The LLM should get exactly what it needs to know. Nothing more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correctness&lt;/strong&gt; — &lt;code&gt;MetadataLoadContext&lt;/code&gt; means the model works with real signatures, not approximations. There is no training cutoff for your NuGet packages.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The system prompt — two months of refinement
&lt;/h2&gt;

&lt;p&gt;Here's the part that doesn't get talked about enough: tools alone don't make an agent. Judgment does.&lt;/p&gt;

&lt;p&gt;After two months of daily use on real production code, I've published the exact system prompt I use at &lt;a href="https://github.com/patilprashant6792-official/sharp-mcp/blob/main/prompts/CODING_SYSTEM_PROMPT.md" rel="noopener noreferrer"&gt;&lt;code&gt;prompts/CODING_SYSTEM_PROMPT.md&lt;/code&gt;&lt;/a&gt; in the repo.&lt;/p&gt;

&lt;p&gt;It's split into two halves:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part A — Engineering philosophy.&lt;/strong&gt; Eleven principles: clarity before action, solve the unstated problem, atomic decomposition, multi-perspective validation. These aren't LLM-specific instructions. They're the principles any senior engineer applies before touching a keyboard. The prompt makes them explicit so the model doesn't skip them under time pressure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part B — Common sense production rules.&lt;/strong&gt; Thirteen domains: error handling, validation, resource management, logging, concurrency, API design, database patterns. One rule from the third-party libraries section is worth quoting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always web search for latest official documentation before using any library. Verify the exact installed version. Validate method signatures and APIs for that specific version. Never assume behavior based on outdated knowledge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That rule exists because of exactly the NuGet hallucination problem sharp-mcp was built to solve. Even with real signatures from &lt;code&gt;MetadataLoadContext&lt;/code&gt;, a model that doesn't verify assumptions before writing code will still find ways to be wrong. The prompt and the tools reinforce each other.&lt;/p&gt;

&lt;p&gt;The third section maps the 23 tools to a strict decision tree — which tool to call first, when never to call &lt;code&gt;read_file_content&lt;/code&gt; on a large C# file, why you always run &lt;code&gt;execute_dotnet_command&lt;/code&gt; before marking anything complete, why you batch all &lt;code&gt;edit_lines&lt;/code&gt; patches in a single call.&lt;/p&gt;

&lt;p&gt;This prompt is why the experience feels like pair programming with a senior .NET engineer rather than autocomplete. And it works with any MCP-capable LLM — not just Claude.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this does not replace
&lt;/h2&gt;

&lt;p&gt;This is not inline autocomplete. It doesn't suggest the next line as you type.&lt;/p&gt;

&lt;p&gt;What it replaces is the reasoning session — when you open a chat to understand a codebase, plan a refactor, check what breaks if you change a method signature, look up how a dependency actually works, or implement a feature that spans multiple files. Those sessions are where context limits, hallucinated APIs, and cloud data exposure all cause real damage.&lt;/p&gt;

&lt;p&gt;That's the scope this was built for. And after two months of using it daily on production .NET backend work, I can say with confidence: it's the most productive I've ever been writing C#.&lt;/p&gt;




&lt;p&gt;If you read the &lt;a href="https://dev.to/prashant_patil_9e62d3fa8a/i-just-wanted-claude-to-stop-hallucinating-my-nuget-apis-somehow-i-ended-up-building-a-full-c-dev-12om"&gt;first article&lt;/a&gt; and thought "sounds interesting but I want to understand how it actually works" — this was written for you. Questions welcome in the comments.&lt;/p&gt;

&lt;p&gt;— Prashant&lt;/p&gt;

</description>
      <category>ai</category>
      <category>csharp</category>
      <category>mcp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>MCP server for C# development with real NuGet reflection</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Mon, 13 Apr 2026 15:08:51 +0000</pubDate>
      <link>https://dev.to/prashant_patil_9e62d3fa8a/i-just-wanted-claude-to-stop-hallucinating-my-nuget-apis-somehow-i-ended-up-building-a-full-c-dev-12om</link>
      <guid>https://dev.to/prashant_patil_9e62d3fa8a/i-just-wanted-claude-to-stop-hallucinating-my-nuget-apis-somehow-i-ended-up-building-a-full-c-dev-12om</guid>
      <description>&lt;h1&gt;
  
  
  sharp-mcp:
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Roslyn-Powered C# Analysis, Real NuGet DLL Reflection, and Safe Live File Editing for Claude, On Your Machine via MCP
&lt;/h2&gt;

&lt;p&gt;If you've ever watched an AI confidently call a NuGet method removed two versions ago — and only found out when your build broke — this is for you.&lt;/p&gt;

&lt;p&gt;Or if you've pasted five service classes into a chat, watched the context fill up, and still got a half-baked answer.&lt;/p&gt;

&lt;p&gt;Or if you work in finance or healthcare and the phrase "your code is sent to our servers" is a non-starter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/patilprashant6792-official/sharp-mcp" rel="noopener noreferrer"&gt;https://github.com/patilprashant6792-official/sharp-mcp&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;Every AI coding tool in 2025 has the same three silent killers for .NET developers specifically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hallucinated APIs.&lt;/strong&gt; LLMs are frozen at their training cutoff. NuGet ships breaking changes constantly. &lt;code&gt;System.Text.Json&lt;/code&gt; changed nullable handling between 6.0 and 8.0. EF Core changed &lt;code&gt;DbContext&lt;/code&gt; configuration between 7.0 and 8.0. &lt;code&gt;IgnoreNullValues&lt;/code&gt; was deprecated mid-lifecycle. The model doesn't know. It generates code that looks right and doesn't compile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context bloat.&lt;/strong&gt; A 500-line service class costs ~2,000 tokens raw. Load ten files and you've burned your entire context budget before writing a single line. Copilot's &lt;code&gt;#codebase&lt;/code&gt; search is widely documented as unreliable — developers end up manually attaching files and hitting the limit anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your code leaves your machine.&lt;/strong&gt; Copilot, Cursor, Windsurf — every cloud AI tool sends your source to an external server with every request. For finance, healthcare, or any regulated industry, that's not a theoretical concern. It's a compliance issue.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sharp-mcp&lt;/code&gt; fixes all three. It runs entirely on your machine, exposes your codebase as structured MCP tools, and — the part no other tool does — reflects your actual installed NuGet DLLs via &lt;code&gt;MetadataLoadContext&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The novel piece: real NuGet DLL reflection
&lt;/h2&gt;

&lt;p&gt;When you ask &lt;code&gt;sharp-mcp&lt;/code&gt; how to use a method from a NuGet package, it doesn't consult training data. Here's what actually happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Resolves the exact version pinned in your &lt;code&gt;.csproj&lt;/code&gt; via &lt;code&gt;NuGet.Protocol&lt;/code&gt; — no guessing&lt;/li&gt;
&lt;li&gt;Downloads the &lt;code&gt;.nupkg&lt;/code&gt; and picks the right &lt;code&gt;net*/&lt;/code&gt; target framework folder with automatic fallback chain&lt;/li&gt;
&lt;li&gt;Downloads transitive dependencies — &lt;code&gt;MetadataLoadContext&lt;/code&gt; needs them to resolve cross-assembly types correctly; without this, reflection on generics and inherited types silently fails&lt;/li&gt;
&lt;li&gt;Loads the DLL into an isolated &lt;code&gt;MetadataLoadContext&lt;/code&gt; — binary inspection only, never executed, zero risk of static constructors or process pollution&lt;/li&gt;
&lt;li&gt;Returns valid, copy-paste-ready C# signatures from your exact binary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parses the XML documentation file shipped alongside the DLL&lt;/strong&gt; — before the temporary directory is deleted — and stores the full doc map in Redis keyed by member ID&lt;/li&gt;
&lt;li&gt;Disposes the context immediately — no assembly leaks, no AppDomain side effects&lt;/li&gt;
&lt;li&gt;Caches the result in Redis for 7 days, keyed on &lt;code&gt;packageId:version:targetFramework&lt;/code&gt; — second call is a Redis read, not a download&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No training cutoff. No hallucinated overloads. No deprecated methods that "still work" in the model's memory. Your DLL. Your truth.&lt;/p&gt;

&lt;p&gt;Token cost comparison for NuGet exploration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you're doing&lt;/th&gt;
&lt;th&gt;Raw dump&lt;/th&gt;
&lt;th&gt;sharp-mcp&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Explore a namespace&lt;/td&gt;
&lt;td&gt;~6,000 tokens&lt;/td&gt;
&lt;td&gt;~250 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Explore a class&lt;/td&gt;
&lt;td&gt;~2,000 tokens&lt;/td&gt;
&lt;td&gt;~400 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fetch one method&lt;/td&gt;
&lt;td&gt;~2,000 tokens&lt;/td&gt;
&lt;td&gt;~120 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  But NuGet reflection alone isn't a dev assistant
&lt;/h2&gt;

&lt;p&gt;Here's the honest part: NuGet reflection solves one problem. What makes &lt;code&gt;sharp-mcp&lt;/code&gt; actually useful for day-to-day .NET development is that all 23 tools form a closed loop. Each one makes the others more powerful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────┐
│                     sharp-mcp loop                       │
│                                                          │
│  understand        explore         edit         verify   │
│  codebase  ──►  NuGet APIs  ──►  files   ──►   build    │
│     ▲                                              │     │
│     └──────────────────────────────────────────────┘     │
└──────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You explore a NuGet API with real signatures → write code against those signatures → edit the right file using Roslyn-derived line numbers → build immediately to catch errors. Break any link in that chain and the whole thing degrades. This is the ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understand: Roslyn analysis, not grep
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;analyze_c_sharp_file&lt;/code&gt; uses a full Roslyn syntax tree walker — not text search — to extract structured metadata from every &lt;code&gt;.cs&lt;/code&gt; file: DI constructor graphs, method signatures with exact start/end line numbers, attributes, XML doc comments, public/private toggle. Batch mode lets you pass &lt;code&gt;Services/A.cs,Services/B.cs,Controllers/C.cs&lt;/code&gt; in one call.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fetch_method_implementation&lt;/code&gt; returns a complete method body with every line numbered. Those line numbers are what Claude uses directly in &lt;code&gt;edit_lines&lt;/code&gt; patch operations — no guessing, no off-by-one errors.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;analyze_method_call_graph&lt;/code&gt; walks every &lt;code&gt;.cs&lt;/code&gt; file in your project before you touch a signature and returns every caller — file, class, exact line number. The difference between a safe refactor and a CI failure at 11pm.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get_project_skeleton&lt;/code&gt; gives you an ASCII folder tree with file sizes and NuGet package list. Pass &lt;code&gt;"*"&lt;/code&gt; and it shows every registered project at once. &lt;code&gt;search_code_globally&lt;/code&gt; finds classes, interfaces, methods, and properties by name across all projects simultaneously.&lt;/p&gt;

&lt;p&gt;All of this is Redis-backed. Roslyn parses each file once on startup, serializes the AST metadata to Redis, and serves every subsequent call in milliseconds. A &lt;code&gt;FileSystemWatcher&lt;/code&gt; with a 300ms debounce evicts and rewrites only the changed file on every save. Claude always sees your code as it exists on disk right now — never stale. This is what makes long feature implementation sessions practical — you never burn tokens re-reading files Claude already knows.&lt;/p&gt;




&lt;h2&gt;
  
  
  Explore: NuGet IntelliSense from your actual binary
&lt;/h2&gt;

&lt;p&gt;The NuGet tools follow exactly the sequence a developer uses in an IDE — not a bulk dump of everything at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_package_namespaces      ← "I installed OpenAI — what namespaces does it expose?"
get_namespace_types         ← "What types exist in OpenAI.Chat?" (~10 tokens/type)
get_type_surface(type)      ← "What can I call on ChatClient?"
get_type_shape(type)        ← "What does ChatCompletion look like?"
get_method_overloads(...)   ← expand specific overload groups on demand
get_member_xml_doc(member)  ← "What does CompleteChat actually do? What are the params for?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each step returns only what the next decision requires. Nothing is dumped until asked for. The entire exploration of an unfamiliar package costs ~800 tokens total vs ~6,000 for a full namespace dump. Over a multi-hour implementation session this compounds significantly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get_member_xml_doc&lt;/code&gt; is the final step in this chain. Once you've identified a type and method, it fetches the full XML documentation for that specific member — summary, parameters, return value, remarks, exceptions, and code examples — straight from the XML doc file that shipped with the package. It covers any member kind: types, methods, properties, fields, events, constructors. Zero extra network cost — the XML file is parsed during the initial package load, before the temporary directory is cleaned up, and stored as a separate Redis entry. Every subsequent call is a pure Redis lookup. For packages that don't ship XML docs, it degrades gracefully with a clear message rather than failing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Edit: surgical file operations with real safety guarantees
&lt;/h2&gt;

&lt;p&gt;Claude can create, edit, move, rename, and delete files — all guarded by per-file semaphore locking (concurrent writes serialized, never dropped), atomic batch-move validation (all destinations validated before any file moves; one failure aborts the entire batch), path sandboxing (traversal structurally impossible — resolved against project root), permanent blocked patterns (&lt;code&gt;bin/&lt;/code&gt;, &lt;code&gt;obj/&lt;/code&gt;, &lt;code&gt;.git/&lt;/code&gt;, secrets, tokens — enforced at the service layer, not a config flag), and automatic Redis cache eviction on every write so the next analysis call sees the updated file immediately.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;edit_lines&lt;/code&gt; applies multiple patch/insert/delete/append operations to a single file atomically. Patches are validated for overlaps then applied bottom-up — original line numbers stay correct for every patch in the batch. This is what lets Claude make multi-location changes in one shot without line drift.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verify: build with structured Roslyn diagnostics
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;execute_dotnet_command&lt;/code&gt; runs &lt;code&gt;dotnet clean + build&lt;/code&gt; and returns structured diagnostics — not raw stderr:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CS0246"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Services/OrderService.cs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"line"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude reads the file path and line number, jumps straight to the problem using the analysis tools, and fixes it. The loop — explore → edit → build → fix — runs entirely inside the conversation without copy-pasting error output.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-project from day one
&lt;/h2&gt;

&lt;p&gt;Register as many projects as you have. Every tool accepts &lt;code&gt;projectName&lt;/code&gt;. Claude can read the skeleton of one microservice, fetch a method from another, edit a third, build a fourth — in one conversation, without context switching. Pass &lt;code&gt;"*"&lt;/code&gt; to any tool to scope it across all registered projects simultaneously.&lt;/p&gt;




&lt;h2&gt;
  
  
  The privacy angle
&lt;/h2&gt;

&lt;p&gt;Claude receives structured metadata — class names, method signatures, line ranges. Not your business logic. Not your proprietary algorithms. Not your customer data. Nothing leaves your machine.&lt;/p&gt;

&lt;p&gt;For .NET developers in finance or healthcare this isn't a nice-to-have. With the EU AI Act in phased enforcement and data residency requirements tightening globally, a tool that processes source code locally is increasingly the only compliant option.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;.NET 10 · Roslyn (Microsoft.CodeAnalysis.CSharp 5.0) · Redis (StackExchange.Redis + NRedisStack) · ModelContextProtocol 0.5 · NuGet.Protocol · System.Reflection.MetadataLoadContext · ngrok SSE transport&lt;/p&gt;

&lt;p&gt;23 MCP tools across 8 tool classes: code analysis, project exploration, NuGet reflection, file operations, dotnet CLI, utility.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/patilprashant6792-official/sharp-mcp
&lt;span class="nb"&gt;cd &lt;/span&gt;sharp-mcp/LocalMcpServer
dotnet run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start Redis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 6379:6379 redis:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expose with ngrok:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register your projects via the web UI — no config files to hand-edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;http://localhost:5000/config.html
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the ngrok &lt;code&gt;/sse&lt;/code&gt; URL to Claude.ai → Settings → Connectors. Claude discovers all 23 tools automatically. Full setup walkthrough in the README.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this doesn't replace
&lt;/h2&gt;

&lt;p&gt;This is not inline autocomplete. It doesn't suggest the next line as you type and doesn't integrate into your IDE as an extension.&lt;/p&gt;

&lt;p&gt;What it replaces is the reasoning session — when you open a chat to understand a codebase, plan a refactor, check what breaks if you change a signature, look up how a dependency actually works, or implement a feature that spans multiple files. That's the scope it's built for. And that's where the closed loop — Roslyn analysis, real NuGet reflection, surgical editing, live build feedback — earns its keep.&lt;/p&gt;




&lt;p&gt;Drop a comment if you've hit any of these walls. Genuinely curious what .NET packages and patterns people are trying to get Claude to reason about.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
