jira-lite-mcp
jira-lite-mcp is a Jira Cloud MCP server for Claude Code that exposes a small set of high-value read and write tools with model-friendly, markdown-aware responses instead of raw API payloads.
Read your work and projects:
jira_my_work(pending issues assigned to you),jira_list_projects(visible projects and keys),jira_project_summary(open counts, breakdown by status/type/priority, unassigned, stale).Inspect issues:
jira_get_issue(basic fields),jira_explain_issue(parent, subtasks, links, comments, possible transitions in one call),jira_search(JQL, paginated withcount/hasMore),jira_issue_fields(issue types and creatable fields per project),jira_get_worklog(estimate, total, per-entry detail).Custom fields by name or id: pass visible names like
"Criterios de aceptación"viafields/extraFields/customFields; the server resolves them against the instance, refreshes its cache, and errors on ambiguous or unknown names.Create and update:
jira_create_issue(validates against the real project/type schema, supportsdryRun, labels, parent, assignee by email/name/accountId, watchers, priority,originalEstimate),jira_update_issue(only sends given fields; non-editable fields error instead of being silently dropped).Move work along:
jira_transition_issue(target by state name, transition name or id, optional comment) andjira_link_issues(relations like "blocks", "relates to").Comment, log time, delete:
jira_add_comment,jira_add_worklog(returns Jira's interpretation in seconds),jira_delete(comments, worklogs, links only — issues cannot be deleted).Rich text is markdown both ways: descriptions, comments and textarea fields round-trip checklists, nested lists, headings, quotes, code blocks, rules, GitHub tables, and inline formatting.
Errors are actionable: invalid parameters are rejected before touching Jira, naming the correct equivalent; invalid transitions/links enumerate the valid options.
Diagnostics:
pingreports version and build timestamp so you can tell a missing capability from an undeployed one.Note vs README: the schema lacks
jira_claim_issue,jira_create_sprintandjira_move_to_sprint, andjira_explain_issueusesextraFieldsrather than the documentedfields.
Provides tools for interacting with Jira Cloud, enabling issue management (create, update, transition, comment, worklog, link), project summaries, search, and retrieval of issue details and fields.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@jira-lite-mcp what's my pending work in Jira?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
jira-lite-mcp
Servidor MCP para Jira Cloud, pensado para trabajar con Claude Code.
No pretende cubrir toda la API de Jira: expone pocas herramientas de alto valor, con respuestas legibles para un modelo en lugar de las respuestas crudas de la API.
Es genérico. No conoce proyectos, épicas ni campos personalizados concretos: los resuelve
contra la instancia a la que se conecta. Los nombres de campo se indican como se ven
("Criterios de aceptación") y el servidor los traduce a su identificador real.
Lo que cambia en cada versión está en CHANGELOG.md, con lo que conviene
revisar en las guías de cada equipo.
Requisitos
Node 20 o superior
Una cuenta de Jira Cloud con token de API
Related MCP server: Jira MCP Server
Instalación
npm install
cp .env.example .env # y rellenar
npm run build.env:
JIRA_URL=https://tu-organizacion.atlassian.net
JIRA_EMAIL=tu-correo@example.com
JIRA_TOKEN=tu-tokenRegistrar en Claude Code
claude mcp add jira-lite --scope user -- node /ruta/absoluta/a/jira-lite-mcp/dist/server.js--scope user lo deja disponible en todos los proyectos, con las credenciales en el .env de
este repositorio.
Comprobar que responde:
claude mcp get jira-liteTras cambiar el código hay que ejecutar
npm run buildy reiniciar la sesión: el cliente arranca el servidor al abrirla y mantiene ese proceso mientras dura, así que hasta entonces sigue sirviendo el código anterior./clearno basta.La herramienta
pingindica qué código está en ejecución:{ "status": "ok", "version": "1.2.0", "built": "2026-07-20T02:16:44.020Z" }Si
builtes anterior a la última compilación, la sesión está sirviendo código antiguo. Es la forma de distinguir una capacidad que no existe de una que no está desplegada.
Registrar en un proyecto concreto (.mcp.json)
Para dejarlo declarado en un repositorio y compartirlo con el equipo, se usa el scope
project, que escribe un .mcp.json en su raíz:
claude mcp add --scope project jira-lite -- node /ruta/absoluta/a/jira-lite-mcp/dist/server.jsEl fichero resultante se commitea. Como cada persona clonará este servidor en una ubicación distinta, la ruta absoluta conviene sustituirla por una variable con valor por defecto:
{
"mcpServers": {
"jira-lite": {
"command": "node",
"args": ["${JIRA_MCP_PATH:-/ruta/por/defecto}/jira-lite-mcp/dist/server.js"]
}
}
}Cada miembro define JIRA_MCP_PATH en su shell y mantiene su propio .env en este
repositorio. No hace falta declarar las credenciales en .mcp.json.
Si se prefiere pasarlas desde el cliente, se añaden como variables del servidor:
"env": {
"JIRA_URL": "${JIRA_URL}",
"JIRA_EMAIL": "${JIRA_EMAIL}",
"JIRA_TOKEN": "${JIRA_TOKEN}"
}⚠️ Nunca escribir el token literal:
.mcp.jsonse versiona.Un cliente que no encuentre la variable entrega el marcador sin sustituir en lugar de omitirlo. El servidor detecta ese caso y recurre al
.env, en vez de intentar autenticarse con la cadena${JIRA_TOKEN}y devolver un error de credenciales sin relación aparente.
La primera vez que alguien abra el proyecto, Claude Code pedirá aprobar los servidores
declarados. claude mcp reset-project-choices restablece esa decisión.
Un servidor con el mismo nombre en varios ámbitos se resuelve por precedencia —local, luego proyecto, luego usuario— y se usa la definición completa del que gane, sin combinar campos.
Herramientas
Lectura
Herramienta | Para qué |
| Issues asignados y pendientes. «¿Qué tengo pendiente en Jira?» |
| Proyectos visibles, con su clave. «¿Qué proyectos hay?» |
| Estado de un proyecto: abiertos, reparto por estado, tipo y prioridad, sin asignar y estancados |
| Un issue con todo su contexto: padre, subtareas, enlaces, comentarios y transiciones posibles |
| Datos básicos de un issue |
| Búsqueda por JQL |
| Tipos de issue de un proyecto y campos que admite cada uno al crearlo |
| Tiempo registrado en un issue: estimación, total y desglose |
jira_explain_issue, jira_get_issue y jira_search aceptan fields: los campos
personalizados a incluir, por su nombre visible o su identificador.
Escritura
Herramienta | Para qué |
| Tomar una tarea: comprueba que está libre, se la asigna y relee para confirmarlo |
| Crear un issue, validando los campos antes de enviarlos |
| Modificar campos de un issue |
| Cambiar de estado, opcionalmente con comentario |
| Enlazar dos issues |
| Comentar |
| Registrar tiempo |
| Crear un sprint en el tablero scrum del proyecto |
| Mover issues a un sprint |
| Eliminar un comentario, un registro de tiempo o un enlace |
Notas de uso
Tomar una tarea se hace con jira_claim_issue, no asignándose a pelo. La herramienta lee
el issue, se detiene si ya tiene dueño, si está cerrada o si está sin asignar pero ya empezada,
y solo entonces escribe la asignación y vuelve a leerla para confirmar que quedó a tu
nombre. Jira no ofrece escritura condicional sobre la persona asignada: si dos personas se
asignan a la vez, la segunda escritura gana y Jira no avisa a la primera, de modo que las
dos se van convencidas de tenerla y el trabajo se hace dos veces. Releyendo, quien perdió lee
el nombre de la otra y se retira.
⚠️ No es una toma atómica. Entre la escritura y la relectura queda una ventana en la que las dos pueden leerse a sí mismas; lo que se consigue es reducirla a dos peticiones en vez de las horas que lleva desfasada una lista generada por la mañana. Cerrarla del todo exigiría algo que Jira no da, así que no se promete.
El estado se cambia con to, y solo si se ganó la asignación: transicionar antes dejaría
«En curso» una tarea que acaba de ser de otra persona. Si la transición falla, la toma no se
niega —la asignación ya está escrita y es ella la que reserva la tarea—: la respuesta lleva
transitionError con el motivo y los estados posibles.
Los campos se indican por su nombre. jira_create_issue y jira_update_issue aceptan
customFields con el nombre visible del campo, y el servidor resuelve el identificador y el
formato correctos contra la instancia:
{ "customFields": { "Criterios de aceptación": "- [ ] Primero\n- [ ] Segundo" } }Un parámetro que no existe da error, y el error dice cómo se llama aquí. Los nombres de
otros servidores de Jira —assigneeAccountId, timetracking, additional_fields,
projectKey— se descartaban en silencio y el issue nacía sin lo que se le había puesto. Ahora
la llamada se rechaza antes de tocar Jira, nombrando el equivalente: la persona asignada es
assignee, la estimación originalEstimate —una cadena suelta, no un objeto— y los campos
personalizados customFields.
El alta devuelve el asignado y la estimación tal como quedaron. Ninguno de los dos vuelve en la respuesta de creación de Jira, y los dos pueden quedar distintos de lo pedido sin que nada falle: la estimación en días se interpreta según la jornada del sitio y una asignación que el proyecto no admite se descarta. Se releen del issue creado para poder contrastarlos.
Un nombre repetido se rechaza en vez de devolver vacío. Una instancia puede tener varios campos con el mismo nombre visible, uno por proyecto. Al leer un issue se piden todos los candidatos y se usa el que aplica a ese proyecto, que es lo normal; si aplica más de uno, el error enumera sus identificadores para elegir. Antes se resolvía al primero, que en otro proyecto no tiene valor: el issue se leía como si el campo estuviera vacío.
El catálogo de campos se refresca solo. Se cachea al primer uso, pero un identificador desconocido lo hace pedirse de nuevo antes de darlo por inexistente. Así un campo creado en Jira con la sesión ya abierta se puede leer sin reiniciarla.
Los campos de texto rico son markdown, en las dos direcciones. Descripciones, comentarios
y campos textarea se leen como markdown en lugar de aplanados a texto corrido, y lo que se
escribe se traduce al formato de la API. Cubre listas de tareas —las casillas marcables del
editor—, listas con viñetas y numeradas anidadas, encabezados, citas, bloques de código,
reglas, tablas con la sintaxis de GitHub y, en línea, negrita, cursiva, tachado, código y enlaces.
{ "customFields": { "Criterios de aceptación": "- [ ] Sin marcar\n- [x] Hecho" } }Al leer, ese mismo campo vuelve con su estructura y con el estado de cada casilla, así que una lista de criterios se distingue de un párrafo suelto. Una línea suelta sigue siendo un párrafo: los saltos con los que se escribió el texto se conservan tal como se ven en Jira.
Se valida antes de escribir. Al crear un issue se comprueban los campos contra el esquema real del proyecto y del tipo. Un payload incorrecto falla en local, sin llegar a la API: Jira reserva la clave del issue al procesar la petición, y una petición inválida la consume igual.
Los estados se indican por su nombre. jira_transition_issue acepta el estado de destino
("Finalizada"), el nombre de la transición ("Listo") o su identificador, y resuelve cuál
aplica contra el workflow del issue.
En JQL los tipos de issue van en inglés. Un sitio traducido muestra Historia o Error,
pero jira_search necesita Story o Bug: escribir el nombre traducido devuelve cero
resultados sin dar error. jira_project_summary no se ve afectado, porque agrupa por tipo
sobre los issues ya recuperados.
Campos obligatorios por convención. Un equipo puede dar por obligatorio un campo que
Jira no marca como tal —y cuya ausencia, por tanto, no señala—. JIRA_REQUIRED_FIELDS lo
convierte en un error al crear:
JIRA_REQUIRED_FIELDS_LAN=Team # solo en el proyecto LAN
JIRA_REQUIRED_FIELDS=Team # en todosNo se rellena nada automáticamente: la creación se rechaza para que el valor lo decida
siempre quien la pide. Con dryRun la comprobación se hace igualmente, sin gastar una clave.
En una subtarea el requisito se comprueba contra su issue padre, porque hereda de él parte del contexto. Algunos campos —el equipo asignado, por ejemplo— Jira ni siquiera admite enviarlos en una subtarea: los rechaza indicando que se heredan. Exigirlos en el payload haría imposible crear subtareas en un proyecto con esta política.
No se pueden eliminar issues. jira_delete cubre comentarios, registros de tiempo y
enlaces, pero no issues: borrar uno destruye trabajo registrado junto con sus subtareas y deja
un hueco permanente en la numeración del proyecto. Para retirar un issue de la circulación,
moverlo a un estado final con jira_transition_issue.
Los sprints cuelgan del tablero, no del proyecto. Y solo los tableros scrum los admiten:
en un proyecto kanban no hay dónde crearlos. jira_create_sprint acepta la clave del proyecto
y localiza su tablero scrum; si hay más de uno, el error los enumera con su boardId en vez de
elegir por su cuenta.
Crear un sprint no lo arranca. Queda en estado future. Iniciarlo cierra el anterior y fija
el compromiso del equipo, así que esa decisión se deja en Jira.
{ "project": "LAN", "name": "Sprint 12", "startDate": "2026-09-01", "endDate": "2026-09-15" }Una fecha sin hora se ancla a medianoche UTC: Jira solo muestra el día, y anclarla a la hora local la desplazaría al día anterior para quien esté al oeste del meridiano.
Un issue pertenece a un solo sprint. jira_move_to_sprint lo saca del anterior, así que
sirve igual para poblar un sprint nuevo que para reubicar trabajo. La API mueve como mucho 50
issues por petición y aplica cada una entera o ninguna: con más de 50 la respuesta indica
cuáles se movieron y qué lote falló, en lugar de dar por hecho que se movió todo.
Los campos personalizados hay que pedirlos. jira_get_issue, jira_explain_issue y
jira_search devuelven un juego fijo de campos; cualquier otro solo viene si se nombra en
fields, porque una instancia con decenas de campos por proyecto haría ilegible cada lectura.
{ "issueKey": "LAN-2766", "fields": ["Criterios de aceptación"] }Esto importa más de lo que parece: la ausencia del campo en la respuesta no significa que el
issue no lo tenga, y los dos casos se leen igual. Un ticket cuyos criterios de aceptación
viven en su campo se lee, sin fields, como un ticket sin criterios. Para modificar un campo
hay que reescribirlo entero, así que leerlo antes —con fields— es lo que evita borrar lo que
hubiera puesto a mano.
Cada campo se devuelve bajo la clave que se pidió: por identificador, el identificador;
por nombre, tal como se escribió. No bajo el nombre canónico del campo, que en un sitio
traducido depende del idioma. Un issue referenciado —parent— se devuelve como {key, summary},
no con el documento entero anidado.
El nombre no identifica: una instancia puede tener varios campos llamados igual, uno por
proyecto. Cuando el nombre es ambiguo se puede pasar el identificador (["customfield_10064"]),
que sí es único. En jira_get_issue y jira_explain_issue un nombre que no se resuelve es un
error; en jira_search se informa en warning y el resto de resultados se devuelve igual,
porque un issue de otro proyecto no debe tumbar la página entera.
Las búsquedas no devuelven el total de coincidencias. El endpoint de Jira pagina y no
informa del total, así que jira_search devuelve cuántos issues trae (count) y si quedan más
(hasMore).
Desarrollo
npm run dev # servidor en modo watch
npm run build # compilar a dist/Inspeccionar el servidor sin pasar por Claude Code:
npx @modelcontextprotocol/inspector --cli node dist/server.js --method tools/list
npx @modelcontextprotocol/inspector --cli node dist/server.js \
--method tools/call --tool-name jira_my_work --tool-arg limit=5La arquitectura y las decisiones de diseño están en docs/plan/PLAN.md.
Available Tools
15 toolsjira_add_commentA
Añade un comentario a un issue de Jira. El texto se envía en texto plano y se convierte al formato que espera la API, conservando los saltos de línea.
Inputs: body (required), issueKey (required).
jira_add_worklogA
Registra tiempo trabajado en un issue de Jira. La respuesta incluye cómo ha interpretado Jira el tiempo enviado, en segundos, porque la duración de una jornada la define la configuración del sitio.
Inputs: issueKey (required), timeSpent (required), comment, started.
jira_create_issueA
Crea un issue en Jira. Valida los campos contra el esquema real del proyecto y del tipo de issue antes de enviarlos, de modo que un payload incorrecto falle sin consumir una clave de issue. Los campos personalizados se indican por su nombre visible o por su identificador, y la persona asignada admite correo o nombre además del accountId. Con dryRun se comprueba el resultado sin crear nada. Conviene consultar antes jira_issue_fields para conocer los campos disponibles.
Inputs: project (required), summary (required), issueType (required), dryRun, +8 more.
jira_deleteA
Elimina de forma permanente un comentario, un registro de tiempo o un enlace entre issues. Los identificadores se obtienen de jira_explain_issue (comentarios y enlaces) o de jira_get_worklog. No permite eliminar issues: para retirar uno de la circulación, moverlo a un estado final con jira_transition_issue.
Inputs: id (required), type (required), issueKey.
jira_explain_issueA
Devuelve un issue con todo su contexto en una sola llamada: descripción en texto legible, issue padre, subtareas, issues enlazados, comentarios recientes y estados a los que puede moverse. Admite pedir campos adicionales por su nombre. Pensado para entender un ticket completo sin encadenar varias consultas.
Inputs: issueKey (required), extraFields.
jira_get_issueA
Obtiene un issue de Jira por su clave: título, tipo, estado, prioridad, responsable, issue padre, etiquetas, fechas, estimación y tiempo dedicado, descripción y enlace web. Admite pedir campos adicionales por su nombre. Para subtareas, enlaces y comentarios, usar jira_explain_issue.
Inputs: issueKey (required), fields.
jira_get_worklogA
Devuelve el tiempo registrado en un issue de Jira: la estimación original, el total dedicado y cada registro con su autor, duración, fecha y descripción. Incluye el identificador de cada registro, necesario para eliminarlo.
Inputs: issueKey (required).
jira_issue_fieldsA
Devuelve los tipos de issue de un proyecto de Jira y, si se indica un tipo, los campos que admite al crearlo: identificador, nombre, si es obligatorio, tipo de dato y valores permitidos. Útil para conocer los campos reales de la instancia antes de crear un issue.
Inputs: project (required), issueType.
jira_link_issuesA
Enlaza dos issues de Jira. La relación se indica tal como se enuncia, desde el primer issue hacia el segundo: "blocks", "is blocked by", "relates to", "duplicates". Se resuelve contra los tipos de enlace de la instancia y, si no existe, la respuesta enumera las relaciones posibles.
Inputs: issueKey (required), relation (required), targetKey (required).
jira_my_workA
Devuelve los issues asignados al usuario autenticado que siguen pendientes, ordenados por fecha de actualización. Responde a preguntas como "¿qué tengo pendiente en Jira?". Cada issue incluye clave, título, tipo, estado, prioridad y fecha de última actualización.
Inputs: limit, project, includeDone.
jira_project_summaryA
Resume el estado de un proyecto de Jira a partir de sus issues abiertos: cuántos hay, cómo se reparten por estado, tipo y prioridad, cuántos están sin asignar y cuántos llevan tiempo sin actualizarse. Devuelve datos agregados, no una valoración.
Inputs: project (required), staleDays.
jira_searchA
Busca issues en Jira usando una consulta JQL. Útil para encontrar tickets por proyecto, estado, asignación, sprint, etc. Devuelve los issues de una página junto con si quedan más resultados; la API de búsqueda no informa del total de coincidencias.
Inputs: jql (required), limit.
jira_transition_issueA
Cambia el estado de un issue de Jira. El destino se indica por el nombre del estado, por el nombre de la transición o por su id, y se resuelve contra las transiciones que el issue admite en ese momento. Si el destino no es válido, la respuesta enumera los estados posibles. Admite un comentario en la misma operación.
Inputs: to (required), issueKey (required), comment.
jira_update_issueA
Actualiza los campos de un issue de Jira. Solo se envían los campos indicados; el resto queda intacto. Valida contra los campos que el issue admite editar, de modo que un campo no editable produce un error en lugar de descartarse en silencio. Los campos personalizados se indican por su nombre visible o por su identificador.
Inputs: issueKey (required), labels, summary, assignee, +5 more.
pingA
Comprueba que el servidor Jira Lite MCP responde e indica qué código está ejecutando: versión declarada y fecha de compilación. Útil para distinguir una capacidad que no existe de una que existe pero no está desplegada en la sesión en curso.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 15 tools
Each tool has a clearly distinct purpose: ping for health, get/search/create/update/transition for individual issues, explain for full context, link for linking, comment/worklog add/get/delete, and project summary. Even related tools like jira_get_issue and jira_explain_issue are complementary, not overlapping.
Most tools follow the consistent pattern 'jira_verb_noun' (e.g., jira_get_issue, jira_create_issue). The only outlier is 'ping' which lacks the 'jira_' prefix. This minor inconsistency prevents a perfect score.
With 15 tools, the set is well-scoped for a Jira lite server. Each tool covers a distinct operation, and there is no bloat. The count is appropriate for the domain.
The tool surface covers most essential Jira operations: CRUD for issues, transitions, linking, comments, worklogs, and project summary. Minor gaps exist (no project listing, no issue deletion, no worklog update), but these are acceptable for a 'lite' server.
Maintenance
Related MCP Connectors
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Hosted Airtable MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Zotero MCP server for Claude and ChatGPT: search, citations, safe writes, PDF passages and pages.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server that enables interaction with JIRA APIs through Claude Desktop, allowing users to search, create, update, and manage JIRA issues using natural language commands.1-
- AlicenseAqualityFmaintenanceA Model Context Protocol server that enables interaction with Jira's REST API using natural language commands, allowing users to manage Jira projects, issues, comments, and workflows through Claude Desktop and other MCP clients.107MIT
- AlicenseAqualityBmaintenanceMCP server for Jira integration with stdio transport. Enables reading, writing, and managing Jira issues and projects directly from Claude Desktop. Supports issue creation, updates, comments, JQL search, and project management.231,137 npm14MIT
- AlicenseNot gradedqualityDmaintenanceA server that exposes Jira Cloud operations as MCP tools, enabling programmatic management of Epics, Stories, Tasks, and Sprints directly from an AI chat or agentic workflow.1MIT