Skip to main content
Glama

jira-mcp

MCP-сервер для доступа к Jira Server / Data Center (и, опционально, к Confluence Server / DC) через atlassian-python-api. Аутентификация — Personal Access Token (Bearer). Транспорт — stdio.

Требования

  • Python ≥ 3.11 (в разработке используется 3.13)

  • uv

Related MCP server: MCP Atlassian Node Server

Установка

Сервер ставится и запускается прямо из репозитория через uvx — клонировать исходники и указывать путь до них не нужно. uvx скачает пакет, соберёт его в изолированном окружении и запустит точку входа:

uvx --from git+https://github.com/nsleader/jira-mcp.git jira-mcp

Чтобы зафиксировать версию, можно указать тег или коммит:

uvx --from git+https://github.com/nsleader/jira-mcp.git@v0.1.0 jira-mcp

Конфигурация

Креды передаются как переменные окружения в конфигурации подключения MCP-сервера (блок env), а не через .env файл.

Переменная

Обязательна

По умолчанию

Описание

JIRA_URL

да

—

Базовый URL Jira, напр. https://jira.example.com

JIRA_PERSONAL_TOKEN

да

—

Personal Access Token (Bearer)

JIRA_SSL_VERIFY

нет

true

Проверка TLS-сертификата

JIRA_TIMEOUT

нет

75

Таймаут запроса, сек

CONFLUENCE_URL

для Confluence

—

Базовый URL Confluence, напр. https://wiki.example.com

CONFLUENCE_PERSONAL_TOKEN

нет

JIRA_PERSONAL_TOKEN

Отдельный PAT Confluence

CONFLUENCE_SSL_VERIFY

нет

как у Jira

Проверка TLS-сертификата

CONFLUENCE_TIMEOUT

нет

как у Jira

Таймаут запроса, сек

PAT создаётся в Jira: Profile → Personal Access Tokens; в Confluence — там же в своём профиле. Confluence — отдельное приложение со своим адресом и, как правило, своим токеном, поэтому CONFLUENCE_URL из JIRA_URL не выводится. Без него сервер работает как обычно, а confluence-инструменты возвращают понятную ошибку о ненастроенном подключении.

Запуск

Сервер общается по stdio и запускается MCP-клиентом. Для локальной проверки можно задать переменные вручную:

JIRA_URL=https://jira.example.com JIRA_PERSONAL_TOKEN=xxxx \
  uvx --from git+https://github.com/nsleader/jira-mcp.git jira-mcp

Подключение к Claude Code

claude mcp add jira \
  -e JIRA_URL=https://jira.example.com \
  -e JIRA_PERSONAL_TOKEN=your-personal-access-token \
  -- uvx --from git+https://github.com/nsleader/jira-mcp.git jira-mcp

Чтобы включить инструменты Confluence, добавьте туда же -e CONFLUENCE_URL=https://wiki.example.com и (если токен отдельный) -e CONFLUENCE_PERSONAL_TOKEN=your-confluence-token.

Подключение к Claude Desktop

Пошаговая инструкция для чистого Mac и пользователя без опыта разработки — docs/install-macos-claude-desktop.md. Короткий вариант — в claude_desktop_config.json:

{
  "mcpServers": {
    "jira": {
      "command": "uvx",
      "args": ["--refresh", "--from", "git+https://github.com/nsleader/jira-mcp.git", "jira-mcp"],
      "env": {
        "JIRA_URL": "https://jira.example.com",
        "JIRA_PERSONAL_TOKEN": "your-personal-access-token"
      }
    }
  }
}

Claude Desktop запускает MCP-серверы с урезанным PATH, поэтому "command": "uvx" у многих не находится (spawn uvx ENOENT). В этом случае укажите абсолютный путь, например /Users/<пользователь>/.local/bin/uvx или /opt/homebrew/bin/uvx.

