Sprucely title background

MCP APIs

Visão geral

As MCP APIs do Sprucely.io expõem a plataforma de dashboards a assistentes de IA e softwares de terceiros através do Model Context Protocol (MCP), um padrão aberto para conectar modelos de IA a ferramentas via HTTP. Qualquer cliente compatível com MCP pode criar dashboards hospedados, listá-los e inspecioná-los, e acrescentar dados a eles de forma programática. Os dashboards criados através das APIs pertencem à sua conta e podem ser compartilhados, incorporados ou editados posteriormente no serviço. Para incorporar os dashboards resultantes ao seu próprio site, consulte as notas de integração simples de dashboard. Se você usa o Claude, a forma mais rápida de começar é o conector Sprucely.io.

Conexão

O servidor MCP é disponibilizado via Streamable HTTP em:

https://www.sprucely.io/mcp

Qualquer cliente MCP pode se conectar a esse endpoint. Por exemplo, um único comando registra o servidor no Claude Code:

claude mcp add --transport http sprucely https://www.sprucely.io/mcp

Você também pode chamar o servidor diretamente com JSON-RPC 2.0 via HTTP. A maioria dos clientes MCP realiza o handshake do protocolo automaticamente; a requisição abaixo lista as ferramentas disponíveis usando uma chave de 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"}'

Autenticação

As requisições são autorizadas com um cabeçalho Authorization Bearer padrão. Dois tipos de credencial são suportados.

Chaves de API - Crie chaves de API na seção MCP do seu perfil. As chaves começam com spr_mcp_, são exibidas apenas uma vez no momento da criação, e podem ser revogadas a qualquer momento. Use-as para scripts, servidores e clientes MCP headless.

OAuth 2.1 - Clientes MCP interativos podem, em vez disso, permitir que os usuários façam login com sua conta Sprucely.io através do OAuth 2.1. O servidor de autorização suporta o fluxo de código de autorização com PKCE (obrigatório), tokens de atualização e registro dinâmico de clientes, de forma que clientes compatíveis se configuram automaticamente a partir dos metadados do recurso:

https://www.sprucely.io/.well-known/oauth-protected-resource

Escopos disponíveis: openid, offline_access, dashboards:read e dashboards:write. Os escopos são aplicados por ferramenta: create_dashboard, add_data e set_sharing exigem dashboards:write e retornam erro sem ele. As demais ferramentas precisam apenas de dashboards:read.

Para clientes que exigem configuração manual, os endpoints do servidor de autorização são:

  • https://www.sprucely.io/oauth/.well-known/openid-configuration - metadados do servidor de autorização
  • https://www.sprucely.io/oauth/auth - endpoint de autorização (PKCE obrigatório)
  • https://www.sprucely.io/oauth/token - endpoint de token
  • https://www.sprucely.io/oauth/reg - registro dinâmico de clientes
  • https://www.sprucely.io/oauth/jwks - chaves de assinatura (JWKS)
  • https://www.sprucely.io/oauth/token/revocation - revogação de token
  • https://www.sprucely.io/oauth/token/introspection - introspecção de token

Ferramentas

O servidor MCP expõe oito ferramentas: create_dashboard, get_dashboard, list_dashboards, add_data, get_dataset_schema, set_sharing, get_embed_code e storage_status.

Os parâmetros de dataset e dashboard abaixo não são um formato específico do MCP - são exatamente o mesmo JSON de dataset/dashboard documentado na página de formato de dados e usado em todos os demais pontos do serviço (a API de importação do runtime independente incorporável, os layouts gerados por IA e o editor de dashboards), portanto tudo o que está descrito naquela referência também se aplica aqui.

create_dashboard - Cria um dashboard hospedado a partir de um dataset embutido e uma árvore de widgets, e retorna links de visualização e incorporação. Parâmetros:

  • name - o título do dashboard (obrigatório)
  • dataset - o dataset a ser visualizado: name, headers (nomes das colunas), types (um tipo de banco de dados por cabeçalho - VARCHAR, BOOLEAN, INTEGER, BIGINT, FLOAT, DOUBLE, DATE ou TIMESTAMP) e entries (linhas, cada uma um array de valores na ordem dos cabeçalhos), até 100 colunas e 50.000 entradas brutas em nível de linha por chamada (obrigatório). As entradas não devem ser pré-agregadas: envie uma linha por registro subjacente, e deixe que o dataFunction de cada gráfico calcule contagens, somas, médias e assim por diante no momento da renderização.
  • dashboard - de 1 a 40 widgets de nível superior, de cima para baixo (obrigatório). Cada widget é um dash_chart (um tipo de gráfico - area, bar, cell, dot, hexbin ou line - mapeamentos de coluna para x, y, d e r, um dataFunction opcional e um título opcional), uma dash_table, um bloco dash_text, um dash_spacer, ou um contêiner dash_stacker_hor/dash_stacker_ver. Empilhadores se aninham recursivamente - os próprios filhos de um empilhador podem incluir outros empilhadores - para organizar widgets em linhas e colunas de profundidade arbitrária. Quais tipos de coluna (categórica, contínua ou data/hora) cada dimensão x/y/d/r de cada tipo de gráfico aceita, e como o agrupamento temporal de uma coluna de data com seasonX/seasonY a torna categórica, está documentado em cada campo via tools/list e na página de formato de dados.
  • theme - cores opcionais em nível de dashboard (fundo, texto, destaques primário/sutil/secundário); qualquer widget ainda pode sobrescrever sua própria cor ou fundo
  • shared - se o dashboard pode ser visualizado por qualquer pessoa com o link (opcional, padrão false). Novos dashboards são privados até que você defina isso como true ou chame set_sharing posteriormente.

