@dpezzettone-memori/mcp-ms-loop
v1.0.5
Published
MCP server for Microsoft Loop files: retrieve Loop content as HTML via Microsoft Graph API.
Readme
MCP MS Loop — Guida completa per system integrator
Server MCP che permette agli Agenti AI di leggere i file Microsoft Loop via Microsoft Graph API, con autenticazione app-only (client credentials). Funziona per file Loop ovunque siano salvati:
- OneDrive personale
- Siti SharePoint (canali Teams)
- App Microsoft Loop (SharePoint Embedded, container
CSP_…)
Indice
- Panoramica architetturale
- Prerequisiti
- Creare l'App Registration su Azure
- Assegnare i permessi API
- Registrazione SPE — passaggio obbligatorio per l'app Loop
- Configurare l'MCP nel gateway
- Tool disponibili
- Permessi minimi necessari
- Troubleshooting
1. Panoramica architetturale
Agente AI
│
▼
MCP Gateway (Rails)
│ inietta TENANT_ID, CLIENT_ID, CLIENT_SECRET
│ come variabili d'ambiente
▼
npx @dpezzettone-memori/mcp-ms-loop ← questo pacchetto
│
▼
Microsoft Graph API
│
├── /drives/{driveId}/items/{itemId}/content?format=html
│ ↓ redirect a westeurope1-mediap.svc.ms (converter HTML)
│
└── /v1.0/search/query (per discovery dei workspace)Le credenziali non passano mai dall'LLM: vengono iniettate dal gateway come variabili d'ambiente, invisibili all'Agente.
2. Prerequisiti
| Requisito | Dettaglio |
|---|---|
| Accesso Azure Portal | Ruolo Application Administrator o superiore sul tenant |
| Accesso Global Admin | Necessario solo per il passaggio PowerShell (§5), una volta sola |
| PowerShell con pwsh | Per il passaggio SPE. Funziona su Windows (nativo) e Linux/macOS via GitHub Codespaces o Azure Cloud Shell |
| Tenant Microsoft 365 | Con licenza che include Microsoft Loop (M365 Business Standard/Premium, E3/E5) |
3. Creare l'App Registration su Azure
- Vai su portal.azure.com → Microsoft Entra ID → App registrations → New registration
- Impostazioni:
- Name: es.
MCP MS Loop - Supported account types:
Accounts in this organizational directory only - Redirect URI: lascia vuoto (non serve per app-only)
- Name: es.
- Clicca Register
- Dalla pagina dell'app, annota:
- Application (client) ID →
CLIENT_ID - Directory (tenant) ID →
TENANT_ID
- Application (client) ID →
- Vai su Certificates & secrets → New client secret
- Description: es.
mcp-loop-secret - Expires: scegli la scadenza appropriata (es. 24 mesi)
- Clicca Add e copia subito il Value →
CLIENT_SECRET
- Description: es.
⚠️ Il
CLIENT_SECRETè visibile solo al momento della creazione. Copialo subito.
4. Assegnare i permessi API
Dalla pagina dell'app → API permissions → Add a permission:
Permessi richiesti (minimi)
| API | Tipo | Permesso | Admin consent |
|---|---|---|---|
| Microsoft Graph | Application | Files.Read.All | Sì |
| Microsoft Graph | Application | FileStorageContainer.Selected | Sì |
Permesso temporaneo (solo per §5, poi rimuovibile)
| API | Tipo | Permesso | Admin consent |
|---|---|---|---|
| SharePoint | Application | Sites.FullControl.All | Sì |
Dopo aver aggiunto tutti i permessi:
- Clicca Grant admin consent for <tenant>
- Verifica che tutti mostrino lo stato ✅ Granted
ℹ️
Sites.FullControl.Allserve solo per eseguireConnect-SPOServicein PowerShell (§5). Una volta completato quel passaggio, può essere rimosso.
5. Registrazione SPE — passaggio obbligatorio per l'app Loop
I file creati nell'app Microsoft Loop vivono in container SharePoint Embedded (SPE). Questi container hanno un modello di autorizzazione separato: non basta avere permessi Graph, bisogna registrare l'app come "guest application" sul container type di Loop tramite PowerShell.
Questo passaggio:
- Si esegue una sola volta per tenant
- Richiede un account Global Admin
- Non è sostituibile via Graph API o interfaccia Azure
ID del container type di Loop (costante per tutti i tenant)
a187e399-0c36-4b98-8f04-1edc167a0996Opzione A — Windows (più semplice)
Apri PowerShell come amministratore:
# Installa il modulo SPO
Install-Module Microsoft.Online.SharePoint.PowerShell -Force
Import-Module Microsoft.Online.SharePoint.PowerShell
# Connetti con login interattivo (apre il browser)
Connect-SPOService -Url "https://<TENANT_NAME>-admin.sharepoint.com" -Interactive
# Registra l'app come guest sul container type di Loop
Set-SPOApplicationPermission `
-OwningApplicationId "a187e399-0c36-4b98-8f04-1edc167a0996" `
-GuestApplicationId "<CLIENT_ID>" `
-PermissionAppOnly "readcontent"Sostituisci:
<TENANT_NAME>con il prefisso del tuo tenant (es.contoso)<CLIENT_ID>con l'Application ID dell'app creata al §3
Se il comando non dà output → ha funzionato. L'assenza di output è il successo.
Opzione B — Linux / macOS / GitHub Codespaces
Connect-SPOService -Interactive non funziona su Linux. Usa l'autenticazione via certificato.
B1. Genera un certificato self-signed e caricalo su Azure
# Genera chiave privata e certificato (1 sola volta)
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \
-days 730 -nodes -subj "/CN=mcp-loop"
# Crea il .pfx (con password) per PowerShell
openssl pkcs12 -export \
-inkey key.pem -in cert.pem \
-out cert.pfx -passout pass:temp123
# Mostra il fingerprint SHA1 per confrontarlo su Azure
openssl x509 -in cert.pem -fingerprint -sha1 -nooutSu Azure Portal → App Registration → Certificates & secrets → Certificates → Upload certificate:
- Carica
cert.pem - Verifica che il thumbprint mostrato su Azure corrisponda all'output del comando
openssl x509 … -fingerprint
B2. Installa PowerShell e il modulo SPO
# Installa pwsh (se non presente)
# Su Debian/Ubuntu:
sudo apt-get install -y powershell
# In GitHub Codespaces è già disponibile, avvia la shell:
pwshInstall-Module Microsoft.Online.SharePoint.PowerShell -Force
Import-Module Microsoft.Online.SharePoint.PowerShell -ForceB3. Risolvi la dipendenza MSAL (solo Linux)
Il modulo SPO su Linux necessita di una DLL che non viene inclusa automaticamente:
# Dalla bash (non da pwsh), individua dove è installato il modulo:
SPOMOD=$(pwsh -c "Split-Path (Get-Module -ListAvailable Microsoft.Online.SharePoint.PowerShell | Select-Object -First 1).Path")
echo "Modulo in: $SPOMOD"
# Crea un progetto dotnet temporaneo per scaricare la DLL
mkdir -p /tmp/getmsal && cd /tmp/getmsal
dotnet new console -n getmsal --force
cd getmsal
dotnet add package Microsoft.Identity.Client --version 4.74.1
dotnet build -o out
# Copia la DLL nella directory del modulo SPO
cp out/Microsoft.Identity.Client.dll "$SPOMOD/"B4. Connetti e registra
Import-Module Microsoft.Online.SharePoint.PowerShell -Force
Connect-SPOService `
-Url "https://<TENANT_NAME>-admin.sharepoint.com" `
-ClientId "<CLIENT_ID>" `
-TenantId "<TENANT_ID>" `
-CertificatePath "/path/to/cert.pfx" `
-CertificatePassword (ConvertTo-SecureString "temp123" -AsPlainText -Force)
Set-SPOApplicationPermission `
-OwningApplicationId "a187e399-0c36-4b98-8f04-1edc167a0996" `
-GuestApplicationId "<CLIENT_ID>" `
-PermissionAppOnly "readcontent"ℹ️
Connect-SPOServicerichiedeSites.FullControl.All(Application) sull'app (aggiunto al §4). Dopo aver completato questo passaggio, puoi rimuovere quel permesso da Azure se vuoi ridurre la superficie di attacco.
6. Configurare l'MCP nel gateway
Comando di avvio (url_command_hidden)
npx -y @dpezzettone-memori/mcp-ms-loopL'opzione -y fa sì che npx scarichi sempre l'ultima versione pubblicata senza chiedere conferma.
Parametri personalizzati (JSON da inserire nella sezione "Parametri" del gateway)
{
"TENANT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"CLIENT_SECRET": "il-valore-del-secret-NON-l-id"
}⚠️
CLIENT_SECRETè il Value del secret (la stringa lunga comeabc123~XYZ...), non l'ID/UUID che compare nell'elenco secrets su Azure.
Questi valori vengono iniettati come variabili d'ambiente nel processo Node.js. Non compaiono mai nei messaggi scambiati con l'LLM.
7. Tool disponibili
getLoopByShareUrl
Recupera il contenuto completo di un file Loop a partire dal link di condivisione.
Parametri:
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| shareUrl | string | Sì | Link completo del file Loop (quello che apri nel browser) |
| includeText | boolean | No (default true) | Se true, restituisce anche il testo plain (HTML strippato) |
Risposta:
{
"name": "1. Procedure commerciali.loop",
"driveId": "b!Fx9UIEaVjk-...",
"itemId": "01GO3C7SLOD...",
"webUrl": "https://memorisrl.sharepoint.com/...",
"lastModified": "2026-05-10T14:23:00Z",
"size": 63529,
"mimeType": "application/octet-stream",
"html": "<html><meta name=\"GENERATOR\" content=\"Microsoft Loop\">...</html>",
"text": "1. Procedure commerciali\n\nPREMESSA\nÈ fondamentale...",
"truncated": false,
"textTruncated": false
}getLoopByItemId
Variante diretta: usa driveId e itemId se già noti (più veloce, salta la risoluzione del link).
Parametri:
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| driveId | string | Sì | ID del drive contenente il file |
| itemId | string | Sì | ID del file |
| includeText | boolean | No (default true) | Include versione testuale |
listLoopContainers
Scopre tutti i workspace Microsoft Loop accessibili all'app. Usa la Microsoft 365 Search API per trovare tutti i file .loop e raggrupparli per drive/workspace.
Nessun parametro richiesto.
Risposta:
[
{
"driveId": "b!Fx9UIEaVjk-...",
"name": "Presales",
"webUrl": "https://memorisrl.sharepoint.com/contentstorage/CSP_.../Document%20Library",
"loopFileCount": 8
},
{
"driveId": "b!zjdElsus6ka...",
"name": "OneDrive",
"webUrl": "https://memorisrl-my.sharepoint.com/personal/.../Documents",
"loopFileCount": 2
}
]listLoopFilesInDrive
Elenca tutti i file .loop e .fluid dentro un drive. La scansione è ricorsiva (i file Loop nell'app Loop sono salvati dentro la sottocartella LoopAppData/).
Parametri:
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| driveId | string | Sì | ID del drive da scansionare (ottenuto da listLoopContainers) |
| path | string | No (default root) | Percorso di partenza dentro il drive |
Risposta:
[
{
"id": "01GO3C7SLODTQUBW...",
"name": "1. Procedure commerciali.loop",
"driveId": "b!Fx9UIEaVjk-...",
"size": 63529,
"webUrl": "https://...",
"lastModified": "2026-05-10T14:23:00Z",
"mimeType": "application/octet-stream"
}
]8. Permessi minimi necessari
Una volta completata la registrazione SPE (§5), la configurazione finale dell'app deve avere solo questi permessi:
| API | Tipo | Permesso | Motivo |
|---|---|---|---|
| Microsoft Graph | Application | Files.Read.All | Leggere i file Loop |
| Microsoft Graph | Application | FileStorageContainer.Selected | Accedere ai container SPE (workspace Loop) |
Tutto il resto (delegated, Sites.Read.All, User.Read, offline_access, Sites.FullControl.All) può essere rimosso.
9. Troubleshooting
403 accessDenied su file nell'app Loop
Il passaggio §5 (Set-SPOApplicationPermission) non è stato eseguito o non ha avuto effetto. Verificare di aver usato il CLIENT_ID corretto e di essersi connessi come Global Admin. La propagazione può richiedere qualche minuto.
400 failed to parse filter parameter su listLoopContainers
Versione vecchia del pacchetto (≤ 1.0.3). Aggiorna all'ultima versione: il tool ora usa la Search API invece dell'API SPE container, che non è accessibile con i permessi minimi.
Connect-SPOService: Object reference not set to an instance of an object
Stai usando Connect-SPOService -Interactive su Linux. Non funziona. Usa l'autenticazione via certificato (§5 Opzione B).
Could not load file or assembly 'Microsoft.Identity.Client'
La DLL MSAL manca nell'ambiente Linux. Segui il passaggio B3 della §5.
Connect-SPOService: (401) Unauthorized (con certificato)
L'app non ha il permesso SharePoint > Sites.FullControl.All (Application) con admin consent. Aggiungilo temporaneamente, esegui Set-SPOApplicationPermission, poi rimuovilo.
listLoopContainers restituisce array vuoto []
La Search API non ha trovato file Loop accessibili. Cause possibili:
- Il passaggio §5 non è stato fatto → file SPE non accessibili
- Non ci sono file
.loopnel tenant - Il tenant usa una region diversa da EMEA/NAM/APAC — contatta supporto Microsoft
Il CLIENT_SECRET è scaduto
Azure mostra la data di scadenza nella sezione Certificates & secrets. Se scaduto, genera un nuovo secret, aggiorna il JSON dei parametri nel gateway.