--refresh заставляет uvx перечитать HEAD репозитория на каждом старте: иначе сборка берётся из кэша и установка остаётся на том коммите, на котором была поставлена. Стоит это меньше секунды, но требует доступа к GitHub при запуске.

Доступные инструменты

Инструмент

Описание

get_issue

Получить задачу по ключу (PROJ-123)

search_issues

Поиск задач по JQL

add_comment

Добавить комментарий к задаче

get_issue_types

Типы задач инстанса или конкретного проекта (что можно передать в create_issue)

create_issue

Создать эпик / задачу / подзадачу — вызывается строго по явной просьбе пользователя

get_transitions

Куда задачу можно перевести из текущего статуса (и какие поля обязательны)

transition_issue

Сменить статус задачи — вызывается строго по явной просьбе пользователя

assign_issue

Назначить, сменить или снять исполнителя задачи — вызывается строго по явной просьбе пользователя

add_worklog

Залогировать время на задачу — вызывается строго по явной просьбе пользователя

get_all_projects

Список всех проектов, видимых пользователю

get_project

Один проект по ключу или id

get_project_roles

Роли проекта и их состав (пользователи и группы) — где искать реального РП

search_users

Поиск пользователей по логину, имени или email (подстрока)

get_all_users

Все пользователи Jira — объединение групп, дающих доступ к Jira

find_groups

Найти группы Jira по названию → узнать нужную для get_all_users

get_user_worklog

Часы одного пользователя за период (Tempo Timesheets)

get_users_worklog

Часы по списку пользователей за период, с разбивкой по каждому

get_team_worklog

Часы всех участников команды Tempo (teamId) за период — отчёт «Logged Time»

get_all_teams

Список всех команд Tempo (id, название, лид)

find_team

Найти команды Tempo по названию (подстрока) → получить teamId

get_team_members

Все участники команды Tempo (ключ, имя, роль, период членства)

get_user_plan

Планы Tempo Planner: на какие проекты и на сколько часов в день запланирован пользователь

get_users_plan

Планы Tempo Planner по списку пользователей за один запрос, с разбивкой по каждому

search_confluence

Поиск страниц Confluence: текст, пространство, метка (CQL под капотом)

get_confluence_page

Прочитать страницу по id / ссылке / space + title — тело в Markdown

get_confluence_page_children

Дочерние страницы — обход дерева пространства вниз

get_confluence_spaces

Список пространств Confluence (ключи для поиска)

Структура

src/jira_mcp/
├── config.py        # настройки из окружения (pydantic-settings)
├── client.py        # фабрики Jira- и Confluence-клиентов (кеш)
├── identity.py      # логин ↔ ключ пользователя: чем ловится «0 часов»
├── server.py        # FastMCP + main()
└── tools/
    ├── issues.py    # инструменты по задачам + create_issue, transition_issue, assign_issue
    ├── projects.py  # проекты и роли проекта (get_project_roles)
    ├── worklogs.py  # отчёты по времени (Tempo Timesheets) + add_worklog
    ├── tempo.py     # Tempo Planner: планирование (get_user_plan)
    └── confluence.py # поиск и чтение статей Confluence

Чтение задач

get_issue и search_issues отдают ответ Jira как есть, с одной правкой: customfield_* получают человеческие имена, а пустые выбрасываются. Jira возвращает каждое кастомное поле, заведённое на инстансе, — на одной задаче это под сотню записей customfield_11704: null, среди которых пара заполненных ничем не отличается от остального.

Читающему модель это ломает: она видит description: null и отвечает, что описания нет, — а текст лежит в «Описании пресейла». Поэтому

"Описание пресейла (customfield_12001)": "{*}Контекст сделки{*}: ..."

Id остаётся в ключе: писать в поля всё равно приходится по id — extra_fields у create_issue, экраны переходов у transition_issue. Каталог полей читается раз на сессию, тем же запросом, которым ищутся agile-поля.

