Server MCP: estendi Claude con .NET 9

estendi claude immagine header

Se è la prima volta che atterrate qui sul mio sito vi do il benvenuto, se invece non è la prima volta beh, bentornati! 🙂

Oggi voglio condividere con voi un progettino che ho portato a termine recentemente, aggiungere funzionalità “personalizzate” a Claude (è l’LLM che utilizzo tutti i giorni)… come? Costruendo un piccolo server MCP tramite .Net 9!

Obiettivo

Tramite una VPN ho accesso ad Home Assistant di casa mia e mi capita spesso di aprire l’app sul telefono e controllare diversi parametri, come ad esempio la temperatura del mio acquario o di quella esterna. Essendo che lavoro tutto il giorno con Claude desktop aperto mi sono chiesto, perché non fare in modo di poter chiedere al mio LLM queste informazioni e magari esporre certe funzionalità? Da qui è nato questo piccolo progetto di integrazione.

In un contesto aziendale questo potrebbe tradursi nell’integrazione delle funzionalità “custom” del proprio ambiente direttamente dal nostro assistente, che sia Claude, Gemini, ChatGPT, Copilot o altro.

Claude, puoi rilasciare il software per il cliente X?
Gemini, quali sono gli ultimi 5 errori più ridondanti nel software in produzione del cliente Z?
Copilot, sai dirmi quanti utenti attivi ora ci sono sulla mia applicazione Z?
Chat GPT, puoi creare un ticket all'ufficio infrastrutture dicendo che non mi funziona più il PC?

Cosa è un server MCP?

Un server MCP (Model Context Protocol) è un software che implementa il protocollo MCP (pensato e sviluppato da Anthropic), il cui obiettivo è quello di definire uno “standard” su come costruire applicazioni che si integrino con modelli AI.

Ad oggi il protocollo definisce 3 elementi principali:

  • Resources: dati o contenuti che il modello può leggere (file, database, ecc.)
  • Tools: funzioni che il modello può eseguire (lo vedremo in questo articolo)
  • Prompts: template di prompt predefiniti che il modello può utilizzare

Questo protocollo è ancora relativamente nuovo, ma è il primo passo nel definire uno standard comune di integrazione per tutti i modelli di AI.

A questo link è disponibile la documentazione ufficiale del protocollo MCP

Architettura del progetto

Questo progetto l’ho realizzato costruendo un server MCP in .NET 9, sfruttando una libreria attualmente in preview. 

Come accennato poco fa, Anthropic ha definito qualche tempo fa il protocollo MCP per poter costruire questo tipo di applicazioni, che a mio avviso sono parte del futuro degli LLM in quanto ti permettono di aggiungere una parte di contesto che molto spesso è privata.

Se caliamo tutto questo in una realtà aziendale potrei integrare la documentazione o alcune funzionalità dei miei strumenti (timbrature, programmi contabili, servizi di sviluppo, ecc) in modo sicuro.

A livello di architettura andremo ad aggiungere a Claude un’integrazione con il nostro server MCP e si occuperà lui di gestire l’instradamento verso il nostro server MCP o di fornirci una risposta classica.

Architettura di integrazione tra server MCP e Agente AI

Creazione di un server MCP

Creazione progetto .NET

Come prima cosa creiamo una nuova applicazione di tipo console.

Una volta fatto aggiungiamo questi due pacchetti nuget:

Bash
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting

Il passo successico è quello di mettere mano al Program.cs, cancelliamo tutto il contenuto del file e completiamo in questo modo:

Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
    // Configure all logs to go to stderr
    consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});

builder.Services
    .AddMcpServer()
    .WithStdioServerTransport()
    .WithToolsFromAssembly();

await builder.Build().RunAsync();

Dalla riga 5 alla riga 10 inizializziamo l’applicazione, configurando il livello di log a Trace.

.AddMcpServer() è un metodo recuperato dalla libreria in preview (ModelContextProtocol) e permette di avviare il server MCP quando avviamo l’applicazione, con tutte le sue relative dipendenze.

