Skip to main content
Glama

ticket-writer MCP

MCP-сервер для MagOneAI. Репортёр оставляет запрос на фичу в свободной форме; рабочий процесс задаёт несколько вопросов, необходимых, чтобы перевести запрос в исполнимый вид, а затем создаёт тикет, в котором указаны проблема, что нужно сделать, критерии приёмки и все архитектурные решения.

Jira, GitHub, GitLab и Linear обслуживаются одним и тем же кодом.

Сервер никогда не обращается к трекеру. Он формирует запрос на создание тикета и возвращает его; отправку выполняет собственный HTTP-узел рабочего процесса.


Как работает рабочий процесс

free text  ──▶  check_request  ──"needs_clarification"──▶  ask the reporter ──┐
                     │                                                        │
                     │◀──────────────────── answers ─────────────────────────┘
                  "ready"
                     │
                     ▼
                render_ticket  ──"possible_duplicate"──▶  human confirms ──┐
                     │                                                     │
                     │◀────────── confirm_not_duplicate ───────────────────┘
              "ready_to_send"
                     │
                     ▼
          HTTP node: POST request.url  ◀── the only write in the workflow
                     │
                     ▼
              issue key + url back to the reporter

В WORKFLOW.md описан контракт по каждому узлу: точный входной и выходной JSON, а также все поля, которые попадают в тикет.


Related MCP server: ProduckAI MCP Server

Почему он не подключается к Jira напрямую

В первом черновике был REST-клиент Jira. Эта версия требовала наличия учётных данных на этой машине, обзавелась сценарием отказа, когда тикет формировался нормально, а POST не проходил, и привязывала рабочий процесс к одному трекеру.

Формирование запроса вместо этого означает:

  • здесь нет учётных данных — заголовки содержат имена {{PLACEHOLDER}}, которые API-узел подставляет из хранилища секретов MagOne

  • любой трекер — новый трекер добавляется одной записью словаря в src/targets.py

  • переиспользование того, что у MagOne уже есть — если подключён трекер через MCP, используйте target="generic" и передайте поля в его инструмент создания

  • легко встраивается шаг согласования — ничего не записывается до вызова формирования

  • тестируется только pytest, и ничем больше — во всём репозитории нет сети

Он также не пишет текст тикета. Агент рабочего процесса — языковая модель, и он лучше, чем любое правило из этого репозитория, умеет превращать сбивчивое сообщение из Slack в формулировку проблемы. Этому серверу принадлежит та часть, которая должна вести себя одинаково при каждом запуске: чек-лист, формулировки вопросов, формат тела и защита от дубликатов.


Инструменты

Инструмент

Назначение

check_request

Достаточно ли этого для создания тикета? Если нет — что спросить.

render_ticket

Запрос на создание тикета, отформатированный для конкретного трекера.

list_targets

Трекеры, ключи конфигурации, какие учётные данные нужны API-узлу.

duplicate_search_query

Необязательный. Строит поисковый запрос для проверки дубликатов.

Все четыре инструмента доступны только для чтения. Каждый ответ содержит status, по которому переключается канвас:

status

Действие рабочего процесса

ready

перейти к render_ticket

needs_clarification

задать questions, повторить цикл

possible_duplicate

показать candidates, получить ответ человека

ready_to_send

передать request в API-узел

error

прочитать hint — обычно отсутствует ключ config


Что делает тикет полным

check_request требует четыре поля, запрашиваемые в таком порядке, не более трёх за один раунд:

  1. problem — что болит сегодня, кого это касается

  2. goal — что должно существовать после завершения, в виде поведения

  3. acceptance_criteria — как ревьюер принимает или отклоняет задачу

  4. architecture_notes — принятые решения, ограничения, которые нужно соблюдать ("none known" допустимо, если дизайн ещё не определён)

affected_users и out_of_scope собираются, когда пользователь их указывает, но никогда не блокируют. Ответ короче 25 символов или повторяющий формулировку вопроса не считается ответом.

Чтобы изменить чек-лист, отредактируйте SLOTS в src/ticket.py — вопросы, порядок и ограничение по количеству определяются этим списком.


Целевые системы

target

config

Учётные данные, которые предоставляет API-узел

jira

base_url, project_key

{{JIRA_BASIC_AUTH}} — base64 email:api_token

github

owner, repo

{{GITHUB_TOKEN}} — PAT с правами чтения/записи Issues

gitlab

project_id, host?

{{GITLAB_TOKEN}} — токен с областью api

linear

team_id, project_id?

{{LINEAR_API_KEY}}

generic

