notiziephp.it

Deploy di un'app MCP Laravel in produzione con Laravel Cloud | Laravel - La stack pulita per Artigiani e agenti

Traduzione da Laravel Blog
17 Aprile 2026 Tempo di lettura: 11 minuti
Deploy di un'app MCP Laravel in produzione con Laravel Cloud | Laravel - La stack pulita per Artigiani e agenti

In un post precedente, abbiamo trattato la creazione di un server MCP per esporre la tua app Laravel a client AI come Claude e ChatGPT. Costruire quel server localmente è semplice. Costruire e distribuire un'app MCP che si connette ad esso è leggermente più complesso.

Questo post porta un workflow di supporto SaaS dagli strumenti locali a un'app Laravel MCP distribuita su Laravel Cloud. Costruirai tre strumenti che danno a Claude accesso in tempo reale ai dati degli abbonamenti, poi testerai e distribuirai l'intera app MCP in produzione con un singolo push Git.

Per l'installazione e il contesto del protocollo, vedi la documentazione Laravel MCP.

Lo Scenario: Costruire un'App MCP per un Workflow di Supporto

Diciamo che il tuo team di supporto usa Claude quotidianamente. Un cliente scrive che la sua prova gratuita è scaduta prima di finire di valutare il prodotto.

Il rappresentante ha bisogno del piano attuale del cliente, dello stato dell'abbonamento, della cronologia delle fatture e della conferma che sia sicuro estendere la prova senza creare conflitti di fatturazione.

Senza strumenti strutturati, quel workflow comprende cinque passaggi manuali:

  • Interrogare il database.
  • Formattare il risultato.
  • Incollarlo in Claude.
  • Interpretare il consiglio di Claude.
  • Tornare al database per agire di conseguenza.

Ogni passaggio introduce errori. Con un server Laravel MCP distribuito, Claude gestisce la ricerca, il controllo delle fatture e l'estensione della prova in un'unica conversazione. Gli strumenti portano tipi, annotazioni e gate di ruolo, così le persone giuste possono fare le cose giuste e nient'altro.

Ma tutto questo non conta se l'app gira solo sul tuo laptop. L'obiettivo è la produzione, quindi costruiamo pensando alla distribuzione fin dall'inizio.

Gli Strumenti MCP

IdentifyCustomerTool

I rappresentanti del supporto devono identificare un cliente tramite email prima di poter fare qualsiasi altra cosa. Questo strumento restituisce il nome del piano, lo stato dell'abbonamento e la data di fine della prova in una forma di risposta tipizzata che Claude può leggere direttamente.

Recupero della Cronologia delle Fatture

Il rappresentante del supporto ora ha il piano e lo stato dell'abbonamento del cliente. La domanda successiva è sempre la stessa: cosa è stato addebitato e quando?

GetInvoiceHistoryTool recupera gli ultimi 12 mesi di voci di fattura per un dato utente. Come lo strumento di identificazione del cliente, è di sola lettura. Claude può scansionare i risultati e segnalare anomalie (addebiti duplicati, buchi nella fatturazione) senza che il rappresentante debba scavare manualmente in Stripe.

Il parametro months usa un vincolo enum così Claude non può richiedere un dump illimitato della cronologia. Lo schema di output dice a Claude esattamente quali campi aspettarsi, rendendo i suoi riepiloghi più affidabili.

IssueTrialExtensionTool

Leggere i dati è metà del lavoro. Un rappresentante che trova un cliente con una prova scaduta deve agire. Questo strumento estende la data di fine della prova e porta #[IsDestructive], che segnala al client MCP che modifica lo stato. Claude presenta gli strumenti distruttivi con un passaggio di conferma esplicito prima di eseguirli.

L'annotazione #[IsDestructive] attiva un passaggio di conferma in Claude, ma non crea un record di cosa è cambiato o chi lo ha cambiato. Per uno strumento che modifica i dati di fatturazione, aggiungi una voce di audit all'interno di handle() prima di restituire:

