Skip to content

haxxornulled/SharpMCPServer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

109 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SharpMCPServer

SharpMCPServer is a .NET 10 MCP platform for real clients, real tools, and real approval gates.

CI Smoke Release License

It runs a host that serves stdio and loopback Streamable HTTP, keeps workspace writes inside explicit sandboxes, routes inference through provider adapters, exposes SSH and AgentRouter tools from the host, ships an in-process Blazor operator dashboard in SharpMCPServer.Web, and keeps the Python-facing AgentRouter bridge in a separate NativeAOT runtime lane instead of blurring that boundary behind CLR tricks.

If you want a toy demo, there are easier repos. If you want something you can point actual clients at and still explain to another engineer later, this is the point.

Protocol baseline: MCP 2025-11-25. The implementation matrix lives in docs/SPEC_COMPLIANCE.md. If you only read one doc next, read docs/GETTING_STARTED.md.

Pipelines

The GitHub Actions pipeline now matches the repo's actual lanes instead of pretending one build command tells the whole story:

  • CI restores with locked dependencies, builds the solution, and runs the repository verification lane on pushes and pull requests to main.
  • Smoke is a separate manual workflow dispatch for the explicit smoke lane when you want the full client-facing process checks.
  • Release packages the host, console client, and chat launcher for tagged v*.*.* releases, then publishes the exact artifacts that were built.
  • Dependabot watches both GitHub Actions and NuGet so workflow and package drift does not sit unnoticed.
  • The local equivalent remains pwsh .\scripts\verify-mcp-phase1.ps1 followed by pwsh .\scripts\Test-Smoke.ps1 -Configuration Release when you want the same shape without waiting on GitHub.

How to read this repo

If code, tests, AGENTS.md, and other docs disagree, use that order.

The code wins. The tests prove it. AGENTS.md sets repo rules. Docs explain the current shape, not the other way around.

What this repo gives you

Surface What it does
SharpMCPServer.Host Main MCP server host for stdio and loopback Streamable HTTP.
SharpMCPServer.Web In-process Blazor operator dashboard for approvals, workspace state, tools, logs, and host health.
SharpMCPServer.Client.Console Direct console client for tool calls, chat mode, and protocol checks.
SharpMCPServer.ChatLauncher Repo-owned wrapper that launches the console with sane defaults.
SharpMCPServer.Application MCP tool, prompt, resource, and task handlers.
SharpMCPServer.Workspace Workspace roots, sandbox persistence, patching, and file policy.
SharpMCPServer.Tools.Workspace Workspace tool surface exposed over MCP.
SharpMCPServer.Inference.* and SharpMCPServer.Tools.Inference Provider routing, prompt intelligence, and inference tool exposure.
SharpMCPServer.Ssh, SharpMCPServer.Tools.Ssh, and SharpMCPServer.ExecutionPlugins.Ssh SSH policy, execution runtime, and SSH-backed AgentRouter execution.
SharpMCPServer.AgentRouter.* Host-owned AgentRouter planning, routing, approval, and execution control plane.
SentinelMCP/ Tool approval, caller binding, audit logging, and security policy enforcement.
python/ and SharpMCPServer.AgentRouter.PythonBridge.Native Standalone NativeAOT AgentRouter bridge and stdlib-only Python wrapper.
samples/mcp-clients/ Safe starter configs for Claude Code, VS Code / Copilot, and Cursor.
scripts/ Verification, smoke, capture, release, and sync scripts.

IDE extension concepts live under product-concepts/ide-extensions/ and are intentionally outside the main solution.

Dashboard

SharpMCPServer.Web is the operator dashboard.

It exists so operators can see approvals, workspace state, tools, logs, and host health without turning MCP traffic into a UI transport. The UI is a live operator surface, not a second host.

The boundary stays explicit: the web app observes and orchestrates, the host executes. The dashboard connects to the running host through typed host services in the same process.

If you want the rationale and boundary rules in one place, read docs/DASHBOARD.md.

Start here

  1. Build the repo.
  2. Start the host.
  3. Ask the server something boring and read-only.
  4. Start the chat launcher if you want interactive use.
  5. Use the sample client configs for first real-client checks.
dotnet build .\SharpMCPServer.slnx -c Debug
dotnet run --project .\SharpMCPServer.Host\SharpMCPServer.Host.csproj
dotnet run --project .\SharpMCPServer.Client.Console\SharpMCPServer.Client.Console.csproj -- `
  --server-path dotnet `
  --server-arg .\SharpMCPServer.Host\bin\Debug\net10.0\SharpMCPServer.Host.dll `
  --working-directory .\SharpMCPServer.Host\bin\Debug\net10.0 `
  --tool server.info
