Lever job boards

Busca en bolsas de trabajo públicas de Lever: resuelve una empresa, lee sus vacantes, lee una completa.

Documentación

mcp-lever

npm CI license MCP Registry Glama M8ven LobeHub Install in Cursor Install in VS Code

Lever es un software de reclutamiento que miles de empresas utilizan para gestionar su contratación, y cada cliente recibe un tablón de empleo público que viene incluido. Cada tablón muestra las posiciones abiertas de esa empresa con su título, su ubicación, el equipo y departamento al que pertenecen, el tipo de compromiso que solicitan, el anuncio completo y el rango salarial cuando la empresa decide publicarlo. Lever aloja un tablón por empresa, ya sea en su instancia global o en su instancia europea, y no publica un índice que los abarque a todos.

Este servidor conecta un cliente de chat con esos tablones. Tú nombras las empresas que te interesan, y él convierte cada nombre en el nombre de sitio que dirige a su tablón, busca sus vacantes, las filtra por ubicación, equipo, tipo de lugar de trabajo, país, salario o por lo recientes que sean, lee una vacante completa y lista las palabras clave por las que cada empresa filtra. No necesita clave API ni cuenta.

Versión française


Instalación

Instalación en un clic

Install in Cursor Install in VS Code

Claude Code

claude mcp add lever -- npx -y mcp-lever

Claude Desktop, Cursor y cualquier cliente que use el formato de configuración estándar

{
  "mcpServers": {
    "lever": {
      "command": "npx",
      "args": ["-y", "mcp-lever"]
    }
  }
}

Se requiere Node 24 o posterior, y no es necesario establecer ninguna variable de entorno.

Con Docker

{
  "mcpServers": {
    "lever": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-lever:2.0.1"]
    }
  }
}

-i mantiene stdin abierto, que es por donde viaja el protocolo, y -t se omite porque un TTY reescribe el flujo. El contenedor necesita HTTPS saliente hacia api.lever.co y api.eu.lever.co, y nada más: sin volumen, sin puerto, sin credencial.

Paquete, sin npm

Descarga mcp-lever-2.0.1.mcpb desde la última versión y ábrelo. Un cliente que admita paquetes MCP lo instala por sí solo, sin npm y sin archivo de configuración que editar. El paquete incluye sus dependencias, por lo que no se descarga nada en el momento de la instalación.

Lo que puedes preguntar

  • "¿Cuáles de Included Health, Netlify y Ramp están contratando en Lever?"
  • "Encuéntrame puestos remotos de ingeniería en esas tres empresas."
  • "Léeme esa vacante completa."
  • "¿Bajo qué ubicaciones lista Included Health sus empleos?"
  • "¿Algo publicado en las últimas dos semanas en Netlify?"

Toda pregunta parte de una empresa, ya que Lever no ofrece búsqueda entre tablones. search_jobs resuelve los nombres que le das, por lo que no se necesita preparación:

resolve_company(["Included Health"])  ->  includedhealth, global instance, publishing
search_jobs(["Included Health"], keyword: "therapist")
get_job("includedhealth", "6f97a19f-…")

Herramientas

HerramientaQué hace
resolve_companyConvierte nombres de empresas en los nombres de sitio de Lever de sus tablones.
search_jobsBusca las vacantes de las empresas que nombras.
get_jobLee una vacante completa, incluido el anuncio.
list_filter_valuesLista las palabras clave bajo las que una empresa archiva sus vacantes.

Un nombre de sitio de Lever distingue mayúsculas, por lo que Flex responde donde flex no devuelve nada. Se prueban cuatro grafías por nombre en cada una de las dos instancias, y la respuesta lista lo que se envió, por lo que no encontrar nada nunca es prueba de que una empresa esté ausente de Lever.

resolve_company

Convierte nombres de empresas en nombres de sitio de Lever, informando de cada instancia que respondió. Toma una lista.

ArgumentoTipoObligatorioQué hace
namesarray de 1 a 25 cadenasNombres de empresas, o nombres de sitio de Lever que ya conozcas.

