Sprucely title background

MCP APIs

Descripción general

Las MCP APIs de Sprucely.io exponen la plataforma de dashboards a asistentes de IA y software de terceros mediante el Model Context Protocol (MCP), un estándar abierto para conectar modelos de IA con herramientas a través de HTTP. Cualquier cliente compatible con MCP puede crear dashboards alojados, listarlos e inspeccionarlos, y añadirles datos de forma programática. Los paneles creados mediante las APIs pertenecen a tu cuenta y pueden compartirse, integrarse o seguir editándose en el servicio. Para integrar los paneles resultantes en tu propio sitio, consulta las notas de integración sencilla de paneles. Si usas Claude, la forma más rápida de empezar es el conector de Sprucely.io.

Conexión

El servidor MCP se sirve mediante Streamable HTTP en:

https://www.sprucely.io/mcp

Cualquier cliente MCP puede conectarse a este endpoint. Por ejemplo, un único comando registra el servidor en Claude Code:

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

También puedes llamar al servidor directamente con JSON-RPC 2.0 sobre HTTP. La mayoría de los clientes MCP completan automáticamente el protocolo de negociación (handshake); la siguiente solicitud lista las herramientas disponibles utilizando una clave 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"}'

Autenticación

Las solicitudes se autorizan mediante un encabezado Authorization Bearer estándar. Se admiten dos tipos de credenciales.

Claves de API - Crea claves de API en la sección de MCP de tu perfil. Las claves empiezan por spr_mcp_, se muestran una sola vez al crearlas y pueden revocarse en cualquier momento. Úsalas para scripts, servidores y clientes MCP sin interfaz gráfica.

OAuth 2.1 - Los clientes MCP interactivos pueden, en cambio, dejar que los usuarios inicien sesión con su cuenta de Sprucely.io mediante OAuth 2.1. El servidor de autorización admite el flujo de código de autorización con PKCE (obligatorio), tokens de actualización y registro dinámico de clientes, de modo que los clientes compatibles se configuran automáticamente a partir de los metadatos del recurso:

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

Ámbitos disponibles: openid, offline_access, dashboards:read y dashboards:write. Los ámbitos se aplican por herramienta: create_dashboard, add_data y set_sharing requieren dashboards:write y devuelven un error sin él. Las demás herramientas solo necesitan dashboards:read.

Para los clientes que requieren configuración manual, los endpoints del servidor de autorización son:

  • https://www.sprucely.io/oauth/.well-known/openid-configuration - metadatos del servidor de autorización
  • https://www.sprucely.io/oauth/auth - endpoint de autorización (PKCE obligatorio)
  • 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 - claves de firma (JWKS)
  • https://www.sprucely.io/oauth/token/revocation - revocación de tokens
  • https://www.sprucely.io/oauth/token/introspection - introspección de tokens

Herramientas

El servidor MCP expone ocho herramientas: create_dashboard, get_dashboard, list_dashboards, add_data, get_dataset_schema, set_sharing, get_embed_code y storage_status.

Los parámetros de dataset y dashboard que aparecen a continuación no son un formato específico de MCP: son exactamente el mismo JSON de dataset/dashboard documentado en la página de formato de datos y utilizado en el resto del servicio (la API de importación del runtime independiente integrable, los diseños generados por IA y el editor de paneles), así que todo lo escrito conforme a esa referencia también aplica aquí.

create_dashboard - Crea un dashboard alojado a partir de un dataset en línea y un árbol de widgets, y devuelve enlaces de visualización e inserción. Parámetros:

  • name - el título del dashboard (obligatorio)
  • dataset - el dataset a visualizar: name, headers (nombres de columna), types (un tipo de base de datos por encabezado - VARCHAR, BOOLEAN, INTEGER, BIGINT, FLOAT, DOUBLE, DATE o TIMESTAMP) y entries (filas, cada una un array de valores en el orden de los encabezados), hasta 100 columnas y 50.000 entradas sin procesar a nivel de fila por llamada (obligatorio). Las entradas no deben estar preagregadas: envía una fila por cada registro subyacente, y deja que el dataFunction de cada gráfico calcule conteos, sumas, promedios, etc. en el momento de renderizar.
  • dashboard - de 1 a 40 widgets de nivel superior, de arriba a abajo (obligatorio). Cada widget es un dash_chart (un tipo de gráfico - area, bar, cell, dot, hexbin o line - mapeos de columna para x, y, d y r, un dataFunction opcional y un título opcional), un dash_table, un bloque dash_text, un dash_spacer, o un contenedor dash_stacker_hor/dash_stacker_ver. Los apiladores se anidan de forma recursiva - los elementos secundarios de un apilador pueden incluir a su vez más apiladores - para organizar los widgets en filas y columnas de profundidad arbitraria. Qué tipos de columna (categórica, continua o temporal) acepta cada dimensión x/y/d/r según el tipo de gráfico, y cómo agrupar por tiempo una columna de fecha con seasonX/seasonY la convierte en categórica, está documentado en cada campo mediante tools/list y en la página de Formato de Datos.
  • theme - colores opcionales para todo el dashboard (fondo, texto, acentos primario/sutil/secundario); cualquier widget puede seguir anulando su propio color o fondo
  • shared - si el dashboard puede ser visto por cualquiera que tenga el enlace (opcional, por defecto false). Los paneles nuevos son privados hasta que se establece este valor en true o se llama después a set_sharing.

