npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

migracion-citas-cli

v0.2.1

Published

Encuentra y monitorea citas de Migración Colombia desde la terminal.

Readme

Migración Citas CLI

Encuentra citas de Migración Colombia sin refrescar el navegador a las 5 p.m.

Instalación · Inicio rápido · Comandos · Sesión · Scripting · MCP

npm version npm downloads

Node 20+ · TypeScript · MIT · solo lectura


El problema

Migración Colombia libera cupos de domingo a jueves a partir de las 5:00 p.m. Se agotan en minutos. La única forma de saber si hay algo es entrar al sitio, elegir trámite, elegir sede, y repetir para cada una de las 34 sedes del país.

Esta CLI revisa las 34 en paralelo en unos segundos, y puede quedarse vigilando y avisarte con un sonido cuando aparezca un cupo.

migracion-citas check -t cedula --all
  Revisando TODAS las sedes · CÉDULA DE EXTRANJERÍA

  [ 1/34] BUENAVENTURA       · sin cupos
  [ 2/34] BOGOTA D.C.        · sin cupos
  [ 3/34] BARRANQUILLA       · sin cupos
  [ 4/34] BUCARAMANGA        ✓ 1 fecha(s)
  [ 5/34] CALI               · sin cupos
  [ 6/34] ARAUCA             ✓ 1 fecha(s)
  ...

  ¡HAY CITAS DISPONIBLES!

  TUNJA (id 27)
  Transversal 11 No. 28A-69, barrio Juan Valdez
  1 fecha(s), 3 cupo(s)

    ▸ miércoles 29 de julio de 2026 [2026-07-29]
      13:45  14:15  14:30

Instalación

Con npm (recomendado)

npm install -g migracion-citas-cli

Requiere Node 20 o superior. No necesitas tener Bun instalado.

Desde el repo (para desarrollar o contribuir)

git clone https://github.com/JGaldo-beep/migracion-citas-cli.git
cd migracion-citas-cli
bun install
bun link          # deja `migracion-citas` disponible en todo el sistema

Binario independiente (no necesita Node ni Bun para correr)

bun run build     # genera dist/migracion-citas
./dist/migracion-citas check -t cedula --all

Sin instalar nada (desde el repo clonado)

bun run bin/cli.ts check -t cedula --all

Inicio rápido

# 1. ¿Qué trámites existen?
migracion-citas tramites

# 2. ¿Qué sedes atienden ese trámite?
migracion-citas sedes -t cedula

# 3. ¿Dónde hay citas AHORA?
migracion-citas check -t cedula --all

# 4. Avísame cuando aparezcan
migracion-citas watch -t cedula --all --sound

Las consultas no requieren iniciar sesión. El login solo sirve para ver tus datos (mis-citas, beneficiarios, perfil).


Comandos

Consultar disponibilidad — sin sesión

| Comando | Qué hace | | --- | --- | | tramites | Lista los 9 trámites con su id y atajo | | sedes -t <trámite> [-s <sede>] | Lista las sedes de ese trámite, o solo una | | check -t <trámite> [-s <sede> \| --all] | Fechas y horarios disponibles | | horarios -t <trámite> -s <sede> [-f <fecha>] | Horarios detallados | | watch -t <trámite> [-s <sede> \| --all] | Monitorea hasta encontrar cupos | | catalogos [-c <nombre>] | Tablas de referencia (documentos, géneros, etnias…) |

Tu cuenta — requiere login

| Comando | Qué hace | | --- | --- | | login | Inicia sesión y guarda la sesión localmente | | mis-citas | Tus citas agendadas (próximas y anteriores) | | beneficiarios | Menores a cargo registrados en tu cuenta | | perfil | Los datos de tu cuenta | | whoami | Estado de la sesión y cuánto le queda | | logout | Cierra la sesión en el servidor y la borra local |

Utilidades

| Comando | Qué hace | | --- | --- | | cache --clear | Borra la caché local de trámites y sedes |

Banderas globales: --json (salida para scripts) y --debug (traza HTTP).


tramites

