migracion-citas-cli
v0.2.1
Published
Encuentra y monitorea citas de Migración Colombia desde la terminal.
Maintainers
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
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:30Instalación
Con npm (recomendado)
npm install -g migracion-citas-cliRequiere 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 sistemaBinario independiente (no necesita Node ni Bun para correr)
bun run build # genera dist/migracion-citas
./dist/migracion-citas check -t cedula --allSin instalar nada (desde el repo clonado)
bun run bin/cli.ts check -t cedula --allInicio 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 --soundLas 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, salvoconductoAtajos: 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-65Para 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 21Si 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ÍZAMOcheck
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 bogotaEse 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 --allSolo fechas, sin bajar horarios (más rápido):
migracion-citas check -t cedula --all --no-horarioswatch
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 --onceEl 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-29catalogos
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: 3Disponibles: 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 · perfilCó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 conexpa 8 horas. - La CLI lee ese
expen vez de adivinar una duración, y lo guarda enexpiresAt. Por esowhoamipuede 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/refreshy renueva el token sin que hagas nada. - Al renovar, las cookies se fusionan: el servidor solo reenvía
mc_session, así quemc_logged(y cualquier cookie futura) se conserva. logoutcierra 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 --manualInicia 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: #004821Scripting 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 cuposNotificació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>&1Có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, CodexLuego 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/citasAgendar 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 buildLos 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