A cambio: una entrada por nombre, que lleva input; found, una lista de { slug, instance, publishes } donde publishes es falso para un sitio que existe y no lista nada hoy; tried, las grafías enviadas en orden; y cached, verdadero cuando esta sesión ya había resuelto ese nombre. Un nombre que responda en ambas instancias vuelve con ambas, y ninguna es elegida: pasa la que quieras decir a las otras herramientas.

search_jobs

Busca las vacantes de las empresas nombradas. Lever aplica los filtros que admite sobre su propia redacción exacta, y este servidor aplica el resto a las vacantes que leyó.

ArgumentoTipoObligatorioQué hace
companiesarray de 1 a 25 cadenasNombres de empresas o nombres de sitio de Lever. Cada uno se resuelve aquí.
keywordcadenanoPalabras para buscar en el título y en el anuncio.
locationarray de 1 a 20 cadenasnoUbicaciones, exactamente como las escribe Lever.
teamarray de 1 a 20 cadenasnoEquipos, exactamente como los escribe Lever.
departmentarray de 1 a 20 cadenasnoDepartamentos, exactamente como los escribe Lever.
commitmentarray de 1 a 20 cadenasnoCompromisos, exactamente como los escribe Lever.
workplace_typearray de 1 a 4 cadenasnoremote, hybrid, onsite o unspecified.
countryarray de 1 a 20 códigos de dos letrasnoPaíses como códigos ISO, como en FR o US.
salary_minnúmero, 0 o másnoEl límite superior más bajo de un rango salarial a conservar.
salary_intervalcadenanoEl período en el que está escrito salary_min, como per-year-salary.
currencycódigo de tres letrasnoLa moneda en la que está escrito salary_min, como en EUR.
posted_within_daysentero, 1 a 3650noCuán reciente debe ser una vacante.
limitentero, 1 a 100, predeterminado 25noVacantes a leer por empresa.
skipentero, 0 a 100000, predeterminado 0noVacantes a omitir por empresa.

Lever mismo aplica location, team, department y commitment; este servidor aplica keyword, workplace_type, country, salary_min, salary_interval, currency y posted_within_days a lo que leyó. list_filter_values publica las palabras clave que toman los primeros cuatro, y una palabra clave que Lever no conozca vuelve como una lista vacía.

A cambio: jobs, cada una llevando id y company_slug, que get_job toma, además de title, location, all_locations, country, workplace_type, team, posted_at, url y apply_url. commitment y department están ausentes cuando la empresa no registra ninguno. salary es null para una vacante publicada sin uno, que nunca es lo mismo que cero, y lleva la interval en la que Lever lo escribió, nunca convertida ni anualizada. per_company da un resultado por empresa, con un status de read, unresolved, empty o failed, que son cuatro respuestas diferentes, y los conteos de read y returned alrededor de los filtros. total_available es siempre null: Lever no publica ningún conteo de resultados. Las filas no llevan texto de anuncio, ya que el tablón de una sola empresa puede alcanzar megabytes.

limit se aplica por empresa, y una empresa cuyas vacantes lo llenen puede publicar más: las notas dicen cuándo ocurrió eso, y que un conteo tomado dentro de esa ventana mide la ventana. posted_within_days recorre hasta cinco páginas por empresa, y Lever pagina por título, por lo que una vacante publicada ayer puede estar en cualquier lugar de un tablón.

get_job

Lee una vacante completa: el anuncio, sus secciones nombradas y el salario tal como se publicó.

ArgumentoTipoObligatorioQué hace
company_slugcadenaEl nombre de sitio de Lever, tal como lo devuelve resolve_company.
job_idcadenaEl identificador de una vacante, tal como lo devuelve una búsqueda.
instanceglobal o eunoLa instancia de la que proviene la fila. La global por defecto.

A cambio: job, que contiene los campos que lleva una fila de búsqueda, además de description, sections como { heading, items }, salary_note para lo que la empresa escribió junto al rango, y source con la dirección de la que se recuperó.

list_filter_values

Lista las palabras clave de equipo, ubicación y compromiso que usa una empresa. Léelo antes de filtrar: Lever coincide con su propia redacción, y el vocabulario pertenece a cada empresa, una escribe Full-time donde otra escribe EE Full-Time.