migracion-citas tramites
  Trámites disponibles:

  • atencion-sire                                      id 27  ATENCIÓN (SIRE)
  • cedula-de-extranjeria                              id  4  CÉDULA DE EXTRANJERÍA
  • certificado-de-movimientos-migratorios             id  5  CERTIFICADO DE MOVIMIENTOS MIGRATORIOS
  • duplicado-de-ppt-perdida-hurto                     id 22  DUPLICADO DE PPT - PERDIDA/HURTO
  • pep-tutor                                          id 26  PEP TUTOR
  • proceso-administrativo-persona-natural-o-juridica  id 28  PROCESO ADMINISTRATIVO - PERSONA NATURAL O JURÍDICA
  • reexpedicion-ppt-correccion-de-informacion         id 21  REEXPEDICIÓN PPT - CORRECCIÓN DE INFORMACIÓN
  • registro-de-extranjero-menor-a-7-anos              id  2  REGISTRO DE EXTRANJERO MENOR A 7 AÑOS
  • salvoconducto                                      id  6  SALVOCONDUCTO

  Total: 9 trámite(s)
  Atajos: cedula, sire, certificado, duplicado, pep, menor, salvoconducto

Atajos: en vez del nombre oficial puedes escribir cedula, sire, certificado, duplicado, pep, proceso, reexpedicion, menor o salvoconducto. También sirve el id (-t 4).


sedes

migracion-citas sedes -t cedula
  Sedes para: CÉDULA DE EXTRANJERÍA

  • ARAUCA            id  3  arauca
    Carrera 21 # 17 -73 - Barrio La Esperanza
  • ARMENIA           id  4  armenia
    Calle 15 A Norte # 11-80 - Urbanizacion La Campiña
  • BARRANQUILLA      id  5  barranquilla
    Carrera 42 # 54-77 Barrio El Recreo
  • BOGOTA D.C.       id  2  bogota-d-c
    Carrera 19 # 92-65

Para ver solo una sede (útil para conocer su id y dirección):

migracion-citas sedes -t cedula -s bogota
  Sedes para: CÉDULA DE EXTRANJERÍA

  • BOGOTA D.C.  id  2  bogota-d-c
    Carrera 19 # 92-65

  Total: 1 sede(s)

Las sedes se resuelven en vivo desde la API. Acepta nombre, atajo o id, y no le importan los acentos ni las mayúsculas:

migracion-citas check -t cedula -s "puerto carreño"
migracion-citas check -t cedula -s puerto-carreno
migracion-citas check -t cedula -s 21

Si el nombre es ambiguo, te lo dice en vez de adivinar:

$ migracion-citas check -t cedula -s puerto
  Error: [VALIDATION_ERROR] "puerto" es ambiguo. Coincide con: PUERTO CARREÑO, PUERTO INÍRIDA, PUERTO LEGUÍZAMO

check

Una sede:

migracion-citas check -t cedula -s bogota
  CÉDULA DE EXTRANJERÍA
  Sede: BOGOTA D.C.

  No hay citas disponibles.

  NO HAY CITAS DISPONIBLES

  Apreciada ciudadanía, el agendamiento de citas para la atención de
  trámites y servicios en los Centros Facilitadores de Servicios
  Migratorios – CFSM y Puestos de Control Migratorio – PCM (con funciones
  de Extranjería) se habilita diariamente, de domingo a jueves a partir de
  las 5:00 p.m. ...

  Monitorea continuamente:  migracion-citas watch -t cedula -s bogota

Ese aviso no está escrito por esta CLI: viene de GET /api/alertas, es el mismo texto oficial que muestra el sitio.

Todas las sedes, en paralelo:

migracion-citas check -t cedula --all

Solo fechas, sin bajar horarios (más rápido):

migracion-citas check -t cedula --all --no-horarios

watch

Revisa cada N minutos hasta encontrar algo, y entonces avisa.

# Todas las sedes, cada 5 minutos, con sonido
migracion-citas watch -t cedula --all --sound

# Una sede, cada minuto
migracion-citas watch -t cedula -s medellin -i 1 --sound

# Una sola pasada (para cron)
migracion-citas watch -t cedula --all --once

El intervalo se limita a 1–120 minutos. Ctrl+C para salir.


horarios

migracion-citas horarios -t cedula -s tunja
migracion-citas horarios -t cedula -s tunja -f 2026-07-29

catalogos

Las tablas de referencia con las que está armado el formulario de agendamiento. Son públicas y se cachean 12 h.

migracion-citas catalogos
migracion-citas catalogos -c parentescos
  Parentescos

  • id  1  Hijo(a)
  • id  2  Menor a cargo
  • id  3  Otro

  Total: 3

Disponibles: tipos-documento, generos, etnias, discapacidades, parentescos.


Sesión

