BrandGhost
Connect an Existing C# MCP Server to Claude Code
All articles

Connect an Existing C# MCP Server to Claude Code

Connect an existing C# MCP server to Claude Code using stdio or HTTP, then understand configuration scope, tool discovery, authorization, and failure evidence.

Connecting a C# MCP server to Claude Code is a client-integration task. The server already exists. Your job is to identify its transport, configure the correct process or endpoint, and establish that the intended tools are available under the right authority.

That boundary matters. Writing a new MCP server, hosting it in ASP.NET Core, and building a C# MCP client are separate tasks. This article focuses on using Claude Code as the client for an existing server without assuming that a saved configuration proves a working connection.

Information checked October 9, 2026 against the current Claude Code MCP reference. Configuration, status reporting, and authentication behavior can change. The sanitized commands and JSON below were not exercised, and no server was launched for this article.

Identify the server you already have

Begin with the server's own documented entry point. Is it a local executable communicating over standard input and output? Is it a remote HTTP endpoint? Does it require authentication? Which tools does it expose, and what effects can those tools have?

Do not infer the transport from the implementation language. A C# server can be packaged as a local process or hosted behind an HTTP endpoint. Claude Code needs the connection shape, not a promise that “it uses .NET.”

Also distinguish the executable from the project. A .csproj is not a server process. A framework-dependent assembly normally has a host invocation, while a self-contained executable has its own launch contract. Use the server's verified distribution instructions rather than inventing a command from a filename.

The existing C# MCP Inspector guide is useful when the server's basic protocol behavior has not yet been established. Client configuration should not become the place where server startup and protocol implementation are debugged simultaneously.

A good starting record includes the server build or package version, transport, executable or URL, required environment variables by name, and one low-risk tool suitable for a smoke check. Keep actual credentials out of that record.

Choose stdio or HTTP from the server's contract

The current Claude reference describes local stdio servers as processes launched by the client. Remote HTTP servers are configured with a URL and transport. SSE is documented as deprecated in favor of HTTP where available.

Stdio is useful when the tool needs local files or a local process boundary. It also means the server runs with the environment and authority supplied to that process. Locality does not make a tool read-only or harmless.

HTTP is useful when an existing hosted service owns the capability and its authorization boundary. It introduces network, authentication, routing, and server-availability considerations. It does not mean Claude Code hosts the server or implements its API.

There are tradeoffs. A local process can be easier to package for a single developer but harder to reproduce across machines if its runtime and paths differ. A remote endpoint can centralize deployment but needs a reviewed authentication and tenancy model.

Choose the transport the server actually supports. Do not add an HTTP URL to a stdio entry and expect the client to repair the mismatch. The reference explicitly says an entry with a URL but no type is read as stdio and rejected.

Register a local C# server with explicit arguments

Assume an existing framework-dependent server assembly is already available at a sanitized path and its documentation specifies dotnet as the launch host. The following command illustrates the current stdio registration syntax:

claude mcp add --transport stdio --scope local shipping-readonly -- dotnet 'C:\tools\ShippingMcp\ShippingMcp.dll'

The command is unexercised. It writes client configuration when run; it does not build the assembly or establish that the tool contracts are read-only. The server name is a label, not authorization.

The -- separator is important. The official reference says it separates Claude's options from the executable and arguments forwarded to the server. Everything after it belongs to the server launch command.

Prefer the already distributed server artifact for this integration example. Using a project-build command as startup would mix connection setup with restore and compilation, add startup work, and execute project-defined build logic. That may be appropriate for a development workflow, but it is a different assumption that should be explicit.

Check whether the client process can resolve the required host executable. A host available in one terminal or IDE is not proof that another process environment sees the same path. Also inspect file access, architecture, runtime requirements, and the server's documented configuration.

Do not put a database password into the registration command for convenience. Command history, process arguments, and saved configuration can expose values. Use the server's approved credential-delivery mechanism and least-privilege identity.

Understand configuration scope before sharing it

Claude Code documents local, project, and user scope for configured MCP servers. Local scope is specific to the current project for the current user. Project scope uses .mcp.json for shared repository configuration. User scope makes the server available across the user's projects.

