Server MCP
Il server MCP (Model Context Protocol) di SupDesk dà agli assistenti IA e agli altri strumenti basati su LLM accesso diretto al centro assistenza, alla bacheca del feedback, al changelog, ai thread di messaggi, ai programmi beta e alla lista d’attesa di un progetto.
Endpoint
https://mcp.supdesk.app/mcpAutenticazione
Passa una chiave API come token Bearer:
Authorization: Bearer sd_live_...Genera le chiavi nella console SupDesk, in Impostazioni workspace → Chiavi API.
La chiave determina il progetto, quindi nessuno strumento accetta un argomento project_id:
non c’è nulla che un modello debba indovinare o possa sbagliare.
Che cosa ottieni
Quali strumenti compaiono dipende dal progetto. Una funzionalità disattivata nelle Impostazioni
del progetto non espone affatto i suoi strumenti in tools/list, esattamente come l’API REST
risponde 404 su quelle rotte.
| Gruppo | Strumenti | Richiede |
|---|---|---|
| Centro assistenza | 10 | Centro assistenza attivo |
| Bacheca del feedback | 5 | Bacheca del feedback attiva |
| Changelog | 5 | Changelog attivo |
| Messaggi | 5 | Messaggi privati attivi |
| Beta testing | 8 | Beta attivo |
| Lista d’attesa | 4 | Lista d’attesa attiva |
| Panoramica | 1 | Sempre disponibile |
La lettura funziona su ogni piano. La scrittura richiede un piano a pagamento — creare,
aggiornare o eliminare con una chiave in sola lettura restituisce forbidden, mentre le letture
con la stessa chiave funzionano senza problemi.
Centro assistenza
list_articles— articoli, con la modifica più recente per prima. Include bozze e archiviati; filtra constatusper ciò che i clienti vedono.get_article— un articolo per id, con il suo corpo in Markdown.search_articles— ricerca full-text sugli articoli pubblicati, ordinata per rilevanza, con stralcio.create_article— crea una bozza. Pubblicare è una chiamata separata, così nulla raggiunge i clienti per sbaglio.update_article— modifica qualsiasi campo; impostastatussupublishedoarchived.delete_article— definitivo; archivia invece, se vuoi conservare l’articolo.list_article_categories,create_article_category,update_article_category,delete_article_category— eliminare una categoria lascia i suoi articoli al loro posto, senza categoria.
Il corpo degli articoli è Markdown, non HTML. Il portale li mostra tramite un visualizzatore che non valuta mai HTML, quindi l’HTML arriva ai lettori come testo letterale.
create_article fallisce con limit_reached non appena la quota di articoli del piano è
esaurita — Free 5, Pro 50, Team illimitati.
Bacheca del feedback
list_feedback— post, i più recenti per primi. Copre tutti e tre i tipi (bug,feature,feedback) se non lo restringi contype.get_feedback,create_feedback,update_feedback— conupdate_feedbackfai avanzare un post lungobacklog → open → planned → in_progress → done.delete_feedback— rimuove il post, i suoi voti e i suoi commenti.
Changelog, messaggi, beta e lista d’attesa
Parità completa con l’API REST, sulle stesse query:
- Changelog —
list_changelog,get_changelog_entry,create_changelog_entry,update_changelog_entry,delete_changelog_entry. Le voci nascono come bozza, perché è la pubblicazione a inviare l’email di annuncio agli iscritti. - Messaggi —
list_threads,get_thread(con lo storico completo),create_thread,reply_to_thread,update_thread. - Beta testing —
list_beta_programs,get_beta_program,create_beta_program,update_beta_program,delete_beta_program,list_beta_testers,add_beta_tester,remove_beta_tester.add_beta_testerè idempotente sull’email e restituisce il token di accettazione; questo server non invia email, quindi consegnare l’invito spetta a te. - Lista d’attesa —
list_waitlist,add_waitlist_signup(idempotente sull’email),update_waitlist_signup,remove_waitlist_signup.
Panoramica
project_stats restituisce conteggi su tutto il progetto — post di feedback per stato, thread
aperti, articoli pubblicati e in bozza, e i voti utile / non utile che quegli articoli hanno
raccolto — così un agente risponde a «quanto è rimasto in sospeso?» senza percorrere quattro
elenchi paginati.
Output strutturato
Ogni strumento dichiara un outputSchema e restituisce sia structuredContent (tipizzato e
validato) sia un blocco di testo content con gli stessi dati in JSON. Elabora quello che il tuo
client supporta.
const result = await mcpClient.callTool("get_article", { id: "8f7a..." });
result.structuredContent.article.title; // tipizzato
JSON.parse(result.content[0].text); // gli stessi dati, come ripiegoAnnotazioni
Ogni strumento porta annotazioni, così un client sa che cosa sta invocando prima di invocarlo:
| Annotazione | Presente su |
|---|---|
readOnlyHint: true | list_*, get_*, search_*, project_stats |
idempotentHint: true | letture e update_* |
destructiveHint: true | delete_*, remove_* |
Paginazione
Gli strumenti di elenco accettano un cursor opaco e restituiscono un next_cursor — rimandalo
indietro per la pagina successiva, e fermati quando è null.
let cursor;
do {
const page = await mcpClient.callTool("list_articles", { status: "published", cursor });
handle(page.structuredContent.data);
cursor = page.structuredContent.next_cursor;
} while (cursor);Un cursore è un token, non aritmetica — trattalo come opaco. Uno malformato restituisce
invalid_request invece di ripartire in silenzio dalla prima pagina, cosa che farebbe ciclare
all’infinito un percorso paginato.
Nota che questa è una convenzione all’interno dello schema degli argomenti di ciascuno strumento. Il cursore a livello di protocollo in MCP si applica agli elenchi di strumenti e risorse, non a ciò che uno strumento restituisce; l’elenco di risorse qui sotto usa il meccanismo vero.
Risorse
Per allegare contenuti del progetto come contesto, invece di chiamare uno strumento e incollare il risultato:
| URI | Contenuto |
|---|---|
supdesk://articles/{slug} | Un articolo di assistenza pubblicato, in Markdown. |
supdesk://board | I post di feedback aperti del progetto, in JSON. |
L’elenco degli articoli è davvero paginato a livello di protocollo e copre solo gli articoli pubblicati — una risorsa è contenuto che un client può mostrare alla lettera, e una bozza non è pubblicata per un motivo.
Prompt
Due punti di partenza, collegati ai dati reali del progetto:
draft_article_from_thread— trasforma una conversazione di assistenza risolta in un articolo del centro assistenza, così il prossimo cliente con quella domanda trova la risposta invece di aprire un thread. Richiede il centro assistenza e i messaggi privati attivi.triage_feedback— valuta un post e raccomanda uno stato, con il ragionamento. Consulta primasearch_articles, così una risposta già esistente emerge invece di proporre nuovo lavoro.
Entrambi usano la capacità di completamento di MCP per i loro argomenti: mentre scrivi una categoria, il server risponde con gli slug di categoria reali del progetto invece di lasciarti indovinare.
Logging
Le scritture in più passi inviano notifiche di avanzamento tramite il logging MCP —
create_article verifica la quota del piano, cerca uno slug libero e poi inserisce, segnalandolo
a ogni passo. Un client senza supporto al logging non ne risente; la scrittura avviene comunque.
Esempi
Claude Desktop
Aggiungi a ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"sup-desk": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.supdesk.app/mcp",
"--header",
"Authorization: Bearer sd_live_..."
]
}
}
}Rispondere a una domanda, o scrivere la risposta
// Verificare se il centro assistenza la copre già.
const hits = await mcpClient.callTool("search_articles", {
query: "reimposta password",
limit: 5
});
if (hits.structuredContent.data.length === 0) {
// Ancora nulla — scrivine uno. Nasce come bozza.
const created = await mcpClient.callTool("create_article", {
title: "Come reimposto la password?",
body: "Apri **Impostazioni**, poi scegli *Reimposta password*.",
category_id: "3c2b..."
});
// Pubblicare è deliberato e separato.
await mcpClient.callTool("update_article", {
id: created.structuredContent.article.id,
status: "published"
});
}Smistare la bacheca
const open = await mcpClient.callTool("list_feedback", {
status: "open",
limit: 10
});
await mcpClient.callTool("update_feedback", {
id: open.structuredContent.data[0].id,
status: "planned"
});Tutto il pendente, in una chiamata
const stats = await mcpClient.callTool("project_stats", {});
// { posts_by_status: { open: 12, planned: 3, ... }, open_threads: 4,
// articles_published: 18, articles_draft: 2,
// article_helpful: 240, article_not_helpful: 11 }Limiti di velocità
Il server MCP condivide i limiti dell’API REST: 120 richieste ogni 60 secondi per progetto. Vedi Limiti di velocità e utilizzo.
Errori
Una chiamata fallita restituisce isError: true con lo stesso vocabolario di errori usato
dall’API REST:
{
"error": {
"code": "limit_reached",
"message": "Your plan allows 5 help-center articles."
}
}| Codice | Significato |
|---|---|
unauthorized | Chiave API mancante, malformata, revocata o sconosciuta. |
forbidden | Chiave valida, ma il piano non ha accesso in scrittura all’API. |
invalid_request | Argomenti errati — incluso un cursor malformato. |
not_found | Nessun id di questo tipo in questo progetto. |
limit_reached | Una quota del piano è esaurita (per esempio il limite di articoli). |
rate_limited | Troppe richieste nella finestra corrente. |
internal_error | Qualcosa è andato storto dalla nostra parte. Riprovare è sicuro. |
L’elenco completo è documentato in Errori.