feat: mejorar skill init-jupyter con detección inteligente
- Añadir PASO 0 para detectar estado del repo (MCP instalado, repo configurado, Jupyter corriendo) - Reglas de Jupyter ahora se insertan al PRINCIPIO de CLAUDE.md - Nuevas conversaciones detectan automáticamente si el repo tiene Jupyter habilitado - Autodetección de puerto libre (8888-8899) - Script run-jupyter-lab.sh guarda puerto en .jupyter-port
This commit is contained in:
@@ -1,138 +1,156 @@
|
||||
---
|
||||
name: init-jupyter
|
||||
description: Inicializa o inicia Jupyter Lab via MCP con kernel compartido. Detecta notebooks existentes automáticamente.
|
||||
description: Inicializa entorno Jupyter para exploración de datos con MCP compartido. Autodetecta puerto y configura repo.
|
||||
argument-hint: [ruta-proyecto]
|
||||
disable-model-invocation: true
|
||||
user-invocable: true
|
||||
allowed-tools: Bash, Read, Write, Edit, Glob
|
||||
---
|
||||
|
||||
# Inicializar/Iniciar Proyecto Jupyter via MCP
|
||||
# Inicializar Entorno Jupyter para Data Science
|
||||
|
||||
Este skill gestiona entornos Jupyter Lab integrados con Claude via MCP. Detecta automáticamente si ya existe un proyecto configurado.
|
||||
Skill para preparar cualquier repo para exploración de datos con Jupyter + Claude colaborando en kernel compartido.
|
||||
|
||||
## Modo de Colaboración (Kernel Compartido)
|
||||
## PASO 0: Verificar estado actual del repo
|
||||
|
||||
**IMPORTANTE**: Para que las ejecuciones de Claude sean visibles en Jupyter Lab, se debe usar el **mismo kernel** que el notebook abierto. Esto permite:
|
||||
- Ver las ejecuciones de Claude en tiempo real en Jupyter Lab
|
||||
- Compartir variables y estado entre Claude y el usuario
|
||||
- Colaboración real entre ambos en el mismo notebook
|
||||
|
||||
## Flujo de decisión
|
||||
|
||||
### 1. Detectar notebooks existentes
|
||||
|
||||
Buscar archivos `.ipynb` en:
|
||||
- Raíz del proyecto
|
||||
- Carpeta `notebooks/`
|
||||
- Cualquier subcarpeta
|
||||
**Ejecutar estas comprobaciones primero:**
|
||||
|
||||
```bash
|
||||
find [ruta] -name "*.ipynb" -type f 2>/dev/null | head -5
|
||||
# 1. ¿MCP instalado globalmente?
|
||||
which jupyter-mcp-server && echo "MCP_OK" || echo "MCP_NO"
|
||||
|
||||
# 2. ¿Repo ya configurado para Jupyter?
|
||||
[ -f .claude/settings.local.json ] && grep -q "jupyter" .claude/settings.local.json && echo "REPO_CONFIG_OK" || echo "REPO_NO_CONFIG"
|
||||
|
||||
# 3. ¿Jupyter corriendo en este repo?
|
||||
pgrep -af "jupyter" | grep "$(pwd)" && echo "JUPYTER_RUNNING" || echo "JUPYTER_STOPPED"
|
||||
|
||||
# 4. ¿CLAUDE.md tiene reglas Jupyter?
|
||||
[ -f .claude/CLAUDE.md ] && grep -q "JUPYTER HABILITADO" .claude/CLAUDE.md && echo "RULES_OK" || echo "RULES_NO"
|
||||
```
|
||||
|
||||
### 2. Si HAY notebooks existentes → Conectar o Iniciar
|
||||
### Resultado: MCP NO instalado
|
||||
|
||||
**2a. Verificar que MCP está configurado con kernel compartido**
|
||||
- Comprobar si existe `.claude/settings.local.json` con configuración de jupyter
|
||||
- Verificar que incluye `--start-new-runtime false` para colaboración
|
||||
- Si no existe o falta la configuración, crearlo (ver paso 3f)
|
||||
|
||||
**2b. Verificar que jupyter-mcp-server está instalado**
|
||||
```bash
|
||||
which jupyter-mcp-server || uv tool install jupyter-mcp-server
|
||||
```
|
||||
|
||||
**2c. Verificar si el script run-jupyter-lab.sh existe**
|
||||
- Si no existe, crearlo (ver paso 3g)
|
||||
|
||||
**2d. Detectar si Jupyter ya está corriendo**
|
||||
```bash
|
||||
# Verificar si hay un servidor Jupyter activo en el puerto esperado
|
||||
curl -s http://localhost:8888/api/status 2>/dev/null && echo "Jupyter activo" || echo "Jupyter no detectado"
|
||||
```
|
||||
|
||||
**2e. Si Jupyter YA está corriendo:**
|
||||
- **NO arrancarlo de nuevo**
|
||||
- Informar al usuario: "Jupyter Lab detectado en http://localhost:8888"
|
||||
- Claude puede conectarse directamente via MCP al kernel existente
|
||||
- El usuario tiene libertad total para gestionar Jupyter manualmente
|
||||
|
||||
**2f. Si Jupyter NO está corriendo:**
|
||||
- Preguntar al usuario si quiere que Claude lo arranque o prefiere hacerlo manualmente con `./run-jupyter-lab.sh`
|
||||
- Si el usuario quiere arrancarlo:
|
||||
```bash
|
||||
source .venv/bin/activate 2>/dev/null || true
|
||||
jupyter lab --no-browser --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.disable_check_xsrf=True
|
||||
```
|
||||
|
||||
**2g. Informar al usuario** que puede usar las herramientas MCP de Jupyter desde Claude.
|
||||
|
||||
### 3. Si NO hay notebooks → Inicializar proyecto completo
|
||||
|
||||
Seguir estos pasos:
|
||||
|
||||
**3a. Validar ubicación**
|
||||
- Si se proporciona `$1`, usar esa ruta
|
||||
- Si no, usar el directorio actual
|
||||
|
||||
**3b. Inicializar proyecto con uv** (si no existe pyproject.toml)
|
||||
```bash
|
||||
cd [ruta] && uv init
|
||||
```
|
||||
|
||||
**3c. Crear entorno virtual**
|
||||
```bash
|
||||
uv venv
|
||||
```
|
||||
|
||||
**3d. Instalar dependencias**
|
||||
```bash
|
||||
uv add jupyter jupyter-collaboration
|
||||
```
|
||||
|
||||
**3e. Instalar jupyter-mcp-server**
|
||||
```bash
|
||||
uv tool install jupyter-mcp-server
|
||||
```
|
||||
|
||||
**3f. Configurar MCP para Claude (con kernel compartido)**
|
||||
Crear o actualizar `.claude/settings.local.json`:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"jupyter": {
|
||||
"command": "jupyter-mcp-server",
|
||||
"args": [
|
||||
"--jupyter-url", "http://localhost:8888",
|
||||
"--start-new-runtime", "false"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Informar:
|
||||
```
|
||||
MCP jupyter-mcp-server instalado.
|
||||
Ejecuta /exit y vuelve a entrar para recargar.
|
||||
Después ejecuta /init-jupyter de nuevo.
|
||||
```
|
||||
**DETENER AQUÍ**
|
||||
|
||||
### Resultado: Repo YA configurado + Jupyter corriendo
|
||||
|
||||
Informar:
|
||||
```
|
||||
Este repo ya tiene Jupyter configurado y está corriendo.
|
||||
Puedes empezar a trabajar directamente con notebooks via MCP.
|
||||
```
|
||||
**DETENER AQUÍ** (no hace falta reconfigurar)
|
||||
|
||||
### Resultado: Repo YA configurado + Jupyter NO corriendo
|
||||
|
||||
Informar:
|
||||
```
|
||||
Este repo tiene Jupyter configurado pero no está corriendo.
|
||||
Ejecuta ./run-jupyter-lab.sh en otra terminal para iniciarlo.
|
||||
```
|
||||
**DETENER AQUÍ**
|
||||
|
||||
### Resultado: Repo NO configurado → Continuar con PASO 1
|
||||
|
||||
---
|
||||
|
||||
## PASO 1: Detectar ruta de trabajo
|
||||
|
||||
```bash
|
||||
RUTA="${1:-.}"
|
||||
cd "$RUTA"
|
||||
pwd
|
||||
```
|
||||
|
||||
**Parámetros clave:**
|
||||
- `--jupyter-url`: URL del servidor Jupyter (por defecto localhost:8888)
|
||||
- `--start-new-runtime false`: **CRÍTICO** - Conecta al kernel existente en lugar de crear uno nuevo
|
||||
---
|
||||
|
||||
**3g. Crear script `run-jupyter-lab.sh`**
|
||||
## PASO 2: Verificar si Jupyter ya corre en ESTE repo
|
||||
|
||||
```bash
|
||||
# Buscar proceso jupyter con el directorio actual
|
||||
REPO_PATH=$(pwd)
|
||||
pgrep -af "jupyter" | grep -E "(lab|notebook)" | grep "$REPO_PATH" || echo "NO_JUPYTER"
|
||||
```
|
||||
|
||||
- Si encuentra proceso → Informar "Jupyter ya está corriendo en este repo" y saltar a Paso 6
|
||||
- Si NO encuentra → Continuar
|
||||
|
||||
---
|
||||
|
||||
## PASO 3: Detectar puerto libre (autodetección)
|
||||
|
||||
```bash
|
||||
# Encontrar primer puerto libre entre 8888-8899
|
||||
for port in 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899; do
|
||||
if ! lsof -i:$port >/dev/null 2>&1; then
|
||||
echo $port
|
||||
break
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
Guardar el puerto detectado para usarlo en los siguientes pasos.
|
||||
|
||||
---
|
||||
|
||||
## PASO 4: Crear/Actualizar archivos del proyecto
|
||||
|
||||
### 4a. Crear estructura si no existe
|
||||
|
||||
```bash
|
||||
mkdir -p .claude notebooks
|
||||
```
|
||||
|
||||
### 4b. Crear `run-jupyter-lab.sh` con puerto autodetectado
|
||||
|
||||
Crear el archivo con el PUERTO detectado en Paso 3:
|
||||
|
||||
Crear un script ejecutable para que el usuario pueda arrancar Jupyter manualmente:
|
||||
```bash
|
||||
cat > run-jupyter-lab.sh << 'SCRIPT'
|
||||
#!/bin/bash
|
||||
# Script para iniciar Jupyter Lab con configuración de colaboración
|
||||
# El usuario puede arrancarlo manualmente y Claude se conectará al kernel existente
|
||||
# Jupyter Lab para colaboración Claude + Usuario
|
||||
# Generado por /init-jupyter
|
||||
|
||||
PORT=${1:-8888}
|
||||
# Autodetectar puerto libre
|
||||
find_free_port() {
|
||||
for port in 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899; do
|
||||
if ! lsof -i:$port >/dev/null 2>&1; then
|
||||
echo $port
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo 8888
|
||||
}
|
||||
|
||||
PORT=${1:-$(find_free_port)}
|
||||
|
||||
# Guardar puerto para que Claude lo lea
|
||||
echo $PORT > .jupyter-port
|
||||
|
||||
# Activar entorno si existe
|
||||
source .venv/bin/activate 2>/dev/null || true
|
||||
|
||||
echo "Iniciando Jupyter Lab en puerto $PORT..."
|
||||
echo "Abre http://localhost:$PORT en tu navegador"
|
||||
echo "══════════════════════════════════════════════════════"
|
||||
echo " Jupyter Lab iniciando en puerto $PORT"
|
||||
echo "══════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Claude se conectará automáticamente al kernel cuando abras un notebook."
|
||||
echo " Abre: http://localhost:$PORT"
|
||||
echo ""
|
||||
echo " Claude se conectará al kernel cuando abras un notebook"
|
||||
echo " Usa Ctrl+C para detener"
|
||||
echo ""
|
||||
echo "══════════════════════════════════════════════════════"
|
||||
|
||||
jupyter lab \
|
||||
--port=$PORT \
|
||||
@@ -140,93 +158,174 @@ jupyter lab \
|
||||
--NotebookApp.token='' \
|
||||
--NotebookApp.password='' \
|
||||
--NotebookApp.disable_check_xsrf=True \
|
||||
--ServerApp.allow_origin='*'
|
||||
--ServerApp.allow_origin='*' \
|
||||
--ServerApp.root_dir="$(pwd)"
|
||||
SCRIPT
|
||||
chmod +x run-jupyter-lab.sh
|
||||
```
|
||||
|
||||
**3h. Crear carpeta notebooks** (opcional)
|
||||
### 4c. Crear/Actualizar `.claude/settings.local.json`
|
||||
|
||||
Usar el PUERTO detectado:
|
||||
|
||||
```bash
|
||||
mkdir -p notebooks
|
||||
```
|
||||
|
||||
**3i. Iniciar Jupyter via MCP**
|
||||
```bash
|
||||
source .venv/bin/activate
|
||||
jupyter lab --no-browser --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.disable_check_xsrf=True
|
||||
```
|
||||
|
||||
## Ejemplos de uso
|
||||
|
||||
**Iniciar/inicializar en directorio actual:**
|
||||
```bash
|
||||
/init-jupyter
|
||||
```
|
||||
|
||||
**Iniciar/inicializar en ruta específica:**
|
||||
```bash
|
||||
/init-jupyter ~/proyectos/mi-analisis
|
||||
```
|
||||
|
||||
## Flujo de trabajo colaborativo (Kernel Compartido)
|
||||
|
||||
### Cómo funciona la colaboración
|
||||
|
||||
1. **Usuario inicia Jupyter Lab** (via este skill)
|
||||
2. **Usuario abre un notebook** en Jupyter Lab → se inicia un kernel
|
||||
3. **Claude se conecta al MISMO kernel** via MCP con `--start-new-runtime false`
|
||||
4. **Ambos comparten**:
|
||||
- El mismo estado de variables
|
||||
- El mismo historial de ejecución
|
||||
- Las salidas son visibles para ambos en tiempo real
|
||||
|
||||
### Pasos para colaborar
|
||||
|
||||
**Opción A - Usuario arranca Jupyter manualmente (recomendado):**
|
||||
1. Ejecutar `./run-jupyter-lab.sh` (o `./run-jupyter-lab.sh 8889` para otro puerto)
|
||||
2. Abrir el navegador en http://localhost:8888
|
||||
3. Abrir o crear el notebook deseado
|
||||
4. Ejecutar `/init-jupyter` - Claude detectará Jupyter y se conectará al kernel existente
|
||||
5. **Claude ya puede ejecutar celdas** y el usuario verá las ejecuciones en su Jupyter Lab
|
||||
|
||||
**Opción B - Claude arranca Jupyter:**
|
||||
1. Ejecutar `/init-jupyter`
|
||||
2. Si no hay Jupyter corriendo, Claude lo arrancará
|
||||
3. Abrir el navegador en http://localhost:8888
|
||||
4. Abrir o crear el notebook deseado
|
||||
5. **Claude ya puede ejecutar celdas**
|
||||
|
||||
### Obtener kernel ID específico (opcional)
|
||||
|
||||
Si hay múltiples kernels corriendo, puedes obtener el ID del kernel activo:
|
||||
```bash
|
||||
curl -s http://localhost:8888/api/kernels | jq '.[0].id'
|
||||
```
|
||||
|
||||
Y configurar MCP con ese kernel específico:
|
||||
```json
|
||||
cat > .claude/settings.local.json << EOF
|
||||
{
|
||||
"mcpServers": {
|
||||
"jupyter": {
|
||||
"command": "jupyter-mcp-server",
|
||||
"args": [
|
||||
"--jupyter-url", "http://localhost:8888",
|
||||
"--runtime-id", "KERNEL_ID_AQUI"
|
||||
"--jupyter-url", "http://localhost:PUERTO",
|
||||
"--start-new-runtime", "false"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
## Notas importantes
|
||||
(Reemplazar PUERTO por el valor real detectado)
|
||||
|
||||
- **Siempre usa MCP**: Jupyter se ejecuta siempre de forma que Claude pueda interactuar via MCP
|
||||
- **Kernel compartido por defecto**: Con `--start-new-runtime false`, Claude usa el kernel existente
|
||||
- **Script `run-jupyter-lab.sh`**: Se crea automáticamente para que el usuario pueda arrancar Jupyter cuando quiera
|
||||
- **Detección automática**: Claude detecta si Jupyter ya está corriendo y no lo arranca de nuevo
|
||||
- **Libertad del usuario**: El usuario puede gestionar Jupyter manualmente, Claude se adapta
|
||||
- Si detecta notebooks existentes, NO reinicializa el proyecto, solo conecta o inicia Jupyter
|
||||
- Si el proyecto ya tiene `pyproject.toml`, no ejecuta `uv init`
|
||||
- La configuración MCP se guarda en `.claude/settings.local.json` del proyecto
|
||||
- El servidor MCP permite a Claude crear, editar y ejecutar celdas de notebooks
|
||||
- **jupyter-collaboration** ya está incluido en las dependencias para sincronización en tiempo real
|
||||
### 4d. Añadir/Actualizar instrucciones en `.claude/CLAUDE.md`
|
||||
|
||||
**IMPORTANTE**: Las reglas de Jupyter deben ir AL PRINCIPIO del archivo para que nuevas conversaciones las vean inmediatamente.
|
||||
|
||||
**Lógica de inserción:**
|
||||
|
||||
1. Verificar si existe `.claude/CLAUDE.md`
|
||||
2. Si existe:
|
||||
- Leer contenido actual
|
||||
- Si NO contiene "JUPYTER HABILITADO" → prepend (añadir al principio)
|
||||
- Si YA contiene → no modificar
|
||||
3. Si no existe → crearlo con las reglas
|
||||
|
||||
**Contenido a insertar AL PRINCIPIO:**
|
||||
|
||||
```markdown
|
||||
# JUPYTER HABILITADO EN ESTE REPO
|
||||
|
||||
Este repositorio está configurado para exploración de datos con Jupyter + Claude.
|
||||
|
||||
## Estado del entorno
|
||||
- **Lanzador**: `./run-jupyter-lab.sh`
|
||||
- **Puerto config**: ver `.jupyter-port` o `.claude/settings.local.json`
|
||||
- **MCP**: jupyter-mcp-server configurado
|
||||
|
||||
## Reglas OBLIGATORIAS para Claude
|
||||
|
||||
### 1. SIEMPRE usar MCP jupyter para ejecutar código Python
|
||||
- Las ejecuciones se ven en tiempo real en Jupyter Lab del usuario
|
||||
- Compartimos variables y estado del kernel
|
||||
- **NUNCA usar bash para ejecutar Python en este repo**
|
||||
|
||||
### 2. Verificar Jupyter activo ANTES de ejecutar
|
||||
```bash
|
||||
pgrep -af "jupyter" | grep "$(pwd)" || cat .jupyter-port 2>/dev/null
|
||||
```
|
||||
- Si no está activo → pedir al usuario: "Ejecuta `./run-jupyter-lab.sh` en otra terminal"
|
||||
|
||||
### 3. Gestión de notebooks
|
||||
- Si un notebook tiene >50 celdas → crear uno nuevo
|
||||
- Nombrar descriptivamente: `01_exploracion.ipynb`, `02_limpieza.ipynb`
|
||||
- Mantener notebooks enfocados en una tarea
|
||||
|
||||
### 4. Antes de código pesado
|
||||
- Avisar al usuario
|
||||
- Usar `%%time` o `tqdm` para progreso
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
|
||||
**Comando bash para prepend:**
|
||||
|
||||
```bash
|
||||
# Si CLAUDE.md existe y NO tiene las reglas
|
||||
if [ -f .claude/CLAUDE.md ]; then
|
||||
if ! grep -q "JUPYTER HABILITADO" .claude/CLAUDE.md; then
|
||||
# Prepend: crear temp con reglas + contenido original
|
||||
cat > .claude/CLAUDE.md.tmp << 'JUPYTER_RULES'
|
||||
[CONTENIDO DE REGLAS AQUÍ]
|
||||
JUPYTER_RULES
|
||||
cat .claude/CLAUDE.md >> .claude/CLAUDE.md.tmp
|
||||
mv .claude/CLAUDE.md.tmp .claude/CLAUDE.md
|
||||
fi
|
||||
else
|
||||
# Crear nuevo
|
||||
cat > .claude/CLAUDE.md << 'JUPYTER_RULES'
|
||||
[CONTENIDO DE REGLAS AQUÍ]
|
||||
JUPYTER_RULES
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PASO 5: Inicializar entorno Python si no existe
|
||||
|
||||
### 5a. Si no existe `pyproject.toml`:
|
||||
|
||||
```bash
|
||||
uv init 2>/dev/null || true
|
||||
uv venv 2>/dev/null || true
|
||||
```
|
||||
|
||||
### 5b. Instalar dependencias de Jupyter:
|
||||
|
||||
```bash
|
||||
source .venv/bin/activate 2>/dev/null || true
|
||||
uv add jupyter jupyterlab pandas numpy matplotlib 2>/dev/null || pip install jupyter jupyterlab pandas numpy matplotlib
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PASO 6: Resumen final al usuario
|
||||
|
||||
Mostrar:
|
||||
|
||||
```
|
||||
═══════════════════════════════════════════════════════════════
|
||||
Entorno Jupyter configurado en: [RUTA]
|
||||
═══════════════════════════════════════════════════════════════
|
||||
|
||||
Puerto asignado: [PUERTO]
|
||||
|
||||
Para empezar:
|
||||
1. En otra terminal ejecuta: ./run-jupyter-lab.sh
|
||||
2. Abre http://localhost:[PUERTO] en tu navegador
|
||||
3. Crea o abre un notebook
|
||||
4. Yo me conecto automáticamente al kernel compartido
|
||||
|
||||
Archivos creados/actualizados:
|
||||
- run-jupyter-lab.sh (lanzador)
|
||||
- .claude/settings.local.json (config MCP)
|
||||
- .claude/CLAUDE.md (reglas de trabajo)
|
||||
|
||||
═══════════════════════════════════════════════════════════════
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comandos útiles post-inicialización
|
||||
|
||||
```bash
|
||||
# Ver puerto actual
|
||||
cat .jupyter-port
|
||||
|
||||
# Verificar Jupyter corriendo
|
||||
pgrep -af jupyter
|
||||
|
||||
# Listar kernels activos
|
||||
curl -s http://localhost:$(cat .jupyter-port)/api/kernels | jq
|
||||
|
||||
# Listar notebooks abiertos
|
||||
curl -s http://localhost:$(cat .jupyter-port)/api/sessions | jq
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notas para uso frecuente
|
||||
|
||||
- El script `run-jupyter-lab.sh` autodetecta puerto cada vez que se ejecuta
|
||||
- El archivo `.jupyter-port` siempre tiene el puerto actual
|
||||
- Si cambias de puerto, actualiza `.claude/settings.local.json` o recarga Claude
|
||||
- Las reglas en `CLAUDE.md` se mantienen entre sesiones
|
||||
|
||||
Reference in New Issue
Block a user