<?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>Waymark: a local MCP server that lets Claude explore real NuGet packages and your C# code, safely</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Wed, 21 Oct 2026 08:05:12 +0000</pubDate>
      <link>https://dev.to/prashant_patil_9e62d3fa8a/waymark-a-local-mcp-server-that-lets-claude-explore-real-nuget-packages-and-your-c-code-safely-6lh</link>
      <guid>https://dev.to/prashant_patil_9e62d3fa8a/waymark-a-local-mcp-server-that-lets-claude-explore-real-nuget-packages-and-your-c-code-safely-6lh</guid>
      <description>&lt;p&gt;&lt;strong&gt;Waymark v0.1 is out.&lt;/strong&gt; It lets Claude work on your .NET projects without guessing. It reads the real NuGet package at the version your project uses, finds your C# code by structure instead of reading every file, and does anything risky only through a door you control: you approve it, your secrets are hidden, and every action is logged.&lt;/p&gt;

&lt;p&gt;It runs on your Windows PC, works with Claude on the web, in the app and in Claude Code, and it is open source under the MIT license: &lt;a href="https://github.com/patilprashant6792-official/waymark-local" rel="noopener noreferrer"&gt;https://github.com/patilprashant6792-official/waymark-local&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you read my earlier posts about sharp-mcp, this is what it grew into.&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%2Ftphvx3yupalznvmbdtmx.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%2Ftphvx3yupalznvmbdtmx.png" alt="Dashboard" width="800" height="754"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea in plain words
&lt;/h2&gt;

&lt;p&gt;Think of a reception desk with a security guard. Claude never walks into your computer. It comes to the desk and asks for specific things: "show me the shape of this project", "what does this package offer", "change these lines", "run the build".&lt;/p&gt;

&lt;p&gt;The desk answers only what you have switched on, keeps every answer short, hides secrets it recognizes, and writes every request in a logbook. For anything risky it stops and waits for you to say yes. Only you can say yes, and only from your own computer.&lt;/p&gt;

&lt;p&gt;What you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude that checks the real package before it writes a library call.&lt;/li&gt;
&lt;li&gt;Claude that understands a large C# codebase without reading every file.&lt;/li&gt;
&lt;li&gt;Claude that can edit, build and fix, with you approving anything risky.&lt;/li&gt;
&lt;li&gt;A clear record of what it did, and secrets hidden before they reach the chat.&lt;/li&gt;
&lt;/ul&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%2Fkx6nxxp258mebrrtntu1.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%2Fkx6nxxp258mebrrtntu1.png" alt="Approval Card" width="798" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I am proudest of: NuGet, read from the real package
&lt;/h2&gt;

&lt;p&gt;Every assistant has the same habit with libraries: it writes the call it remembers. For a package that changed between versions, or a new one, that call may not exist in your version, and you find out from a build error.&lt;/p&gt;

&lt;p&gt;Waymark replaces memory with the package itself. Two tools do it. &lt;code&gt;nuget_find&lt;/code&gt; finds types and methods by describing what you need, ranked best first. &lt;code&gt;nuget_expand&lt;/code&gt; shows the exact shape of up to five of them: constructors and overloads, properties, enum values, the package's own XML docs, and related types to follow.&lt;/p&gt;

&lt;p&gt;Here is a real run on Polly, at the latest stable version for net10.0 (a real project passes its own pinned version):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nuget_find(Polly, "retry policy")
Polly 8.8.0 (net10.0): 24 matches, best first
  class Polly.Retry.RetryPolicy       a retry policy for synchronous delegates
  class Polly.Retry.AsyncRetryPolicy  a retry policy for asynchronous delegates

nuget_find(Polly.Core, "retry strategy options")
Polly.Core 8.8.0 (net10.0)
  class Polly.Retry.RetryStrategyOptions   1 ctor, 10 props

