Headless Tracker
Deja de construir paneles de portafolio: describe la vista que deseas y deja que Claude la renderice. Servidor MCP de solo lectura para Bybit, Binance, billeteras EVM, Solana y Polymarket.
Documentación
headless-tracker
🤖 Este proyecto está siendo desarrollado y mantenido de forma autónoma por Hex, un agente de desarrollo de IA. Registro de decisiones: decisions.md · Registro diario de compilación: daily-log.md · Hex en Bluesky · Equipo en solitario. Sin humanos en el bucle de desarrollo.
⚠️ No es asesoramiento financiero. HeadlessTracker es una herramienta de agregación de datos de cartera. Solo con fines informativos. Consulte DISCLAIMER.md para el texto completo.
Un servidor MCP de solo lectura que permite que tu host de IA (Claude Desktop, Claude Code, Cursor, ChatGPT) vea toda tu cartera de criptomonedas en exchanges, billeteras on-chain y mercados de predicción — sin darle nunca tus claves API, y sin capacidad de operar o mover fondos. Lee los números; no puede tocar el dinero.
↑ Lo que tu host de IA renderiza a partir de los datos de HeadlessTracker — una pregunta, seis plataformas, una vista. El servidor devuelve los números; el host dibuja la imagen. (Datos de muestra; la visual es lo que un host renderiza sobre la salida de la herramienta.)
↑ Y la entrada cruda: salida real de npx headless-tracker demo — seis plataformas, sin cuentas, sin claves API. Luego pregúntale a tu host de IA al respecto.
↑ Mismos datos, una pregunta diferente. Pregunta “¿cómo están mis posiciones?” y tu IA renderiza una vista de trader en su lugar. No hay un único panel — el host dibuja el que pidas. (Próximamente plantillas: contribuye con una vista, no con un conector.)
La tesis: los hosts de IA (Claude Desktop, Claude Code, Cursor, ChatGPT) generan paneles bajo demanda a partir de datos estructurados. Construir otra interfaz de tracker es trabajo desperdiciado en 2026 — no hay una única interfaz que construir, tu IA renderiza cualquier vista que pidas. Construye la capa de datos; deja que el host de IA sea el renderizador.
Estado: Listo para producción y disponible en npm (insignia de versión arriba). Seis conectores (Bybit, Binance, MetaMask/EVM, Solana, Hyperliquid, Polymarket), 15 herramientas MCP, un panel interactivo de múltiples pestañas, una CLI para consultas en terminal y una suite de 428 pruebas. Funciona con Node estándar (npx headless-tracker) o Bun, y funciona de extremo a extremo con Claude Desktop.
Lista completa de características
- 6 conectores: Bybit, Binance Spot+Futures, MetaMask multi-cadena + multi-billetera, Solana multi-billetera, Hyperliquid (perp + spot, solo dirección), Polymarket
- 15 herramientas MCP: 6 de datos + 7 de gestión de cuentas/tokens + 2 paneles de MCP App
- 3 prompts MCP (vistas):
portfolio-dashboard,weekly-review,risk-check— ver TEMPLATES.md, y contribuye con una vista - MCP App de panel interactivo: 3 pestañas (Cartera / Semanal / Riesgo) con gráficos de dona y barras, selector de moneda, botón de actualización
- MCP App de Configuración en vivo para configuración y administración
- Consultas de cartera por CLI:
show holdings / pnl / transactions(sin necesidad de Claude) - Listas de tokens ERC-20 personalizadas; FIFO + Costo Promedio en historial de transacciones
- Visualización multi-moneda (USD/EUR/GBP/HUF); precios spot e históricos de CoinGecko + Jupiter
- PnL por ventana de tiempo (
--timeframe=24h|7d|30d|ytd) - Suite de 428 pruebas; funciona con Node estándar o Bun
- Solo lectura y local-first: sin órdenes/retiros/transferencias; 4 de 6 conectores solo necesitan una dirección pública; los secretos viven en el llavero de tu sistema operativo y nunca entran en el contexto del modelo — ver SECURITY.md
Consulta ROADMAP.md para ver qué está hecho, qué sigue y qué está intencionalmente fuera de alcance.
Qué hace
Se conecta a tus cuentas (solo lectura), normaliza todo en un esquema único y lo expone como herramientas MCP. Luego le preguntas a Claude (o a cualquier host MCP):
- "¿Qué poseo?"
- "¿Cómo está dividida mi cartera entre cripto y mercados de predicción?"
- "Muestra mis posiciones de Polymarket agrupadas por evento."
- "Actualiza Bybit y dime mi P&L de BTC."
El host de IA genera el gráfico, la tabla, el desglose. No construyes una interfaz.
Pruébalo en 60 segundos (sin claves API)
La versión sin configuración — un comando, sin cuentas, sin claves, ni siquiera una dirección. Ve una cartera de muestra completa (cinco plataformas; cripto + efectivo + mercados de predicción) renderizada exactamente como la recibe tu host de IA:
npx headless-tracker demo
account symbol class qty value price
────────────────────── ─────────────────── ────────── ──────── ─────── ───────
bybit:UNIFIED BTC crypto 0.420000 $25704 $61200
binance:spot SOL crypto 95.0000 $14440 $152.00
metamask:0xd8d2…f1a3 WBTC crypto 0.150000 $9150 $61000
solana:7vfC…Wd9k JUP crypto 1800.00 $1656 $0.9200
polymarket:0x9c1a…7b20 RATE-CUT-2026 (YES) prediction 1500.00 $930.00 $0.6200
…
Total: $104126 (15 positions across 5 venues)
Allocation by asset class:
crypto $88024 84.5% ████████████████████
cash $14900 14.3% ███
prediction $1202 1.2% █
También imprime las preguntas en inglés sencillo que le harías a Claude ("¿qué poseo en todo?", "¿cómo está dividido?") mapeadas a la herramienta MCP que responde cada una. Cuando quieras tus propios números, es el mismo bucle con una dirección real o una clave de solo lectura:
No deberías tener que entregar tus claves de exchange a una herramienta nueva solo para saber si es buena. Solana, Hyperliquid y Polymarket leen direcciones on-chain públicas, así que puedes apuntar HeadlessTracker a cualquier billetera que puedas ver (la tuya incluida) con cero credenciales. (Hyperliquid es completamente sin claves — posiciones perp, equidad de cuenta y saldos spot se leen solo de la dirección desde la que operas.)
# install (or prefix any command with `npx`)
npm install -g headless-tracker
# add a public Solana wallet: no API key, just the address
headless-tracker setup solana
# Solana address (base58): <paste any public address>
# (press ENTER through the optional RPC + dust prompts)
# print the holdings right in your terminal, no Claude required
headless-tracker show holdings
account symbol class qty value price
───────────────── ────── ────── ──────── ─────── ────────
solana:7Xk2…q9Fa SOL crypto 12.4081 $2604 $209.88
solana:7Xk2…q9Fa USDC crypto 540.0000 $540.00 $1.00
solana:7Xk2…q9Fa JUP crypto 1200.00 $612.00 $0.5100
Total: $3756 (3 positions across 1 accounts)
(Ejemplo de salida; el id de cuenta está acortado aquí por ancho. Tus números provienen de la cadena en vivo.)
Ese es el bucle completo: instalar, apuntar a una dirección pública, ver tenencias normalizadas. Cuando quieras tus cuentas privadas (Bybit, Binance), setup también. Cada conector usa credenciales de solo lectura, guardadas en el llavero de tu sistema operativo, nunca escritas en disco y nunca enviadas a ningún lugar excepto a la API del propio exchange. Luego conéctalo a Claude y pregunta "¿qué poseo?" para obtener los mismos datos como un panel nativo de chat.
Configuración no interactiva (scripts, Docker, CI)
setup también funciona sin prompts — pasa banderas y guarda cualquier secreto en una variable de entorno (nunca en la línea de comandos, para que no quede en el historial de tu shell):
# public-address connectors: everything via flags, zero secrets
headless-tracker setup solana --address=<base58> --dust=0.5
headless-tracker setup hyperliquid --address=0x... # perp + spot, no key
headless-tracker setup polymarket --proxy-wallet=0x...
# connectors with a secret: non-secret config via flags, secret via env
HT_SETUP_ETHERSCAN_KEY=… headless-tracker setup metamask --address=0x... --chains=1,137
HT_SETUP_API_KEY=… HT_SETUP_API_SECRET=… headless-tracker setup bybit --account-type=UNIFIED --also=FUND
Sin llavero / sin llavero del SO (Docker, WSL, muchos servidores Linux, CI): no hay un Secret Service al que escribir, así que setup registra la cuenta e imprime la variable de entorno exacta HEADLESS_TRACKER_<CONNECTOR>_<ACCOUNT> a configurar con un objeto JSON de credenciales — p. ej. HEADLESS_TRACKER_SOLANA_<ADDR>='{"address":"…","dustThresholdUsd":0.5}'. Configúrala en el entorno de tu servidor MCP y las herramientas de datos leerán las credenciales de ahí. Nada se escribe nunca en disco.
Panel interactivo (panel de UI en vivo)
Para hosts que admiten MCP Apps — Claude Desktop, ChatGPT, Goose, VS Code — di:
Muestra mi panel
El host renderiza un iframe en sandbox en el panel de chat con tres pestañas en vivo:
- Cartera — KPIs de valor total, tabla de posiciones principales, dona de asignación por símbolo (top 7 + cola "Otros"), advertencias + fallos
- Semanal — KPIs de delta de ventana de 7 días, tabla de operaciones recientes, divulgación de símbolos omitidos (con razones)
- Riesgo — auditoría de concentración (posición única, plataforma, reserva de stablecoin, sobrepeso en mercados de predicción) calificada como PASS / WARN / ALERT, dona por plataforma
Además, un selector de moneda (USD / EUR / GBP / HUF) y un botón de actualización. El iframe hace sus propias llamadas de herramientas de seguimiento mientras el usuario hace clic en las pestañas — sin necesidad de prompts adicionales una vez abierto. Argumentos opcionales:
Abre el panel en HUF, pestaña semanal
Implementación: src/mcp/apps/dashboard/ (TS del lado del navegador empaquetado en un solo dist/mcp-apps/dashboard.html mediante bun run build:apps, se distribuye con el paquete). El artefacto empaquetado se incluye dentro del paquete npm para que los usuarios que ejecutan npx headless-tracker no necesiten un paso de compilación.
Si tu host aún no renderiza MCP Apps, la herramienta render_dashboard sigue devolviendo una confirmación textual. Usa el recetario de prompts a continuación como alternativa — mismos flujos de trabajo, mismos datos, solo sin panel de UI en vivo.
Panel de configuración (UI en vivo para configuración + administración)
Para una configuración que no te lleve a una terminal, pregunta:
Abrir configuración
La MCP App de Configuración se abre con cuatro pestañas:
- Cuentas — lista de cuentas configuradas con un botón Eliminar (diálogo de confirmación de una vía; elimina tanto del llavero del SO como del registro).
- Agregar Cuenta — formularios para Bybit / Binance / MetaMask / Solana / Hyperliquid / Polymarket. Cada formulario valida contra la API upstream antes de persistir las credenciales. Divulgación de seguridad explícita en la parte superior: las credenciales enviadas a través del formulario transitan el proceso de Claude Desktop en ruta al llavero. Los seis conectores usan credenciales DE SOLO LECTURA por diseño (Bybit "Read" solamente, sin Withdraw; Binance "Enable Reading" solamente, sin Trade o Withdraw; Etherscan es un token de límite de tasa de datos públicos; la billetera proxy de Polymarket ya es pública; las direcciones de Solana y Hyperliquid son identificadores on-chain públicos — Hyperliquid no necesita clave ni firma en absoluto). Fuga en el peor caso = lectura de cartera, nunca movimiento de fondos. Para confianza cero, el flujo CLI (
bun run setup <connector>) sigue disponible. - Billeteras — agrega una dirección de billetera adicional a una cuenta existente de MetaMask O Solana (multi-billetera bajo una cuenta MCP, compartiendo la misma clave/selector de cadena de Etherscan o URL RPC).
- Tokens Personalizados — lista / agrega / elimina tokens ERC-20 por cadena. Los datos de tokens son públicos on-chain; sin participación del llavero.
Cualquier ruta (CLI o UI de Configuración) escribe en el mismo ~/.headless-tracker/cache.db + llavero del SO, así que las cuentas creadas por cualquiera de las dos aparecen de inmediato en el panel y en la CLI.
Inicio rápido
1. Instalar
Sin clonar, sin paso de compilación, sin necesidad de Bun. El paquete funciona con Node estándar (≥ 22.5) o Bun. Instálalo globalmente:
npm install -g headless-tracker
O ejecuta cualquier comando sin instalar prefijando npx, p. ej. npx headless-tracker setup solana. (Compilar desde el código fuente para desarrollo usa Bun — ver Desarrollo.)
2. Configura tus cuentas (interactivo)
Ejecuta la configuración para cada integración que quieras. Cada una solicita credenciales, las valida y las almacena en el llavero de tu sistema operativo (Llavero de macOS, Secret Service de Linux, Credential Vault de Windows). En una máquina sin llavero, consulta Sin llavero / sin llavero del SO a continuación.
headless-tracker setup bybit
headless-tracker setup binance
headless-tracker setup metamask
headless-tracker setup solana
headless-tracker setup polymarket
Verifica lo configurado:
headless-tracker list-accounts
Sin llavero / sin llavero del SO (Docker, WSL, servidores, CI)
El llavero del SO necesita un servicio de secretos en ejecución (Secret Service / D-Bus en Linux, Llavero en macOS, Credential Vault en Windows). Muchos entornos reales no tienen uno: un contenedor Docker, WSL, un servidor Linux básico, un trabajo de CI. Allí, la escritura en el llavero falla.
En ese caso setup no aborta. Aún registra la cuenta y luego imprime la variable de entorno exacta a configurar, por ejemplo:
⚠ OS keychain unavailable, so credentials were NOT stored (...). The account is
registered. ... set the HEADLESS_TRACKER_SOLANA_<ADDR> environment variable to a
JSON object in your MCP server's env, then restart.
Configura esa variable con el JSON de credenciales del conector en el bloque env de tu servidor MCP (o en tu shell), luego reinicia. La variable de entorno siempre tiene prioridad sobre el llavero, así que esto también funciona como una anulación explícita. Formas JSON por conector (usa claves API de solo lectura — consulta la nota de seguridad en la sección del panel de Configuración):
| Conector | Variable de entorno (impresa por setup) | Valor JSON |
|---|---|---|
| Bybit | HEADLESS_TRACKER_BYBIT_<ACCOUNTTYPE> | {"apiKey":"...","apiSecret":"...","accountType":"UNIFIED"} |
| Binance | HEADLESS_TRACKER_BINANCE_KEY_<FIRST6> | {"apiKey":"...","apiSecret":"...","includeFutures":false} |
| MetaMask | HEADLESS_TRACKER_METAMASK_0X<ADDR> | {"address":"0x...","etherscanApiKey":"...","chainIds":[1],"trackCommonTokens":true,"hasEtherscanPro":false} |
| Solana | HEADLESS_TRACKER_SOLANA_<ADDR> | {"address":"<base58>"} (opcional "rpcUrl", "dustThresholdUsd") |
| Hyperliquid | HEADLESS_TRACKER_HYPERLIQUID_0X<ADDR> | {"address":"0x..."} (opcional "dustThresholdUsd") |
| Polymarket | HEADLESS_TRACKER_POLYMARKET_0X<ADDR> | {"proxyWallet":"0x...","sizeThreshold":0.01} |
El nombre de la variable se deriva del identificador de cuenta (setup imprime la cadena exacta, para que no tengas que construirla a mano). Ejemplo para un bloque env de configuración de Claude Desktop / MCP:
"env": {
"HEADLESS_TRACKER_SOLANA_<ADDR>": "{\"address\":\"<base58 address>\"}"
}
Opcional: tiempo de espera de solicitud
Cada consulta por cuenta está limitada por un plazo (30s por defecto) para que un upstream colgado nunca pueda bloquear una llamada de herramienta: se degrada a un fallo network_timeout para esa cuenta mientras el resto devuelve resultados. Anúlalo con HEADLESS_TRACKER_REQUEST_TIMEOUT_MS (por ejemplo, súbelo si rastreas muchas cadenas EVM en una sola cuenta de MetaMask y ves timeouts espurios).
3. Conecta Claude Desktop
Edita tu claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"headless-tracker": {
"command": "npx",
"args": ["-y", "headless-tracker"]
}
}
}
Esa es toda la configuración: sin rutas absolutas, sin ubicación de clonado, sin Bun. npx -y headless-tracker sin subcomando inicia el servidor MCP sobre stdio (npx cachea después de la primera ejecución). Si instalaste globalmente con npm i -g headless-tracker, puedes usar "command": "headless-tracker" sin args en su lugar.
Reinicia Claude Desktop (Cmd+Q y vuelve a abrir; la "nueva conversación" dentro de la app no recarga la configuración).
4. Pruébalo
Abre una nueva conversación en Claude Desktop:
¿Qué hay en mi cartera?
¿Cómo está dividida mi cartera entre cripto y mercados de predicción?
Muestra mis posiciones de Polymarket ordenadas por valor actual.
Si Claude no ve las herramientas, revisa ~/Library/Logs/Claude/mcp-server-headless-tracker.log.
5. Usa el panel interactivo (MCP App)
Una vez que la configuración funcione, pregunta:
Muestra mi panel
El panel de UI en vivo aparece en el chat. Consulta la sección Panel interactivo más arriba para ver qué hay en cada pestaña y cómo pasar argumentos.
6. Usa los prompts predefinidos (paneles de un clic)
El servidor MCP incluye tres plantillas de prompt. Aparecen en el selector de prompts de Claude Desktop (el menú / o de adjuntos, según la versión) y en Claude Code como comandos de barra. Cada uno guía a Claude a través de un flujo de trabajo específico con múltiples herramientas:
| Prompt | Qué hace |
|---|---|
portfolio-dashboard | Llama a get_holdings + get_allocations + get_pnl + get_polymarket_positions en paralelo y renderiza un panel completo de múltiples secciones (artefacto HTML cuando es compatible). |
weekly-review | Delta de ventana de 7 días + mayores movimientos + transacciones recientes + una observación. La advertencia de aproximación se presenta con honestidad (cesta actual a precios históricos, NO transacciones dentro de la ventana). |
risk-check | Concentración / venue / reserva de stablecoin / sobreponderación en mercados de predicción / concentración por cadena. Cada dimensión se puntúa como PASS / WARN / ALERT con los porcentajes reales. |
También puedes pegar cualquiera de estos prompts directamente: son texto plano. Consulta el cookbook a continuación.
Cookbook de prompts
Copia y pega estos en cualquier cliente compatible con MCP. Cada uno espera que el servidor MCP headless-tracker esté configurado. Ninguno requiere código nuevo en el lado del servidor.
Rápido "¿dónde estoy parado?"
Construye un panel completo de mi cartera. Llama a get_holdings, get_allocations (por asset_class y por symbol), get_pnl y get_polymarket_positions en paralelo y sintetiza un único artefacto de panel. Muestra las 10 posiciones principales, el desglose por clase de activo y el PnL total. Sé honesto sobre los campos NULL: no inventes.
Rápido "¿cómo fue esta semana?"
Dame un resumen de 7 días. Llama a get_pnl con timeframe=7d, get_holdings y get_transactions con since=7d. Muestra windowDelta con la advertencia de aproximación ("cesta actual a precios históricos, no transacciones dentro de la ventana"), lista las transacciones por exchange y termina con una observación breve sobre qué impulsó el cambio.
Rápido "¿debería preocuparme?"
Haz una verificación de riesgo de mi cartera. Llama a get_holdings y get_allocations (por symbol, por asset_class, por connector). Puntúa cada uno: concentración de posición única (ALERT > 40%), concentración de venue (ALERT > 70%), reserva de stablecoin (WARN < 5%, ALERT = 0%), prediction-market overweight (WARN > 15%). Salida como tabla de Markdown.
Temporada de impuestos
Necesito hacer mis impuestos. Llama a get_transactions para el último año (since=365d). Luego llama a get_pnl con include_history=true y method=fifo. Agrupa el PnL realizado por symbol y por mes. Marca cualquier venta con base de costo desconocida (depósitos/transferencias sin precio): esos son vacíos honestos que tendré que investigar por separado.
Vista en HUF (o EUR / GBP)
Muestra mi cartera en florines húngaros. Llama a get_holdings con currency=HUF. Ordena por valor descendente. Suma el total en HUF y dime si la fuente de FX fue la API en vivo o el fallback estático.
Revisión de apuestas en Polymarket
Guíame a través de mis posiciones de Polymarket. Llama a get_polymarket_positions con group_by_event=true. Luego llama a get_pnl con include_history=true para obtener el PnL realizado vía FIFO sobre /trades. Para cada evento, muestra: título, mis tenencias de resultado, valor actual, PnL realizado hasta ahora y fecha de fin. Marca cualquier posición canjeable que deba reclamar.
Consultas rápidas de cartera desde la CLI (sin necesidad de Claude)
Para la pregunta de 3 segundos "¿qué hay en mi cartera?" sin abrir Claude Desktop:
headless-tracker show holdings
headless-tracker show pnl
headless-tracker show transactions --since=7d
Cada uno imprime una tabla de texto. Los filtros funcionan: show holdings --account-id=bybit:UNIFIED, show holdings --asset-class=crypto, show transactions --since=24h --account-id=metamask:0xabc.
Visualización multi-moneda
show holdings usa USD por defecto. Pasa --currency= para valores convertidos con FX en vivo:
headless-tracker show holdings --currency=HUF
headless-tracker show holdings --currency=EUR
Las tasas de FX provienen de una API pública gratuita (exchangerate-api.com) con frankfurter.dev como fallback, más un fallback estático si ambos fallan (que aparece como advertencia para que sepas que los números mostrados pueden estar desactualizados por unos pocos puntos porcentuales). Compatibles: USD, EUR, GBP, HUF.
Métodos de base de costo (FIFO vs Promedio)
Para un P&L realizado honesto basado en tu historial de transacciones (no en metadatos del conector que pueden mezclar realizado + no realizado para mercados de predicción):
headless-tracker show pnl --include-history=true
headless-tracker show pnl --include-history=true --method=average
--method=fifo (por defecto): consume el lote más antiguo primero por cada venta.
--method=average: agrupa todas las adquisiciones con precio; vende al promedio ponderado en ejecución.
Ambos métodos preservan la regla del "desconocido honesto": los tokens recibidos por transferencia entrante de wallet (sin precio) producen realizedPnl: null para cualquier venta que los use — NO un número inventado. El PnL realizado cuenta solo ventas cuyos lotes consumidos tenían base de costo conocida.
PnL por ventana de tiempo
headless-tracker show pnl --timeframe=7d
headless-tracker show pnl --timeframe=24h
headless-tracker show pnl --timeframe=ytd
Valora tu cesta actual a precios históricos de CoinGecko y reporta el delta vs. ahora. Aproximación: NO tiene en cuenta transacciones dentro de la ventana — responde "si hubiera mantenido esta cesta exacta hace N días, ¿cuánto he ganado?". Las posiciones de Polymarket y cripto sin mapeo en CoinGecko se omiten (contadas en skippedSymbols). La granularidad histórica gratuita de CoinGecko es diaria, así que --timeframe=24h es "cierre de ayer vs. ahora".
Tokens ERC-20 personalizados
La lista de tokens de MetaMask incluida cubre USDC, USDT, WETH, WBTC, LINK, DAI. Para rastrear tokens específicos de proyectos:
headless-tracker token add metamask:0xabc 1 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 USDC 6
headless-tracker token list
headless-tracker token remove metamask:0xabc 1 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Los tokens personalizados se almacenan por cuenta en el almacén de cuentas SQLite (NO en el llavero: son identificadores públicos en cadena, no secretos).
Integraciones compatibles
| Conector | Autenticación | Estado | Notas |
|---|---|---|---|
| Bybit V5 | Clave API + secreto | ✓ Completo | Cuentas UNIFIED / SPOT / CONTRACT / FUND. Clave de solo lectura. |
| Binance | Clave API + secreto | ✓ Tenencias | Cuenta Spot (/api/v3/account) + wallet/posiciones de Futuros opcional (/fapi/v2/account). Clave de solo lectura (solo "Enable Reading"). Stablecoins valoradas a $1; activos no estables valorados vía lote /api/v3/ticker/24hr?type=MINI. Las posiciones abiertas de futuros aparecen como Tenencias separadas con lado/apalancamiento/PnL/liquidación en metadatos. El historial de transacciones es ok([]) para v0.13 — diferido. Solo binance.com (binance.us diferido). |
| MetaMask / wallets EVM | Clave API de Etherscan V2 | ✓ Completo | Una sola clave cubre Ethereum, Polygon, BSC, Base, Arbitrum, Optimism. Tokens nativos + ERC-20 comunes incluidos (USDC, USDT, WETH, WBTC, LINK, DAI) para saldos; transferencias nativas + ERC-20 para transacciones. Listas de tokens personalizados vía headless-tracker token add .... Multi-wallet por cuenta (una clave de Etherscan, múltiples direcciones). BSC/Base requieren Etherscan Pro en el nivel gratuito (se omiten automáticamente con advertencia en caso contrario). |
| Polymarket | Dirección de wallet proxy (sin clave API) | ✓ Completo | Usa la data-api pública. Posiciones + historial de transacciones BUY/SELL (hasta ~1000 más recientes) vía /trades?user=PROXY. Las posiciones de pérdida liquidada (mercados resueltos por $0 que la data-api aún devuelve) se filtran con un umbral de polvo basado en valor (dustThresholdUsd, por defecto $0.01). |
| Wallets Solana | Dirección Base58 (sin clave API) | ✓ Tenencias | RPC pública de Solana + Jupiter Price API v2. SOL nativo + tokens SPL (programa Token v1; Token-2022 diferido). Multi-wallet por cuenta, URL RPC premium opcional (Helius/QuickNode/Triton) para usuarios que rastrean 3+ wallets. Metadatos fijos para mints principales (USDC/USDT/mSOL/JUP/JTO/PYTH/BONK/RNDR/WIF/JLP). El historial de transacciones es ok([]) para v0.12 — llega en v0.14 con RPC premium opt-in. |
| Hyperliquid | Dirección EVM (sin clave API, sin firma) | ✓ Completo | Endpoint público info. El equity de la cuenta Perp se reporta como el valor neto en USD de la cuenta (colateral + PnL no realizado); las posiciones abiertas de perp aparecen como Tenencias separadas con tamaño con signo, nocional, PnL no realizado, precio de entrada/liquidación y apalancamiento en metadatos — su nocional deliberadamente no se suma al patrimonio neto (sobreestimaría una cuenta apalancada). Los saldos Spot se valoran vía pares USDC de spotMetaAndAssetCtxs; USDC = $1, tokens sin precio se filtran por polvo. Historial de transacciones vía fills recientes (userFills, hasta 2000). Multi-dirección por cuenta. |
Para agregar un nuevo conector, implementa Connector desde src/connectors/types.ts y agrégalo a CONNECTOR_FACTORIES en src/mcp/orchestrator.ts. ~150-400 líneas de código por conector según los seis existentes (depende de si la API upstream es REST/SDK/RPC y qué tan rica es la forma de la respuesta).
Herramientas MCP expuestas
| Herramienta | Propósito | Prompts comunes |
|---|---|---|
get_holdings | Tenencias actuales en todas las cuentas | "qué poseo", "muestra mi cartera", "posiciones actuales" |
get_pnl | Resumen agregado de ganancias/pérdidas | "cómo me va", "cuál es mi P&L", "estoy arriba o abajo" |
get_polymarket_positions | Especializado en Polymarket, agrupado por evento | "muestra mis apuestas de Polymarket", "apuestas electorales" |
get_transactions | Historial de transacciones con filtro since | "muestra mis transacciones recientes", "transacciones esta semana" |
get_allocations | Desglose por grupo (clase de activo / conector / cadena / símbolo) | "cómo está dividida mi cartera", "posiciones más grandes" |
refresh_data | Forzar invalidación de caché | "refresca", "obtén lo más reciente", "trae ahora" |
Las herramientas de datos aceptan un filtro opcional account_id (por ejemplo, metamask:0xabc..., bybit:UNIFIED). Sin filtro, consultan todo.
Gestión de cuentas y configuración (todas las escrituras de credenciales son claves API de solo lectura almacenadas en el llavero del sistema operativo):
| Herramienta | Propósito |
|---|---|
setup_connector | Configurar un conector escribiendo credenciales de solo lectura en el llavero del sistema operativo |
list_accounts | Listar cuentas configuradas sin exponer credenciales |
add_wallet_address | Agregar otra dirección de wallet a una cuenta existente de MetaMask o Solana |
remove_account | Eliminar una cuenta y sus credenciales del llavero |
add_custom_token | Rastrear un token ERC-20 específico de proyecto en una cuenta de MetaMask |
remove_custom_token | Dejar de rastrear un token ERC-20 personalizado (datos públicos en cadena, sin llavero) |
list_custom_tokens | Listar los tokens ERC-20 personalizados rastreados por cuenta de MetaMask |
Paneles de MCP App (UI interactiva renderizada en el chat):
| Herramienta | Propósito |
|---|---|
render_dashboard | Panel de dashboard interactivo: tenencias, P&L, asignaciones, mercados de predicción |
render_settings | Panel de configuración: una alternativa GUI al flujo de configuración CLI |
Por qué local-first
- Las claves API nunca salen de tu máquina. Almacenadas en el llavero de tu sistema operativo mediante
@napi-rs/keyring. - La caché es SQLite local (el controlador integrado del runtime:
node:sqliteen Node,bun:sqliteen Bun). Sin servidor, sin SaaS, sin pings de analítica. - Sin telemetría por defecto. El informe de errores es estrictamente opcional: solo hace algo si tú configuras un
SENTRY_DSN, y aun así nunca envía datos de cartera — ni montos, saldos, direcciones de billetera, claves API ni etiquetas de cuenta, solo la clase de error y un mensaje/pila depurado más qué conector falló. Consulta decisions.md (2026-06-06) para los detalles. - Solo lectura por diseño. Sin firma de transacciones. Nada de lo que esta herramienta puede hacer puede hacerte perder dinero.
- TTL de caché por conector (billeteras cripto 60s, exchanges 120s, Polymarket 30s) mantiene las cosas rápidas sin golpear las APIs ascendentes.
Arquitectura
┌────────────────────────────┐
│ headless-tracker │
│ (Node or Bun) │
│ ──────────────────────── │
│ src/connectors/ │
│ bybit.ts │
│ metamask.ts │
│ polymarket.ts │
│ src/types.ts (schema) │
│ src/cache.ts (SQLite) │
│ src/vault.ts (keyring) │
│ src/accounts.ts (registry)│
│ src/mcp/orchestrator.ts │ ← parallel fan-out + in-flight Promise dedup
│ src/mcp/server.ts │ ← McpServer + 15 tools
│ ▲ │
│ │ stdio MCP │
└───────┼────────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌──────▼──────┐ ┌─────▼─────┐ ┌──────▼──────┐
│Claude Desktop│ │Claude Code│ │ Cursor/Codex│
│ ChatGPT │ │ │ │ ZED, etc. │
└──────────────┘ └───────────┘ └─────────────┘
Ejemplos de prompts y respuestas
El objetivo de headless-tracker es que no escribas SQL ni aprendas una CLI — le preguntas a Claude. Algunas sesiones de ejemplo:
"¿Qué poseo?"
Claude llama a
get_holdings({})y devuelve un desglose formateado: "Actualmente tienes 0.5 BTC ($30,000), 2 ETH ($5,000) en Bybit, más 1 ETH en tu billetera MetaMask, y una posición en Polymarket sobre las elecciones de 2024 valorada en $60. Valor total de la cartera: ~$35,060."
"Muestra mis apuestas de Polymarket agrupadas por evento."
Claude llama a
get_polymarket_positions({ group_by_event: true })y renderiza una tabla agrupada por evento con título, tus tenencias de resultados Sí/No, valor total del evento y P&L en efectivo combinado por evento.
"¿Cómo estoy dividido entre cripto y mercados de predicción?"
Claude llama a
get_allocations({ by: "asset_class" })y devuelve un desglose porcentual: "97.5% cripto ($35,000), 2.5% predicción ($1,000)."
"Actualiza mis datos y muestra las tenencias más recientes."
Claude llama a
refresh_data({})y luego aget_holdings({})— la caché se invalida, se obtienen datos frescos de todas las APIs ascendentes en paralelo, y Claude renderiza el nuevo estado.
"Dame un panel de cartera completo."
Claude llama a múltiples herramientas en paralelo (
get_holdings,get_allocations,get_pnl,get_polymarket_positions) y sintetiza un panel de múltiples secciones. La deduplicación de Promises en vuelo del orquestador asegura que cada conector se llame como máximo una vez incluso cuando el abanico es amplio.
Desarrollo
Compilar desde el código fuente usa Bun 1.3+. Los usuarios finales no necesitan esto — consulta Inicio rápido.
git clone https://github.com/tamasPetki/HeadlessTracker.git
cd headless-tracker
bun install
bun test # 377 tests, ~5s
bun run typecheck # bun --bun tsc --noEmit
bun run build:apps # bundle the dashboard MCP App into dist/mcp-apps/
bun run build # build the Node-runnable dist/ (what npm ships)
bun run start # start MCP server on stdio (debug only)
bun run setup bybit # interactive credential setup
Para añadir un conector, sigue el patrón existente en src/connectors/. La interfaz Connector impone un manejo de errores uniforme Result<T> en todas las integraciones — no hay ruta de lanzamiento de excepciones para fallos esperados (autenticación, límite de tasa, red).
Preguntas frecuentes
¿Se enviarán mis claves API a algún lugar? No. Están almacenadas en el llavero de tu sistema operativo y solo se envían a la API ascendente para la que son (la API de Bybit para claves de Bybit, la API de Etherscan para claves de Etherscan). El servidor MCP se ejecuta completamente en tu máquina.
Polymarket tiene mis posiciones pero Claude no puede verlas.
Asegúrate de haber usado tu dirección de billetera proxy de Polymarket, no tu dirección de MetaMask. Encuéntrala en la interfaz de Polymarket en Configuración → Billetera. Vuelve a ejecutar setup polymarket si usaste la incorrecta.
Bybit devuelve auth_failed. Verifica que la clave API tenga permisos de Lectura de Billetera + Lectura de Trading (NO se necesita Retiro). Si configuraste una lista blanca de IP en la clave, asegúrate de que la IP pública actual de tu máquina esté en ella.
Etherscan devuelve rate_limited. El nivel gratuito es de 5 llamadas/seg, 100k/día. Cada actualización de MetaMask cuesta (1 + N tokens) llamadas por cadena. Si tienes 4 cadenas × 7 tokens comunes, eso son 32 llamadas por actualización. Distribuye tus solicitudes de actualización; el TTL de caché (60s para MetaMask) está ahí por una razón.
¿Puedo usar esto sin Claude Desktop?
Sí — cualquier host compatible con MCP funciona (Claude Code, Cursor, Codex, ZED, ChatGPT una vez que su soporte MCP se estabilice). Conéctalo de la misma manera; solo cambia qué archivo de configuración de cliente editas. También hay una CLI (headless-tracker show holdings/pnl/transactions) para consultas de terminal que no necesitan un host de IA en absoluto.
El P&L realizado parece incorrecto.
Para Polymarket, el get_pnl por defecto devuelve realizedPnl: null porque el campo cashPnl del conector mezcla realizado + no realizado. Pasa include_history=true (o --include-history=true desde la CLI) para obtener el número honesto calculado con FIFO sobre tu historial de /trades. Para MetaMask, los tokens transferidos en cadena no tienen una base de costo conocida — include_history=true los reporta como unknownSalesCount en lugar de inventar $0.
¿Puede una cuenta de MetaMask rastrear múltiples billeteras?
Sí. v0.8 añadió addresses[] a las credenciales de MetaMask. La CLI de configuración aún pide una billetera (compatibilidad hacia atrás), pero el conector acepta una lista. Edita la entrada del vault directamente para añadir más direcciones a la misma cuenta, compartiendo la misma clave de Etherscan + selección de cadena. Un comando CLI wallet add está en la lista de v0.9 si hay demanda.
¿Esto soporta [mi exchange / cadena / mercado favorito]? Todavía no. Abre un issue o PR. La interfaz de Connector está abierta para extensión y los 3 conectores existentes son implementaciones de referencia que suman ~600 líneas.
¿Qué hay del historial de transacciones para Polymarket?
Soportado desde v0.7.1: get_transactions devuelve operaciones de COMPRA/VENTA desde el endpoint público de data-api /trades?user=PROXY, hasta ~1000 de las más recientes. La data-api ignora los parámetros de consulta con límite de tiempo, por lo que el filtro since se aplica en el lado del cliente; la paginación termina temprano una vez que una página cae antes del corte.
¿Por qué no hay interfaz de usuario? Claude Desktop, ChatGPT y Cursor generan paneles más ricos bajo demanda de lo que yo enviaría en v1. Construir una interfaz duplica trabajo que el host de IA ya hace mejor. Si quieres una interfaz web alojada, consulta bulltrapp.com.
Relacionados
bulltrapp.com — un rastreador de cartera web alojado por el mismo mantenedor. Mismo espacio de problema, diferente superficie. Usa uno o ambos.
Licencia
MIT