ArgumentoTipoObligatorioQué hace
company_slugcadenaEl nombre de sitio de Lever, tal como lo devuelve resolve_company.
instanceglobal o eunoLa instancia en la que vive este sitio. La global por defecto.
fieldsarray de 1 a 3 de team, location, commitmentnoQué vocabularios leer. Cada uno cuesta una solicitud, y los tres se leen por defecto.

A cambio: company_slug, instance y fields que contienen una lista de { value, count } para cada vocabulario solicitado. Un count es null donde Lever no publicó ninguna cifra junto a la categoría.

Configuración

No hay nada que configurar. El servidor no lee ninguna variable de entorno, y el bloque mcpServers anterior está completo tal como está escrito.

El ritmo, el tiempo de espera y la caché son ajustes de la capa del cliente, que Como biblioteca muestra cómo pasar. El intervalo entre dos solicitudes se puede ampliar allí y nunca reducir.

Errores

Cada fallo lleva uno de seis códigos, un mensaje y, cuando ayuda, los valores que habrían sido aceptados.

CódigoQué ocurrióQué hacer
not_foundLever respondió y no tiene ese sitio ni esa oferta.Verifica el nombre del sitio con resolve_company.
invalid_inputLos argumentos fueron rechazados antes de enviar cualquier solicitud.Lee el mensaje, que indica el argumento y qué requiere.
rate_limitedLever pidió a este cliente que reduzca la velocidad.Espera y vuelve a llamar con los mismos argumentos. La oferta sigue en el tablón.
parse_failureLever respondió en un formato que este cliente no puede leer.Repórtalo en el rastreador de incidencias.
network_errorLa solicitud no se completó.Inténtalo de nuevo en breve.
timeoutLa solicitud superó su plazo.Pide menos empresas o un limit más pequeño.

Como biblioteca

La capa que lee Lever se publica por separado, con su propio ritmo, su caché y sus errores, y sin ningún protocolo adjunto.

import { Client } from "mcp-lever/client";

const client = new Client({ minIntervalMs: 2000 });
const resolved = await client.resolveCompany("Included Health");
const jobs = await client.listPostings(resolved.found[0], { limit: 10 });
console.log(jobs.length);

ClientOptions toma minIntervalMs, timeoutMs, cacheTtlMs y fetchImpl. Un intervalo por debajo del mínimo publicado se ignora, por lo que el mínimo se mantiene aquí también.

Ritmo y atribución

Ambos hosts de API publican Crawl-delay: 1, por lo que las solicitudes salen de una en una con al menos un segundo entre ellas, y ese mínimo se mantiene sin importar cómo esté configurado el cliente. El User-Agent lleva el proyecto y una dirección donde se puede contactar a una persona, y no imita a ningún navegador.

Las lecturas van a api.lever.co y api.eu.lever.co, que son los hosts que Lever documenta para sus datos de publicación. Las páginas de carreras de jobs.lever.co se dejan intactas.

Cada oferta lleva la dirección de su página de Lever y su URL de postulación. Da crédito a la empresa y enlaza esa página cuando muestres una oferta.

Este servidor MCP es un proyecto no oficial, sin afiliación con Lever ni con las empresas cuyos tablones lee.

Privacidad

Este servidor no recopila nada sobre ti y no envía nada a su autor. Se ejecuta en tu máquina, contacta a api.lever.co y api.eu.lever.co y nada más, guarda sus respuestas en memoria mientras se ejecuta y no escribe nada en el disco. PRIVACY.md indica qué lleva una solicitud y qué ajustes cambian cualquier parte de ello.

Desarrollo

npm install
npm run build:fixtures
npm test
npm run check

Las pruebas se ejecutan contra fixtures generados y no hacen ninguna solicitud de red. La suite en vivo, npm run test:live, hace una solicitud por ruta y se ejecuta cada noche contra el propio servicio.

Contribuciones

Errores, preguntas e ideas van en el rastreador de incidencias. Las solicitudes de extracción son bienvenidas; abrir una incidencia primero ayuda a acordar la forma del cambio. Consulta CONTRIBUTING.md.

