Skip to main content
Glama

mcp-testops — MCP-сервер для Allure TestOps

MCP-сервер (stdio) поверх API Allure TestOps: проекты, тест-кейсы с шагами, тест-планы, запуски и результаты, справочники. Написан на официальном Python SDK mcp v2 (MCPServer из mcp.server, проверено на mcp 2.3.0) и httpx; транспорт — stdio, сервер не слушает портов и запускается клиентом подпроцессом.

30 инструментов: 17 read + 13 write. Generic-инструмента «любой путь под /api» нет сознательно: чего не хватает, добавляется именованным инструментом с телом из схемы — почему именно так, в docs/03-tools-spec.md §7.

Контракт — API allure-testops-service 527u04, снимок от 2026-11-09 (634 пути, 845 операций, 803 схемы). Полного снимка в репозитории нет: scripts/refresh_spec.sh получает его с вашего стенда в openapi/api-docs.json, и тогда контрактные тесты сверяют по нему тела запросов и формы ответов. Лицензия — MIT (LICENSE).

Инструменты

Домен

Инструменты

Проекты

list_projects, get_project

Тест-кейсы

list_test_cases, get_test_case, get_test_case_steps, get_test_case_history, search_test_cases, validate_aql, create_test_case, update_test_case, delete_test_case, add_test_case_step

Тест-планы

list_test_plans, get_test_plan, create_test_plan, update_test_plan, delete_test_plan

Запуски и результаты

list_launches, get_launch, get_launch_statistic, list_test_results, get_test_result, create_launch, close_launch, reopen_launch, delete_launch, add_test_result, run_test_cases

Справочники

list_statuses, list_reference

Что стоит знать до первого вызова:

  • API называет AQL полем rql. search_test_cases(name=...) превращает имя в запрос name ~ "…" на сервере; validate_aql проверяет запрос до поиска и отдаёт {valid, count}.

  • TestCaseDto не содержит сценария — шаги читаются get_test_case_steps.

  • get_test_case_history отвечает на «в каких прогонах гонялся этот кейс».

  • run_test_cases выбирает кейсы через ids/leafs_include (selection.leafsInclude) или сохранённый filter_id; поля rql в выборке нет.

  • Сложные аргументы — JSON-строкой: tags_json, links_json, custom_fields_json, scenario_json, tree_selection_json. Примеры — в docstring каждого инструмента.

  • Ответы компактные: HTML-дубли текстов (*Html) вырезаны, листинги без отступов и с totalElements/totalPages/number.

  • Ошибки — данные: {"ok": false, "error": "HTTP 404 on GET /api/testcase/1: …"} вместо исключения.

Related MCP server: Dependency-Track MCP Server

Установка

Четыре пути: npm (без установки или глобально), uv, готовый бинарник, пакет Python.

1. Через npm

Пакет опубликован: @gribanoveu/mcp-testops. Нужен Node 18+, Python не нужен: при первом запуске обёртка скачивает бинарник своей платформы (22–40 МБ) из этого же Release в ~/.cache/mcp-testops/ и дальше запускает его оттуда.

npx -y @gribanoveu/mcp-testops          # без установки: скачает, запустит и закеширует
npm install -g @gribanoveu/mcp-testops  # глобально: в PATH появляется команда mcp-testops
mcp-testops                             # то же самое, без npx на каждый запуск
npx -y @gribanoveu/mcp-testops@0.1.5    # закрепить версию — тем же способом обновляются

Всё служебное обёртка пишет в stderr (в том числе строку о загрузке бинарника при первом запуске), stdout остаётся протоколу MCP.

2. Через uv

uvx --from git+https://github.com/gribanoveu/mcp-testops mcp-testops   # из репозитория, работает сейчас
uvx mcp-testops                                                       # после публикации в PyPI

uvx собирает пакет в кеш и запускает; нужен только uv.

3. Бинарник из Releases

Скачайте файл под свою систему из Releases, распакуйте и сделайте исполняемым (macOS/Linux):

chmod +x mcp-testops-<platform>
./mcp-testops-<platform>          # без TESTOPS_TOKEN — exit 1 и понятное сообщение

Система

Файл ассета

macOS Apple Silicon

mcp-testops-darwin-arm64

Linux x86_64

mcp-testops-linux-x64

Linux arm64

mcp-testops-linux-arm64

Windows x86_64

