Skip to main content
Glama

Naukri MCP Server

CI

117-tool atomic MCP server for automating Naukri.com (India's largest job portal). Search jobs, apply in bulk, manage your profile, track applications, research companies, and monitor recruiter activity -- all from your MCP client. Designed for Claude Code's progressive Tool Search loading (default since Jan 2026), so each tool is single-purpose and discoverable on demand.

*Tech stack: Python 3.0+, FastMCP...

Key capabilities:

  • Search & Apply -- keyword search, ...

  • Application Tracking -- local JSON persistence + 3-tier sync from the backend ...

  • Profile Management ...

  • Company Research -- ...

  • Performance Analytics ...

  • Smart Automation ...


Architecture

naukri.py                    # Entry point (FastMCP run)
naukri_server/
  __init__.py                # FastMCP setup + lifespan (browser start/stop)
  config.py                  # Constants, API endpoints, timeouts
  browser.py                 # PagePool (3 tabs) + TokenManager (JWT caching)
  api.py                     # Deduplicated _api_request, @api_tool decorator
  cache.py                   # Answer cache for auto-apply screening questions
  scoring.py                 # Alias-aware fit scoring
  validation.py              # Response validators (job lists, profiles, etc.)
  utils.py                   # Shared helpers
  tools/                     # 27 tool modules (117 tools)
    auth.py                  # Login, OTP verification, login status
    search.py                # Job search, recommendations
    jobs.py                  # Job detail, similar, compare, bulk, report fraud
    apply.py                 # Applications: list, detail, apply, batch, purge, stale, follow-up
    tracking.py              # Saved jobs: list, save, unsave, sync
    smart_apply.py           # Smart apply with fit scoring
    auto_hunt.py             # One-call automated job hunting
    profile.py               # Profile CRUD, dashboard, boost, audit
    resume_photo.py          # Resume/photo info, upload, download, delete
    resume_builder.py        # Resume templates, builder status, tailor
    sync.py                  # Sync applications/saved jobs, export
    insights.py              # Application insights, salary, match analytics, skill gap, taxonomy
    performance.py           # Search impressions, recruiter activity
    companies.py             # Company search, jobs, slug, research, follow/unfollow
    ambitionbox.py           # Salary data, reviews, interviews (AmbitionBox)
    inbox.py                 # Recruiter messages, NVites, mark_interested
    notifications.py         # Notification feed, mark read, count, summary
    settings.py              # Account settings, blocked companies, email, visibility, subscription
    alerts.py                # Job alert CRUD
    early_access.py          # Pre-posted roles from top companies
    mock_interview.py        # AI mock interview topics, sessions, history
    reminders.py             # Follow-up reminders
    daily_brief.py           # Morning dashboard summary
    health.py                # Endpoint validation, browser pool, AmbitionBox checks
    debug/                   # Multi-action debug tool (16 actions)

Hybrid Browser + REST Strategy

Naukri's Akamai CDN blocks (REST) calls. The server uses a hybrid approach:

| Strategy... | Used By | Why | | ... | ...

PagePool

...

TokenManager

...

3-Tier Sync Fallback

...


Related MCP server: LinkedIn MCP Server

Quick Start for AI Consumers

1.  naukri_auth_status()             # Check session
    naukri_login(method="google")              # Authenticate (Google SSO or email)
2.  naukri_daily_brief()                     # Morning dashboard: recommendations + analytics
3.  naukri_auto_hunt(keywords="...", location="...")  # One-call job hunt with fit scoring
4.  naukri_assess_fit(job_id=...)           # Pre-flight check before applying
    naukri_apply(job_id=...)   # Submit application
5.  naukri_compare_jobs(job_ids=[id1, id2, id3])  # Side-by-side with fit scores
6.  naukri_accept_nvite(nvite_job_id="...")  # Respond to recruiter NVites
7.  naukri_sync_applications()       # Pull latest from Naukri backend
    naukri_list_applications()       # Query local tracking
8.  naukri_research_company(keyword="...")  # Unified: Naukri + AmbitionBox data
    naukri_company_intel(company="slug", intel_type="interviews")  # Interview tips
9.  naukri_tailor_resume(job_id=...)  # Get tailoring suggestions
    naukri_update_profile(...)     # Apply them
10. naukri_download_resume(save_path="...")  # Download resume

Apply flow detail: If a job has screening questions, the first naukri_apply() call returns them. Remember to pass...


Tools (117 atomic)

Almost every tool follows the single-purpose atomic pattern — one MCP tool per operation. Only naukri_company_intel and naukri_debug keep an action/intel_type parameter (see the "Dispatcher tools" subsection below for why). Designed for Claude Code's progressive Tool Search loading (default since Jan 2026), so many focused tools cost no more than a few multi-purpose ones.

Auth

...

...

Autonomous Agent

  • naukri_agent_status() — Estado del agente + últimas 5 ejecuciones + resumen de configuración

  • naukri_agent_config() — Configuración completa

  • naukri_agent_update_config(updates) — Aplica un parche a la configuración con JSON

  • naukri_agent_run_now(ctx=None) — Ejecuta un ciclo observe→decide→act→learn

  • naukri_agent_approve(cycle_id) — Aplica las decisiones pendientes

  • naukri_agent_reject(cycle_id) — Rechaza las decisiones pendientes

  • naukri_agent_history(limit=10) — Historial reciente de ejecuciones

  • naukri_agent_decisions(cycle_id) — Decisiones por empleo para un ciclo

Programador en segundo plano

  • naukri_scheduler_status() — Estado del programador + información de última ejecución por tarea

  • naukri_enable_task(task_name) — Habilita una tarea deshabilitada

  • naukri_disable_task(task_name) — Deshabilita una tarea

  • naukri_run_task_now(task_name) — Ejecuta una tarea inmediatamente

  • naukri_task_history(task_name=None, limit=20) — Historial reciente de ejecuciones

Recordatorios y entrevistas

  • naukri_list_reminders(include_past=True, include_app_status=True) — Todos los recordatorios con estado de vencimiento

  • naukri_set_reminder(job_id, days=7, ...) — Crear/actualizar recordatorio

  • naukri_interview_prep(job_id) — Paquete de preparación para entrevistas

  • naukri_add_interview_round(job_id, round_type, ...) — Registrar ronda de entrevista

  • naukri_list_interview_rounds(job_id=None) — Listar rondas

  • naukri_compare_offers(job_ids) — Comparar varias ofertas de empleo

Herramientas de despacho (solo quedan 2 — conservadas por diseño)

  • naukri_company_intel(company, intel_type="salary|reviews|interviews") — Tres acciones comparten la misma resolución de company y el flujo de autenticación de AmbitionBox; dividirlas duplicaría esa orquestación.

  • naukri_debug(action=...) — 16 acciones de depuración solo para desarrollo repartidas en navegador/API/descubrimiento; el coste de catálogo es real aquí incluso con carga progresiva, ya que la mayoría de los usuarios nunca las invocan.

Otros

  • naukri_daily_brief — Panel matutino: 16 fuentes + acciones recomendadas

  • naukri_health_check — Validación de endpoints + pool de navegadores + AmbitionBox


Configuración

Requisitos previos

  • Python 3.10+

  • Playwright Chromium (instalado mediante playwright install chromium)

Instalación

python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -r requirements.txt
pip install -e ../jobcore     # shared scoring engine - see below
playwright install chromium

La dependencia jobcore

La taxonomía de habilidades, la puntuación de ajuste y el análisis de salarios viven en un paquete hermano, jobcore; naukri_server/scoring.py y los módulos de puntuación de domain/ son finos envoltorios de reexportación sobre él. No está en PyPI, así que se instala de una de dos maneras, y las dos se mantienen deliberadamente aparte:

dónde

cómo

por qué

desarrollo local

pip install -e ../jobcore

editar jobcore y naukri juntos, sin reinstalar

CI

requirements-ci.txt, fijado a un commit exacto

el runner no tiene checkout de ../jobcore

No añadas la URL del repositorio git a requirements.txt. Pisa la instalación editable: después de pip install -e ../jobcore, una invocación posterior de pip install -r requirements.txt desinstala el paquete editable y lo reemplaza por un checkout de git, en silencio, porque pip no imprime ninguna línea de "already satisfied" para un requisito con URL directa. Medido en un venv limpio el 2026-08-20 y reproducido dos veces. La iteración local importa más que la comodidad del CI aquí, así que CI es el lado que instala desde git.

Si reconstruyes el venv, o ves ModuleNotFoundError: jobcore, vuelve a ejecutar pip install -e ../jobcore desde este directorio.

Incrementar la versión fijada en requirements-ci.txt es así como se adopta un cambio de jobcore: deliberadamente un commit visible y revisable en lugar de un @master movible que pudiera poner el CI de este repositorio en rojo sin que aquí haya cambiado nada.

Primer inicio de sesión

Inicia el servidor:

python naukri.py

Después llama a naukri_login(method="google") desde tu cliente MCP. Se abre una ventana visible de Chromium donde puedes:

  1. Google SSO (recomendado): Haz clic en "Login with Google" — usa la sesión guardada de Google del perfil de Chrome, no se necesitan credenciales.

  2. Email/contraseña: Pasa method="email", email="...", password="...".

La sesión del navegador se guarda en chrome-profile/ (se crea automáticamente, está ignorado por git). Este directorio es específico de la máquina: contiene cookies, almacenamiento local y credenciales cacheadas. No lo copies entre máquinas.

Duración de la sesión

Las sesiones persisten aproximadamente 30 días. Cuando caducan, el servidor lo detecta al arrancar o en la primera llamada a la API y devuelve un error "Not logged in". Vuelve a autenticarte con naukri_login(method="google").

Configuración del cliente MCP

{
  "mcpServers": {
    "naukri": {
      "command": "python",
      "args": ["naukri.py"],
      "cwd": "/path/to/mcp-servers/naukri"
    }
  }
}

Variables de entorno

Todas son opcionales. Se definen en el shell o en un archivo .env.

Variable

Por defecto

Descripción

NAUKRI_NAV_TIMEOUT

20000

Tiempo de espera de navegación de Playwright (ms)

NAUKRI_ELEMENT_TIMEOUT

5000

Tiempo de espera de elementos de Playwright (ms)

NAUKRI_API_TIMEOUT

30

Tiempo de espera de la API REST de aiohttp (segundos)

NAUKRI_MAX_TABS

3

Máximo de pestañas concurrentes en el PagePool

Ubicaciones de los archivos de datos

Todos los archivos de datos viven en la raíz del proyecto y están ignorados por git.

Archivo

Propósito

chrome-profile/

Perfil de navegador persistente de Playwright. Específico de la máquina, nunca hacerle commit.

applications.json

Seguimiento local de candidaturas. Escrito por apply, batch_apply y sync.

saved_jobs.json

Empleos locales guardados/marcados como favoritos. Escrito por saved_jobs y sync.

questions.json

Caché de respuestas a preguntas de selección. Se autocompleta al hacer apply; batch apply lo usa para auto-respuestas.

*.backup

Copia de seguridad automática antes de sobrescribir cualquier archivo JSON (escritura atómica: escribir en .tmp, desde el respaldo existente, renombrar).


Características de resiliencia

  • Sesión aiohttp global — sesión única compartida para todas las llamadas REST, evita la sobrecarga de conexión

  • Capa de API deduplicada_api_request con el decorador @api_tool normaliza todas las interacciones REST

  • Bloqueo de renovación — la renovación JWT de un solo escritor evita tormentas de 401 en paralelo

  • Validación al arranque — el estado del navegador y del token se valida antes de aceptar llamadas a herramientas

  • Seguridad de cancelación de batch apply — se conserva el progreso parcial si se interrumpe el lote

  • Copia de seguridad de datos — archivos .backup antes de cada sobrescritura de JSON

  • Purga automática del TTL de caché — las entradas caducadas de la caché de respuestas expiran automáticamente

  • Escrituras atómicas — el estado de sincronización se escribe mediante archivo temporal + renombrado para evitar corrupción

  • Caché TTL de perfil — los datos de perfil se cachean durante 30 segundos para reducir llamadas API redundantes


Limitaciones conocidas

Bloqueo de la CDN de Akamai

Naukri utiliza Akamai Bot Manager. Varios endpoints devuelven 406 Not Acceptable o 403 Forbidden cuando se los llama directamente por REST sin una sesión de navegador:

  • Búsqueda (naukri_search_jobs) — siempre usa la intercepción del navegador; REST directo está bloqueado

  • Modificaciones del perfil (naukri_update_profile()) — PUT/DELETE bloqueados por Akamai; se usa automatización del navegador en su lugar

  • Alertas de empleo — las operaciones CRUD van por automatización de la interfaz del navegador por el mismo motivo

Es un comportamiento esperado. Las herramientas que requieren interacción con el navegador se documentan como tal. Si ves errores 406 en herramientas que deberían usar REST, comprueba el estado del login con naukri_auth_status(): un token caducado hace que Akamai clasifique las solicitudes como tráfico de bots.

Scraping de AmbitionBox

AmbitionBox es un sitio SSR de Next.js. Las herramientas de salarios y reseñas extraen __NEXT_DATA__ de las páginas renderizadas en el servidor. Si AmbitionBox cambia la estructura de sus páginas, estas herramientas pueden devolver errores. naukri_health_check incluye una comprobación de AmbitionBox: un estado "warn" ahí es esperado periódicamente y no bloquea la funcionalidad principal de Naukri.


Solución de problemas

Problema

Solución

Errores "Not logged in"

La sesión caduca (~30 días). Llama a naukri_login(method="google") para volver a autenticarte.

La búsqueda devuelve vacío / 406

Esperado para REST directo. naukri_search_jobs usa la intercepción del navegador y debería funcionar. Si falla, ejecuta naukri_health_check.

Timeouts en conexiones lentas

Aumenta NAUKRI_NAV_TIMEOUT (p. ej., 30000) y NAUKRI_API_TIMEOUT (p. ej., 60).

Límites de peticiones / tope diario

Naukri limita las aplicaciones diarias según el tipo de cuenta. El campo daily_applied en las respuestas de apply muestra el número actual. Los suscriptores de Naukri 360 obtienen límites más altos.

La pestaña del navegador se bloquea

El PagePool recupera automáticamente las pestañas rotas en el siguiente acquire(). Si el bloqueo persiste, reinicia el servidor.

Bucles de renovación de token

Elimina chrome-profile/ y vuelve a autenticarte desde cero.

naukri_sync falla en los 3 niveles

Normalmente indica una sesión no válida. Inicia sesión primero. Si ya has iniciado sesión, pasa force_browser=True para omitir el nivel REST.

AmbitionBox salario/reviews roto

Ejecuta naukri_health_check para confirmar. Si AmbitionBox entrega "warn", las herramientas centrales de Naukri no se ven afectadas.

Comprobación de estado

Ejecuta naukri_health_check() para validar todas las integraciones de una vez. Prueba la sesión de login, la API de perfil, la API de búsqueda (aquí 406 es normal), recomendaciones, panel, viveza del PagePool y el scraping de AmbitionBox.

Devuelve {summary: {ok: N, warn: N, fail: N}, checks: [...]} con el tiempo por comprobación.


Acceso remoto

Ejecuta el servidor en tu máquina que esté siempre encendida y conéctate desde cualquier lugar (Claude web en audiencias cowork, móvil, etc.). Soporta dos modos de autenticación y pueden funcionar en un solo servidor.

Decisión rápida

Cliente

Modo de autenticación

Por qué

Claude Code CLI

Bearer (MCP_SHARED_SECRET)

claude mcp add --transport http ... --header "Authorization: Bearer ..." funciona directo

Claude Desktop

Bearer (MCP_SHARED_SECRET)

Admite la configuración headers en claude_desktop_config.json

Claude.ai web

OAuth (MCP_OAUTH_ENABLED=1)

La interfaz web solo expone los campos de OAuth client_id/secret, no el bearer

Ambos a la vez

Bearer + OAuth (define ambas variables)

Un solo servidor: el load_access_token del proveedor OAuth cae al secreto compartido

Paso 1 — Generar secretos

# Bearer secret (for Claude Code / Desktop)
python -c "import secrets; print(secrets.token_urlsafe(48))"

# OAuth client_id + client_secret (for Claude.ai web)
python -c "import secrets; print('client_id=claude-ai-web')"
python -c "import secrets; print('client_secret=' + secrets.token_urlsafe(48))"

Paso 2 — Configurar .env

Copia .env.example a .env y rellénalo. El archivo .env está ignorado por git. Configuración mínima para activar AMBOS modos de autenticación:

MCP_REMOTE=1
MCP_PORT=8321
MCP_PUBLIC_URL=https://naukri.<your-domain>

# Bearer (Claude Code + Desktop)
MCP_SHARED_SECRET=<paste output from token_urlsafe(48)>

# OAuth (claude.ai web)
MCP_OAUTH_ENABLED=1
MCP_OAUTH_CLIENT_ID=claude-ai-web
MCP_OAUTH_CLIENT_SECRET=<paste output from token_urlsafe(48)>
MCP_OAUTH_AUTO_APPROVE=1

Si MCP_REMOTE=1 pero no hay ninguna variable de autenticación, el servidor se niega a arrancar: esta es la comprobación de seguridad que evita exponer accidentalmente a MCP a internet.

Paso 3 — Nombre de host público (se recomienda Cloudflare Tunnel)

Cloudflare Tunnel te da una URL pública HTTPS estable sin necesidad de abrir puertos del firewall. Plan gratuito, ancho de banda sin límite.

winget install Cloudflare.cloudflared
cloudflared tunnel login
cloudflared tunnel create naukri-mcp
cloudflared tunnel route dns naukri-mcp naukri.<your-domain>

Edita %USERPROFILE%\.clared\config.yml:

tunnel: <UUID-from-create-command>
credentials-file: C:\Users\<you>\.cloudflared\<UUID>.json
ingress:
  - hostname: naukri.<your-domain>
    service: http://localhost:8321
  - service: http_status:404

Ejecuta el túnel: cloudflared túnel run noskri-mcp (o cloudflared service install para inicar automático).

Alternativas: Tailscale Funnel (peer-to-peer, menor latency para dispositivos de confianza) o ngrok (más sencilo grtis).

Paso 4 — Iniciar el servidor

# Load env vars from .env (PowerShell — use a one-liner or a helper script)
Get-Content .env | Where-Object { $_ -match '^[A-Z_]+=.+' } | ForEach-Object {
    $name, $val = $_ -split '=', 2
    [Environment]::SetEnvironmentVariable($name, $val, "Process")
}

python naukri.py --http

Los registros debrían mostrar: Auth: OAuth provider enabled (issur=https://naukri.<your-domain>, bearer-fall=yes) y Arthmide: 0.0.0.0:11321.

Paso 5 — Conectar clientes

Claude Code CLI (usar bearer):

claude mcp add --transport http naukri https://naukri.<your-domain>/mcp `
  --header "Authorization: Bearer <MCP_SHARED_SECRET>"

Claude Desktop (usar bearer):

En claude_desktop_config.json:

{
  "mcpServers": {
    "naukri": {
      "url": "https://naukri.<your-domain>/mcp",
      "transport": "http",
      "headers": { "Authorization": "Bearer <MCP_SHARED_SECRET>" }
    }
  }
}

Claude.ai web (usar OAuth):

Configuración → Conectores → Añadir conector personalizado

  • URL: https://naukri.<your-domain>/mcp

  • OAuth Client ID: nub-ai-web (debe coincirir con MCP_OAUTH_CLIENT_ID)

  • OAuth Client Secret: pega MCP_OAUTH_CLIENT_SECRET

Claude.ai descubrirá automáticamente los metadatos de rios (A.C.P. escrve .well-known/oauth-authorization-server y los endpoints /authorize y /token).

Prueba de humo (curl)

# 401 expected — no auth header
curl -i https://naukri.<your-domain>/mcp

# Bearer flow — should return MCP JSON-RPC instead of 401
curl -i -H "Authorization: Bearer <MCP_SHARED_SECRET>" `
  https://naukri.<your-domain>/mcp

# OAuth metadata discovery
curl https://naukri.<your-domain>/.well-known/oauth-authorization-server | jq .

Refuerzo del host en Windows

El MCP necesita una sesión de Chrome con intface gráfica, así que el equipo anfitrión debe permanecer despierto y con la sesión iniciada.

# Disable sleep / hibernate while plugged in
powercfg /change standby-timeout-ac 0
powercfg /change hibernate-timeout-ac 0
# Disable screen-off (optional — Chrome stays alive when display sleeps,
# but this avoids GPU pauses)
powercfg /change monitor-timeout-ac 0

Behavior

Result

Bloqueo de pantalla

Chrome sigue activo, el MCP funciona

Cerrar sesión

Chrome se detiene, MCP falla — mantén la sesión de usuario activa

Desconexión de RDP

El proceso sigue ejecutándose en el host, MCP funciona

Suspensión del sistema

Chrome se reanuda pero las llamadas en curso fallan — desactiva la suspensión

Uso manual de Chrome

Chrome en Windows no puede ejecutar dos instancias con distito --user-data-dir. No abras el mismo perfil manualmente miestras el MCP está en ejecución.

Monitoreización

El estado "tunnel healthy" de Cloudflare solo reflea el enlace edge↔cloudflared, no el enlace original. Añade una pruevida externo externo (e.g., UptimeRobot, gratuito) que consulte https://naukri.<your-domain>/.well-known/oauth-authorization-server (se espera 200) para que receibas una notificación cuando la máquina anfitera esté realmente inalcanzable.

Referencia del modo de autenticación

Variable de entorno

Requerido para

Notas

MCP_REMOTE=1

Enlace público

Sin esto, el servidor se queda en 127.0.0.1

MCP_PORTA

Puerto personalizado

Default 8321

MCP_PUBLIC_URL

El emisor de OA2 / metdatos del RS

Defaulto a http://localhost:8321

MCP_SHARED_SECRET

Autenticación bearer

>=32 caracteres; rota el secreto cambiando la variable de entorno el yn reinicar

MCP_OAU_ENABLED=1

Modo OAuth

Habilita /authorize, /token, /register, /revoke

MCP_OAU_CLIENT_ID

OAuth

ID de cliente pre-registrado para claude.ai

MCP_OAU_CLIENT_SECRET

OAuth

>=32 caracteres

MCP_OAU_AUTO_APPROVE

UX de OAuth

1 omice la pantana de consentemien (defaul), 0 muestra la página Aprovar/Denegar en /oauth/consenttamp

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Give AI agents the LinkedIn tools to find, qualify, engage, and follow up with prospects.

  • Search AI-native jobs, inspect application forms, and fetch free interview-prep resources.

  • AI-powered browser automation — navigate, click, fill forms, and extract data from any website.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Sundeepg98/naukri-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server