dotnet run --project .\SharpMCPServer.ChatLauncher\SharpMCPServer.ChatLauncher.csproj -- --provider lmstudio

Swap lmstudio for ollama if that is the local provider you actually have running. Add --allow-workspace-write only when you intentionally want to test write approval and audit behavior.

What you can do with it

  • Talk to a real MCP host over stdio or Streamable HTTP.
  • Use the Blazor dashboard to see live host state, approvals, tools, and logs without mixing presentation concerns into protocol traffic.
  • Inspect workspace roots, read files, apply patches, and manage sandboxes without turning the server into a machine-wide filesystem API.
  • Route inference through local or remote providers with explicit trust boundaries, then move from LM Studio / Ollama to OpenAI, Anthropic, or Codex when the project needs it.
  • Browse public URLs and GitHub content with bounded, read-only fetch tools instead of turning the host into a general crawler.
  • Use SSH as a constrained tool surface instead of a free-form shell dump.
  • Run AgentRouter workflows through a separate control plane instead of pretending they are just chat prompts.
  • Manage SSH profiles through the repo-owned CLI instead of hand-editing ad hoc JSON or exposing secrets in tool arguments.
  • Bridge Python into the AgentRouter runtime through a NativeAOT boundary that stays boring on purpose.

Common first commands

Once the host is up, these are the first tools people usually try:

dotnet run --project .\SharpMCPServer.Client.Console\SharpMCPServer.Client.Console.csproj -- `
  --server-path dotnet `
  --server-arg .\SharpMCPServer.Host\bin\Debug\net10.0\SharpMCPServer.Host.dll `
  --working-directory .\SharpMCPServer.Host\bin\Debug\net10.0 `
  --tool workspace.roots.list

dotnet run --project .\SharpMCPServer.Client.Console\SharpMCPServer.Client.Console.csproj -- `
  --server-path dotnet `
  --server-arg .\SharpMCPServer.Host\bin\Debug\net10.0\SharpMCPServer.Host.dll `
  --working-directory .\SharpMCPServer.Host\bin\Debug\net10.0 `
  --tool inference.providers.list

dotnet run --project .\SharpMCPServer.Client.Console\SharpMCPServer.Client.Console.csproj -- `
  --server-path dotnet `
  --server-arg .\SharpMCPServer.Host\bin\Debug\net10.0\SharpMCPServer.Host.dll `
  --working-directory .\SharpMCPServer.Host\bin\Debug\net10.0 `
  --tool web.fetch --arguments {"url":"https://example.com"}

dotnet run --project .\SharpMCPServer.Client.Console\SharpMCPServer.Client.Console.csproj -- `
  --server-path dotnet `
  --server-arg .\SharpMCPServer.Host\bin\Debug\net10.0\SharpMCPServer.Host.dll `
  --working-directory .\SharpMCPServer.Host\bin\Debug\net10.0 `
  --tool ssh.profiles.list

dotnet run --project .\SharpMCPServer.Client.Console\SharpMCPServer.Client.Console.csproj -- `
  --server-path dotnet `
  --server-arg .\SharpMCPServer.Host\bin\Debug\net10.0\SharpMCPServer.Host.dll `
  --working-directory .\SharpMCPServer.Host\bin\Debug\net10.0 `
  --ssh-profile list

If prompt intelligence is configured, try prompt.intelligence.analyze or prompt.intelligence.optimize after that.

For SSH profile creation and maintenance, see docs/SSH_PROFILE_MANAGER.md. That is the repo-owned CLI surface for listing, creating, linking, and deleting SSH profiles.

Architecture Workflow

The boundary matters more than the amount of code.

There are two runtime lanes in this repo:

  • the MCP host lane, which real MCP clients talk to
  • the standalone AgentRouter bridge lane, which Python uses directly

SharpMCPServer.ChatLauncher is a wrapper around the console client. It does not replace the host.

MCP host lane

