MCP Experiments

An experimental dotnet MCP server that returns the current time, based on Laurent Kempé's tutorial.

MCP Experiments

These MCP experiments are based on Laurent Kempé's tutorial.

There is a dotnet MCP server over stdio that provides a function to return the current time.

There is a dotnet MCP client that makes it available to a local LLM which invokes it.

It uses the official mcp-csharp-sdk.

Develop

Build all MCP projects:

dotnet build

Start the MCP server over SSE and streamable HTTP:

dotnet run --project MyMCPServer.Sse --launch-profile https

Claude Desktop

To add it to Claude Desktop, change the claude_desktop_config.json like this:

{
    "mcpServers": {
        "getTime": {
            "command": "D:\\McpExperiments\\MyMCPServer.Stdio\\bin\\Debug\\net9.0\\MyMCPServer.Stdio.exe"
        },
        "getCli": {
            "command": "D:\\McpExperiments\\MyMCPServer.Stdio.Cli\\bin\\Debug\\net9.0\\MyMCPServer.Stdio.Cli.exe",
            "args": [ 
                "mcp"
            ]
        },
        "getVibe": {
            "command": "D:\\McpExperiments\\MyMCPServer.Sse\\claude_desktop.cmd"
        }
    }
}

Claude Desktop supports remote MCP servers as "Connectors" (Building Remote MCP Servers), but adding custom ones only on Pro/Max or Enterprise/Team plans (Getting Started with Custom Connectors Using Remote MCP).

We can use mcp-remote for that. By default is uses Dynamic Client Registration and stores its client credentials in ~\.mcp-auth.

Authorization

Web-based MCP servers using SSE or streamable HTTP should require authorization.

Microsoft plans to implement all specified authentication protocols described in the MCP spec, but there is no roadmap yet.

In this repository I am experimenting with differnt kinds of authentication and authorization for MCP servers. To test it, we can use the mcp inspector and the browser developer tools.

npx @modelcontextprotocol/inspector

MCP server as Identity Provider

According to the first specification the MCP server should also be an OAuth authorization server. To experiment with that, I built a light-weight OAuth server base on https://youtu.be/EBVKlm0wyTE.

MCP server as Resource Provider

According to the current specification the MCP server should provide Protected Resource Metadata to point to an OAuth server's Authorization Service Metadata. That AS should implement Dynamic Client Registration.

We use Duende Identity Server to build a centralized Authorization Server. Unfortunately Duende does not yet support MCP in combination with @modelcontextprotocol/inspector. So I had to apply a few adjustments to my experimental instance of Duende.

  • provide the OIDC discovery document also at .well-known/oauth-authorization-server
  • the discovery document needs to also include the registration_endpoint endpoint for DCR
  • MCP inspector does not register clients with any scopes, so we add all scopes to the newly registered clients
  • MCP inspector does not follow redirects of DCR endpoint, so we cannot use frontchannel authorization
  • MCP inspector does not provide scopes during the /authorize request (just the resource indicator), so we inject all scopes of the resource to bypass Duende's missing scope validation

As next steps I need to look into MCP inspector to better understand if it could

  • pass scopes during DCR and /authorize
  • follow redirects and deal with DCR requiring authorization

Resources

Related Servers