O resultado traz o dashboardId e o datasetId do novo dashboard (necessários posteriormente para add_data, get_dataset_schema, set_sharing e get_embed_code), além de seu url, viewUrl e trecho de incorporação iframe. Exemplo - criar um dashboard com um gráfico de barras e uma cor de destaque em nível de 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 - Retorna o nome, o status de compartilhamento, os IDs de dataset e os links de um dashboard. Parâmetro: dashboardId (obrigatório). Exemplo:

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 - Lista os dashboards da sua conta, ordenados pela última atualização, cada um com seu próprio datasetIds, para que um dataset possa ser passado diretamente para get_dataset_schema ou add_data sem uma chamada separada a get_dashboard. Parâmetros: limit e offset para paginação, query para um filtro de nome sem diferenciação entre maiúsculas e minúsculas (todos opcionais). Exemplo:

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 - Acrescenta entradas ao dataset de um dashboard existente; todo dashboard que usa esse dataset é atualizado automaticamente. Parâmetros:

  • dashboardId - o dashboard ao qual acrescentar (obrigatório)
  • entries - linhas alinhadas posicionalmente aos cabeçalhos do dataset, até 50.000 por chamada (obrigatório) - aplica-se a mesma regra de dados brutos em nível de linha de create_dashboard. Chame get_dataset_schema antes, caso ainda não conheça os nomes/ordem exatos das colunas do dashboard. Use isso para carregar datasets grandes em lotes ou para manter dashboards atualizados.
  • run_id - uma chave de idempotência opcional para esse lote específico (opcional). Se uma chamada anterior a add_data com o mesmo dashboardId e run_id já tiver sido bem-sucedida, chamar novamente retorna esse resultado anterior em vez de acrescentar as linhas uma segunda vez, de forma que um lote possa ser repetido com segurança após um timeout ou uma conexão interrompida - use um novo run_id para cada lote distinto (por exemplo, um UUID ou um hash do seu conteúdo).

Exemplo:

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 - Retorna os nomes e tipos das colunas de um dataset. Use-a antes de chamar add_data (ou de criar um novo gráfico sobre o mesmo dataset) sempre que os nomes/ordem/tipos exatos das colunas não forem previamente conhecidos, por exemplo em uma nova sessão ou quando outro agente criou o dashboard. Parâmetro: datasetId (obrigatório). Exemplo:

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 - Ativa ou desativa o link público de um dashboard. Desativá-lo revoga o acesso também a todas as revisões anteriores do dashboard, de forma que um link compartilhado no passado deixa de funcionar. Parâmetros: dashboardId e shared (ambos obrigatórios). Exemplo:

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 - Retorna o link de visualização compartilhável e um trecho de incorporação iframe para um dashboard - o mesmo link/código de incorporação que create_dashboard e set_sharing já retornam, para quando forem necessários novamente isoladamente. O link só funciona para outras pessoas enquanto o dashboard estiver compartilhado. Parâmetro: dashboardId (obrigatório). Exemplo:

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 - Informa quanto armazenamento a conta já utilizou e quanto ainda resta, útil antes de uma chamada a create_dashboard ou add_data grande o suficiente para arriscar o limite de armazenamento do plano. Sem parâmetros. Exemplo:

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
}

Limites e erros

  • O endpoint MCP aceita 25 requisições por minuto por cliente e corpos de requisição de até 25 MB - carregue datasets maiores em lotes de add_data.
  • Datasets aceitam até 100 colunas e 50.000 linhas por chamada, e um dashboard aceita até 40 widgets em cada nível de aninhamento. Dashboards armazenados contam para a cota de armazenamento do seu plano - chame storage_status para verificar a margem restante antes de uma chamada grande a create_dashboard ou add_data.
  • Códigos de status HTTP padrão são usados: 401 para credenciais ausentes ou inválidas (com um desafio WWW-Authenticate apontando para os metadados do recurso), 403 para credenciais revogadas ou insuficientes, 413 para requisições grandes demais e 429 em caso de limitação de taxa.