La tua tabella activity_logs ora registra chi ha esteso quale prova, di quanti giorni e quando. Se un rappresentante esegue lo strumento due volte sullo stesso account o sorge una disputa di fatturazione in seguito, hai una traccia completa di ogni azione intrapresa tramite il server MCP.

Registra tutti e tre gli strumenti sul server ed esponi l'endpoint in routes/ai.php:

Proteggere l'Endpoint MCP

Autenticazione del Client MCP

Il file delle route applica il middleware auth:sanctum, ma questo solleva una domanda pratica: come fa il client MCP a ottenere un token in primo luogo?

Il client MCP ha bisogno di un token API Sanctum con scope alle azioni che deve eseguire. Generi questo token una volta per client, lo conservi in modo sicuro lato client e lo ruoti con una cadenza programmata. Abbiamo scritto una guida sulle migliori pratiche di autenticazione e sicurezza Laravel MCP per maggiori dettagli.

Creazione di un Token con Scope

Verifica delle Abilità negli Strumenti

Le abilità dei token diventano utili quando vuoi un singolo endpoint MCP ma diversi livelli di permesso. Un'integrazione di sola lettura potrebbe ricevere un token con solo mcp:read. All'interno di uno strumento distruttivo, controlla l'abilità prima di procedere:

Rotazione dei Token

I token dovrebbero avere una data di scadenza. Quando un token si avvicina alla scadenza, generane uno nuovo e aggiorna la configurazione del client MCP. Per la rotazione automatica, programma un job che crei un nuovo token e revochi quello vecchio:

Mantieni la durata dei token abbastanza breve che un token trapelato faccia danni limitati, ma abbastanza lunga che la rotazione non sia un compito quotidiano. Novanta giorni è un punto di partenza ragionevole.

Rate Limiting sull'Endpoint MCP

Ogni chiamata di strumento MCP colpisce il tuo database. Un client mal configurato o un loop di prompt injection può scatenare centinaia di chiamate al minuto. Il rate limiting è la prima linea di difesa.

Il rate limiter integrato di Laravel funziona sulla route MCP allo stesso modo in cui funziona su qualsiasi endpoint API:

Trenta chiamate al minuto sono generose per un workflow di supporto. Se i tuoi strumenti sono pesanti in lettura, potresti consentirne di più. Se sono pesanti in scrittura, restringi il limite.

Per gli strumenti distruttivi in particolare, considera un limite più rigoroso per strumento all'interno del metodo handle():

Questo impedisce a un singolo operatore di estendere le prove in un loop, sia per errore che tramite una prompt injection che convince Claude a riprovare continuamente.

Gestire gli Errori con Eleganza

Ogni metodo handle() mostrato finora presuppone il percorso felice. In produzione, le cose si rompono. Un ID utente potrebbe non corrispondere a un abbonamento. Stripe potrebbe essere giù. La domanda non è se gli errori accadono, ma cosa vede Claude quando accadono.

Un'eccezione non gestita restituisce un errore grezzo al client MCP. Claude proverà a interpretarlo, ma i trace di stack grezzi non sono contesto utile per un assistente AI. Le risposte di errore strutturate danno a Claude qualcosa su cui può agire.

Avvolgi il corpo di ogni metodo handle() in un try/catch che mappi le eccezioni in risposte di errore tipizzate. Ecco IdentifyCustomerTool con gestione esplicita degli errori:

Tre cose da notare:

  1. Errori di validazione restituiscono il primo messaggio leggibile. Claude può inoltrarlo direttamente al rappresentante del supporto ("Quell'indirizzo email non è stato trovato nel nostro sistema").
  2. Modelli mancanti restituiscono un sostantivo chiaro ("Utente non trovato") invece di un percorso di classe.
  3. Errori imprevisti vengono segnalati al tuo tracker di errori, ma Claude vede solo un messaggio generico. Non far mai trapelare dettagli interni attraverso la risposta MCP.