For initial integration, local scope limits accidental distribution of machine-specific paths. For a team workflow, project scope can make the server declaration reviewable, but it requires a portable launch contract and deliberate approval.

Here is an illustrative project-scoped configuration for the same existing Windows artifact:

{
  "mcpServers": {
    "shipping-readonly": {
      "type": "stdio",
      "command": "dotnet",
      "args": [
        "C:\\tools\\ShippingMcp\\ShippingMcp.dll"
      ]
    }
  }
}

This example shows the documented wrapper and command/argument shape. The absolute path is intentionally sanitized and machine-specific. Do not commit it as a team standard unless every intended environment has that documented artifact location.

A portable team configuration needs an agreed artifact layout or a reviewed environment-variable strategy from the current reference. That should be solved through distribution, not by hoping that each user adjusts an undocumented path.

Review existing configuration before adding another entry with the same name. A server might already be supplied by user settings, project settings, or a plugin. Understanding the source avoids accidentally connecting to a different capability than the task expects.

Connect an existing HTTP endpoint without rebuilding it

For a server already hosted over HTTP, register the exact documented MCP endpoint:

claude mcp add --transport http --scope local shipping-api 'https://mcp.example.com/mcp'

The reserved example domain is a placeholder for a server you already own or are authorized to use; it is not a working service. The example demonstrates syntax and has not been run.

An application homepage or health endpoint is not automatically an MCP endpoint. Confirm the server's route and transport contract. The existing ASP.NET Core MCP hosting guide covers server-hosting concerns that this client article does not implement.

If the remote server uses OAuth, the current Claude reference describes authentication through /mcp. If it uses another authentication mechanism, follow the server's approved process and the current client documentation. Do not assume every endpoint supports the same flow.

TLS, issuer validation, token audience, and tool authorization remain server and infrastructure responsibilities as applicable. Securing remote MCP servers in C# explains those concerns at the server boundary.

Client registration grants a route to a capability. It does not prove that the authenticated identity is appropriate for every operation the server advertises.

Separate registration, connection, and discovery

The MCP reference says an Added ... message means configuration was written. It does not mean the server connected successfully. That distinction is the first thing to check when setup appears complete but no tools are available.

Use the documented management commands to inspect the configuration and connection status:

claude mcp list
claude mcp get shipping-readonly

Both commands are unexercised here. In an interactive session, /mcp provides the server panel. The current reference describes statuses such as connected, needs authentication, failed to connect, and pending approval.

A project-scoped server may remain pending until the user reviews it interactively. That is not a transport failure. Likewise, a server can connect but advertise no tools, or a tool can be present but fail when called.

Discovery is another boundary. The client obtains the server's capabilities and tool definitions. A tool name appearing in the interface is evidence of discovery, not proof of successful tool execution or correct application behavior.

The documentation also describes caching and background connection behavior, which can vary by version and rollout. Do not claim a connection occurred merely because a cached tool list is visible. Inspect the current status and the result of an authorized low-risk call.

Verify one low-risk tool through the complete path

Choose a tool whose effect is narrow and understood, such as retrieving a public schema summary or a synthetic development record. Identify its required arguments and expected result shape from the server's actual contract.

Then separate the observations. Did the client discover the tool? Did it invoke the intended server? Did authentication succeed? Did the server return protocol content? Did that content represent the expected application result?

An MCP-level success can still contain an application-level error. Conversely, a connection failure says nothing about the correctness of the server's domain logic. Keep the report aligned with the boundary actually observed.

For C# developers who need to understand that boundary in their own applications, building an MCP client in C# covers connection, discovery, invocation, and result handling. Claude Code plays the client role in this article; there is no need to implement another C# client merely to configure it.

Do not use a production write as the first smoke check. Even a tool designed for idempotent updates can affect shared state. Start with a reviewed read operation under an identity that cannot perform unwanted writes.

Treat server content as data, not instructions

The official Claude MCP reference warns that servers fetching external content can expose the session to prompt injection. A returned document or tool description can contain text that attempts to redirect the agent's task.

The right response is not to avoid all useful data. It is to maintain a boundary between retrieved content and authority. An issue body can describe a request, but it should not silently grant permission to publish, reveal secrets, or change unrelated infrastructure.