Licencia

MIT, consulta LICENSE. Las ofertas pertenecen a las empresas que las publicaron.


mcp-lever (francés)

Versión en inglés

Lever es un software de reclutamiento que usan miles de empresas para llevar a cabo sus contrataciones, y cada cliente recibe con él un sitio de ofertas público. Cada sitio muestra los puestos abiertos de esa empresa con su título, ubicación, equipo y departamento al que pertenecen, el tipo de contrato solicitado, el anuncio completo y el rango salarial cuando la empresa ha elegido publicar uno. Lever aloja un sitio por empresa, en su instancia global o en su instancia europea, y no publica ningún índice que los atraviese.

Este servidor conecta un cliente de conversación con estos sitios. Nombras las empresas que te interesan, y él traduce cada nombre al identificador que direcciona su sitio, busca en sus ofertas, las filtra por ubicación, equipo, modalidad de trabajo, país, salario o frescura de publicación, lee una oferta completa y lista las formulaciones según las cuales cada empresa clasifica las suyas. Sin clave de API, sin cuenta.

Instalación

Instalación en un clic

Install in Cursor Install in VS Code

Claude Code

claude mcp add lever -- npx -y mcp-lever

Claude Desktop, Cursor y cualquier cliente con formato de configuración estándar

{
  "mcpServers": {
    "lever": {
      "command": "npx",
      "args": ["-y", "mcp-lever"]
    }
  }
}

Se requiere Node 24 o más reciente, y no hay ninguna variable de entorno que completar.

Con Docker

{
  "mcpServers": {
    "lever": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-lever:2.0.1"]
    }
  }
}

-i mantiene la entrada estándar abierta, que es el canal del protocolo, y -t se omite porque un TTY reescribe el flujo. El contenedor necesita acceso HTTPS saliente a api.lever.co y api.eu.lever.co, y nada más: ningún volumen, ningún puerto, ningún identificador.

Bundle, sin npm

Descarga mcp-lever-2.0.1.mcpb desde la última publicación y ábrelo. Un cliente que gestiona bundles MCP lo instala solo, sin npm y sin archivo de configuración que modificar. El bundle incluye sus dependencias, por lo que nada se descarga en la instalación.

Lo que se puede pedir

  • «¿Cuáles de Included Health, Netlify y Ramp reclutan en Lever?»
  • «Encuéntrame puestos de ingeniería en remoto en estos tres.»
  • «Léeme esta oferta completa.»
  • «¿Bajo qué ubicaciones clasifica Included Health sus ofertas?»
  • «¿Algo publicado en los últimos quince días en Netlify?»

Cada pregunta parte de una empresa, ya que Lever no ofrece ninguna búsqueda que atraviese los sitios. search_jobs resuelve por sí mismo los nombres que se le dan, por lo que no hay nada que preparar:

resolve_company(["Included Health"])  ->  includedhealth, instance mondiale, publie
search_jobs(["Included Health"], keyword: "therapist")
get_job("includedhealth", "6f97a19f-…")

Las herramientas

HerramientaQué hace
resolve_companyTraduce nombres de empresas a identificadores de sitios Lever.
search_jobsBusca en las ofertas de las empresas nombradas.
get_jobLee una oferta completa, anuncio incluido.
list_filter_valuesLista las formulaciones bajo las cuales una empresa clasifica.

Un identificador de sitio Lever distingue mayúsculas y minúsculas, por lo que Flex responde donde flex no devuelve nada. Se prueban cuatro ortografías por nombre en cada una de las dos instancias, y la respuesta lista lo que se envió: no encontrar nada nunca prueba que una empresa esté ausente de Lever.

resolve_company

Traduce nombres de empresas a identificadores de sitios Lever, indicando cada instancia que respondió. Toma una lista.

ArgumentoTipoRequeridoQué hace
namesmatriz de 1 a 25 cadenasNombres de empresas, o identificadores ya conocidos.