%%{init: {'theme':'dark','flowchart': {'curve': 'basis'}, 'themeVariables': {'background': '#0b0f14', 'primaryColor': '#111827', 'primaryBorderColor': '#94a3b8', 'primaryTextColor': '#f8fafc', 'secondaryColor': '#111827', 'tertiaryColor': '#111827', 'lineColor': '#cbd5e1', 'fontFamily': 'ui-sans-serif, system-ui, sans-serif'}}}%%
flowchart TB
    classDef client fill:#0f172a,stroke:#818cf8,color:#f8fafc,stroke-width:1.5px;
    classDef edge fill:#0b1f2a,stroke:#22d3ee,color:#f8fafc,stroke-width:1.5px;
    classDef core fill:#111827,stroke:#94a3b8,color:#f8fafc,stroke-width:1.5px;
    classDef tool fill:#052e16,stroke:#4ade80,color:#dcfce7,stroke-width:1.5px;
    classDef policy fill:#1f2937,stroke:#fb923c,color:#f8fafc,stroke-width:1.5px;
    classDef external fill:#1e1b4b,stroke:#c084fc,color:#f5f3ff,stroke-width:1.5px;

    subgraph Clients["Client entry points"]
        direction LR
        Console([SharpMCPServer.Client.Console]):::client
        Chat([SharpMCPServer.ChatLauncher]):::client
        Real([Claude Code / VS Code / Cursor]):::client
    end

    subgraph Host["MCP host"]
        direction TB
        Edge([stdio or loopback Streamable HTTP]):::edge
        Core([SharpMCPServer.Host<br/>Application + Infrastructure + session state]):::core
        Tools([Workspace / Inference / SSH / AgentRouter tools]):::tool
    end

    subgraph Governance["Policy and approvals"]
        direction TB
        Sentinel([SentinelMCP]):::policy
        Approval([approval tokens and audit]):::policy
    end

    subgraph Capabilities["Host-owned capabilities"]
        direction LR
        Workspace([Workspace sandboxes]):::external
        Inference([Local and remote inference providers]):::external
        Ssh([SSH execution]):::external
        Router([AgentRouter runtime]):::external
    end

    Console --> Edge
    Chat --> Console
    Real --> Edge
    Edge --> Core --> Tools
    Tools --> Workspace
    Tools --> Inference
    Tools --> Ssh
    Tools --> Router
    Tools -. approval-gated work .-> Sentinel
    Sentinel --> Approval
Loading

The host owns transport, session state, tool composition, and policy enforcement. It does not consume the Python bridge lane.

Standalone AgentRouter bridge

%%{init: {'theme':'dark','flowchart': {'curve': 'basis'}, 'themeVariables': {'background': '#0b0f14', 'primaryColor': '#111827', 'primaryBorderColor': '#94a3b8', 'primaryTextColor': '#f8fafc', 'secondaryColor': '#111827', 'tertiaryColor': '#111827', 'lineColor': '#cbd5e1', 'fontFamily': 'ui-sans-serif, system-ui, sans-serif'}}}%%
flowchart LR
    classDef client fill:#0f172a,stroke:#818cf8,color:#f8fafc,stroke-width:1.5px;
    classDef bridge fill:#1e1b4b,stroke:#c084fc,color:#f5f3ff,stroke-width:1.5px;
    classDef router fill:#052e16,stroke:#4ade80,color:#dcfce7,stroke-width:1.5px;

    Python([python/]):::client
    Native([SharpMCPServer.AgentRouter.PythonBridge.Native]):::bridge
    Router([AgentRouter runtime]):::router

    Python --> Native --> Router
Loading

This lane is separate from the MCP host. It is the Python-facing NativeAOT path for AgentRouter consumers.

Runtime and plugin rules

Plugins may shape behavior.

Plugins may not self-authorize behavior.

All runtime and plugin execution still flows through SentinelMCP and the platform tool gateway.

Real client setup

If you want to hook up Claude Code, VS Code / GitHub Copilot, or Cursor, start with samples/mcp-clients/README.md.

The compatibility checklist lives in docs/REAL_MCP_CLIENT_COMPATIBILITY.md, and first-run staging notes live in docs/REAL_CLIENT_STAGING.md.

Configuration

The main host knobs live in SharpMCPServer.Host/appsettings.json:

  • McpTransport:Http for loopback HTTP, replay, and authorization.
  • McpWorkspace for workspace roots, sandbox paths, and byte limits.
  • McpInference for provider routing and prompt intelligence.
  • McpTools:Ssh for SSH policy and allow/deny rules.
  • SentinelMCP:ApprovalJwt for approval token settings.
  • Dashboard for the loopback operator dashboard endpoint and refresh cadence.

If provider setup is the part you want to get right first, read docs/INFERENCE_PROVIDERS.md before you start tweaking random JSON.

If you are only using the Python bridge, see python/README.md and docs/INSTALL.md.

Build and test

This is the part where the repo stops being charming and starts being honest. If the build or tests disagree with the prose, trust the command output and fix the thing that is actually broken.

dotnet restore .\SharpMCPServer.slnx
dotnet build .\SharpMCPServer.slnx -c Debug
dotnet test .\SharpMCPServer.slnx -c Debug

For the normal end-to-end verification lane, use pwsh .\scripts\verify-mcp-phase1.ps1.

Read next

Releases

No releases published

Packages

 
 
 

Contributors