Applica lo stesso pattern try/catch a ogni strumento che tocca il database o un servizio esterno.

Gate sugli Strumenti per Ruolo con shouldRegister

IssueTrialExtensionTool scrive sul database. Non dovrebbe essere disponibile a ogni utente autenticato. Il metodo shouldRegister permette a ogni strumento di ispezionare la richiesta corrente e decidere se registrarsi o meno. Il gate vive all'interno dello strumento, non sparso nel middleware o nella logica del controller.

Un amministratore di fatturazione vede tutti e tre gli strumenti. Un agente di supporto in sola lettura ne vede due. Quando shouldRegister restituisce false, lo strumento è invisibile al client MCP. Claude non scopre mai che esiste e non può essere indotto a tentare la chiamata. Questo è un guardia più affidabile di un controllo di permesso a runtime dentro handle perché la superficie di attacco scompare del tutto.

Lo stesso pattern funziona per l'accesso basato su abbonamento. Se certi strumenti devono apparire solo per utenti con piani a pagamento:

Testare la Tua App MCP

Laravel MCP include helper di test che ti permettono di chiamare gli strumenti direttamente sulla classe del server e fare assert sulla risposta. Chiami lo strumento nello stesso modo in cui lo fa Claude, poi incateni gli assert fluidi sul risultato.

Test dello Strumento di Sola Lettura

Il metodo SupportServer::tool() chiama IdentifyCustomerTool con gli argomenti forniti e restituisce una risposta di test. assertStructuredContent valida la forma JSON esatta che Claude riceve. assertHasErrors conferma che i fallimenti di validazione restituiscono errori strutturati invece di eccezioni grezze.

Test dello Strumento Distruttivo

Lo strumento di estensione della prova modifica i dati. I test verificano sia la risposta che lo stato del database, oltre alla traccia di audit.

actingAs($admin) imposta l'utente autenticato per la richiesta, allo stesso modo in cui Sanctum autentica un vero client MCP. Lo strumento vede $request->user() come admin, quindi i log di audit registrano l'attore corretto.

Test del Gate shouldRegister

Il metodo shouldRegister controlla quali strumenti Claude può vedere. Testa che i non-admin non vedano mai lo strumento distruttivo:

Quando shouldRegister restituisce false, il server risponde come se lo strumento non esistesse. La chiamata assertHasErrors conferma che lo strumento è invisibile, non solo proibito.

Questi test chiamano ogni strumento allo stesso modo in cui fa il client MCP: attraverso il server, con argomenti e un utente autenticato opzionale. Non ci sono oggetti di richiesta manuali da costruire né array di risposta da destrutturare. Gli assert fluidi si leggono come una specifica di ciò che Claude dovrebbe vedere.

Deploy su Laravel Cloud in Minuti

Tutto fino a questo punto gira sulla tua macchina locale. Gli strumenti funzionano, i gate sono in atto e Claude può interrogare dati live attraverso l'endpoint MCP. Ora tutto ciò che devi fare è distribuire l'app MCP.

Laravel Cloud è la destinazione di produzione per questo server. Gestisce provisioning, scaling, deploy con zero downtime e SSL automaticamente. Inoltre, è appositamente progettato per app Laravel, così distribuisci più velocemente senza gestire infrastruttura. Puoi registrarti e iniziare gratuitamente.

