DEV Community

Cover image for Waymark: a local MCP server that lets Claude explore real NuGet packages and your C# code, safely
Prashant Patil
Prashant Patil

Posted on

Waymark: a local MCP server that lets Claude explore real NuGet packages and your C# code, safely

Waymark v0.1 is out. 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.

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: https://github.com/patilprashant6792-official/waymark-local

If you read my earlier posts about sharp-mcp, this is what it grew into.

Dashboard

The idea in plain words

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".

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.

What you get:

  • Claude that checks the real package before it writes a library call.
  • Claude that understands a large C# codebase without reading every file.
  • Claude that can edit, build and fix, with you approving anything risky.
  • A clear record of what it did, and secrets hidden before they reach the chat.

Approval Card

The part I am proudest of: NuGet, read from the real package

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.

Waymark replaces memory with the package itself. Two tools do it. nuget_find finds types and methods by describing what you need, ranked best first. nuget_expand 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.

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

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; }
Enter fullscreen mode Exit fullscreen mode

Same library, two generations of API, and the assistant sees both at the version you actually use.

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.

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

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.

Built for C#, not just for text

Most assistants treat code as text: they read a file to find a line. Waymark treats C# as C#.

Finding. 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:

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

code_callers shows who calls a method, code_types shows everything that derives from or implements a type, and code_grep 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.

Writing. Edits go in by line number, using the numbers code_method just returned, so Claude changes exactly the lines it read. file_edit_lines 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 cmd_dotnet build 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.

Where it came from

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: how it stops Claude from inventing library methods, and the decisions behind it.

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.

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.

Try it

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.

  1. git clone https://github.com/patilprashant6792-official/waymark-local.git
  2. cd waymark-local, then run install.cmd.
  3. Open http://localhost:47100, paste your ngrok address on Setup, and add a project folder on Workspaces.
  4. 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)

This is early software (v0.1). Please read the limits further down before you point it at anything important.

The detail

Everything above is the idea. Everything below is how the safety side works, for those who want to check my claims.

Two doors

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.

Gates, approvals and secrets

Gated edits and commands. 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.

The Commands page showing Off, Ask and Auto gates for each operation

Secrets hidden, everything logged. Every result passes the same pipeline: private keys, cloud tokens, JWTs, connection strings and named values such as password or api key are replaced by markers like [redacted:kind]. 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.

Updates are update.cmd; uninstall.cmd keeps your data unless you ask otherwise.

What it does not do

I would rather you hear these from me:

  • There is no sandbox. 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.
  • Secret hiding goes by shape. A secret in an unusual form can get through. Deleting a chat does not take a leaked secret back; rotate it.
  • The C# index is name-based for callers. code_callers matches by method name, so overloads and same-named methods can produce false callers. Other files are found with code_grep, which scans the disk on each call.
  • NuGet lookups have limits. 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.
  • One tunnel, one machine. ngrok is the only tunnel today, and it is Windows only, for one user.
  • Connectors (for example database access) are not built; the page is hidden for now.

I built Waymark with Claude's help, and I read and decide what goes in.

What I would like from you

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

The code, the guide and the safety notes are in the repository. Issues and pull requests are welcome.

Top comments (0)