Создание задач

create_issue создаёт issue через rest/api/2/issue от имени владельца токена. Иерархия Jira Server/DC не лежит в обычных полях, поэтому сервер сам разбирается с agile-полями Greenhopper (их id различаются от инстанса к инстансу и находятся по типу схемы в rest/api/2/field):

  • issue_type="Epic" → в обязательное поле Epic Name пишется epic_name, а если он не задан — summary

  • обычный тип + parent="PROJ-1" → ключ эпика пишется в Epic Link

  • подзадача (subtask: true) + parent="PROJ-2" → поле parent; без parent вызов отклоняется до похода в Jira

Тип задачи резолвится по имени (регистронезависимо) или id заранее: если такого типа нет, ошибка перечисляет доступные, а не возвращает голый HTTP 400. Имена типов на инстансах переименовывают и локализуют — при сомнениях сначала get_issue_types(project_key).

Остальные поля — description, assignee (логин Server/DC), priority, labels, components, due_date; всё, что не покрыто сигнатурой (story points, обязательные кастомные поля), передаётся через extra_fields, например {"customfield_10004": 3}.

Как и add_worklog, инструмент пишущий и в описании помечен как вызываемый строго по просьбе пользователя: удалить созданную задачу сервер не умеет.

Смена статуса

Статус в Jira Server/DC нельзя присвоить напрямую — он результат перехода workflow, а набор переходов зависит от текущего статуса, схемы проекта и прав владельца токена. Поэтому transition_issue сначала читает rest/api/2/issue/{key}/transitions, а потом постит найденный переход.

  • target — имя целевого статуса (Ready For Test), имя перехода (Start Progress) или числовой id перехода; сравнение регистронезависимое, приоритет у целевого статуса (кнопка и её результат в workflow нередко называются по-разному)

  • если такого перехода нет, ошибка перечисляет доступные из текущего статуса — вместо голого HTTP 400

  • задача уже в нужном статусе → changed: false, без запроса на запись

  • comment уходит в update (добавление комментария в рамках перехода), resolution — в поля закрывающего перехода, всё остальное для экранов перехода передаётся через fields по id поля (см. required_fields в get_transitions)

Инструмент пишущий и помечен как вызываемый строго по просьбе пользователя: переход виден всей команде (доски, уведомления, автоматизации), а обратного перехода в workflow может не быть.

Смена исполнителя

assign_issue меняет исполнителя через отдельный эндпоинт PUT rest/api/2/issue/{key}/assignee: ему нужно только право «Assign Issues», а не «Edit Issues» и поле на экране редактирования.

  • assignee — логин (acutina) или ключ пользователя (JIRAUSER18613); ключ сначала резолвится в логин, потому что Server/DC назначает по логину. Неизвестное имя (чаще всего это отображаемое имя вроде «Кутина Анастасия») отклоняется до записи с подсказкой сначала вызвать search_users

  • assignee=None или пустая строка снимает исполнителя (если проект разрешает задачи без исполнителя)

  • задача уже на этом человеке → changed: false, без запроса на запись; в ответе — исполнитель до и после

Инструмент пишущий и помечен как вызываемый строго по просьбе пользователя: назначение рассылает уведомления.

Логирование времени

add_worklog пишет worklog через core-API Jira (rest/api/2/issue/{key}/worklog) от имени владельца токена; Tempo на Server/DC читает те же worklog'и, поэтому списанное время видно в отчётах выше.

  • time_spent — синтаксис Jira: 2h, 90m, 2h 30m, 1d 4h

  • started — YYYY-MM-DD (привязывается к 09:00 локального времени, чтобы worklog не уехал на предыдущий день в восточных таймзонах), YYYY-MM-DDTHH:MM или метка времени со смещением; по умолчанию — сейчас

В описании инструмента явно указано, что он вызывается строго по просьбе пользователя: это единственный инструмент, пишущий время, и отменить запись из сервера нельзя.

