Construyendo granola-cli: Notas de Reuniones con IA en tu Terminal
Aviso: Este proyecto es una herramienta de código abierto independiente y no está afiliada, respaldada ni conectada con Granola.ai.
¿Y si pudieras consultar tu historial de reuniones como una base de datos? granola-cli trae tus notas de reuniones de Granola.ai a la línea de comandos—busca en transcripciones, exporta a JSON, y canaliza tareas directamente a Claude Code o tu gestor de tareas.
¿Qué es Granola?
Granola es un asistente de reuniones con IA que se integra en tu barra de menú. Graba el audio del sistema, transcribe localmente y usa LLMs para producir resúmenes estructurados: decisiones clave, tareas, puntos de discusión. No hay bots uniéndose a tus llamadas, ni notificaciones incómodas de "Granola está grabando" para tus compañeros. En Buffer, se ha convertido en una herramienta diaria para nuestro equipo.
Las notas que genera son excelentes. Pero llegué a un límite.
El Problema que Necesitaba Resolver
Quería datos en crudo en mi terminal. Quería alimentar las sincronizaciones de ingeniería de la semana pasada a Claude Code para planificar mi próximo sprint. Quería buscar en transcripciones o canalizar tareas directamente a mi gestor de tareas.
Copiar y pegar desde una interfaz web no bastaba. Encontré la investigación de Joseph Thacker sobre ingeniería inversa de la API de Granola, más el repositorio getprobo/reverse-engineering-granola-api. El trabajo base existía. Una CLI adecuada para uso diario, no.
Así que construí una.
Cómo Mapeé la API de Granola
La aplicación de escritorio de Granola almacena tokens de autenticación en un archivo JSON local. La CLI lee estas credenciales, las guarda de forma segura en el keychain de tu sistema mediante cross-keychain (sobre el cual escribí anteriormente), y las usa para llamar a las APIs internas de Granola.
Endpoints clave que mapeé:
POST /v2/get-documents— listar reuniones con paginación por cursorPOST /v1/get-document-metadata— notas y datos de participantesPOST /v1/get-document-transcript— segmentos de transcripción con detección de hablantePOST /v2/get-document-lists— carpetas y organización del espacio de trabajo
Consulta, Filtra y Exporta tus Reuniones
Listar y Filtrar
# Reuniones recientesgranola meeting list --limit 10# Filtrar por fecha (soporta lenguaje natural)granola meeting list --date yesterdaygranola meeting list --since "last week"granola meeting list --since 2025-12-01 --until 2025-12-15# Filtrar por asistente o búsquedagranola meeting list --attendee "[email protected]"granola meeting list --search "quarterly planning"
Ver Contenido
# Detalles completos de la reunión con participantesgranola meeting view <id># Tus notas manuscritas (convertidas de ProseMirror a Markdown)granola meeting notes <id># Resumen generado por IA con decisiones clave y tareasgranola meeting enhanced <id># Transcripción completa con detección de hablantegranola meeting transcript <id>granola meeting transcript <id> --timestamps
Exportar para Pipelines
# Exportar todo sobre una reunióngranola meeting export <id> --format jsongranola meeting export <id> --format toon# Canalizar a LLMsgranola meeting enhanced <id> --output toon | llm "What were the action items?"
40% Menos Tokens con TOON
La CLI soporta TOON (Token-Oriented Object Notation), un formato diseñado para consumo de LLMs. TOON entrega los mismos datos estructurados que JSON usando 40% menos tokens.
Cuando canalizas datos de reuniones a Claude u otro modelo, cada token ahorrado significa más contexto para tu pregunta. TOON determina si cabe una reunión o tres en tu ventana de contexto.
$ granola meeting export abc123 --format json | wc -c15234$ granola meeting export abc123 --format toon | wc -c9140
Los mismos datos. 40% más pequeño. Esa es la diferencia entre hacer una pregunta de seguimiento o alcanzar tu límite de contexto.
Convirtiendo el Historial de Reuniones en Contexto para IA
Por esto lo construí: para potenciar mis agentes de IA.
Uso Claude Code intensivamente. Con granola-cli instalada, puedo pedirle a Claude que analice mis reuniones directamente:
Tú: Revisa mis sincronizaciones de ingeniería de la semana pasada y lista cualquier bloqueo mencionado.Claude: Consultaré tus reuniones recientes usando granola-cli.[Ejecuta: granola meeting list --since "last week" --search "sync"]Encontré 3 sincronizaciones de ingeniería. Analizando transcripciones...Bloqueos mencionados:1. Inestabilidad del pipeline de CI bloqueando el release (sync del 18 de diciembre)2. Esperando revisión de diseño para el rediseño del dashboard (sync del 19 de diciembre)3. Problemas de rate limiting en la API con la integración de terceros (sync del 20 de diciembre)
Sin copiar y pegar. Sin cambiar de ventanas. Claude lee los datos directamente y me da respuestas.
También he construido Agent Skills que revisan el historial de reuniones, resumen decisiones y destacan bloqueos de sincronizaciones anteriores. Tu historial de reuniones se convierte en una base de datos consultable para tu flujo de trabajo de IA.
Bajo el Capó
Almacenamiento Seguro de Credenciales
Me niego a almacenar tokens de API en archivos de configuración en texto plano.
Demasiadas herramientas CLI descargan secretos en
~/.config/toolname/credentials.json. Un git add . accidental o una copia de
seguridad mal configurada expone tus tokens.
La CLI almacena credenciales mediante cross-keychain en el gestor de credenciales nativo de tu sistema operativo: macOS Keychain, Windows Credential Manager o Linux Secret Service. Estos sistemas cifran secretos en reposo, se integran con tu sesión de inicio y siguen las mejores prácticas de seguridad de la plataforma. Tus tokens de Granola nunca tocan el sistema de archivos en forma legible.
Actualización de Tokens con Bloqueo de Archivos
Granola usa tokens de actualización de un solo uso: cada token funciona una vez antes de invalidarse. Esto mejora la seguridad pero crea una condición de carrera: si dos procesos CLI actualizan simultáneamente, uno obtiene un token válido mientras el otro desperdicia el token de actualización y falla.
La CLI resuelve esto con bloqueo basado en archivos. Antes de actualizar, el proceso adquiere un bloqueo exclusivo en un archivo temporal. Si otro proceso ya está actualizando, el segundo espera (timeout de 30 segundos) en lugar de competir. El bloqueo se libera inmediatamente después de completar la actualización, por lo que las invocaciones paralelas de la CLI funcionan sin problemas: se turnan cuando es necesario.
Conversión de ProseMirror a Markdown
Granola almacena notas en formato ProseMirror, el mismo framework de texto enriquecido que usan Notion, The New York Times y Atlassian. Representa contenido como un árbol JSON de nodos con marcas (formato) adjuntas.
La CLI recorre este árbol, convirtiéndolo a Markdown. Los encabezados se
convierten en líneas #, las listas en elementos -, las marcas de texto en
sus equivalentes de Markdown: negrita se envuelve en **, cursiva en *,
código en comillas invertidas. La conversión preserva estructuras anidadas, por
lo que una lista con viñetas dentro de una cita en bloque se renderiza
correctamente. El resultado: Markdown legible que puedes canalizar a otras
herramientas, buscar con grep o alimentar a un LLM.
Análisis de Fechas en Lenguaje Natural
Nadie escribe fechas ISO voluntariamente. La CLI acepta "today", "yesterday", "3
days ago", "last week" o fechas parciales como "Dec 1". Para rangos, combina
--since y --until con cualquier formato. El parser se encarga del resto.
El parser normaliza la entrada, maneja casos límite (¿qué significa "last week" un lunes?) y devuelve timestamps UTC que coinciden con las expectativas de la API de Granola. El caso común—"muéstrame las reuniones de ayer"—se convierte en un solo flag intuitivo.
4 Horas con Claude Code Opus 4.5
Construí esta herramienta en aproximadamente 4 a 5 horas programando en pareja con Claude Code Opus 4.5. Me enfoqué en la arquitectura y la intención mientras Claude manejaba la implementación. El resultado: una CLI lista para producción con TypeScript estricto, más del 95% de cobertura de pruebas en más de 630 casos de prueba, y diseño modular—todo en una sola tarde.
Esto es "vibe engineering" en la práctica. Me salté la fase de planificación extensa, describí lo que quería, revisé el resultado e iteré rápidamente.
Comenzar
# Instalarnpm install -g granola-cli# Login (lee credenciales de tu aplicación de escritorio de Granola)granola auth login# Lista tus reunionesgranola meeting list
El código fuente está en github.com/magarcia/granola-cli. Issues y PRs bienvenidos.
Artículos relacionados:
- Almacenamiento Seguro de Secretos en Node.js con cross-keychain - La librería que granola-cli usa para almacenamiento seguro de credenciales
- Pedir a la IA que construya la herramienta en lugar de hacer la tarea - Cómo abordo el desarrollo asistido por IA