Tool exposure also deserves review. A server connected for code lookup may advertise administrative operations alongside read operations. Do not automatically allow every tool because the connection itself is trusted.

Server-side authorization is the stronger boundary for shared systems. A narrowly privileged identity protects resources even when client-side reasoning is imperfect. Client permissions can further limit tool use, but they should not be the sole protection for a production service.

An existing MCP integration guide for another client can help explain similar trust concerns. Its configuration filename and CLI flags belong to that client, not Claude Code.

Troubleshoot the earliest failing boundary

If a stdio server fails to connect, inspect executable resolution and arguments first. Does the assembly exist? Can the required runtime host start it? Does it exit immediately because configuration is missing? Does it write unrelated text to the protocol output stream?

For HTTP, inspect the exact endpoint, network reachability, authentication state, and returned error. A 404 at the homepage is not evidence that an MCP route is invalid, while a 401 generally requires authentication investigation rather than changing transport at random.

If the server connects but tools are absent, inspect advertised capabilities and tool discovery. If tools are discovered but calls fail, inspect arguments, server authorization, and application results. Changing every configuration layer at once makes these cases harder to distinguish.

Retain redacted evidence: the configured server name, transport, client version, server version, status, and failure category. Do not paste authorization headers, expanded secret-bearing URLs, or environment dumps into a public report.

The current reference describes automatic reconnect behavior for remote servers and says stdio servers are not automatically reconnected. That distinction can explain why a local process needs explicit attention after exiting. Check the current documentation rather than assuming identical recovery across transports.

Consider unattended execution separately

An interactive trust flow is not the same as headless startup. The current headless documentation says ordinary -p runs load project MCP configuration without the interactive per-server approval prompt.

Review the repository and server configuration before using it in automation. A cloned configuration can launch a local process, and that process may inherit authority from the runner. Treat it as executable configuration, not merely a list of data sources.

Bare mode skips automatic MCP discovery and permits explicit command-line configuration through the documented options. That favors deliberate startup inputs but requires the caller to supply needed context and authentication. Neither launch mode makes an external tool intrinsically safe.

For unattended runs, keep the result report narrow. Configuration loaded, server connected, tool discovered, and tool call succeeded are distinct observations. State which ones occurred and which were not verified.

Frequently asked questions

Does a C# MCP server require a special Claude Code adapter?

Not solely because it is written in C#. Claude Code connects through the server's supported MCP transport. The integration needs the documented executable and arguments or HTTP endpoint, plus the appropriate authentication and configuration.

What does the double dash in a stdio command do?

The official reference says -- separates Claude's configuration options from the server launch command and arguments. This prevents server flags from being parsed as Claude options. Keep the executable and its arguments after that separator.

Does Added mean the server is connected?

No. It means the configuration was written. Inspect claude mcp list, claude mcp get, or /mcp for status, then distinguish connection from discovery and a successful authorized tool call.

Should server configuration be local or project-scoped?

Local scope is useful for initial user-specific integration. Project scope makes a shared declaration reviewable through .mcp.json, but requires portable paths, reviewed authority, and appropriate approval. Neither scope is a place to publish secrets.

Can a connected read-only server still present risk?

Yes. The name does not enforce read-only behavior, and retrieved content may contain prompt-injection attempts. Review actual tool effects and use server-side least privilege. Client trust should not substitute for resource authorization.

Why does a server work interactively but not in automation?

The environment, authentication, configuration sources, and launch mode may differ. Bare mode omits automatic discovery; ordinary headless runs have different trust-dialog behavior. Compare the exact startup and failure boundary instead of assuming a protocol defect.

A connection is a chain of evidence

Connecting an existing C# MCP server to Claude Code means translating a known server contract into a reviewed client configuration. The useful result is not just a saved JSON entry. It is an understood sequence from registration to connection, discovery, and an authorized tool result.

Keeping those boundaries separate makes troubleshooting clearer and prevents tool availability from being mistaken for permission to act on every resource the server can reach.

Get the Dev Leader Newsletter

C#, .NET, and software engineering content every Saturday.

Subscribe to the newsletter
An error has occurred. This application may no longer respond until reloaded. Reload