El resultado incluye el dashboardId y el datasetId del nuevo dashboard (necesarios después para add_data, get_dataset_schema, set_sharing y get_embed_code), además de su url, viewUrl y el fragmento de inserción iframe. Ejemplo - crear un dashboard con un gráfico de barras y un color de acento para todo el panel:

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 - Devuelve el nombre de un dashboard, su estado de uso compartido, los IDs de dataset y los enlaces. Parámetro: dashboardId (obligatorio). Ejemplo:

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 los dashboards de tu cuenta, ordenados por última actualización, cada uno con su propio datasetIds, de modo que un dataset se puede pasar directamente a get_dataset_schema o add_data sin necesidad de una llamada aparte a get_dashboard. Parámetros: limit y offset para la paginación, query para un filtro de nombre que no distingue mayúsculas de minúsculas (todos opcionales). Ejemplo:

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 - Añade entradas al dataset de un dashboard existente; todos los paneles que usan ese dataset se actualizan automáticamente. Parámetros:

  • dashboardId - el dashboard al que añadir los datos (obligatorio)
  • entries - filas alineadas por posición con los encabezados del dataset, hasta 50.000 por llamada (obligatorio) - se aplica la misma regla de datos sin procesar a nivel de fila que en create_dashboard. Llama primero a get_dataset_schema si no conoces ya los nombres/el orden exactos de las columnas del panel. Úsalo para cargar datasets grandes por lotes o para mantener actualizados los dashboards.
  • run_id - una clave de idempotencia opcional para este lote concreto (opcional). Si una llamada anterior a add_data con el mismo dashboardId y run_id ya se completó correctamente, volver a llamar devuelve ese resultado anterior en lugar de añadir las filas por segunda vez, de modo que un lote se puede reintentar de forma segura tras un tiempo de espera agotado o una conexión interrumpida - usa un run_id nuevo por cada lote distinto (por ejemplo, un UUID o un hash de su contenido).

Ejemplo:

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 - Devuelve los nombres y tipos de columna de un dataset. Úsalo antes de llamar a add_data (o de crear un nuevo gráfico sobre el mismo dataset) siempre que no conozcas ya los nombres/el orden/los tipos exactos de las columnas, por ejemplo en una sesión nueva o cuando otro agente creó el dashboard. Parámetro: datasetId (obligatorio). Ejemplo:

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 - Activa o desactiva el enlace público de un dashboard. Al desactivarlo también se revoca el acceso a todas las revisiones anteriores del panel, de modo que un enlace que se compartió en el pasado deja de funcionar. Parámetros: dashboardId y shared (ambos obligatorios). Ejemplo:

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 - Devuelve el enlace de visualización compartible y un fragmento de código iframe para insertar un dashboard - el mismo enlace/código de inserción que ya devuelven create_dashboard y set_sharing, para cuando se necesitan de nuevo por separado. El enlace solo funciona para otras personas mientras el panel esté compartido. Parámetro: dashboardId (obligatorio). Ejemplo:

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 de cuánto almacenamiento ha usado la cuenta y cuánto queda disponible, útil antes de una llamada a create_dashboard o add_data lo bastante grande como para arriesgar el límite de almacenamiento del plan. Sin parámetros. Ejemplo:

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
}

Límites y errores

  • El endpoint MCP acepta 25 solicitudes por minuto por cliente y cuerpos de solicitud de hasta 25 MB - carga los datasets más grandes en lotes con add_data.
  • Los datasets admiten hasta 100 columnas y 50.000 filas por llamada, y un dashboard admite hasta 40 widgets en cada nivel de anidamiento. Los paneles almacenados cuentan para la cuota de almacenamiento de tu plan - llama a storage_status para comprobar el margen disponible antes de una llamada grande a create_dashboard o add_data.
  • Se utilizan códigos de estado HTTP estándar: 401 si faltan credenciales o son inválidas (con un desafío WWW-Authenticate que apunta a los metadatos del recurso), 403 para credenciales revocadas o insuficientes, 413 para solicitudes de tamaño excesivo y 429 cuando se supera el límite de solicitudes.