migracion-citas login                       # pide correo y contraseña
migracion-citas login -e [email protected]      # solo pide contraseña
MIGRACION_PASSWORD=... migracion-citas login -e [email protected]
  Iniciar sesión en Migración Colombia

  Correo: [email protected]
  Contraseña:

  Autenticando... ✓

  Sesión guardada.
  Cuenta: Ana Ramírez · [email protected]
  Válida por: 7h 59m
  Archivo: C:\Users\tu-usuario\.migracion-citas-cli\session.json

  Ahora puedes usar: mis-citas · beneficiarios · perfil

Cómo funciona la sesión

Esto es lo que más se rompe en un CLI, así que vale la pena explicarlo:

  • El servidor entrega la cookie mc_session, que es un JWT con exp a 8 horas.
  • La CLI lee ese exp en vez de adivinar una duración, y lo guarda en expiresAt. Por eso whoami puede decirte con honestidad cuánto te queda.
  • Antes de cualquier comando autenticado, si quedan menos de 30 minutos, la CLI llama sola a POST /auth/refresh y renueva el token sin que hagas nada.
  • Al renovar, las cookies se fusionan: el servidor solo reenvía mc_session, así que mc_logged (y cualquier cookie futura) se conserva.
  • logout cierra la sesión también en el servidor, no solo borra el archivo.

El aviso de "sesión cerrada por inactividad a los 15 minutos" que ves en el navegador es un temporizador del sitio web, no una regla del servidor. Por eso la CLI puede mantener la sesión durante las 8 horas reales del token.

migracion-citas whoami
  Sesión activa
  Ana María Ramírez Torres
  [email protected]
  Expira en: 7h 48m
  Iniciada: 29/7/2026, 10:35:04 a. m.

Alternativa: cookies manuales

Si prefieres no escribir tu contraseña en la terminal:

migracion-citas login --manual

Inicia sesión en el navegador, copia el header Cookie desde DevTools → Network → cualquier petición a /citas/api/, y pégalo.

Dónde vive tu sesión

| | | | --- | --- | | Archivo | ~/.migracion-citas-cli/session.json | | Permisos | 0600 (solo tu usuario, en sistemas Unix) | | Contenido | la cookie, cuándo expira y un snapshot de tu perfil |

Tu contraseña nunca se guarda en disco. Nada se envía a ningún servidor que no sea apps.migracioncolombia.gov.co. Para borrar todo: migracion-citas logout.


mis-citas

migracion-citas mis-citas
  Tus citas (1)

  Próximas

  ▸ CÉDULA DE EXTRANJERÍA
      viernes 31 de julio de 2026  14:15
      Sede: BOGOTA D.C.
      Carrera 19 # 92-65
      Estado: AGENDADA
      Radicado: #004821

Scripting y automatización

Todo comando acepta --json. La salida va a stdout; los logs van a stderr, así que puedes hacer pipe con seguridad.

migracion-citas check -t cedula -s tunja --json
{
  "ok": true,
  "results": [
    {
      "sede": { "id": 27, "nombre": "TUNJA", "slug": "tunja", "direccion": "Transversal 11 No. 28A-69, barrio Juan Valdez" },
      "tramite": { "id": 4, "nombre": "CÉDULA DE EXTRANJERÍA", "slug": "cedula-de-extranjeria" },
      "disponible": true,
      "fechas": ["2026-07-29"],
      "dias": [
        {
          "fecha": "2026-07-29",
          "slots": [
            { "id": 88, "hora": "13:45", "cupos": 1 },
            { "id": 18, "hora": "14:15", "cupos": 1 },
            { "id": 19, "hora": "14:30", "cupos": 1 }
          ]
        }
      ],
      "cupos": 3,
      "checkedAt": "2026-07-29T15:52:03.114Z"
    }
  ]
}

Solo las sedes con cupos:

migracion-citas check -t cedula --all --json \
  | jq -r '.results[] | select(.disponible) | "\(.sede.nombre): \(.cupos) cupos"'
BUCARAMANGA: 2 cupos
ARAUCA: 1 cupos
TUNJA: 3 cupos

Notificación de escritorio (macOS):

migracion-citas check -t cedula --all --json \
  | jq -e '[.results[] | select(.disponible)] | length > 0' >/dev/null \
  && osascript -e 'display notification "¡Hay citas!" with title "Migración"'

Cron cada 10 minutos entre 5 y 8 p.m.:

*/10 17-20 * * 0-4 /usr/local/bin/migracion-citas watch -t cedula --all --once --json >> ~/citas.log 2>&1

Código de salida: 0 si todo salió bien, 1 si hubo un error (sede inválida, sin sesión, API caída).


MCP: úsalo desde Claude o Cursor

La CLI trae un servidor MCP para que un agente pueda consultar citas por ti.