mcp-testops-win32-x64.exe

Для Intel Mac готового бинарника нет: сборка под x64 на раннере GitHub падает на несовпадении OpenSSL в cryptography. На Intel Mac ставьте колесо (пункт 4) или используйте uvx mcp-testops.

4. Пакет Python

Нужен Python 3.10+. Колесо py3-none-any — одно на все платформы:

pip install https://github.com/gribanoveu/mcp-testops/releases/download/v0.1.5/mcp_testops-0.1.5-py3-none-any.whl
python -m mcp_testops

Или из исходников (для разработки, с тестами и CLI-командами SDK):

python -m venv .venv && . .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[test]" "mcp[cli]"             # mcp[cli] — mcp dev / mcp run / mcp version
python -m mcp_testops                          # stdio; без TESTOPS_TOKEN падает с понятным сообщением

Что уже опубликовано: npm — 0.1.5, в registry.npmjs.org. PyPI пока нет, поэтому uvx mcp-testops без --from ещё не работает: нужен проект mcp-testops и trusted publisher для .github/workflows/publish-pypi.yml. Публикация в npm двухшаговая: workflow ставит версию в очередь (npm stage publish), мейнтейнер с 2FA одобряет её (npm stage approve <stage-id>).

Настройка

Всё, что зависит от стенда и проекта, приходит из окружения — один пакет поднимается под разные проекты.

Переменная

Обязательна

По умолчанию

Смысл

TESTOPS_TOKEN

да

—

API-токен; без него старт прерывается с TESTOPS_TOKEN is not set

TESTOPS_BASE_URL

нет

https://testops.net

хост стенда

TESTOPS_PROJECT_ID

нет

—

проект по умолчанию для инструментов без project_id

TESTOPS_VERIFY_SSL

нет

false

проверка TLS; внутренний стенд на самоподписанном CA

TESTOPS_TIMEOUT

нет

60

таймаут запроса, секунды

TESTOPS_READ_ONLY

нет

false

true — регистрируются только read-инструменты (17 из 30)

MCP_SERVER_NAME

нет

testops

имя сервера в клиенте

Подключение в Cursor

Cursor читает MCP-серверы из mcp.json: глобально — ~/.cursor/mcp.json, для одного проекта — <репозиторий>/.cursor/mcp.json. Сервер локальный, транспорт stdio: клиент сам запускает команду и общается с ней через stdin/stdout.

С бинарником

{
  "mcpServers": {
    "testops": {
      "type": "stdio",
      "command": "/absolute/path/to/mcp-testops-darwin-arm64",
      "args": [],
      "env": {
        "TESTOPS_BASE_URL": "https://testops.net",
        "TESTOPS_TOKEN": "****",
        "TESTOPS_PROJECT_ID": "65",
        "TESTOPS_READ_ONLY": "true"
      }
    }
  }
}

С пакетом Python

{
  "mcpServers": {
    "testops": {
      "type": "stdio",
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["-m", "mcp_testops"],
      "env": {
        "TESTOPS_BASE_URL": "https://testops.net",
        "TESTOPS_TOKEN": "****",
        "TESTOPS_PROJECT_ID": "65"
      }
    }
  }
}
  • Путь к команде — абсолютный. Клиент запускает сервер из неожиданного рабочего каталога, относительный путь или голое имя из виртуального окружения не найдётся.

  • Токен — только в локальном файле. Если mcp.json лежит в репозитории, пишите "${env:TESTOPS_TOKEN}": Cursor подставит переменную окружения, и секрет в git не попадёт. В этом README вместо него ****.

  • Окружение сервера — это ровно этот блок env. Переменные вашей оболочки в процесс сервера не попадают, поэтому TESTOPS_BASE_URL и TESTOPS_PROJECT_ID лучше указать явно.

  • Проверка: после сохранения файла перезагрузите конфиг MCP (Cursor: Customize → MCPs) и убедитесь, что в списке 30 инструментов — тогда сервер ответил на initialize.

Остальные клиенты, которые запускают локальную команду по stdio (Claude Desktop, ~/.config/...-подобные), используют ту же пару command/args плюс свой env; в Claude Desktop это claude_desktop_config.json с тем же объектом mcpServers.

Запуск без установки

Если не хочется держать файл и путь к нему, клиенту можно отдать команду, которая всё делает сама:

