Panoramica
Le API MCP di Sprucely.io espongono la piattaforma di dashboard ad assistenti IA e software di terze parti tramite il Model Context Protocol (MCP), uno standard aperto per collegare modelli IA a strumenti tramite HTTP. Qualsiasi client compatibile con MCP può creare dashboard ospitate, elencarle e ispezionarle, e aggiungervi dati in modo programmatico. Le dashboard create tramite le API appartengono al tuo account e possono essere condivise, incorporate o modificate ulteriormente nel servizio. Per incorporare le dashboard risultanti nel tuo sito, consulta le note sull’integrazione semplice della dashboard. Se utilizzi Claude, il modo più rapido per iniziare è il connettore Sprucely.io.
Connessione
Il server MCP viene servito su Streamable HTTP all’indirizzo:
https://www.sprucely.io/mcpQualsiasi client MCP può connettersi a questo endpoint. Ad esempio, un singolo comando registra il server in Claude Code:
claude mcp add --transport http sprucely https://www.sprucely.io/mcpPuoi anche richiamare il server direttamente con JSON-RPC 2.0 su HTTP. La maggior parte dei client MCP esegue automaticamente l’handshake del protocollo; la richiesta seguente elenca gli strumenti disponibili utilizzando una chiave API:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Autenticazione
Le richieste sono autorizzate tramite un header Authorization Bearer standard. Sono supportati due tipi di credenziali.
Chiavi API - Crea le chiavi API nella sezione MCP del tuo profilo. Le chiavi iniziano con spr_mcp_, vengono mostrate una sola volta al momento della creazione e possono essere revocate in qualsiasi momento. Usale per script, server e client MCP headless.
OAuth 2.1 - I client MCP interattivi possono invece permettere agli utenti di accedere con il proprio account Sprucely.io tramite OAuth 2.1. Il server di autorizzazione supporta il flusso authorization code con PKCE (obbligatorio), i refresh token e la registrazione dinamica dei client, così i client compatibili si configurano automaticamente a partire dai metadati della risorsa:
https://www.sprucely.io/.well-known/oauth-protected-resourceScope disponibili: openid, offline_access, dashboards:read e dashboards:write. Gli scope vengono applicati per singolo strumento: create_dashboard, add_data e set_sharing richiedono dashboards:write e restituiscono un errore in sua assenza. Gli altri strumenti necessitano solo di dashboards:read.
Per i client che richiedono una configurazione manuale, gli endpoint del server di autorizzazione sono:
https://www.sprucely.io/oauth/.well-known/openid-configuration- metadati del server di autorizzazionehttps://www.sprucely.io/oauth/auth- endpoint di autorizzazione (PKCE obbligatorio)https://www.sprucely.io/oauth/token- endpoint dei tokenhttps://www.sprucely.io/oauth/reg- registrazione dinamica dei clienthttps://www.sprucely.io/oauth/jwks- chiavi di firma (JWKS)https://www.sprucely.io/oauth/token/revocation- revoca dei tokenhttps://www.sprucely.io/oauth/token/introspection- introspezione dei token
Strumenti
Il server MCP espone otto strumenti: create_dashboard, get_dashboard, list_dashboards, add_data, get_dataset_schema, set_sharing, get_embed_code e storage_status.
I parametri dataset e dashboard descritti di seguito non sono un formato specifico di MCP - sono esattamente lo stesso JSON di dataset/dashboard documentato nella pagina Formato Dati e utilizzato in tutto il resto del servizio (l’API di importazione del runtime incorporabile standalone, i layout generati dall’IA e l’editor delle dashboard), quindi tutto ciò che è stato scritto facendo riferimento a quella pagina si applica anche qui.
create_dashboard - Crea una dashboard ospitata a partire da un dataset inline e da un albero di widget, e restituisce i link di visualizzazione e di incorporamento. Parametri:
name- il titolo della dashboard (obbligatorio)dataset- il dataset da visualizzare:name,headers(nomi delle colonne),types(un tipo di database per ogni intestazione -VARCHAR,BOOLEAN,INTEGER,BIGINT,FLOAT,DOUBLE,DATEoTIMESTAMP) eentries(le righe, ciascuna un array di valori nell’ordine delle intestazioni), fino a 100 colonne e 50.000 righe di dati grezzi, non aggregati, per chiamata (obbligatorio). Le righe non devono essere pre-aggregate: invia una riga per ogni record sottostante, e lascia che ladataFunctiondi ciascun grafico calcoli conteggi, somme, medie e così via al momento del rendering.dashboard- da 1 a 40 widget di primo livello, dall’alto verso il basso (obbligatorio). Ogni widget è undash_chart(un tipo di grafico -area,bar,cell,dot,hexbinoline- mappature di colonna perx,y,der, unadataFunctionfacoltativa e un titolo facoltativo), undash_table, un bloccodash_text, undash_spacer, oppure un contenitoredash_stacker_hor/dash_stacker_ver. Gli impilatori si annidano ricorsivamente - i figli di un impilatore possono a loro volta includere altri impilatori - per disporre i widget in righe e colonne con una profondità arbitraria. Quali tipi di colonna (categoriale, continua o temporale) accettano le dimensionix/y/d/rdi ciascun tipo di grafico, e come il raggruppamento temporale di una colonna data conseasonX/seasonYla trasformi in categoriale, è documentato per ciascun campo tramite tools/list e nella pagina Formato Dati.theme- colori facoltativi validi per l’intera dashboard (sfondo, testo, accenti primario/tenue/secondario); ogni widget può comunque sovrascrivere il proprio colore o sfondoshared- se la dashboard è visibile a chiunque abbia il link (facoltativo, predefinito false). Le nuove dashboard sono private finché non lo imposti su true o richiamiset_sharingin un secondo momento.
Il risultato include il dashboardId e il datasetId della nuova dashboard (necessari in seguito per add_data, get_dataset_schema, set_sharing e get_embed_code), oltre a url, viewUrl e allo snippet di incorporamento iframe. Esempio - creare una dashboard con un grafico a barre e un colore di accento per l’intera dashboard:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "create_dashboard",
"arguments": {
"name": "Regional Sales",
"dataset": {
"name": "Sales",
"headers": ["region", "revenue"],
"types": ["VARCHAR", "DOUBLE"],
"entries": [
["North", 1250.5],
["South", 980.25],
["East", 1420.0]
]
},
"dashboard": {
"type": "dash",
"children": [
{ "type": "dash_chart", "chartType": "bar", "x": "region", "d": "revenue", "dataFunction": "sum", "title": "Revenue by region" }
]
},
"theme": { "themePrimary": "#6E2BDC" }
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"dashboardId": "dash_a1b2c3d4",
"datasetId": "data_e5f6g7h8",
"name": "Regional Sales",
"shared": false,
"rows": 3,
"columns": 2,
"url": "https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4",
"viewUrl": "https://www.sprucely.io/service/dashboards/view/123/dash_a1b2c3d4",
"iframe": "<iframe src=\"https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4\" style=\"width:100%;height:640px;border:0\" title=\"Sprucely dashboard\" loading=\"lazy\"></iframe>"
}get_dashboard - Restituisce il nome di una dashboard, lo stato di condivisione, gli ID dei dataset e i link. Parametro: dashboardId (obbligatorio). Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_dashboard",
"arguments": {
"dashboardId": "dash_a1b2c3d4"
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"dashboardId": "dash_a1b2c3d4",
"name": "Regional Sales",
"shared": false,
"archived": false,
"datasetIds": ["data_e5f6g7h8"],
"source": "mcp",
"updatedAt": "2026-07-29T10:15:00.000Z",
"url": "https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4",
"viewUrl": "https://www.sprucely.io/service/dashboards/view/123/dash_a1b2c3d4",
"iframe": "<iframe src=\"https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4\" style=\"width:100%;height:640px;border:0\" title=\"Sprucely dashboard\" loading=\"lazy\"></iframe>"
}list_dashboards - Elenca le dashboard del tuo account, ordinate per ultimo aggiornamento, ciascuna con i propri datasetIds, così un dataset può essere passato direttamente a get_dataset_schema o add_data senza una chiamata separata a get_dashboard. Parametri: limit e offset per la paginazione, query per un filtro sul nome che non distingue tra maiuscole e minuscole (tutti facoltativi). Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "list_dashboards",
"arguments": {
"limit": 10,
"query": "sales"
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"total": 1,
"limit": 10,
"offset": 0,
"hasMore": false,
"dashboards": [
{
"dashboardId": "dash_a1b2c3d4",
"name": "Regional Sales",
"shared": false,
"datasetIds": ["data_e5f6g7h8"],
"source": "mcp",
"updatedAt": "2026-07-29T10:15:00.000Z",
"url": "https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4",
"viewUrl": "https://www.sprucely.io/service/dashboards/view/123/dash_a1b2c3d4",
"iframe": "<iframe src=\"https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4\" style=\"width:100%;height:640px;border:0\" title=\"Sprucely dashboard\" loading=\"lazy\"></iframe>"
}
]
}add_data - Aggiunge righe al dataset di una dashboard esistente; ogni dashboard che utilizza quel dataset si aggiorna automaticamente. Parametri:
dashboardId- la dashboard a cui aggiungere i dati (obbligatorio)entries- le righe allineate posizionalmente alle intestazioni del dataset, fino a 50.000 per chiamata (obbligatorio) - si applica la stessa regola sui dati grezzi e non aggregati dicreate_dashboard. Richiama primaget_dataset_schemase non conosci già i nomi/l’ordine esatti delle colonne della dashboard. Usalo per caricare dataset di grandi dimensioni a lotti, oppure per mantenere le dashboard aggiornate.run_id- una chiave di idempotenza facoltativa per questo specifico lotto (facoltativo). Se una precedente chiamataadd_datacon lo stessodashboardIderun_idè già andata a buon fine, richiamarla di nuovo restituisce quel risultato precedente invece di aggiungere di nuovo le righe, così un lotto può essere ritentato in sicurezza dopo un timeout o una connessione interrotta - usa un nuovorun_idper ogni lotto distinto (ad esempio un UUID o un hash del suo contenuto).
Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "add_data",
"arguments": {
"dashboardId": "dash_a1b2c3d4",
"entries": [
["West", 875.0]
],
"run_id": "batch-2026-07-29T10:20:00Z"
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"dashboardId": "dash_a1b2c3d4",
"datasetId": "data_e5f6g7h8",
"addedRows": 1,
"url": "https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4",
"viewUrl": "https://www.sprucely.io/service/dashboards/view/123/dash_a1b2c3d4",
"iframe": "<iframe src=\"https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4\" style=\"width:100%;height:640px;border:0\" title=\"Sprucely dashboard\" loading=\"lazy\"></iframe>"
}
# Calling again later with the same dashboardId + run_id (e.g. after a dropped
# connection) is safe: the rows are not appended twice, and the response also
# carries "duplicate": true instead of appending again.get_dataset_schema - Restituisce i nomi e i tipi delle colonne di un dataset. Usalo prima di richiamare add_data (o prima di costruire un nuovo grafico sullo stesso dataset) ogni volta che non conosci già i nomi/l’ordine/i tipi esatti delle colonne, ad esempio in una nuova sessione o quando la dashboard è stata creata da un altro agente. Parametro: datasetId (obbligatorio). Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "get_dataset_schema",
"arguments": {
"datasetId": "data_e5f6g7h8"
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"datasetId": "data_e5f6g7h8",
"headers": ["region", "revenue"],
"types": ["VARCHAR", "DOUBLE"]
}set_sharing - Attiva o disattiva il link pubblico di una dashboard. Disattivarlo revoca l’accesso anche a ogni revisione precedente della dashboard, quindi un link condiviso in passato smette di funzionare. Parametri: dashboardId e shared (entrambi obbligatori). Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "set_sharing",
"arguments": {
"dashboardId": "dash_a1b2c3d4",
"shared": true
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"dashboardId": "dash_a1b2c3d4",
"shared": true,
"url": "https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4",
"viewUrl": "https://www.sprucely.io/service/dashboards/view/123/dash_a1b2c3d4",
"iframe": "<iframe src=\"https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4\" style=\"width:100%;height:640px;border:0\" title=\"Sprucely dashboard\" loading=\"lazy\"></iframe>"
}get_embed_code - Restituisce il link di visualizzazione condivisibile e uno snippet di incorporamento iframe per una dashboard - lo stesso link/codice di incorporamento già restituiti da create_dashboard e set_sharing, per quando servono di nuovo da soli. Il link funziona per gli altri solo mentre la dashboard è condivisa. Parametro: dashboardId (obbligatorio). Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 8,
"method": "tools/call",
"params": {
"name": "get_embed_code",
"arguments": {
"dashboardId": "dash_a1b2c3d4"
}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"dashboardId": "dash_a1b2c3d4",
"shared": true,
"url": "https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4",
"viewUrl": "https://www.sprucely.io/service/dashboards/view/123/dash_a1b2c3d4",
"iframe": "<iframe src=\"https://www.sprucely.io/service/dashboards/embed/123/dash_a1b2c3d4\" style=\"width:100%;height:640px;border:0\" title=\"Sprucely dashboard\" loading=\"lazy\"></iframe>"
}storage_status - Indica quanto spazio di archiviazione ha utilizzato l’account e quanto ne resta, utile prima di una chiamata create_dashboard o add_data abbastanza grande da rischiare di superare il limite di archiviazione del piano. Nessun parametro. Esempio:
curl -X POST https://www.sprucely.io/mcp \
-H "Authorization: Bearer spr_mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 9,
"method": "tools/call",
"params": {
"name": "storage_status",
"arguments": {}
}
}'
# Result (result.structuredContent in the JSON-RPC response):
{
"used": 5242880,
"limit": 104857600,
"percent": 5,
"plan": "Regular",
"over": 0,
"blocked": false
}Limiti ed errori
- L’endpoint MCP accetta 25 richieste al minuto per client e corpi di richiesta fino a 25 MB - carica i dataset più grandi in più lotti con
add_data. - I dataset accettano fino a 100 colonne e 50.000 righe per chiamata, e una dashboard accetta fino a 40 widget per ogni livello di annidamento. Le dashboard salvate contano ai fini della quota di archiviazione del tuo piano - richiama
storage_statusper verificare il margine residuo prima di una chiamatacreate_dashboardoadd_datadi grandi dimensioni. - Vengono utilizzati i codici di stato HTTP standard: 401 per credenziali mancanti o non valide (con una richiesta WWW-Authenticate che punta ai metadati della risorsa), 403 per credenziali revocate o insufficienti, 413 per richieste di dimensioni eccessive e 429 in caso di rate limiting.