bun run setup-mcp     # detecta y configura Claude Code, Cursor, Windsurf, Codex

Luego reinicia tu IDE y pregunta en lenguaje natural:

¿Hay citas de cédula de extranjería en Medellín o Cali esta semana?

Herramientas expuestas (todas de solo lectura):

| Herramienta | Sesión | Qué hace | | --- | :---: | --- | | listar_tramites | — | Trámites disponibles | | listar_sedes | — | Sedes de un trámite | | consultar_disponibilidad | — | Fechas y horarios de una sede | | buscar_citas_todas_las_sedes | — | Barre las 34 sedes | | consultar_horarios | — | Horarios de una fecha | | aviso_sin_disponibilidad | — | Aviso oficial de Migración | | catalogo | — | Tablas de referencia | | estado_sesion | ✓ | Si hay sesión y cuánto le queda | | mis_citas | ✓ | Tus citas agendadas | | mis_beneficiarios | ✓ | Tus menores a cargo |

Las tres últimas reutilizan la sesión de migracion-citas login. Si no hay sesión responden autenticado: false en vez de fallar.


Alcance

Esta herramienta solo lee. No agenda, no cancela y no modifica nada.

Es una decisión deliberada: agendar desde un script en un servicio público con cupos escasos crea citas reales que alguien más podría necesitar, y abre la puerta al acaparamiento. La CLI te dice dónde y cuándo hay cupo; tú reservas en el sitio oficial.

  Agenda tu cita en:
  https://apps.migracioncolombia.gov.co/citas

Agendar una cita en Migración Colombia es gratis y no requiere intermediarios.


Cómo funciona

bin/cli.ts                    Commander: registro de comandos y flags globales
│
├── src/commands/             Una función por comando; solo formatea y decide
│   ├── check · horarios · watch · sedes · tramites
│   ├── cuenta                mis-citas · beneficiarios · perfil
│   ├── catalogos
│   └── login                 login · whoami · logout
│
├── src/services/
│   ├── api/client.ts         Único punto de red. Envelope, reintentos, refresh
│   ├── auth/session-manager  Persistencia + expiración leída del JWT
│   ├── cache/cache-manager   Caché en disco con TTL y versión
│   ├── catalog.ts            Resolución nombre/atajo/id → id real
│   └── availability.ts       Lógica de dominio; concurrencia limitada a 6
│
├── src/lib/                  banner · render · text · errors · logger
├── src/mcp/server.ts         Servidor MCP (10 herramientas)
└── discovery/                Cómo se descubrió la API (notas + prompts)

Decisiones que importan

Los ids no están hardcodeados. Migración agrega sedes y cambia ids. Todo se resuelve en vivo contra /api/tramites y /api/sedes, y se cachea 12 h. Una versión temprana tenía un mapa fijo donde medellin apuntaba a 14, que en realidad es Manizales. Hay un test de regresión para eso.

La disponibilidad nunca se cachea. Un cupo de hace cinco minutos ya no existe. CACHE_TTL.disponibilidad = 0.

Los errores 4xx no se reintentan. Reintentar una contraseña incorrecta tres veces no la vuelve correcta, y sí te puede bloquear.

Un 200 con HTML es un error. Si Migración cambia una ruta, Next.js devuelve la página completa con status 200. La CLI lo detecta y te dice que la API cambió, en vez de fallar con un error de JSON incomprensible.

Los acentos importan. PUERTO CARREÑO se normaliza con NFD antes de comparar, así carreno y carreño encuentran lo mismo.

El log va a stderr. stdout queda limpio para --json y para MCP.


Desarrollo

bun install
bun test              # tests offline
bun run test:live     # tests de contrato contra la API real
bun run type-check
bun run lint
bun run build

Los tests offline usan payloads reales capturados de la API como fixtures. Los tests live verifican que el contrato no cambió (que el trámite 4 siga siendo Cédula de Extranjería, que no aparezca mojibake, que las fechas sigan en YYYY-MM-DD) y solo corren con MIGRACION_LIVE_TESTS=1.

¿Cómo se descubrió la API?

No hay documentación pública. Se levantó con agent-browser: grabar el tráfico del sitio, leer los bundles de Next.js y verificar cada endpoint a mano. El proceso completo, los endpoints y las trampas encontradas están en discovery/.


Aviso

Proyecto independiente, sin relación con Migración Colombia. Consume los mismos endpoints públicos que usa el sitio web oficial, a un ritmo comparable al de una persona navegando. Úsalo con criterio.

Licencia

MIT