mcp-testops
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., "@mcp-testops show the latest launch statistics for project 42"
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.
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).
Инструменты
Домен | Инструменты |
Проекты |
|
Тест-кейсы |
|
Тест-планы |
|
Запуски и результаты |
|
Справочники |
|
Что стоит знать до первого вызова:
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 # после публикации в PyPIuvx собирает пакет в кеш и запускает; нужен только uv.
3. Бинарник из Releases
Скачайте файл под свою систему из Releases, распакуйте и сделайте исполняемым (macOS/Linux):
chmod +x mcp-testops-<platform>
./mcp-testops-<platform> # без TESTOPS_TOKEN — exit 1 и понятное сообщениеСистема | Файл ассета |
macOS Apple Silicon |
|
Linux x86_64 |
|
Linux arm64 |
|
Windows x86_64 |
|
Для 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>).
Настройка
Всё, что зависит от стенда и проекта, приходит из окружения — один пакет поднимается под разные проекты.
Переменная | Обязательна | По умолчанию | Смысл |
| да | — | API-токен; без него старт прерывается с |
| нет |
| хост стенда |
| нет | — | проект по умолчанию для инструментов без |
| нет |
| проверка TLS; внутренний стенд на самоподписанном CA |
| нет |
| таймаут запроса, секунды |
| нет |
|
|
| нет |
| имя сервера в клиенте |
Подключение в 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/ — аналитика, а не описание готового сервера:
Документ | О чём |
| устройство API: авторизация, пагинация, ошибки, AQL, полиморфные ответы |
| сущности и связи: Project → TestCase → TestPlan → Launch → TestResult |
| спецификация инструментов: сигнатура, эндпоинт, тело, ответ |
| разбор чужого примера и его ошибок (Д1–Д11) — «чего не делать»; сам снимок примера из репозитория убран |
| этапы M0–M4 и критерии приёмки |
| что проверить на стенде: авторизация, синтаксис AQL, лимиты, дерево |
Если документ расходится с кодом, прав код: источник правды — openapi/api-docs.json и контрактные
тесты. Что сделано на каждом этапе — CHANGELOG.md.
Available Tools
30 toolsadd_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
Scored across 30 tools
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.
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.
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.
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
Related MCP Connectors
Search Bluesky posts and feeds; read profiles, threads, and trends. STDIO or Streamable HTTP.
Manage PocketBase Cloud projects, instances, deploys, domains, collections and records.
Manage Jitsu data pipelines: destinations, streams, connections, functions, live events.
Manage Pipefork API projects, drafts, connections, secrets, and deployments through MCP.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables EHR Copilot operations such as order cloning, queue building, and execution trace analysis over stdio.-
- AlicenseNot gradedqualityCmaintenanceEnables 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 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables 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
- AlicenseCqualityBmaintenanceEnables 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.179Apache 2.0