A cambio: una entrada por nombre, que lleva input ; found, una lista de { slug, instance, publishes } donde publishes es falso para un sitio que existe y no lista nada hoy ; tried, las ortografías enviadas en orden ; y cached, verdadero cuando la sesión ya había resuelto ese nombre. Un nombre que responde en ambas instancias regresa con ambas, y ninguna es elegida: pasa la que apuntes a las otras herramientas.

search_jobs

Busca en las ofertas de las empresas nombradas. Lever aplica los filtros que gestiona sobre su propia formulación exacta, y este servidor aplica los demás a las ofertas que ha leído.

ArgumentoTipoRequeridoQué hace
companiesmatriz de 1 a 25 cadenasNombres de empresas o identificadores. Cada uno se resuelve aquí.
keywordcadenanoPalabras para buscar en el título y en el anuncio.
locationmatriz de 1 a 20 cadenasnoUbicaciones, exactamente como Lever las escribe.
teammatriz de 1 a 20 cadenasnoEquipos, exactamente como Lever los escribe.
departmentmatriz de 1 a 20 cadenasnoDepartamentos, exactamente como Lever los escribe.
commitmentmatriz de 1 a 20 cadenasnoTipos de contrato, exactamente como Lever los escribe.
workplace_typematriz de 1 a 4 cadenasnoremote, hybrid, onsite o unspecified.
countrymatriz de 1 a 20 códigos de dos letrasnoPaíses en código ISO, como FR o US.
salary_minnúmero, 0 o másnoEl límite inferior más bajo del rango a conservar.
salary_intervalcadenanoEl período en el que salary_min está escrito, por ejemplo per-year-salary.
currencycódigo de tres letrasnoLa moneda en la que salary_min está escrito, como EUR.
posted_within_daysentero, 1 a 3650noLa antigüedad máxima de una oferta.
limitentero, 1 a 100, predeterminado 25noOfertas a leer por empresa.
skipentero, 0 a 100000, predeterminado 0noOfertas a omitir por empresa.

Lever aplica por sí mismo location, team, department y commitment ; este servidor aplica keyword, workplace_type, country, salary_min, salary_interval, currency y posted_within_days a lo que ha leído. list_filter_values publica las formulaciones que toman los primeros cuatro, y una formulación que Lever ignora regresa en lista vacía. En retour : jobs, chacune portant id et company_slug, que get_job reprend, plus title, location, all_locations, country, workplace_type, team, posted_at, url et apply_url. commitment et department sont absents quand l'entreprise ne les renseigne pas. salary vaut null pour une offre publiée sans fourchette, ce qui ne vaut jamais zéro, et porte l'interval dans lequel Lever l'a écrite, jamais converti ni annualisé. per_company donne une issue par entreprise, avec un status valant read, unresolved, empty ou failed, qui sont quatre réponses différentes, et les comptes read et returned de part et d'autre des filtres. total_available vaut toujours null : Lever ne publie aucun compte de résultats. Les lignes ne portent pas l'annonce, un site d'entreprise pouvant peser plusieurs mégaoctets.

limit s'applique par entreprise, et une entreprise dont les offres le remplissent en publie peut-être davantage : les notes le signalent, et disent qu'un compte pris dans cette fenêtre mesure la fenêtre. posted_within_days parcourt jusqu'à cinq pages par entreprise, et Lever pagine par intitulé, donc une offre publiée hier peut se trouver n'importe où dans un site.

get_job

Lit une offre en entier : l'annonce, ses sections nommées, et le salaire tel que publié.

ArgumentTypeRequisCe qu'il fait
company_slugchaîneouiL'identifiant du site, rendu par resolve_company.
job_idchaîneouiL'identifiant d'une offre, rendu par une recherche.
instanceglobal ou eunonL'instance d'où vient la ligne. La mondiale par défaut.

En retour : job, qui porte les champs d'une ligne de recherche, plus description, sections en { heading, items }, salary_note pour ce que l'entreprise a écrit à côté de la fourchette, et source avec l'adresse d'où l'offre a été lue.

list_filter_values

Liste les formulations d'équipe, de lieu et de contrat qu'une entreprise emploie. À lire avant de filtrer : Lever fait correspondre sa propre formulation, et le vocabulaire appartient à chaque entreprise, l'une écrivant Full-time là où une autre écrit EE Full-Time.