Логин и ключ пользователя

У человека в Jira два имени: логин (acutina, меняется при смене фамилии) и ключ (JIRAUSER18613, не меняется никогда). До Jira 6.0 ключ совпадал с логином, поэтому у старых сотрудников разницы не видно — у всех, кого завели позже, она есть.

Две части Tempo расходятся в том, какое из имён им нужно:

API

Фильтр

Принимает

Tempo Timesheets (часы)

worker

ключ

Tempo Planner (планы, календарь)

assigneeKeys, user

логин

Ни одна из них не ругается на чужое имя: фильтр просто ни с кем не совпадает, и ответ приходит пустой. Отчёт от этого не ломается — он врёт: «Кутина за неделю залогировала 0 часов» выглядит как факт.

Поэтому инструменты принимают любое из двух имён и приводят его к нужному сами (identity.py, кеш на время жизни процесса, поиск через rest/api/2/user). get_user_worklog возвращает разрешённый worker_key, get_user_plan — login, а by_user в групповых отчётах ключуется ключом и несёт display с человеческим именем. Имя человека («Кутина») именем пользователя не является — его сначала ищут через search_users.

Tempo Planner

get_user_plan читает раздел планирования через rest/tempo-planning/1/allocation и рабочий календарь пользователя (rest/tempo-core/1/user/schedule), поэтому разбивка по дням не учитывает выходные и праздники — так же, как сам Tempo. На Server/DC это плагин Jira: работает тот же JIRA_URL и PAT, отдельный Tempo-токен не нужен.

Confluence

Четыре инструмента только на чтение: найти статью и прочитать её.

Поиск. search_confluence собирает CQL из обычных аргументов — query (полнотекстовый text ~), space, label, content_type — и по умолчанию сортирует по релевантности; newest_first=true переключает на «что менялось недавно». Для запросов, которые сигнатурой не выразить (creator = jsmith AND lastmodified > -7d), есть параметр cql — он идёт на сервер как есть. Маркеры подсветки совпадений (@@@hl@@@), которые Server подмешивает в заголовок и excerpt, вычищаются. В ответе total — общее число совпадений, а не размер выданной страницы результатов.

Чтение. get_confluence_page принимает id, любую ссылку на страницу (?pageId=123, /pages/123/Title, /display/SPACE/Title) либо пару space + title. Тело берётся из отрендеренного body.view (макросы уже раскрыты) и конвертируется в Markdown: заголовки, списки, таблицы и блоки кода сохраняются, разметка макросов — нет; относительные ссылки достраиваются до абсолютных. Другие варианты — format="text", "html" и "storage" (исходный XHTML, нужен только чтобы где-то отредактировать страницу).

Длинные статьи режутся по max_chars (по умолчанию 20000), чтобы не забивать контекст: в ответе есть content_chars, truncated и next_offset — следующий кусок читается тем же инструментом с offset.

Рядом с текстом возвращается контекст статьи: пространство, версия, кто и когда менял, метки и хлебные крошки ancestors. Вниз по дереву — get_confluence_page_children; ключи пространств — get_confluence_spaces (персональные ~user скрыты, если не попросить include_personal).

Разработка

uv run ruff check
uv run pytest

Available Tools

19 tools
add_commentB

Add a comment to a Jira issue.

Args: issue_key: The issue key, e.g. PROJ-123. comment: The comment body (plain text / Jira wiki markup).

Inputs: comment (required), issue_key (required). Returns: object

add_worklogA

Log time on a Jira issue, as the user who owns the API token.

CALL THIS TOOL STRICTLY ON THE USER'S EXPLICIT REQUEST. It is the only tool here that writes: it creates a real worklog under the user's name and cannot be undone from this server. Never call it on your own initiative — not after finishing a task, not to "correct" hours seen in a report, not as a step inferred from some other request. If the user has not asked to log time, ask them first.