{
  "mcpServers": {
    "testops": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@gribanoveu/mcp-testops"],
      "env": {
        "TESTOPS_BASE_URL": "https://testops.net",
        "TESTOPS_TOKEN": "****"
      }
    }
  }
}

Первый запуск скачивает бинарник вашей платформы (~22–40 МБ) в ~/.cache/mcp-testops/, следующие идут из кеша. Если пакет поставлен глобально (npm i -g @gribanoveu/mcp-testops), то в конфиге хватит "command": "mcp-testops" без args. Без Node есть вариант с uv: "command": "uvx", "args": ["--from", "git+https://github.com/gribanoveu/mcp-testops", "mcp-testops"], а когда пакет будет на PyPI — просто "args": ["mcp-testops"].

Ограничения и риски

  • Авторизация не подтверждена спекой: в снимке нет security/securitySchemes; используется Authorization: Api-Token <token> — это допущение (docs/06-open-questions.md, вопрос 1). При 401/403 первым делом проверить, не нужен ли Bearer.

  • TESTOPS_VERIFY_SSL=false по умолчанию — осознанное послабление для самоподписанного CA: TLS не проверяется. На стенде с валидным сертификатом выставлять true.

  • TESTOPS_READ_ONLY скрывает 13 write-инструментов из 30; на рабочем проекте включать явно.

  • Нет generic-вызова и загрузки файлов: дерево, общие шаги, дефекты, вложения и импорт результатов через MCP недоступны; для вложений и архивов нужен отдельный именованный инструмент (multipart JSON-строкой не собрать).

  • Удаление кейса — мягкое: DELETE /api/testcase/{id} отвечает 202 и уводит кейс в корзину; восстановление не выведено (docs/06-open-questions.md, вопрос 8).

  • Логи: только метод, путь, код и длительность; токен, заголовки и тела не пишутся. Логгер httpx при старте приглушён — он логирует полные URL вместе с текстом rql.

Разработка и проверка