нет — передайте fields в собственный MCP этого трекера

Различия, которые рендерер берёт на себя, чтобы агенту не приходилось:

  • Jira в description ожидает ADF, а не markdown. Передача markdown-строки — самый частый способ, которым падает самодельный узел Jira.

  • GitLab ожидает метки в виде строки через запятую; GitHub и Jira — в виде списка.

  • В GitHub нет поля приоритета, поэтому приоритет становится меткой priority-*.

  • Linear — это GraphQL: одна конечная точка, мутация в теле запроса.

Добавление трекера: одна запись в TARGETS с build(), возвращающим (url, headers, body). Вот и всё изменение.


Защита от дубликатов

Этот сервер не умеет искать, поэтому рабочий процесс передаёт ему данные: duplicate_search_query строит запрос, поисковый узел выполняет его, результаты возвращаются в render_ticket как existing_issues=[{key, summary, url}]. Краткие описания, у которых пересечение токенов ≥ 0.6, возвращаются как possible_duplicate.

Нет поискового узла — нет проверки — тикет всё равно формируется. Такова цена за то, что у нас нет собственного поискового клиента для каждого трекера.


Запуск

python -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytest -q          # 47 tests, no network, no account

Локальный MCP через stdio для Claude Desktop:

MCP_TRANSPORT=stdio .venv/bin/python -m src.server

Деплой:

docker build -t ticket-writer .
docker run -p 8000:8000 -e TICKET_WRITER_TOKEN=$(openssl rand -hex 32) ticket-writer
curl localhost:8000/health

Зарегистрируйте https://your-host/mcp в MagOneAI с заголовком Authorization: Bearer $TICKET_WRITER_TOKEN, точно так же, как настроен Outlook MCP. TICKET_WRITER_TOKEN — единственная переменная окружения, которая требуется серверу; у MCP_TRANSPORT, HOST, PORT и LOG_LEVEL есть рабочие значения по умолчанию. Установите max_iterations примерно в 12.


Создайте настоящий тикет для проверки

scripts/send.py делает ровно то, что делает API-узел: формирует запрос, подставляет плейсхолдер из одноимённой переменной окружения и отправляет POST:

.venv/bin/python scripts/send.py --target jira \
  --config base_url=https://you.atlassian.net project_key=KAN --dry   # payload only

export JIRA_BASIC_AUTH=$(printf '%s' 'you@mail.com:API_TOKEN' | base64)
.venv/bin/python scripts/send.py --target jira \
  --config base_url=https://you.atlassian.net project_key=KAN         # 201 + issue key

TESTING.md описывает, что доказывает каждый набор тестов, живой прогон против Jira Cloud и таблицу ошибок.


Безопасность

  • Bearer-токен берётся из переменной окружения и никогда не передаётся через узел рабочего процесса — токен, проходящий через канвас, попадает в логи запуска.

  • Никакие учётные данные трекера никогда не попадают на этот сервер. Заголовки — это плейсхолдеры; config принимает расположения, а не секреты. Это проверяется тестом.

  • /health не требует аутентификации для проверок платформы; всё остальное — требует. Сервер отказывается запускаться по HTTP без заданного токена.

  • Пользователь контейнера — не root.

  • Текст репортёра — это данные, а не инструкции. Он сохраняется дословно в блоке цитаты и никогда не интерпретируется. Об этом говорят докстринги инструментов, потому что именно их читает агент.

  • Защита от дубликатов и проверка полноты — это то, что стоит между болтливым Slack-каналом и сотней мусорных тикетов. Не добавляйте флаг, который пропускает обе проверки.


Структура

src/server.py    MCP surface: tool defs, transport, auth
src/ticket.py    pure: rubric, questions, body in markdown + ADF, dup scoring
src/targets.py   pure: what each tracker's API wants — one entry per tracker
tests/           47 tests: the rules, the tool surface, HTTP and auth
scripts/send.py  stands in for the API node, for end-to-end checks
WORKFLOW.md      node-by-node input/output contract
TESTING.md       what is covered, what is not

ticket.py ничего не знает ни об одном трекере; targets.py ничего не знает о том, что делает тикет хорошим. Если добавление обязательного поля означает правку targets.py, разделение нарушено.

F
license - not found
Not graded
quality - not tested
C
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

  • Turns vague automation requests into tool stacks, prompts, QA checks, and human boundaries.

  • Decision intelligence for product teams. Turn scattered feedback into signal you can act on.

  • Manage feature requests, votes, roadmaps, and changelogs from any MCP client.

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/AlanAAG/ticket-writer-mcp'

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