Note preliminari
Contenuto fornito “as-is”, non adatto a dati clinici reali senza valutazione DPIA. Prima di qualunque prova:
- Lavorate esclusivamente su dataset di test o dati anonimizzati secondo una procedura documentata e validata.
- Backup della cartella di lavoro prima di ogni sessione.
- Nessun endpoint cloud su PHI (Protected Health Information): il modello deve essere locale (Ollama, vLLM) anche in fase di prova. Un errore di configurazione con dati reali è un data breach.
- Non inserite secrets nei prompt o nei file di configurazione versionati.
- MCP e Goose sono tecnologie in rapida evoluzione: verificate la documentazione ufficiale della versione installata, soprattutto per la sintassi dei server.
- Questa integrazione non costituisce software medicale. Non usatela per finalità diagnostiche, di triage o per supporto decisionale clinico.
Cosa è Goose e cosa è MCP
Goose (block.github.io/goose) è un agent desktop e CLI open source rilasciato da Block a gennaio 2025, licenza Apache 2.0. La caratteristica chiave ai nostri fini è l’adesione al Model Context Protocol (MCP), lo standard pubblicato da Anthropic a fine 2024 come protocollo di interoperabilità tra agent LLM e tool/fonti dati. Un server MCP espone capability (resources, tools, prompts); Goose le consuma via JSON-RPC.
Per un’azienda sanitaria o per una software house che sviluppa prodotti sanitari, la combinazione apre una possibilità concreta: sperimentare un agent sopra i propri dati senza far uscire i dati dall’infrastruttura, e senza reimplementare integrazioni ad hoc.
Caso d’uso: esplorare un bundle FHIR anonimizzato di esempio
Scenario: un team di sviluppo sta progettando un modulo che interroga una cartella contenente bundle FHIR anonimizzati a scopo di test. Vogliamo verificare se un agent può aiutare lo sviluppatore a fare domande esplorative (conteggi per tipo di risorsa, distribuzione delle osservazioni, conformità allo schema minimo richiesto) senza scrivere per primo un tool ad-hoc.
1. Preparazione dei dati di test
Usate solo dati sintetici o pubblicamente rilasciati a scopo di sviluppo. Il progetto Synthea (Apache 2.0, synthetichealth.github.io/synthea) genera bundle FHIR di pazienti fittizi. In alternativa, adattate i vostri dataset applicando una procedura di anonimizzazione certificata internamente.
mkdir -p ~/fhir-lab/input ~/fhir-lab/reports
# Copiate qui solo JSON di test o sintetici:
cp /path/al/bundle-sintetico.json ~/fhir-lab/input/
# Read-only per sicurezza:
chmod 444 ~/fhir-lab/input/*.json
2. Server MCP minimale, read-only, in Python
Un server MCP che espone solo due tool: list_bundles (elenca i file JSON nella directory) e bundle_metadata (restituisce conteggi e tipi di risorsa per un bundle, senza contenuti clinici). Il server non legge mai i campi anagrafici.
# ~/fhir-lab/fhir_mcp_server.py
import json, os
from pathlib import Path
from mcp.server.fastmcp import FastMCP # dipende dalla versione dell'SDK
BASE = Path(os.environ["FHIR_LAB_DIR"]) # obbligatoria, no default rischiosi
assert BASE.is_dir(), "FHIR_LAB_DIR non valida"
app = FastMCP("fhir-lab-readonly")
@app.tool()
def list_bundles() -> list[str]:
"""Elenca i file .json nella directory di input."""
return sorted(p.name for p in (BASE / "input").glob("*.json"))
@app.tool()
def bundle_metadata(filename: str) -> dict:
"""Conteggi aggregati dei resourceType in un bundle. Nessun contenuto clinico."""
p = (BASE / "input" / filename).resolve()
if BASE / "input" not in p.parents:
raise ValueError("path traversal")
bundle = json.loads(p.read_text())
counts = {}
for entry in bundle.get("entry", []):
rt = entry.get("resource", {}).get("resourceType", "Unknown")
counts[rt] = counts.get(rt, 0) + 1
return {"filename": filename, "totalEntries": sum(counts.values()), "byType": counts}
if __name__ == "__main__":
app.run()
Tre elementi di sicurezza elementare:
BASErichiesta via env: niente path hardcoded, niente fallback.- Check anti path-traversal: il parametro
filenamenon può uscire dalla directory dichiarata. - Funzioni read-only: nessuna funzione mutante esposta al modello.
Installazione delle dipendenze in un virtualenv isolato:
python3 -m venv ~/fhir-lab/.venv
source ~/fhir-lab/.venv/bin/activate
pip install "mcp[cli]" # nome del pacchetto dipende dalla release
3. Configurare Goose perché usi il server e un modello locale
# Provider locale via Ollama:
ollama pull qwen2.5:14b # o altro modello adeguato
# Configurazione Goose (il comando esatto può variare tra versioni):
goose configure
# Scegliere: provider = Ollama; model = qwen2.5:14b
Collegare il server MCP al profilo Goose (sintassi indicativa — adattare al formato config.yaml della versione installata):
extensions:
fhir-lab:
type: stdio
command: /home/utente/fhir-lab/.venv/bin/python
args: ["/home/utente/fhir-lab/fhir_mcp_server.py"]
env:
FHIR_LAB_DIR: "/home/utente/fhir-lab"
4. Sessione con Goose
cd ~/fhir-lab
goose session
Prompt utili nel REPL:
- “Elenca i bundle disponibili con il tool
list_bundles.” - “Per ciascun bundle, mostra il conteggio per resourceType usando
bundle_metadata. Riassumi in una tabella.” - “Quali bundle non contengono
Observation? Restituisci la lista.”
L’agente chiama i tool MCP per rispondere: nessun dato clinico entra nel prompt, solo i metadati che il server espone deliberatamente.
Limiti e avvertenze
- Anonimizzazione ≠ sicurezza: un dataset “anonimizzato” può contenere PHI per re-identificazione indiretta. Usate procedure documentate (pseudonimizzazione, generalizzazione, k-anonymity o equivalenti) prima di considerarlo utilizzabile in un esperimento AI.
- Il server MCP è parte del vostro TCB: un bug che aggira il check di path-traversal, o un tool “mutante” aggiunto per comodità, apre una superficie di attacco su dati sensibili. Trattate il codice del server come trattate quello che scrive su DB clinici.
- Il modello locale non è “senza rischi”: le tracce delle sessioni Goose (home dell’utente, shell history, swap) possono comunque contenere metadati interrogati. Proteggete la workstation come un client clinico.
- Non è software medicale: anche esempi che sembrano innocui (conteggi per tipo) non sono validati clinicamente. Qualsiasi uso diagnostico o assistenziale richiede un percorso regolatorio (MDR, ISO 13485, IEC 62304) estraneo al perimetro di questo tutorial.
Link: block.github.io/goose — modelcontextprotocol.io — synthetichealth.github.io/synthea