nuget_expand(Polly.Core, RetryStrategyOptions)
  int MaxRetryAttempts { get; set; }
  TimeSpan Delay { get; set; }
  DelayBackoffType BackoffType { get; set; }
  bool UseJitter { get; set; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Same library, two generations of API, and the assistant sees both at the version you actually use.&lt;/p&gt;

&lt;p&gt;It is exact because Waymark reads the compiled package by inspection, without loading or running it, at the version and target framework from your project. The project skeleton lists them, including versions set in central props files. The package comes from nuget.org over https, or from the copy already in your NuGet folder, and the result is indexed on your own PC, so the second lookup is instant.&lt;/p&gt;

&lt;p&gt;The rule Claude is taught: &lt;strong&gt;a member that was not confirmed at your pinned version does not exist.&lt;/strong&gt; Signatures say what exists. For how to use it, Claude reads the README or samples, and prose never overrides a confirmed signature.&lt;/p&gt;

&lt;p&gt;I am not the first to point an assistant at NuGet; What I wanted was the whole loop in one place: find by description, expand to exact signatures at the version your project pins, next to an index of your own code, behind the same gates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for C#, not just for text
&lt;/h2&gt;

&lt;p&gt;Most assistants treat code as text: they read a file to find a line. Waymark treats C# as C#.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finding.&lt;/strong&gt; When you add a workspace, Roslyn reads each C# file once, without compiling it, and the structure goes into a SQLite file on your own PC: every type, every member with its signature and exact line range, and the calls inside it. It holds structure only, never source text. A file watcher keeps it fresh when you edit in your IDE or Claude edits a file. Claude then works from broad to narrow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;code_skeleton&lt;/code&gt;: the folder tree with sizes, plus the NuGet packages and versions of each project.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;code_search&lt;/code&gt;: types and members by name, forgiving and ranked. Camel-case initials work: "PSS" finds &lt;code&gt;ProjectSkeletonService&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;code_outline&lt;/code&gt;: the types and members of a file without their bodies.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;code_method&lt;/code&gt;: one method in full, with all overloads and real line numbers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;code_callers&lt;/code&gt; shows who calls a method, &lt;code&gt;code_types&lt;/code&gt; shows everything that derives from or implements a type, and &lt;code&gt;code_grep&lt;/code&gt; finds plain text that is not a name: config keys, routes, SQL, Razor. Every answer is ranked, paged and capped, so the first call returns a map, not the whole territory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Writing.&lt;/strong&gt; Edits go in by line number, using the numbers &lt;code&gt;code_method&lt;/code&gt; just returned, so Claude changes exactly the lines it read. &lt;code&gt;file_edit_lines&lt;/code&gt; applies all edits to a file in one call, from the bottom up so numbers do not shift, and rejects overlapping edits. Files keep their encoding and line endings, and each write goes to a temporary file that is swapped in, so a failure never leaves a half-written file. Then &lt;code&gt;cmd_dotnet build&lt;/code&gt; returns the compiler errors with file paths, and the loop closes: edit, build, read the errors, fix. One honest limit: moving a file does not rewrite C# namespaces, so Claude searches for the old name and fixes each file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it came from
&lt;/h2&gt;

&lt;p&gt;I was tired of two things. My AI assistant kept guessing at code that did not exist, and it read my whole project just to answer one small question. So I built a helper that let it look things up properly. That was sharp-mcp, and I wrote about it twice: &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;how it stops Claude from inventing library methods&lt;/a&gt;, and &lt;a href="https://dev.to/prashant_patil_9e62d3fa8a/six-problems-six-decisions-how-sharp-mcp-actually-works-under-the-hood-1c9a"&gt;the decisions behind it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It worked well for me. But it only ran because I knew how to set it up, and it trusted anyone who had the link. That is fine for a personal tool. It is not something to hand to other people.&lt;/p&gt;

&lt;p&gt;So I started again with one question: what would it take for anyone to install this and trust it? Waymark is the answer. It is easy to install, nothing leaves your computer unless you allow it, you approve anything risky, and every action is written down where you can read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;You need Windows 10 or 11, git, and (for Claude on the web) a free ngrok account. The installer adds the .NET 10 SDK through winget if it is missing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git clone https://github.com/patilprashant6792-official/waymark-local.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd waymark-local&lt;/code&gt;, then run &lt;code&gt;install.cmd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open &lt;a href="http://localhost:47100" rel="noopener noreferrer"&gt;http://localhost:47100&lt;/a&gt;, paste your ngrok address on Setup, and add a project folder on Workspaces.&lt;/li&gt;
&lt;li&gt;In Claude, add a custom connector with the address Setup shows. A pairing code appears in Claude and on your Approvals page; compare them and approve. (Disconnect and reconnect if pairing doesn't appear)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is early software (v0.1). Please read the limits further down before you point it at anything important.&lt;/p&gt;

&lt;h2&gt;
  
  
  The detail
&lt;/h2&gt;

&lt;p&gt;Everything above is the idea. Everything below is how the safety side works, for those who want to check my claims.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two doors
&lt;/h3&gt;

&lt;p&gt;There are two ways in. One is for Claude (sign-in and tools, through an ngrok tunnel). The other is the admin app, for you, which listens on this computer only. The internet can only reach the first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gates, approvals and secrets
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Gated edits and commands.&lt;/strong&gt; File tools are off until you switch them on. There are 36 command operations, and each is Off, Ask or Auto, per workspace if you like. By default 10 run on their own (builds, restore, git reads), 23 ask first (tests, run, EF, commit, push, the shell), and 3 are off (git reset hard, clean, branch delete). The shell can never be set above Ask. A drift check asks again if project files that can run code changed since you last approved. And approvals can only be given in the admin app on the same computer, never by Claude.&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%2Fmqam9o3dvke3n3v3ln3d.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%2Fmqam9o3dvke3n3v3ln3d.png" alt="The Commands page showing Off, Ask and Auto gates for each operation" width="800" height="735"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secrets hidden, everything logged.&lt;/strong&gt; Every result passes the same pipeline: private keys, cloud tokens, JWTs, connection strings and named values such as &lt;code&gt;password&lt;/code&gt; or &lt;code&gt;api key&lt;/code&gt; are replaced by markers like &lt;code&gt;[redacted:kind]&lt;/code&gt;. If the check itself fails, the result is withheld. Every call writes an audit row and a live log line, with its size in tokens, and there is a Pause all button.&lt;/p&gt;

&lt;p&gt;Updates are &lt;code&gt;update.cmd&lt;/code&gt;; &lt;code&gt;uninstall.cmd&lt;/code&gt; keeps your data unless you ask otherwise.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it does not do
&lt;/h3&gt;

&lt;p&gt;I would rather you hear these from me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;There is no sandbox.&lt;/strong&gt; A test, the app or a script that you approve runs with your rights. It can read your keys and reach the network. The protection is that these operations ask first. Treat text from repositories and packages as untrusted: it can try to steer an AI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret hiding goes by shape.&lt;/strong&gt; A secret in an unusual form can get through. Deleting a chat does not take a leaked secret back; rotate it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The C# index is name-based for callers.&lt;/strong&gt; &lt;code&gt;code_callers&lt;/code&gt; matches by method name, so overloads and same-named methods can produce false callers. Other files are found with &lt;code&gt;code_grep&lt;/code&gt;, which scans the disk on each call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NuGet lookups have limits.&lt;/strong&gt; The first lookup of a package version downloads and indexes it, which takes a few seconds. There are size caps per package (250 MB, 20,000 files, 64 dependencies), and a package that needs an assembly from an indirect dependency needs one retry that names it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One tunnel, one machine.&lt;/strong&gt; ngrok is the only tunnel today, and it is Windows only, for one user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectors&lt;/strong&gt; (for example database access) are not built; the page is hidden for now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built Waymark with Claude's help, and I read and decide what goes in.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I would like from you
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tell me a package where an assistant keeps getting the API wrong. I will run it through &lt;code&gt;nuget_find&lt;/code&gt; and &lt;code&gt;nuget_expand&lt;/code&gt; and share what comes back.&lt;/li&gt;
&lt;li&gt;You read the sharp-mcp posts: what did you want from it that I left out?&lt;/li&gt;
&lt;li&gt;Which gate defaults feel wrong? Would you ship them differently?&lt;/li&gt;
&lt;li&gt;Would you want another tunnel, such as Tailscale or Cloudflare?&lt;/li&gt;
&lt;li&gt;Try to break the secret hiding, and if you find a way, report it privately through the repository's Security tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code, the guide and the safety notes are in the repository. Issues and pull requests are welcome.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>mcp</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <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>