Connetti il tuo repository, configura le variabili d'ambiente nel dashboard, e ogni git push sul ramo di produzione attiva un deploy automatico. Non c'è server da provisioning, nessun Nginx da configurare e nessun certificato SSL da rinnovare.

  1. Connetti il tuo repository. Accedi a Laravel Cloud, crea un nuovo progetto e connetti il tuo repository GitHub o GitLab. Cloud costruisce un'immagine Docker ottimizzata per Laravel a ogni push, usando la versione di PHP che specifichi.
  2. Imposta le variabili d'ambiente. Aggiungi tutto ciò di cui la tua app ha bisogno per la produzione nel dashboard di Cloud, inclusa la tua APP_KEY, le credenziali del database e qualsiasi configurazione Laravel Sanctum necessaria per autenticare i client MCP.
  3. Aggiungi un comando di deploy. Nelle impostazioni di deploy, configura:
  1. Push per distribuire.

Laravel Cloud rileva il push, costruisce l'immagine Docker, esegue i comandi di deploy sul database live, quindi porta online il nuovo container terminando elegantemente il vecchio. L'integrazione di Claude del tuo team di supporto rimane disponibile per tutto il tempo. L'endpoint è live su https://your-app.laravel.cloud/mcp/support entro pochi minuti dal push, con zero downtime.

Questa velocità conta perché lo sviluppo di strumenti MCP è iterativo. Scrivi uno strumento, lo testi con Claude, ti accorgi che la risposta ha bisogno di un campo in più, fai push della modifica ed è live prima che tu finisca di scrivere il ticket. Non c'è un ciclo stage-test-promote a meno che tu non lo costruisca.

Per saperne di più su ciò che Cloud gestisce oltre ai deploy MCP, vedi la documentazione.

Monitorare la Tua App in Produzione

Un server MCP distribuito è una superficie API che un modello AI chiama in modo autonomo. Non puoi rivedere ogni invocazione in tempo reale. Logging e monitoraggio colmano questa lacuna.

Registrazione delle Invocazioni degli Strumenti

Aggiungi un middleware o un listener che registri ogni chiamata di strumento con i parametri, l'utente autenticato e il tempo di risposta:

Registra su un canale dedicato mcp così le invocazioni degli strumenti non si perdono nel log dell'applicazione. In config/logging.php, aggiungi un canale che scrive su un file separato o che invia al tuo aggregatore di log.

Cosa Monitorare

Traccia queste metriche dai tuoi log MCP:

  • Numero di invocazioni per strumento: Un picco in uno strumento distruttivo potrebbe significare un loop di prompt injection o un client mal configurato.
  • Tasso di errore per strumento: Un aumento improvviso di errori not_found nello strumento di ricerca potrebbe significare un problema di sincronizzazione dei dati a monte.
  • Latenza p95 per strumento: Gli strumenti MCP bloccano il thread di conversazione. Se uno strumento impiega più di qualche secondo, la risposta di Claude sembra lenta al rappresentante.
  • Utenti unici all'ora: Aiuta a dimensionare correttamente i rate limit in base ai modelli di utilizzo effettivi.

Il divario tra "strumento che ho costruito per me" e "strumento che usa tutto il mio team di supporto" una volta significava settimane di lavoro sull'infrastruttura. Con laravel/mcp e Laravel Cloud, è un singolo git push.

Scrivi gli strumenti nei pattern Eloquent che già conosci, definisci gli schemi che dicono a Claude esattamente cosa aspettarsi, gate di accesso con shouldRegister e distribuisci su un ambiente Cloud gestito che si occupa del resto.

I tre strumenti in questo post coprono il nucleo di un workflow di supporto: identifica il cliente con IdentifyCustomerTool, controlla la sua cronologia di fatturazione con GetInvoiceHistoryTool e agisci con IssueTrialExtensionTool. Le annotazioni #[IsReadOnly] e #[IsDestructive] mantengono informato Claude. Il gate shouldRegister mantiene i tuoi dati al sicuro.

Quando sei pronto per andare oltre, leggi la documentazione Laravel MCP per risorse, prompt, OAuth 2.1. Poi, prova Laravel Cloud (con $5 di credito di utilizzo) per vedere quanto è veloce l'intero ciclo.

Condividi su: LinkedIn

Altri articoli recenti