ArgumentTypeRequisCe qu'il fait
company_slugchaîneouiL'identifiant du site, rendu par resolve_company.
instanceglobal ou eunonL'instance où vit ce site. La mondiale par défaut.
fieldstableau de 1 à 3 parmi team, location, commitmentnonLes vocabulaires à lire. Chacun coûte une requête, et les trois sont lus par défaut.

En retour : company_slug, instance, et fields qui porte une liste de { value, count } pour chaque vocabulaire demandé. Un count vaut null là où Lever n'a publié aucun chiffre à côté de la catégorie.

Configuration

Il n'y a rien à configurer. Le serveur ne lit aucune variable d'environnement, et le bloc mcpServers ci-dessus est complet tel quel.

Le rythme, le délai et le cache sont des réglages de la couche cliente, que Comme bibliothèque montre comment passer. L'écart entre deux requêtes peut y être élargi et jamais resserré.

Erreurs

Chaque échec porte un des six codes, un message, et quand cela aide les valeurs qui auraient été acceptées.

CodeCe qui s'est passéQue faire
not_foundLever a répondu, et n'a ni ce site ni cette offre.Vérifiez l'identifiant avec resolve_company.
invalid_inputLes arguments ont été refusés avant toute requête.Lisez le message, qui nomme l'argument et ce qu'il prend.
rate_limitedLever demande à ce client de ralentir.Attendez, puis rappelez avec les mêmes arguments. L'offre est toujours en ligne.
parse_failureLever a répondu dans une forme que ce client ne lit pas.Signalez-le sur le suivi d'incidents.
network_errorLa requête n'a pas abouti.Réessayez sous peu.
timeoutLa requête a dépassé son délai.Demandez moins d'entreprises, ou un limit plus petit.

Comme bibliothèque

La couche qui lit Lever est publiée seule, avec son rythme, son cache et ses erreurs, sans protocole attaché.

import { Client } from "mcp-lever/client";

const client = new Client({ minIntervalMs: 2000 });
const resolved = await client.resolveCompany("Included Health");
const jobs = await client.listPostings(resolved.found[0], { limit: 10 });
console.log(jobs.length);

ClientOptions prend minIntervalMs, timeoutMs, cacheTtlMs et fetchImpl. Un écart sous le plancher publié est ignoré, donc le plancher tient également ici.

Rythme et attribution

Les deux hôtes d'API publient Crawl-delay: 1, donc les requêtes partent une à une avec au moins une seconde entre elles, et ce plancher tient quelle que soit la configuration du client. Le User-Agent porte le projet et une adresse où joindre une personne, et n'imite aucun navigateur.

Les lectures vont vers api.lever.co et api.eu.lever.co, les hôtes que Lever documente pour ses données d'offres. Les pages carrières jobs.lever.co sont laissées tranquilles.

Chaque offre porte l'adresse de sa page Lever et son adresse de candidature. Créditez l'entreprise et renvoyez vers cette page quand vous montrez une offre.

Ce MCP est un projet non officiel, sans affiliation à Lever ni aux entreprises dont il lit les sites.

Confidentialité

Ce serveur ne collecte rien sur vous et n'envoie rien à son auteur. Il tourne sur votre machine, ne joint que api.lever.co et api.eu.lever.co, garde ses réponses en mémoire le temps qu'il tourne, et n'écrit rien sur le disque. PRIVACY.md dit ce qu'une requête emporte et quels réglages changent cela.

Développement

npm install
npm run build:fixtures
npm test
npm run check

Les tests s'exécutent sur des fixtures engendrées et n'émettent aucune requête. La suite en direct, npm run test:live, émet une requête par route et tourne chaque nuit contre le service lui-même.

Contribuer

Les anomalies, les questions et les idées ont leur place dans le suivi d'incidents. Les propositions de modification sont bienvenues ; ouvrir un ticket d'abord aide à s'accorder sur la forme du changement. Voir CONTRIBUTING.md.

Licence

MIT, voir LICENSE. Les offres appartiennent aux entreprises qui les ont publiées.