Args: issue_key: The issue to log against, e.g. PROJ-123. time_spent: Duration in Jira syntax — 2h, 90m, 2h 30m, 1d 4h (w/d/h/m). Jira converts it using the instance's working day/week, so 1d is usually 8h, not 24h. started: When the work happened. YYYY-MM-DD (anchored at 09:00 local time), YYYY-MM-DDTHH:MM, or a timestamp with an offset. Defaults to now — pass the date explicitly when logging for a past day. comment: Optional worklog comment (plain text / Jira wiki markup).

Returns the created worklog: id, time_spent, started, author and a browse link to the issue.

Inputs: issue_key (required), time_spent (required), comment, started. Returns: object

create_issueA

Create a Jira issue — epic, task, story or sub-task.

CALL THIS TOOL STRICTLY ON THE USER'S EXPLICIT REQUEST. It writes a real issue into the project under the token owner's name and this server cannot delete it afterwards. Never create issues on your own initiative (not to "track" work you are doing, not as an inferred step of another request). When several issues are described at once, confirm the list with the user before creating them.

Args: project_key: Target project key, e.g. PROJ. summary: Single-line title of the issue. issue_type: Type name as it appears in Jira — Task (default), Epic, Story, Bug, Sub-task… Call get_issue_types when unsure; names are instance-specific and may be localised. description: Body text (plain text / Jira wiki markup). parent: Key of the parent issue. For a sub-task this is its parent task (required). For any other type this is the epic it belongs to — it is written to the Epic Link field. epic_name: Short board label for an epic. Epics only; defaults to summary when omitted. assignee: Username (Server/DC login) to assign the issue to. priority: Priority name, e.g. Major. labels: Labels to set. components: Component names to set. due_date: Due date, YYYY-MM-DD. extra_fields: Raw field overrides merged in last, for anything this signature does not cover — e.g. story points or a required custom field: {"customfield_10004": 3}.