.WithStdioServerTransport() Questo definisce il metodo di comunicazione “standard input/output” tra il server (MCP) ed il client (AI). Claude interagirà tramite linea di comando con la nostra applicazione, questa strategia di comunicazione è la più indicata per questo contesto.

.WithToolsFromAssembly() questa funzione effettua una scansione dell’assembly e aggiunge tutti i “tool” disponibili per il nostro modello. Le classi/metodi da esporre al modello saranno opportunamente marcate con un decoratore

Creazione di un tool MCP

Creiamo una nuova classe nel nostro progetto e la chiamiamo “IotMcpTools“: qui andremo a definire tutti i metodi e le e funzionalità esposte al nostro agente AI. La potete posizionare dove meglio credete all’interno del vostro progetto in quanto verrà trovata dinamicamente in fase di avvio.

IotMcpTool.cs
using ModelContextProtocol.Server;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThinkAsADev.MCP.McpTools
{
    [McpServerToolType]
    public static class IotMcpTool
    {
        [McpServerTool, Description("Get temperature of specific room")]
        public static string GetTemperature(string roomName)
        {
            int temperature = new Random().Next(18, 25);
            
            //Integrations with HomeAssistant or others tools

            return $"{temperature}°C";
        }
    }
}

Come anticipato prima, la classe ha il decoratore “[McpServerToolType]” mentre il metodo ha il decoratore [McpServerTool, ...], con anche una descrizione della funzione del metodo. Questa descrizione è fondamentale poiché sarà letta e compresa dal nostro modello di LLM!

Come ultimo passaggio verifichiamo che l’applicazione si avvii correttamente. Potete premere il play sul vostro IDE oppure lanciare il comando dotnet run.

Integrazione con Claude Desktop

Dobbiamo ora istruire Claude Desktop che c’è un nuovo server MCP in locale a sua disposizione e per farlo dovremo modificare un file di configurazione dell’applicazione, appositamente pensato per questo scopo.

Apriamo Claude e andiamo su File–> Impostazioni

Si aprirà una maschera, selezioniamo “Sviluppatori” e premiamo sul pulsante “Modifica configurazione“.

Si aprirà il file explorer, nel quale troveremo un file che si chiama “claude_desktop_config.json

File di configurazione claude_desktop_config.json nella directory di Claude
File di configurazione claude_desktop_config.json nella directory di Claude

Apriamolo e aggiungiamo questo json (la prima volta il file dovrebbe essere vuoto e presentare solo due parentesi graffe):

claude_desktop_config.json
{
    "mcpServers": {
        "ThinkAsADev.com": {
            "command": "dotnet",
            "args": [
                "run",
                "--project",
                "C:\\Sorgenti\\ThinkAsADev.MCP\\ThinkAsADev.MCP",
                "--no-build"
            ]
        }
    }
}

ATTENZIONE  Sostituite “C:\Sorgenti\ThinkAsADev.MCP\ThinkAsADev.MCP” con il percorso della vostra applicazione!

ThinkAsADev.com” è il nome che ho dato al mio server MCP, potete cambiarlo a vostro piacimento per identificarlo nella UI di Claude.

Salviamo il file e chiudiamo Claude (Attenzione, va chiuso dalla barra in basso a sinistra!)

Chiusura app claude
Chiusura app claude

Riapriamo Claude, se avremo fatto le cose correttamente avremo a disposizione un nuovo tool cliccando sull’icona delle impostazioni.

Integrazione con il server MCP appena creato
Integrazione con il server MCP appena creato

Una volta avviato Claude eseguirà in background la vostra applicazione questo significa che se effettuate delle modifiche al codice sorgente non sarete più in grado di ricompilare (perchè Claude blocca i file). Per farlo dovrete richiudere claude. Un’alternativa valida è quella di creare una directory sul vostro PC dove copiare i file di build del vostro progetto, in modo tale che Claude non utilizzi gli stessi del vostro progetto.

Funzionerà? Proviamo a chiedergli qualcosa!

Come vedere è stato chiamato il metodo GetTemperature della nostra applicazione, è anche possibile vedere il payload che ha creato e la response Json ritornata dal servizio.

Quanto ci abbiamo messo per creare un server MCP ed integrarlo? E’ bastata una manciata di minuti per farlo, ed è proprio questo che mi ha sorpreso la prima volta che mi sono messo a fare questo progetto.

La parte più “complessa” arriva dopo ovviamente, quando bisogna integrare i servizi all’interno della nostra applicazione.

Testing e Debug

Fino adesso abbiamo visto come creare un semplice tool e come integrarlo con Claude, ma come facciamo a testarlo o fare del debug? Scopriamolo insieme.

Prima di partire

Come vi avevo detto prima, Claude blocca i file del nostro progetto poichè li esegue in background. La soluzione migliore a questo problema è di copiare il compilato della nostra applicazione in una directory dedicata (es. C:\MCPServer\ThinkAsADev), ed aggiornare poi il file claude_desktop_config.json in modo tale da fargli puntare al nuovo percorso.

In alternativa dovremo stoppare momentaneamente Claude o rimuovere la nostra applicazione dal file claude_desktop_config.json.

Preparazione ambiente

Il test ed il debug è eseguito tramite un pacchetto node JS che si occuperà di “simulare” di essere un LLM e ci metterà a disposizione una GUI dove poter testare i metodi.

Il primo passo è quello di installare Node.JS, successivamente apriamo un terminale ed installiamo il pacchetto che ci serve:

Bash
npm install @modelcontextprotocol/inspector

Ora spostiamoci da terminale nella directory del nostro progetto

Bash
cd C:\Sorgenti\ThinkAsADev.MCP\ThinkAsADev.MCP

e lanciamo il nostro server MCP tramite il pacchetto che abbiamo appena installato:

Bash
npx @modelcontextprotocol/inspector dotnet run

L’output sarà il seguente:

output comando "npx @modelcontextprotocol/inspector dotnet run"
Output comando “npx @modelcontextprotocol/inspector dotnet run”

Possiamo notare che in fondo a tutto compare un indirizzo IP con una porta, se la apriamo nel nostro browser si aprirà una webapp generata dal pacchetto installata.

MCP Inspector GUI

La prima volta copiamo nel browser il link con il token in querystring MCP_PROXY_AUTH_TOKEN, in modo tale da inizializzare l’autenticazione. Premiamo ora sul pulsante “Connect”

MCP inspector - Lista dei tool disponibili
MCP inspector – Lista dei tool disponibili

Premendo il pulsante “Tool list” apparirà l’elenco di tutti i metodi che avremo esposto nella nostra applicazione. Se clicchiamo sul nostro metodo (che in questo contesto è chiamato tool) sarà possibile provarlo nella sezione di destra.

MCP inspector - Test del tool
MCP inspector – Test del tool

Conclusioni

Questo articolo è stata un’introduzione alle potenzialità dei server MCP, che ci permettono di estendere le funzionalità dei nostri servizi IA con elementi della nostra realtà (personale o aziendale). La mia esigenza è stata quella di integrare Claude con la mia domotica ma in un contesto aziendale ci vedo davvero molte potenzialità, soprattutto in contesti dove è disponibile un IA aziendale (es. Copilot).

Il progetto che abbiamo visto in questo articolo permette di creare un progetto locale in .NET 9 da collegare a Claude Desktop, il passo successivo è quello di renderlo pubblico (in una intranet aziendale o all’esterno), tenendo sempre in considerazione che la sicurezza è fondamentale: se tralasciamo questo aspetto ed esponiamo funzionalità della nostra realtà allora il disastro sarà dietro l’angolo, soprattutto in un contesto storico come questo dove gli attacchi informatici sono sempre più all’ordine del giorno.

Spero di avervi entusiasmato almeno un pochettino, non vi nascondo che seguiranno altri articoli legati a questo tema!

A presto!

Condividi questo articolo
Shareable URL
Post precedente

Progettare una domotica resiliente

Prosimo post

Combattere il pericoloso gas radon con la domotica – Caso studio

Leggi il prossimo articolo

FluentValidation

Nel corso della mia vita da sviluppatore ho realizzato mantenuto ed esteso centinaia e centinaia di applicazioni…
fluent validation article header