---
name: write_mcp_jupyter_config
kind: function
lang: bash
domain: infra
version: "1.2.0"
purity: impure
signature: "write_mcp_jupyter_config([project_dir: string], [port: int]) -> string"
description: "Genera o actualiza .mcp.json para un analisis Jupyter. La entrada jupyter usa el wrapper jupyter_mcp_serve.sh con env overrides (venv, root y puerto del analisis), de modo que el MCP arranca su propio Jupyter con el venv del analisis. Merge con jq reemplazando la entrada jupyter entera."
tags: [mcp, jupyter, config, setup, infra, notebook]
uses_functions: [jupyter_mcp_serve_bash_infra]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
  - name: project_dir
    desc: "directorio del proyecto/analisis Jupyter (default: directorio actual)"
  - name: port
    desc: "puerto Jupyter del analisis (default: 8888)"
output: "ruta del archivo .mcp.json generado o actualizado"
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/infra/write_mcp_jupyter_config.sh"
---

## Ejemplo

```bash
source write_mcp_jupyter_config.sh
path=$(write_mcp_jupyter_config $HOME/fn_registry/analysis/finanzas 8890)
echo "Config MCP en: $path"
# Genera .mcp.json con:
#   "command": "bash"
#   "args": [".../bash/functions/infra/jupyter_mcp_serve.sh"]
#   "env": {
#     "JUPYTER_MCP_VENV":  ".../analysis/finanzas/.venv",
#     "JUPYTER_MCP_ROOT":  ".../analysis/finanzas",
#     "JUPYTER_MCP_PORT":  "8890",
#     "JUPYTER_MCP_TOKEN": ""
#   }
```

## Cuando usarla

- Al crear un analysis Jupyter nuevo (la usa el pipeline `init_jupyter_analysis`).
- Tras mover/recrear un venv y necesitar regenerar el `.mcp.json` del analysis.
- Para reparar un `.mcp.json` con el comando viejo (console-script directo que no arranca Jupyter, o `python -m jupyter_mcp_server.server`).

## Gotchas

- **Usa el wrapper, no el console-script directo**: el `.mcp.json` apunta a `jupyter_mcp_serve.sh` (ver `jupyter_mcp_serve_bash_infra`), que arranca (o reusa) el Jupyter del analisis con su venv antes de exec del MCP. Con el console-script directo (`jupyter-mcp-server --jupyter-url ...`) el MCP solo se CONECTA: si el server no esta levantado no hay kernel y las operaciones sobre notebooks fallan. Con el wrapper basta abrir Claude desde el analisis — no hace falta lanzar `run-jupyter-lab.sh` aparte.
- **El venv del kernel es el del analisis** (`JUPYTER_MCP_VENV`), no `python/.venv` del repo. Asi cada analisis ejecuta con sus propias dependencias sin contaminar el venv canonico. Este fix nacio de un caso real (analisis `nats`): trabajar desde la raiz de `fn_registry` cargaba el MCP global (8899, venv `python/.venv`) que no tenia `nats-py`.
- **Reuso por puerto**: si ya hay un Jupyter escuchando en `JUPYTER_MCP_PORT` (p.ej. lanzado por `run-jupyter-lab.sh`, que es colaborativo), el wrapper lo reusa en vez de arrancar otro. Si no hay ninguno, el wrapper levanta uno propio (sin `--collaborative`, suficiente para el MCP). Para colaboracion humana en tiempo real, lanzar `run-jupyter-lab.sh` antes.
- **NUNCA `python -m jupyter_mcp_server.server`** — `server.py` no tiene bloque `__main__`; importa y sale 0, el MCP nunca arranca. El entrypoint real es el console-script `jupyter-mcp-server`, que el wrapper localiza dentro del venv del analisis.
- **Requiere `jupyter-mcp-server` instalado en el venv del analisis**: `uv pip install jupyter-mcp-server`. La funcion aborta si el console-script no existe.
- **Localiza el wrapper subiendo directorios** desde `project_dir` (hasta 8 niveles) buscando `bash/functions/infra/jupyter_mcp_serve.sh`; si no lo encuentra, usa `FN_REGISTRY_ROOT`. Aborta si no aparece por ninguna via.
- **Merge con jq usa `+` (shallow)** en el mapa de servidores para reemplazar la entrada `jupyter` entera; `*` (deep) dejaba keys huerfanas de configs viejas (p.ej. el bloque `args` del console-script directo).

## Capability growth log

- v1.2.0 (2026-06-03) — el `.mcp.json` generado usa el wrapper `jupyter_mcp_serve.sh` con env overrides (`JUPYTER_MCP_VENV/ROOT/PORT/TOKEN`) en vez del console-script directo. Garantiza que el MCP arranca su propio Jupyter con el venv del analisis (antes solo conectaba y usaba el venv equivocado si se abria Claude desde la raiz del repo). Declara dependencia `jupyter_mcp_serve_bash_infra`.
- v1.1.0 (2026-05-28) — fix comando roto: console-script `jupyter-mcp-server` + flags stdio en vez de `python -m ...server` + env vars. Merge `+` para reemplazar entrada entera. Tag `notebook`.