python -m py_compile src/mcp_testops/*.py src/mcp_testops/tools/*.py
pytest -q                                        # 56 тестов; 12 контрактных — со снимком спеки
mcp version                                      # версия официального SDK
mcp dev src/mcp_testops/__init__.py              # Inspector: что увидит модель
python -m mcp_testops                            # stdio, читает TESTOPS_* из env

Собрать standalone-бинарник локально (то же, что делает релизный workflow):

pip install -e ".[build]"
pyinstaller --onefile --name mcp-testops --distpath dist-bin --workpath build/pyi \
  --collect-submodules mcp.server --collect-all pydantic --collect-all anyio \
  --hidden-import mcp_testops packaging/entry.py

Переснять снимок спеки перед этапом и посмотреть дифф:

scripts/refresh_spec.sh          # curl /api-docs/ в openapi/api-docs.json.new + дифф путей и схем

Скрипт не перезаписывает openapi/api-docs.json: сначала читаются версия и дифф, потом снимок меняется и гоняются pytest -q. Полного снимка в репозитории нет — его получают этим скриптом со своего стенда; пока снимка нет, tests/test_contract.py помечается skipped, остальные 56 тестов работают.

Скилл для агента

В skills/testops-mcp/SKILL.md — инструкция для модели: карта из 30 инструментов, готовые цепочки (найти кейс → шаги → прогон → результаты), формы JSON-аргументов, чего инструменты не умеют и что делать, если ответ не тот. Положите каталог skills/testops-mcp/ в папку скиллов клиента (Kibo, Claude Code) — он подхватит его по описанию из frontmatter.

Структура

testops-mcp/
├── src/mcp_testops/
│   ├── __init__.py       # импорт модулей инструментов (регистрация) + main()
│   ├── __main__.py       # from . import main; main()
│   ├── config.py         # TESTOPS_* из env, размеры страниц, ретраи, enum'ы
│   ├── client.py         # TestOpsError, httpx-клиент, _send/_api/_paged, логи
│   ├── helpers.py        # guard, разбор аргументов, компактность ответа
│   ├── bodies.py         # тела запросов — чистые функции для контрактных тестов
│   ├── server.py         # mcp = MCPServer(...) и _write (read-only)
│   └── tools/            # проекты, кейсы, планы, запуски, справочники
├── tests/                # test_contract.py, test_client.py, test_tool_guards.py
├── scripts/refresh_spec.sh  # получить снимок спеки с вашего стенда
├── openapi/              # выборки из спеки: api-inventory.md, key-schemas.json
├── docs/                 # аналитика API и план, по которым писался сервер (01–06)
├── packaging/entry.py     # точка входа для standalone-бинарника
├── npm/                  # обёртка `npx -y @gribanoveu/mcp-testops`
├── skills/testops-mcp/    # SKILL.md — как пользоваться сервером агенту
├── AGENTS.md             # правила работы над сервером
├── CHANGELOG.md          # что сделано, по этапам
├── LICENSE               # MIT
└── pyproject.toml        # hatchling, mcp>=2,<3, httpx

Документация

docs/ — аналитика, а не описание готового сервера:

Документ

О чём

docs/01-contract.md

устройство API: авторизация, пагинация, ошибки, AQL, полиморфные ответы

docs/02-domain-model.md

сущности и связи: Project → TestCase → TestPlan → Launch → TestResult

docs/03-tools-spec.md

спецификация инструментов: сигнатура, эндпоинт, тело, ответ

docs/04-current-implementation.md

разбор чужого примера и его ошибок (Д1–Д11) — «чего не делать»; сам снимок примера из репозитория убран

docs/05-plan.md

этапы M0–M4 и критерии приёмки

docs/06-open-questions.md

что проверить на стенде: авторизация, синтаксис AQL, лимиты, дерево

Если документ расходится с кодом, прав код: источник правды — openapi/api-docs.json и контрактные тесты. Что сделано на каждом этапе — CHANGELOG.md.

Available Tools

30 tools
add_test_case_stepA

Add a step to a test case scenario and return {createdStepId, steps_count}.

Exactly one of body (step text), attachment_id, shared_step_id is required. parent_step_id makes the new step a child of an existing step.

Inputs: test_case_id (required), body, attachment_id, parent_step_id, +1 more. Returns: result

add_test_resultA

Record a test result in a launch and return {ok, id, name, launchId}.

status must be one of failed, broken, passed, skipped, unknown, in_progress; any other value fails here, without a request. duration, start and stop are milliseconds (int64). test_case_id links the result to a test case. JSON-string arguments: tags_json [{"id": 3, "name": "smoke"}] links_json [{"name": "JIRA", "type": "issue", "url": "https://jira/browse/ABC-1"}] custom_fields_json [{"customField": {"id": 12, "name": "Severity"}, "name": "high"}]

Inputs: name (required), status (required), launch_id (required), stop, +12 more. Returns: result

close_launchB

Close a launch; the API answers 204. Results are read-only afterwards.

Inputs: launch_id (required). Returns: result

create_launchB

Create a launch and return {ok, id, name, projectId}.

tags_json: [{"id": 3, "name": "regress"}]; links_json: [{"name": "JIRA", "type": "issue", "url": "https://jira/browse/ABC-1"}].

Inputs: name (required), autoclose, tags_json, links_json, +2 more. Returns: result

create_test_caseA

Create a test case and return {ok, id, name, projectId}.

name is required, project_id defaults to TESTOPS_PROJECT_ID. JSON-string arguments: tags_json [{"id": 3, "name": "smoke"}] (the API requires the tag id) links_json [{"name": "JIRA", "type": "issue", "url": "https://jira/browse/ABC-1"}] members_json [{"id": 7, "name": "ivanov", "role": {"id": 1, "name": "MEMBER"}}] (role is an object RoleDto, not a plain string) custom_fields_json [{"customField": {"id": 12, "name": "Severity"}, "name": "high"}] (the API requires both id and name of the custom field) scenario_json {"steps": [{"type": "body", "body": "Open the form"}]} Ids for status_id, workflow_id and test_layer_id come from list_statuses and list_reference. More steps are added with add_test_case_step.

Inputs: name (required), automated, status_id, tags_json, +11 more. Returns: result

create_test_planB

Create a test plan and return {ok, id, name, projectId}.

base_rql is the AQL selection of the plan (e.g. tag.name = "smoke"). tree_selection_json: {"leafsInclude": [1001], "inverted": false} - the plan takes TreeSelectionDto, which has no filterId (that one belongs to running cases).

Inputs: name (required), tree_id, base_rql, project_id, +1 more. Returns: result

delete_launchB

Delete a launch together with all its results; the API answers 204.

Inputs: launch_id (required). Returns: result

delete_test_caseA

Delete a test case; the API answers 202 and moves it to the trash.

Without force a case that has run results may stay; force=true deletes it anyway, together with its scenario. Restoring a case is not exposed as a tool.

Inputs: test_case_id (required), force. Returns: result

delete_test_planA

Delete a test plan; the API answers 204. The test cases themselves stay.

Inputs: test_plan_id (required). Returns: result

get_launchC

Get one launch: id, name, projectId, closed, createdDate, autoclose, releaseId, tags, links.

Inputs: launch_id (required). Returns: result

get_launch_statisticA

Status counts of a launch as {passed: n, failed: n, broken: n, skipped: n, ...}.

Cheaper than listing the results: one request instead of paging through them.

Inputs: launch_id (required). Returns: result

get_projectC

Get one project by id: id, name, abbr, isPublic, isVersioned, launchCount, automationPercent.

Inputs: project_id (required). Returns: result

get_test_caseA

Get one test case by id: texts, status, workflow, testLayer, tags, links.

The answer does NOT contain the scenario/steps (TestCaseDto has none) and says so with "steps_not_included": true - read them with get_test_case_steps.

Inputs: test_case_id (required). Returns: result

get_test_case_historyA

Which launches ran a test case, and with what result.

Answers "where was this case run": each row is {testResultId, launchId, launchName, status, start, stop, duration, message, testedBy}. launch_id narrows to one launch, search narrows by result text. project_id defaults to TESTOPS_PROJECT_ID. For the full result of one row use get_test_result(testResultId).

Inputs: test_case_id (required), page, size, sort, +3 more. Returns: result

get_test_case_stepsA

Read the scenario (steps) of a test case.

as_tree=true (default) returns nested steps: {id, body, expectedResult, attachmentId, sharedStepId, children}. as_tree=false returns the raw scenarioSteps map by id. A shared step appears as a node with sharedStepId only - its own steps are not inlined. Attachment contents are not inlined either.

Inputs: test_case_id (required), as_tree. Returns: result

get_test_planC

Get one test plan: id, name, projectId, baseRql, testCasesCount, treeSelection.

Inputs: test_plan_id (required). Returns: result

get_test_resultA

Get one test result: status, duration, message, trace and the text fields.

The *Html duplicates are dropped. For the small table of a whole launch use list_test_results or get_launch_statistic.

Inputs: test_result_id (required). Returns: result

list_launchesB

List launches of a project: id, name, closed, createdDate, statistic.

statistic holds status counts as the API returns them, e.g. {passed, failed, broken, skipped, unknown} or StatisticDto with inProgress, pending and total; it is absent when the launch shape carries none. The API answers with two different launch shapes; both are read into this summary. project_id defaults to TESTOPS_PROJECT_ID; sort defaults to "created_date,DESC".

Inputs: page, size, sort, search, +2 more. Returns: result

list_projectsA

List TestOps projects, ordered by name.

search: optional substring of the project name; favorite: only starred projects. page starts at 0, size is capped at 100. Returns {content, totalElements, totalPages, number} with id, name, abbr, isPublic, isVersioned, launchCount, automationPercent per project.

Inputs: page, size, search, favorite. Returns: result

list_referenceA

List a reference dictionary by kind: workflow, testlayer, custom_field or tag.

Returns id and name of every entry - they are what create_test_case wants in workflow_id, test_layer_id and custom_fields_json. custom_field is project scoped (project_id defaults to TESTOPS_PROJECT_ID) and accepts query; tag is a flat list without pagination, so query is applied here.

Inputs: kind (required), page, size, query, +1 more. Returns: result

list_statusesA

List test statuses (id, name, color) - they give status_id for create_test_case.

workflow_id narrows the answer to one workflow. The endpoint takes no project id: statuses are defined by workflows, not by projects.

Inputs: page, size, sort, workflow_id. Returns: result

list_test_casesA

List test cases of a project as rows: id, name, status, automated, flaky, testLayer.

Rows carry no description and no steps - read one case with get_test_case and its steps with get_test_case_steps. project_id defaults to TESTOPS_PROJECT_ID. sort: "property,ASC|DESC", e.g. "createdDate,DESC".

Inputs: page, size, sort, project_id. Returns: result

list_test_plansB

List test plans of a project: id, name, projectId, baseRql, testCasesCount.

project_id defaults to TESTOPS_PROJECT_ID; search narrows by name.

Inputs: page, size, search, tree_id, +1 more. Returns: result

list_test_resultsC

List results of a launch: id, name, testCaseId, status, duration, message, trace, start, stop.

status is one of failed, broken, passed, skipped, unknown, in_progress.

Inputs: launch_id (required), page, size, sort. Returns: result

reopen_launchB

Reopen a closed launch so results can be added again; the API answers 204.

Inputs: launch_id (required). Returns: result

run_test_casesA

Create a launch with one manual result per selected test case.

Select the cases with one of: ids (comma separated or JSON array of tree leaf ids, becomes selection.leafsInclude), leafs_include (explicit JSON array) or filter_id (saved filter); ids and leafs_include are mutually exclusive. The API field is leafsInclude: there is no leafIds and no rql in the selection. assignees: comma separated user logins; tags_json: [{"id": 3, "name": "regress"}]. Returns {ok, launchId, name, projectId}.

Inputs: launch_name (required), ids, assignees, filter_id, +4 more. Returns: result

search_test_casesB

Search test cases with AQL (the API calls it rql) and return full cases.

Give either rql or name. name becomes the AQL query name ~ "" on the server, nothing is filtered client-side. Examples (syntax to be verified on the stand): name ~ "login", status.name = "Draft", tag.name = "smoke". Returns {content: [case fields], rql, totalElements, totalPages, number}.

Inputs: rql, name, page, size, +3 more. Returns: result

update_test_caseA

Update fields of a test case; only the arguments you pass are sent.

An empty string means "leave the field alone" unless clear=true, where an empty string clears the field. JSON-string arguments are the same as in create_test_case.

Inputs: test_case_id (required), name, clear, duration, +13 more. Returns: result

update_test_planA

Update fields of a test plan; only the arguments you pass are sent.

An empty string means "leave the field alone" unless clear=true, where an empty string clears the field. tree_selection_json: {"leafsInclude": [1001], "inverted": false}.

Inputs: test_plan_id (required), name, clear, tree_id, +2 more. Returns: result

validate_aqlA

Check an AQL query (the API calls it rql) before running search_test_cases.

Returns {ok, valid, count}: count is how many test cases the query selects, so a typo is caught before a real search. project_id defaults to TESTOPS_PROJECT_ID; deleted=true counts removed cases too. rql is required.

Inputs: rql, deleted, project_id. Returns: result

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 30 tools

    Disambiguation4/5

    The surface is large but the descriptions actively separate near-pairs: list_test_cases vs search_test_cases (AQL), get_test_case vs get_test_case_steps, list_launches vs get_launch_statistic vs list_test_results, and run_test_cases vs create_launch+add_test_result. Remaining overlaps (get_test_case_history vs list_test_results for result data, list_test_plans vs get_test_plan) are documented but still require the agent to read carefully.

    Naming Consistency5/5

    Uniform snake_case verb_noun pattern throughout: get_/list_/create_/update_/delete_/add_/search_/validate_/run_/close_/reopen_ plus a single noun. Even the unusual composite (run_test_cases) fits the same grammar, so intent is predictable from the name alone.

    Tool Count3/5

    30 tools is above the comfortable range and the surface spans five sub-domains (cases, steps, plans, launches, results, reference data), plus helper tools like validate_aql. Each tool maps to a real API operation, so it is not padding, but the breadth makes the set heavy to navigate.

    Completeness3/5

    CRUD is complete for test cases, plans and launches, but notable gaps exist around the sub-resources: steps can only be added (no update/delete/reorder step), test results can be created but not updated or deleted, and restore-from-trash is explicitly absent. Shared steps and attachments are referenced by id but have no listing tools, which will force dead ends.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables MCP clients to query projects, fetch findings, trigger analysis, upload CycloneDX BOMs, and check async token status against an OWASP Dependency-Track instance via stdio.
      24 npm
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables MCP clients to interact with the Crewmeister API over local stdio, covering operations for members, teams, time tracking, salary exports, and related platform resources.
      Apache 2.0
    • A
      license
      C
      quality
      B
      maintenance
      Enables MCP clients to interact with the current xMatters REST API over stdio, covering people, devices, groups, on-call schedules, events, incidents, workflows, services, integrations, and subscriptions. It is read-only by default and requires explicit operator opt-in plus per-call confirmation for mutations.
      179
      Apache 2.0