CLI Coming Soon
    Back to catalog

    Build an MCP server in .NET 11 and connect it to Claude

    Published · Last updated

    Abstract cover: a terminal window joined by a line to a stack of three server units, one marked orange

    Short answer

    The .NET 11 SDK (11.0.100, released November 10, 2026) ships an MCP server template. Run dotnet new mcpserver -o MyMcpServer, build it, then add it to Claude Code with claude mcp add --transport stdio <name> -- dotnet run --project <path>.

    We ran every step below on a fresh Ubuntu 24.04 Boat machine on 2026-11-11, then deleted the machine. Each output block is pasted as the terminal printed it. Facts come from Microsoft's .NET blog, Microsoft Learn, NuGet and Anthropic's docs, quoted and linked where they appear.

    What .NET 11 is and how long it is supported

    Microsoft announced .NET 11 on November 10, 2026 (.NET blog). The post says: ".NET 11 is a Standard Term Support (STS) release with two years of support under the .NET support policy." It adds that STS and LTS releases "have the same quality and servicing policies; the difference is the length of support."

    The .NET support policy lists .NET 11 with an original release date of November 10, 2026, release type STS, support phase Active, and end of support on November 14, 2028. .NET 10, the LTS release, has the same end of support date. The policy also says "The maintenance support period is the final 6 months of support for any release (STS or LTS)." The same blog post notes that ".NET 8 and .NET 9 reach end of support on November 10, 2026."

    On MCP, the post says: "The .NET 11 SDK includes an MCP server template. MCP gives AI applications a common way to discover and call tools and services. The template uses the official MCP C# SDK and includes a working sample tool, so you can start exposing your own functionality without first installing a separate template package". Its command is dotnet new mcpserver -o MyMcpServer, which is what we ran.

    Versions we used

    Versions used in this run, with publish dates
    PieceExact versionPublished
    .NET SDK (with runtime 11.0.0)11.0.1002026-11-10 (releases.json)
    mcpserver template inside the SDKMicrosoft.McpServer.ProjectTemplates.11.0 11.0.02026-11-10 (NuGet)
    mcpserver template from NuGet (optional)Microsoft.McpServer.ProjectTemplates 1.2.12026-05-08 (NuGet)
    MCP C# SDK the template referencesModelContextProtocol 2.1.02026-08-05 (NuGet)
    Claude Code2.1.316 (npm, @anthropic-ai/claude-code)2026-10-31 (npm)
    Publish dates from the NuGet and npm registries and Microsoft's 11.0 releases.json, checked 2026-11-11. The newest ModelContextProtocol on NuGet that day was 2.4.0; the template still references 2.1.0.

    Step 1: install the .NET 11 SDK at an exact version

    Microsoft's manual install steps for Linux download a binary release, extract it into DOTNET_ROOT and put it on PATH. We pinned SDK 11.0.100, the build listed in Microsoft's 11.0 releases.json with release date 2026-11-10, and checked the tarball against the SHA-512 in that file.

    One change from Microsoft's example: it appends the SDK to the end of PATH. Our machine image already had a .NET 8 SDK at /usr/bin/dotnet, so on the first try dotnet --version printed 8.0.129 and dotnet new mcpserver failed with "No templates found matching: 'mcpserver'." Putting $DOTNET_ROOT first fixed it. Telemetry is off with DOTNET_CLI_TELEMETRY_OPTOUT=1.

    Commands we ran
    DOTNET_FILE=dotnet-sdk-11.0.100-linux-x64.tar.gz
    curl -fsSLO https://builds.dotnet.microsoft.com/dotnet/Sdk/11.0.100/$DOTNET_FILE
    # SHA-512 copied from the 11.0.100 entry in releases.json
    echo "1bec9cca2ec689b1e80245b84f2b53c9441d1aa6daccf2ceb27490768bffa95954fa585bd275def31069d874d543d9ba9e6591fe9ade2dbd9f34ec5c0fd0050c  $DOTNET_FILE" | sha512sum -c
    export DOTNET_ROOT=$HOME/.dotnet
    mkdir -p "$DOTNET_ROOT" && tar zxf "$DOTNET_FILE" --no-same-owner -C "$DOTNET_ROOT"
    export PATH=$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH
    export DOTNET_CLI_TELEMETRY_OPTOUT=1
    dotnet --version
    dotnet --list-sdks
    dotnet --list-runtimes
    Output, as captured
    dotnet-sdk-11.0.100-linux-x64.tar.gz: OK
    11.0.100
    11.0.100 [/home/user/.dotnet/sdk]
    Microsoft.AspNetCore.App 11.0.0 [/home/user/.dotnet/shared/Microsoft.AspNetCore.App]
    Microsoft.NETCore.App 11.0.0 [/home/user/.dotnet/shared/Microsoft.NETCore.App]

    Step 2: generate the project

    The template is already in the SDK. Its templates folder holds this package, which is Microsoft.McpServer.ProjectTemplates.11.0 11.0.0 on NuGet (published 2026-11-10, owners Microsoft and dotnetframework):

    Commands we ran
    ls $DOTNET_ROOT/templates/*/ | grep -i mcp
    Output, as captured
    microsoft.mcpserver.projecttemplates.11.0.11.0.0.nupkg

    The first dotnet command also printed the SDK's first-run message.

    Commands we ran
    dotnet new list mcpserver
    Output, as captured
    Welcome to .NET 11.0!
    ---------------------
    SDK Version: 11.0.100
    
    ----------------
    Installed an ASP.NET Core HTTPS development certificate.
    To trust the certificate, run 'dotnet dev-certs https --trust'
    Learn about HTTPS: https://aka.ms/dotnet-https
    
    ----------------
    Write your first app: https://aka.ms/dotnet-hello-world
    Find out what's new: https://aka.ms/dotnet-whats-new
    Explore documentation: https://aka.ms/dotnet-docs
    Report issues and find source on GitHub: https://github.com/dotnet/core
    Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
    --------------------------------------------------------------------------------------
    These templates matched your input: 'mcpserver'
    
    Template Name   Short Name  Language  Tags         
    --------------  ----------  --------  -------------
    MCP Server App  mcpserver   [C#]      Common/AI/MCP

    The template options, as the SDK prints them:

    Commands we ran
    dotnet new mcpserver --help
    Output, as captured
    MCP Server App (C#)
    Author: Microsoft
    Description: A project template for creating a Model Context Protocol (MCP) server using C# and the ModelContextProtocol package.
    
    Usage:
      dotnet new mcpserver [options] [template options]
    
    Options:
      -n, --name <name>       The name for the output being created. If no name is specified, the name of the output directory is used.
      -o, --output <output>   Location to place the generated output.
      --dry-run               Displays a summary of what would happen if the given command line were run if it would result in a template creation. [default: False]
      --force                 Forces content to be generated even if it would change existing files. [default: False]
      --no-update-check       Disables checking for the template package updates when instantiating a template. [default: False]
      --project <project>     The project that should be used for context evaluation.
      -lang, --language <C#>  Specifies the template language to instantiate.
      --type <project>        Specifies the template type to instantiate.
    
    Template options:
      -t, --transport <local|remote>  Whether to create a 'local' (stdio transport) or 'remote' (http transport) MCP server
                                      Type: choice
                                        local   A console application will be created to use the stdio transport as a local MCP server
                                        remote  An ASP.NET Core web application will be created to use the http transport as a remote MCP server
                                      Default: local
      --aot                           Whether to enable the MCP server for publishing as a native AOT application.
                                      Type: bool
                                      Default: false
      --self-contained                Whether to enable the MCP server for publishing as a self-contained application.
                                      Type: bool
                                      Default: true
      -f, --framework <net11.0>       The target framework for the project.
                                      Type: choice
                                        net11.0  
                                      Default: net11.0
      --no-restore                    If specified, skips the automatic restore of the project on create.
                                      Type: bool
                                      Default: false

    We kept the defaults: local transport (stdio), self-contained on, AOT off, framework net11.0.

    Commands we ran
    dotnet new mcpserver -o MyMcpServer
    Output, as captured
    The template "MCP Server App" was created successfully.
    
    Processing post-creation actions...
    Restoring /home/user/work/MyMcpServer/MyMcpServer.csproj:
      Determining projects to restore...
      Restored /home/user/work/MyMcpServer/MyMcpServer.csproj (in 22.53 sec).
    Restore succeeded.

    The generated file tree

    Listed right after creation, before the build. The obj/ files come from the restore the template runs.

    Commands we ran
    find MyMcpServer -type f | sort
    Output, as captured
    MyMcpServer/.mcp/server.json
    MyMcpServer/MyMcpServer.csproj
    MyMcpServer/obj/MyMcpServer.csproj.nuget.dgspec.json
    MyMcpServer/obj/MyMcpServer.csproj.nuget.g.props
    MyMcpServer/obj/MyMcpServer.csproj.nuget.g.targets
    MyMcpServer/obj/project.assets.json
    MyMcpServer/obj/project.nuget.cache
    MyMcpServer/Program.cs
    MyMcpServer/README.md
    MyMcpServer/Tools/RandomNumberTools.cs

    Microsoft's MCP server quickstart describes the main files. Program.cs is "A file defining the application as an MCP server and registering MCP services such as transport type and MCP tools." RandomNumberTools.cs is "A class defining an example MCP server tool that returns a random number between user-specified min/max values." server.json is "A file defining how and where your MCP server is published."

    Program.cs

    Output, as captured
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    
    var builder = Host.CreateApplicationBuilder(args);
    
    // Configure all logs to go to stderr (stdout is used for the MCP protocol messages).
    builder.Logging.AddConsole(o => o.LogToStandardErrorThreshold = LogLevel.Trace);
    
    // Add the MCP services: the transport to use (stdio) and the tools to register.
    builder.Services
        .AddMcpServer()
        .WithStdioServerTransport()
        .WithTools<RandomNumberTools>();
    
    await builder.Build().RunAsync();

    Tools/RandomNumberTools.cs

    Output, as captured
    using System.ComponentModel;
    using ModelContextProtocol.Server;
    
    /// <summary>
    /// Sample MCP tools for demonstration purposes.
    /// These tools can be invoked by MCP clients to perform various operations.
    /// </summary>
    internal class RandomNumberTools
    {
        [McpServerTool]
        [Description("Generates a random number between the specified minimum and maximum values.")]
        public int GetRandomNumber(
            [Description("Minimum value (inclusive)")] int min = 0,
            [Description("Maximum value (exclusive)")] int max = 100)
        {
            return Random.Shared.Next(min, max);
        }
    }

    MyMcpServer.csproj

    Output, as captured
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFramework>net11.0</TargetFramework>
        <RuntimeIdentifiers>win-x64;win-arm64;osx-arm64;linux-x64;linux-arm64;linux-musl-x64</RuntimeIdentifiers>
        <OutputType>Exe</OutputType>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
    
        <!-- Set up the NuGet package to be an MCP server -->
        <PackAsTool>true</PackAsTool>
        <PackageType>McpServer</PackageType>
    
        <!-- Set up the MCP server to be a self-contained application that does not rely on a shared framework -->
        <SelfContained>true</SelfContained>
        <PublishSelfContained>true</PublishSelfContained>
    
        <!-- Set up the MCP server to be a single file executable -->
        <PublishSingleFile>true</PublishSingleFile>
    
        <!-- Set recommended package metadata -->
        <PackageReadmeFile>README.md</PackageReadmeFile>
        <PackageId>SampleMcpServer</PackageId>
        <PackageVersion>0.1.0-beta</PackageVersion>
        <PackageTags>AI; MCP; server; stdio</PackageTags>
        <Description>An MCP server using the MCP C# SDK.</Description>
      </PropertyGroup>
    
      <!-- Include additional files for browsing the MCP server. -->
      <ItemGroup>
        <None Include=".mcp\server.json" Pack="true" PackagePath="/.mcp/" />
        <None Include="README.md" Pack="true" PackagePath="/" />
      </ItemGroup>
    
      <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Hosting" Version="11.0.0" />
        <PackageReference Include="ModelContextProtocol" Version="2.1.0" />
      </ItemGroup>
    
    </Project>

    The project targets six runtime identifiers and sets SelfContained and PublishSingleFile. The quickstart says that by default the command "creates a self-contained tool package targeting all of the most common platforms that .NET is supported on." The .mcp/server.json file holds placeholders such as <your package ID here> until you publish to NuGet.

    Step 3: build it

    Commands we ran
    dotnet build MyMcpServer
    Output, as captured
      Determining projects to restore...
      All projects are up-to-date for restore.
      MyMcpServer -> /home/user/work/MyMcpServer/bin/Debug/net11.0/linux-x64/MyMcpServer.dll
    
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:02.51
    build exit: 0

    Step 4: run it and call the tool

    A stdio MCP server reads JSON-RPC messages on stdin and writes replies on stdout. It prints nothing until a client talks to it. To run it and see a real tool call, we used a 28-line Python client that starts dotnet run --project MyMcpServer, sends initialize, lists the tools and calls the first one with min 1 and max 100.

    client.py, the test client we ran
    # Minimal MCP stdio client: initialize, tools/list, tools/call. Prints every line sent and received.
    import json, subprocess, sys, signal
    signal.alarm(180)
    cmd = sys.argv[1:]
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                         stderr=open("server-stderr.log", "w"), text=True)
    def send(m):
        s = json.dumps(m)
        print(">>> " + s, flush=True)
        p.stdin.write(s + "\n"); p.stdin.flush()
    def recv():
        line = p.stdout.readline()
        print("<<< " + line.rstrip(), flush=True)
        return json.loads(line)
    send({"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {
        "protocolVersion": "2025-06-18", "capabilities": {},
        "clientInfo": {"name": "ayclaude-test-client", "version": "1.0.0"}}})
    recv()
    send({"jsonrpc": "2.0", "method": "notifications/initialized"})
    send({"jsonrpc": "2.0", "id": 2, "method": "tools/list"})
    tools = recv()["result"]["tools"]
    name = tools[0]["name"]
    send({"jsonrpc": "2.0", "id": 3, "method": "tools/call",
          "params": {"name": name, "arguments": {"min": 1, "max": 100}}})
    recv()
    p.stdin.close()
    p.wait(timeout=30)
    print("server exit code:", p.returncode, flush=True)
    Commands we ran
    python3 client.py dotnet run --project MyMcpServer
    Output, as captured
    >>> {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": {"name": "ayclaude-test-client", "version": "1.0.0"}}}
    <<< {"result":{"protocolVersion":"2025-06-18","capabilities":{"logging":{},"tools":{"listChanged":true}},"serverInfo":{"name":"MyMcpServer","version":"1.0.0.0"}},"id":1,"jsonrpc":"2.0"}
    >>> {"jsonrpc": "2.0", "method": "notifications/initialized"}
    >>> {"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
    <<< {"result":{"tools":[{"name":"get_random_number","description":"Generates a random number between the specified minimum and maximum values.","inputSchema":{"type":"object","properties":{"min":{"description":"Minimum value (inclusive)","type":"integer","default":0},"max":{"description":"Maximum value (exclusive)","type":"integer","default":100}}}}]},"id":2,"jsonrpc":"2.0"}
    >>> {"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "get_random_number", "arguments": {"min": 1, "max": 100}}}
    <<< {"result":{"content":[{"type":"text","text":"64"}]},"id":3,"jsonrpc":"2.0"}
    server exit code: 0
    client exit: 0

    The tool is named get_random_number and returned 64. The template's Program.cs sends all logs to stderr, because stdout carries the protocol. Here is what the server wrote there during the same run:

    Output, as captured
    info: ModelContextProtocol.Server.StdioServerTransport[857250842]
          Server (stream) (MyMcpServer) transport reading messages.
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Production
    info: Microsoft.Hosting.Lifetime[0]
          Content root path: /home/user/work
    info: ModelContextProtocol.Server.McpServer[570385771]
          Server (MyMcpServer 1.0.0.0) method 'initialize' request handler called.
    info: ModelContextProtocol.Server.McpServer[570385771]
          Server (MyMcpServer 1.0.0.0), Client (ayclaude-test-client 1.0.0) method 'tools/list' request handler called.
    info: ModelContextProtocol.Server.McpServer[1867955179]
          Server (MyMcpServer 1.0.0.0), Client (ayclaude-test-client 1.0.0) method 'initialize' request handler completed in 16.4853ms.
    info: ModelContextProtocol.Server.McpServer[1867955179]
          Server (MyMcpServer 1.0.0.0), Client (ayclaude-test-client 1.0.0) method 'tools/list' request handler completed in 10.4492ms.
    info: ModelContextProtocol.Server.McpServer[570385771]
          Server (MyMcpServer 1.0.0.0), Client (ayclaude-test-client 1.0.0) method 'tools/call' request handler called.
    info: ModelContextProtocol.Server.McpServer[2065726448]
          "get_random_number" completed. IsError = False.
    info: ModelContextProtocol.Server.McpServer[1867955179]
          Server (MyMcpServer 1.0.0.0), Client (ayclaude-test-client 1.0.0) method 'tools/call' request handler completed in 38.7849ms.
    info: ModelContextProtocol.Server.StdioServerTransport[1221292038]
          Server (stream) (MyMcpServer) transport completed reading messages.
    info: Microsoft.Hosting.Lifetime[0]
          Application is shutting down...
    info: ModelContextProtocol.Server.StdioServerTransport[1375634372]
          Server (stream) (MyMcpServer) shutting down.
    info: ModelContextProtocol.Server.StdioServerTransport[1256455528]
          Server (stream) (MyMcpServer) shut down.

    Optional: pin the template package from NuGet

    Microsoft's quickstart lists the .NET 10.0 SDK as a prerequisite and installs the template with dotnet new install Microsoft.McpServer.ProjectTemplates. It notes: "The Microsoft.McpServer.ProjectTemplates template package is currently in preview." On .NET 11 you can skip this step. If you want the NuGet package anyway, pin the version. We installed 1.2.1 (published 2026-05-08, owners Microsoft and dotnetframework on NuGet) on a second clean machine and compared its output with the SDK's template.

    Commands we ran
    dotnet new mcpserver -o A --no-restore      # SDK template
    dotnet new install Microsoft.McpServer.ProjectTemplates@1.2.1
    dotnet new mcpserver -o B --no-restore      # after installing 1.2.1
    diff A/A.csproj B/B.csproj; echo "diff exit: $?"
    diff -r A B -x '*.csproj' -x README.md; echo "diff exit: $?"
    Output, as captured
    The following template packages will be installed:
       Microsoft.McpServer.ProjectTemplates@1.2.1
    
    Success: Microsoft.McpServer.ProjectTemplates@1.2.1 installed the following templates:
    Template Name   Short Name  Language  Tags         
    --------------  ----------  --------  -------------
    MCP Server App  mcpserver   [C#]      Common/AI/MCP
    
    diff exit: 0
    diff exit: 0

    Both runs produced the same files. The only change we saw: after installing 1.2.1, the --framework option also offers older targets.

    Output, as captured
      -f, --framework <net10.0|net11.0|net8.0|net9.0>  The target framework for the project.
                                                         net11.0  
                                                         net10.0  .NET 10
                                                         net9.0   .NET 9
                                                         net8.0   .NET 8
                                                       Default: net11.0

    Step 5: connect it to Claude Code

    Anthropic's Claude Code MCP docs give the syntax for a local stdio server: claude mcp add [options] <name> -- <command> [args...]. They explain: "For stdio servers, the -- (double dash) separates Claude's own options, such as --transport, --env, and --scope, from the command and arguments that run the server." Without a scope flag, "Each command writes to local scope unless you add --scope project or --scope user."

    The command after -- is the one Microsoft's quickstart puts in its mcp.json examples: dotnet run --project <path>. We installed Claude Code 2.1.316 from npm at that exact version and pointed CLAUDE_CONFIG_DIR at an empty folder, so the box's own settings would not show up in the list.

    Commands we ran
    npm install --prefix ~/cc @anthropic-ai/claude-code@2.1.316
    export PATH=$HOME/cc/node_modules/.bin:$PATH
    export CLAUDE_CONFIG_DIR=$HOME/claude-clean
    claude --version
    cd ~/work
    claude mcp add --transport stdio dotnet-mcp -- dotnet run --project $HOME/work/MyMcpServer
    claude mcp list
    claude mcp get dotnet-mcp
    Output, as captured
    2.1.316 (Claude Code)
    
    Added stdio MCP server dotnet-mcp with command: dotnet run --project /home/user/work/MyMcpServer to local config
    File modified: /home/user/claude-clean/.claude.json [project: /home/user/work]
    exit: 0
    
    Checking MCP server health…
    
    dotnet-mcp: dotnet run --project /home/user/work/MyMcpServer - ✔ Connected
    exit: 0
    
    dotnet-mcp:
      Scope: Local config (private to you in this project)
      Status: ✔ Connected
      Type: stdio
      Command: dotnet
      Args: run --project /home/user/work/MyMcpServer
      Environment:
    
    To remove this server, run: claude mcp remove dotnet-mcp -s local
    exit: 0

    The docs say claude mcp list "shows a health status next to each server it lists, such as ✔ Connected, ! Needs authentication, or ✘ Failed to connect." Our server shows ✔ Connected, which means Claude Code started it and connected. For a running session, the docs list /mcp to check server status.

    What we could not test

    • A tool call made by Claude. That needs a logged-in Claude Code. We kept the throwaway machine free of any credentials, so the prompt stopped at login:
    Commands we ran
    claude -p "Use the dotnet-mcp tool to get a random number between 1 and 100" --allowedTools mcp__dotnet-mcp
    Output, as captured
    Not logged in · Please run /login
    exit: 1
    • The tool call in Step 4 went straight to the server over MCP, without Claude. On your own logged-in machine you can ask Claude Code for a random number between 1 and 100. We have not seen that run, so this page shows no output for it.
    • Claude Desktop. It is a desktop app and our machine had no desktop session. Anthropic's local MCP article says Claude Desktop installs local servers as desktop extensions (.mcpb files) and that "Desktop extensions support Node.js, Python, and binary MCP servers." We did not package or test this server as an extension.
    • The Claude API MCP connector. The connector docs say: "The server must be publicly exposed through HTTP (supports both Streamable HTTP and SSE transports). Local STDIO servers cannot be connected directly." Our server is stdio. The template's --transport remote option creates an HTTP server instead; we did not build or test that variant.
    • Windows and macOS. We only ran linux-x64. We did not run dotnet pack, publish to NuGet, or try the --aot option.

    Where Microsoft.Extensions.AI fits

    The .NET blog splits the AI pieces this way: "Build AI-powered, agentic applications with Microsoft.Extensions.AI (MEAI) for model access, MCP for tool integration, and Microsoft Agent Framework (MAF) for agents and workflows." MEAI is for apps that call models: it "provides abstractions such as IChatClient and IEmbeddingGenerator" (.NET blog). Microsoft Learn adds that "Most consuming applications and services should reference the Microsoft.Extensions.AI package along with one or more libraries that provide concrete implementations of the abstractions" (Microsoft.Extensions.AI docs).

    A server like this one does not call a model, so the template does not reference MEAI. The MCP C# SDK still brings in the abstractions: our restore pulled Microsoft.Extensions.AI.Abstractions 10.8.3 as a dependency of ModelContextProtocol 2.1.0 (from obj/project.assets.json). The ModelContextProtocol package describes itself as "The official C# SDK for the Model Context Protocol, enabling .NET applications, services, and libraries to implement and interact with MCP clients and servers."

    Next steps

    To write your own tool, add a method with the [McpServerTool] and [Description] attributes, the same shape as GetRandomNumber above, and register its class in Program.cs. For the model to run on the Claude side, see Claude Code with Claude Fable 5.2: setup and cost.

    Sources

    All fetched and checked 2026-11-11.

    Related guides