Sprucely title background

API MCP

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/mcp

Qualsiasi 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/mcp

Puoi 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-resource/mcp

Scope 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 autorizzazione
  • https://www.sprucely.io/oauth/auth - endpoint di autorizzazione (PKCE obbligatorio)
  • https://www.sprucely.io/oauth/token - endpoint dei token
  • https://www.sprucely.io/oauth/reg - registrazione dinamica dei client
  • https://www.sprucely.io/oauth/jwks - chiavi di firma (JWKS)
  • https://www.sprucely.io/oauth/token/revocation - revoca dei token
  • https://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, DATE o TIMESTAMP) e entries (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 la dataFunction di 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 è un dash_chart (un tipo di grafico - area, bar, cell, dot, hexbin o line - mappature di colonna per x, y, d e r, una dataFunction facoltativa e un titolo facoltativo), un dash_table, un blocco dash_text, un dash_spacer, oppure un contenitore dash_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 dimensioni x/y/d/r di ciascun tipo di grafico, e come il raggruppamento temporale di una colonna data con seasonX/seasonY la 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 sfondo
  • shared - se la dashboard è visibile a chiunque abbia il link (facoltativo, predefinito true). Le nuove dashboard sono pubbliche finché non lo imposti su false o richiami set_sharing in 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 di create_dashboard. Richiama prima get_dataset_schema se 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 chiamata add_data con lo stesso dashboardId e run_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 nuovo run_id per 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 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_status per verificare il margine residuo prima di una chiamata create_dashboard o add_data di grandi dimensioni.
  • Qualsiasi problema con le credenziali - mancanti, scadute, revocate o non valide per altri motivi - restituisce 401 con una challenge WWW-Authenticate che punta ai metadati della risorsa, così il client sa di doversi autenticare di nuovo invece di fermarsi. Gli altri codici sono 413 per le richieste troppo grandi, 429 in caso di limitazione della frequenza (con header Retry-After), 405 per una GET o una DELETE (il trasporto è stateless: non c’è alcuno stream SSE autonomo da aprire né alcuna sessione da chiudere, quindi invia ogni richiesta come POST) e 503 se in quel momento una credenziale non può essere verificata.
  • Gli errori restituiti prima che la chiamata raggiunga uno strumento sono oggetti di errore JSON-RPC 2.0. Uno strumento che invece viene eseguito e poi fallisce - ID dashboard sconosciuto, scope mancante, spazio di archiviazione esaurito - restituisce un risultato normale con isError impostato e una spiegazione nel testo.