Returns the created issue: key, id, url and the resolved type/parent, so the key can be reused directly (e.g. as parent for the epic's children).

Inputs: summary (required), project_key (required), labels, parent, +8 more. Returns: object

find_groupsA

Find Jira groups by name — use it to discover the license group name.

Handy when you don't know which group holds all users. Search e.g. users to find candidates like jira-users / jira-software-users, then pass the right one to get_all_users.

Args: query: Substring to match against group names (default users). limit: Maximum number of groups to return (default 20).

Inputs: limit, query. Returns: object

find_teamA

Find Tempo teams whose name contains query (case-insensitive).

Tempo has no server-side team search, so this lists every team and filters locally. Handy to turn a team name into the teamId that get_team_worklog needs.

Args: query: Substring to match against the team name. expand: Optional comma-separated Tempo expand fields (e.g. lead,program).

Inputs: query (required), expand. Returns: result

get_all_projectsA

List all Jira projects visible to the authenticated user.

Args: include_archived: Include archived projects in the result. expand: Optional comma-separated list of fields to expand (e.g. description,lead,url).

Inputs: expand, include_archived. Returns: result

get_all_teamsA

List every Tempo team (id, name, lead, …).

Use this to discover a team's numeric teamId for get_team_worklog. To look one up by name, prefer find_team.

Args: expand: Optional comma-separated Tempo expand fields (e.g. lead,program).

Inputs: expand. Returns: result

get_all_usersA

List all Jira users (union of the groups that grant Jira access).

Jira Server/DC has no single "all users" endpoint — users are enumerated through group membership. By default this reads every group that grants Jira Software access on this instance and de-duplicates the members. Pass groups to target specific group(s) instead.

Args: groups: Group names to read. Defaults to the instance's Jira Software license groups. status: Which users to return by account state — active (default, enabled users only), inactive (deactivated / blocked / former employees, active=false), or all.

Inputs: groups, status. Returns: result

get_issueA

Get a single Jira issue by key (e.g. PROJ-123).

Args: issue_key: The issue key, e.g. PROJ-123. fields: Optional comma-separated list of fields to return (e.g. summary,status,assignee). Defaults to all fields.

Inputs: issue_key (required), fields. Returns: object

get_issue_typesA

List the issue types available for create_issue.

Call this first when unsure what issue_type a project accepts — instances rename and translate types (Task/Задача, Story, Sub-task), so guessing produces a 400.

Args: project_key: Optional project key to restrict to the types actually enabled in that project's scheme. Without it, every type on the instance is returned.

Inputs: project_key. Returns: result

get_projectA

Get a single Jira project by its key or id.

Args: project_key: The project key or id, e.g. PROJ or 10001. expand: Optional comma-separated list of fields to expand (e.g. description,lead,url).

Inputs: project_key (required), expand. Returns: object

get_team_membersA

List all members of a Tempo team.

Reads rest/tempo-teams/2/team/{team_id}/member/. Each member's key is the same value the Tempo worklog worker field carries — so it's what you pass on to per-user worklog tools. Note this is the Tempo team roster, not a Jira user group (see get_all_users for groups).

Args: team_id: Tempo team id (e.g. 79). raw: Return Tempo's untouched membership objects instead of the flattened key / display_name / role / membership-window shape. Use when you need fields not surfaced by default.

Inputs: team_id (required), raw. Returns: result

get_team_worklogA

Hours every member of a Tempo team logged in a date range, per worker.

Reproduces Tempo's "Logged Time" report grouped by worker (the Tempo.jspa#/reports/logged-time?teamId=…&groupBy=worker view): one worklog search filtered by teamId covers the whole team for [date_from, date_to] (both inclusive). The team roster is fetched separately so members who logged nothing still appear with 0 hours.

Args: team_id: Tempo team id (the teamId from the report URL, e.g. 79). date_from: Start date, inclusive, YYYY-MM-DD. date_to: End date, inclusive, YYYY-MM-DD. include_subtasks: Include worklogs on subtasks (the report's includeSubtasks toggle). Defaults to Tempo's own default. breakdown: Optional per-worker grouping — day, project, issue, both (=project+issue), all, or a comma combo like day,project. Each requested dimension appears as by_day / by_project / by_issue inside every worker's entry (e.g. day → hours-per-day per worker, the whole timesheet matrix, in ONE call — never call this once per user). only_active: Keep only current employees on an open team membership (default). Set False to include people who left the company or moved off the team — a team's roster accumulates them for years, so the default keeps the report to the people working now. exclude_absence: Drop vacation / sick-leave worklogs, which Tempo logs against a dedicated Absence account. Off by default so totals match Tempo's own report; turn it on to read the numbers as actual workload — otherwise a week of vacation looks identical to a week of work (8h/day either way).

Inputs: date_to (required), team_id (required), date_from (required), breakdown, +3 more. Returns: object

get_user_planA

What a user is planned for in Tempo Planner over a date range.

Answers "which projects is this person allocated to, for how many hours per day": fetches the user's plan allocations and expands them into planned hours within [date_from, date_to] (both inclusive), using the user's Tempo working-day calendar so weekends and public holidays are excluded exactly as Tempo itself does.

Args: username: Jira username / login (Tempo assignee key). date_from: Start date, inclusive, YYYY-MM-DD. date_to: End date, inclusive, YYYY-MM-DD. breakdown: Pass day to add by_day — planned hours for each date in the range, split by project inside each day. Omit for the compact view (plans + per-project totals only).

Returns plans (each allocation with its hours_per_day, period and target project/issue), by_project totals for the range, and optionally by_day.

Inputs: date_to (required), username (required), date_from (required), breakdown. Returns: object

get_users_planA

What a group of users is planned for in Tempo Planner, per user.

One allocation request covers every user in usernames for [date_from, date_to] (both inclusive) — never call this once per user. Each user's plans are then expanded against their own working-day calendar (calendars differ: part-time, regional holidays), so weekends and public holidays are excluded exactly as Tempo does.

Args: usernames: Jira usernames / logins (Tempo assignee keys). date_from: Start date, inclusive, YYYY-MM-DD. date_to: End date, inclusive, YYYY-MM-DD. breakdown: Pass day to add by_day inside every user's entry — planned hours for each date, split by project within each day. Omit for the compact view.

Returns by_user (each user's plans, by_project totals and optionally by_day, users sorted by planned hours desc; users with no plans appear with 0) and cross-user by_project totals.

Inputs: date_to (required), date_from (required), usernames (required), breakdown. Returns: object

get_users_worklogA

Total hours a group of users logged in a date range, per user.

Uses the Tempo Timesheets API: one search covers every user in usernames for [date_from, date_to] (both inclusive) — a single request, regardless of team size or breakdown. by_user always lists each worker's total; breakdown nests that worker's own day/project/ issue split inside their entry (still one request — never call this once per user).

Args: usernames: Tempo workers (Jira usernames / keys). date_from: Start date, inclusive, YYYY-MM-DD. date_to: End date, inclusive, YYYY-MM-DD. project: Optional project key to restrict to (e.g. PROJ). breakdown: Optional per-worker grouping — day, project, issue, both (=project+issue), all, or a comma combo like day,project. Each requested dimension appears as by_day / by_project / by_issue inside every user's entry (e.g. day → hours-per-day per worker in one call).

Inputs: date_to (required), date_from (required), usernames (required), project, +2 more. Returns: object

get_user_worklogA

Total hours a user logged in a date range, optionally broken down.

Uses the Tempo Timesheets API: one search returns all of the user's worklogs in [date_from, date_to] (both inclusive), filtered server-side.

Args: username: Tempo worker (Jira username / key). date_from: Start date, inclusive, YYYY-MM-DD. date_to: End date, inclusive, YYYY-MM-DD. project: Optional project key to restrict to (e.g. PROJ). breakdown: Optional grouping — day, project, issue, account, both (=project+issue), all, or a comma-separated combo like day,project. When day is combined with project/issue the project/issue hours are nested inside each day; otherwise they are flat for the period. exclude_absence: Drop vacation / sick-leave worklogs (Tempo's Absence account). Off by default so totals match Tempo.

Inputs: date_to (required), username (required), date_from (required), project, +2 more. Returns: object

search_issuesA

Search issues with a JQL query.

Args: jql: A JQL query, e.g. project = PROJ AND status = "In Progress". limit: Maximum number of issues to return (default 50).

Inputs: jql (required), limit. Returns: object

search_usersA

Search Jira users by name, username or email fragment.

Args: query: Substring to match against username, display name or email. limit: Maximum number of users to return (default 50). include_inactive: Include deactivated users in the result.

Inputs: query (required), limit, include_inactive. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 19 tools

    Disambiguation5/5

    Each tool targets a distinct resource and action. For example, get_project vs get_all_projects, search_users vs get_all_users, and the three worklog tools (get_user_worklog, get_users_worklog, get_team_worklog) have clear scopes (single user, group, team) with no overlap.

    Naming Consistency5/5

    Tool names follow a consistent verb_noun pattern: get_* for retrieval, search_* for search, add_* for creation, create_issue, and find_* for lookup. No mixed conventions or vague verbs.

    Tool Count5/5

    19 tools is well-scoped for a Jira/Tempo integration covering projects, issues, users, teams, worklogs, and plans. Each tool serves a clear purpose without being too few or too many.

    Completeness4/5

    The tool set covers core workflows: project/issue retrieval, user/team discovery, worklog and plan queries, and limited write operations (add_worklog, create_issue, add_comment). Missing update/delete operations for issues, but the primary focus on reporting is well-supported.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers