Skip to main content
Glama

⚠️ This project is no longer maintained

Use the official server instead: makeplane/plane-mcp-server.

This project existed for one reason: the official Plane MCP server was written in TypeScript, and a Python implementation was useful. That reason is gone — the official server is now Python too, actively maintained, and covers 204 operations through 30 resource-shaped tools.

Nothing here is broken; it simply stopped being the better choice. The npm package @mikey-semy/plane-mcp is deprecated for the same reason.

Thanks to everyone who installed it. Archived September 2026.


Plane MCP Server - Python Implementation

Python FastMCP NPM License Original

Plane's Model Context Protocol Server - Python реализация 🔌 ⌨️ 🔥

Предоставляет 48 инструментов для работы с проектами, задачами, модулями и циклами в Plane.

Оригинальный проект: makeplane/plane-mcp-server (TypeScript) plane.so | Topics: model-context-protocol mcp-server python fastmcp

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

  • ARCHITECTURE.md - Архитектура и сравнение stdio vs

  • USAGE.md - Подробная инструкция по использованию NPM пакета

  • COPILOT_USAGE.md - Как использовать с GitHub Copilot в VSCode

  • CONTRIBUTING.md - Руководство для контрибьюторов

  • CHANGELOG.md - История изменений

  • NPM_PUBLISH.md - Публикация форка в NPM

Related MCP server: plane-client

✨ Возможности

  • ✅ 48 инструментов - полное покрытие Plane API

  • ✅ ** Transport** - HTTP сервер для удалённого доступа

  • ✅ stdio Transport - для локальной интеграции с Claude Desktop

  • ✅ Полный CRUD для Issues, Projects, Modules, Cycles

  • ✅ Metadata Management - полное управление типами задач, метками, статусами

  • ✅ Module/Cycle Issues - управление задачами в модулях и циклах

  • ✅ Worklogs - отслеживание времени работы

  • ✅ Issue Comments - работа с комментариями

  • ✅ Readable Identifiers - поддержка PROJECT-123 формата

  • ✅ Асинхронная архитектура - быстрая обработка запросов

  • ✅ Docker Ready - готовые конфигурации для контейнеризации

📊 Краткий обзор инструментов

User (2 tools)

  • get_current_user - информация о текущем пользователе

  • get_workspace_members - список участников workspace

Metadata (14 tools)

Issue Types (4):

  • get_issue_type, create_issue_type, update_issue_type, delete_issue_type

States (5):

  • list_states, get_state, create_state, update_state, delete_state

Labels (5):

  • list_labels, get_label, create_label, update_label, delete_label

Projects (3 tools)

  • get_projects - список всех проектов

  • create_project - создание нового проекта

  • list_project_issues - список задач проекта

Issues (7 tools)

  • get_issue - детали конкретной задачи

  • get_issue_using_readable_identifier - получить задачу по читаемому ID (FIRST-123)

  • create_issue - создание задачи

  • update_issue - обновление задачи

  • delete_issue - удаление задачи

  • get_issue_comments - получить комментарии к задаче

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

Modules (5 tools)

  • list_modules - список модулей проекта

  • get_module - детали модуля

  • create_module - создание модуля

  • update_module - обновление модуля

  • delete_module - удаление модуля

Module Issues (3 tools)

  • list_module_issues - список задач в модуле

  • add_module_issues - добавить задачи в модуль

  • delete_module_issue - удалить задачу из модуля

Cycles (5 tools)

  • list_cycles - список циклов проекта

  • get_cycle - детали цикла

  • create_cycle - создание цикла

  • update_cycle - обновление цикла

  • delete_cycle - удаление цикла

Cycle Issues (4 tools)

  • list_cycle_issues - список задач в цикле

  • add_cycle_issues - добавить задачи в цикл

  • delete_cycle_issue - удалить задачу из цикла

  • transfer_cycle_issues - перенести задачи из одного цикла в другой

Worklogs (5 tools)

  • get_issue_worklogs - список рабочих логов задачи

  • get_total_worklogs - общее время логов проекта

  • create_worklog - создать рабочий лог

  • update_worklog - обновить рабочий лог

  • delete_worklog - удалить рабочий лог

Всего: 48 инструментов

🚀 Быстрый старт

Вариант 1: NPM (рекомендуется для локального использования)

Требования: Node.js 18+, uv

✅ Пакет опубликован в NPM: @mikey-semy/plane-mcp

# Использование без установки (npx)
npx -y @mikey-semy/plane-mcp

# Или глобальная установка
npm install -g @mikey-semy/plane-mcp
plane-mcp

Переменные окружения:

# Windows PowerShell
$env:PLANE_API_KEY="plane_xxxxxxxxxxxxxxxxxxxx"
$env:PLANE_WORKSPACE_SLUG="your-workspace-slug"
$env:PLANE_API_HOST_URL="https://api.plane.so/"  # опционально

# Linux/macOS
export PLANE_API_KEY="plane_xxxxxxxxxxxxxxxxxxxx"
export PLANE_WORKSPACE_SLUG="your-workspace-slug"
export PLANE_API_HOST_URL="https://api.plane.so/"  # опционально

Вариант 2: Docker (для продакшена)

1. Создайте .env файл:

cp .env.example .env

Отредактируйте .env и добавьте свои данные:

# Обязательные переменные
PLANE_API_KEY=plane_xxxxxxxxxxxxxxxxxxxx
PLANE_WORKSPACE_SLUG=your-workspace-slug

# Опциональные (значения по умолчанию)
PLANE_API_HOST_URL=https://api.plane.so/
MCP_HOST=0.0.0.0
MCP_PORT=8000

# Порт на хосте (если 8000 занят, измените на другой)
HOST_PORT=8000

Примечание: Если порт 8000 уже занят, измените HOST_PORT на другой (например, 8001, 9000).

2. Запуск с Docker Compose:

docker-compose up -d

Сервер будет доступен на http://localhost:HOST_PORT/ (по умолчанию http://localhost:8000/)

3. Проверка работы:

# Проверка здоровья контейнера
docker-compose ps

# Просмотр логов
docker-compose logs -f

# Остановка
docker-compose down

Локальная установка (для разработки)

Требования

  • Python 3.12+

  • uv (для управления пакетами)

Установка

# Установка uv (если ещё не установлен)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Клонирование и установка зависимостей
cd plane-mcp
uv sync

# Создание .env файла
cp .env.example .env
# Отредактируйте .env, добавьте свои ключи

# Запуск сервера
uv run plane-mcp

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

Переменные окружения

Переменная

Описание

По умолчанию

Обязательная

PLANE_API_KEY

API ключ Plane

-

✅

PLANE_WORKSPACE_SLUG

Slug вашего workspace

-

✅

PLANE_API_HOST_URL

URL Plane API

https://api.plane.so/

❌

MCP_HOST

Хост для HTTP сервера

0.0.0.0

❌

MCP_PORT

Порт контейнера (внутренний)

8000

❌

HOST_PORT

Порт хоста (внешний) для Docker

8000

❌

Для продакшена: используйте .env.production с вашими настройками.

🌐 Развёртывание

Публичный NPM пакет

✅ Пакет опубликован и доступен: @mikey-semy/plane-mcp

Любой пользователь может использовать:

npx -y @mikey-semy/plane-mcp

Docker развёртывание

Используйте Docker Compose для продакшен развёртывания. Сервер будет доступен по HTTP на указанном порту.

Пример URL после развёртывания:

https://your-domain.com:9000/

Настройте свой домен в .env.production и используйте reverse proxy (Traefik/Nginx) для SSL.

⚠️ Безопасность развёртывания

ВАЖНО: endpoint предоставляет полный доступ к вашему Plane API!

Рекомендуемые меры защиты:

  1. 🔒 Не публикуйте URL публично - SSE endpoint содержит ваш API ключ

  2. 🛡️ Используйте VPN - ограничьте доступ только для вашей сети

  3. 🔐 Basic Auth - добавьте authentication на уровне Traefik/Nginx

  4. 🌐 IP Whitelist - разрешите доступ только с определённых IP

  5. 📝 Логирование - отслеживайте все подключения

  6. 🔄 Регулярно ротируйте API ключи

Пример Traefik с Basic Auth:

labels:
  - "traefik.http.middlewares.auth.basicauth.users=user:$$apr1$$..."
  - "traefik.http.routers.mcp.middlewares=auth"

Для личного использования рекомендуем stdio, а не публичный SSE сервер.

Использование с MCP клиентами

FastMCP автоматически поддерживает:

  • SSE (Server-Sent Events) - HTTP транспорт на http://host:port/sse

  • stdio - стандартный ввод/вывод для локальных клиентов

🤔 Какой вариант выбрать?

stdio (локальный) - рекомендуется:

  • ✅ Можно работать с несколькими workspace одновременно

  • ✅ Разные API ключи для разных workspace

  • ✅ Полный контроль над конфигурацией

  • ⚠️ Требует установку uv локально

SSE (удалённый) - для централизованного использования:

  • ✅ Не требует Python/uv на клиентской машине

  • ✅ Быстрое подключение (сервер уже работает)

  • ✅ Единая конфигурация для команды

  • ⚠️ Фиксированный workspace на сервере

  • ⚠️ Требует сетевое подключение к серверу

  • 🔒 Не публикуйте публичные URL - используйте VPN или authentication!

📖 Подробнее: COPILOT_USAGE.md

Подключение через VSCode

Добавьте конфигурацию в .vscode/mcp.json или mcp.json в корне проекта:

Вариант 1: NPM пакет (stdio) - для работы с разными workspace

Позволяет переключаться между workspace просто меняя env:

{
  "servers": {
    "plane-profitool": {
      "command": "npx",
      "args": ["-y", "@mikey-semy/plane-mcp"],
      "env": {
        "PLANE_API_KEY": "YOUR_PLANE_API_KEY",
        "PLANE_API_HOST_URL": "https://plane.equiply.ru/",
        "PLANE_WORKSPACE_SLUG": "profitool-store"
      }
    },
    "plane-another-project": {
      "command": "npx",
      "args": ["-y", "@mikey-semy/plane-mcp"],
      "env": {
        "PLANE_API_KEY": "YOUR_PLANE_API_KEY",
        "PLANE_API_HOST_URL": "https://plane.equiply.ru/",
        "PLANE_WORKSPACE_SLUG": "another-workspace"
      }
    }
  }
}

Вариант 2: Удалённое подключение (SSE)

Подключение к вашему развёрнутому серверу. Внимание: workspace фиксирован на сервере!

Без авторизации:

{
  "servers": {
    "plane": {
      "url": "https://your-mcp-server.example.com:9000/sse"
    }
  }
}

С Basic Auth (рекомендуется для production):

{
  "servers": {
    "plane": {
      "url": "https://mcp.plane.lol.ru:9000/sse",
      "headers": {
        "Authorization": "Basic YWRtaW46UlolXJlUGFzc3dvcmQxMjM="
      }
    }
  }
}

Примечание:

  • Замените your-mcp-server.example.com на адрес вашего сервера.

  • Для генерации Authorization заголовка см. _AUTH.md

  • НЕ используйте формат https://user:pass@host/ - не поддерживается клиентами MCP

Для работы с несколькими workspace через : разверните отдельный сервер для каждого workspace.

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

Добавьте конфигурацию в claude_desktop_config.json:

Windows: %APPDATA%\Claude\claude_desktop_config.json macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Вариант 1: NPM пакет (рекомендуется)

{
  "mcpServers": {
    "plane": {
      "command": "npx",
      "args": ["-y", "@mikey-semy/plane-mcp"],
      "env": {
        "PLANE_API_KEY": "plane_xxxxxxxxxxxxxxxxxxxx",
        "PLANE_WORKSPACE_SLUG": "your-workspace-slug",
        "PLANE_API_HOST_URL": "https://api.plane.so/"
      }
    }
  }
}

Вариант 2: Локальная установка (uv)

{
  "mcpServers": {
    "plane": {
      "command": "uv",
      "args": ["run", "plane-mcp"],
      "env": {
        "PLANE_API_KEY": "plane_xxxxxxxxxxxxxxxxxxxx",
        "PLANE_WORKSPACE_SLUG": "your-workspace-slug",
        "PLANE_API_HOST_URL": "https://api.plane.so/"
      }
    }
  }
}

После сохранения конфигурации перезапустите VSCode или Claude Desktop.

Разработка

Структура проекта

plane-mcp/
├── src/
│   └── plane_mcp/
│       ├── __init__.py
│       ├── server.py          # Основной сервер
│       ├── schemas/           # Pydantic модели (новая структура)
│       │   ├── __init__.py
│       │   ├── base.py        # Базовые классы и миксины
│       │   ├── project.py     # Project
│       │   ├── issue.py       # Issue, IssueType
│       │   ├── module.py      # Module, ModuleIssue
│       │   ├── cycle.py       # Cycle, CycleIssue
│       │   ├── metadata.py    # State, Label
│       │   └── worklog.py     # IssueWorkLog
│       ├── common/
│       │   ├── request_helper.py  # HTTP клиент для Plane API
│       │   └── version.py
│       └── tools/
│           ├── cycle_issues.py
│           ├── cycles.py
│           ├── issue_comments.py
│           ├── issues.py
│           ├── metadata.py
│           ├── module_issues.py
│           ├── modules.py
│           ├── projects.py
│           ├── user.py
│           └── worklogs.py
├── pyproject.toml
├── Dockerfile
└── docker-compose.yml

Архитектура схем

Все Pydantic модели организованы с использованием наследования для DRY-кода:

Базовые классы (base.py):

  • PlaneBaseModel - корневой класс с общими настройками

  • TimestampedModel - добавляет created_at, updated_at

  • AuditedModel - добавляет created_by, updated_by

  • WorkspaceOwnedModel - добавляет workspace

  • ProjectOwnedModel - добавляет project

  • SoftDeletableModel - добавляет deleted_at

  • ArchivableModel - добавляет archived_at

  • ExternallyIdentifiableModel - добавляет external_id, external_source

  • SortableModel - добавляет sort_order

  • FullAuditModel - объединяет все вышеперечисленные + id

Доменные модели:

  • project.py - Project (наследуется от FullAuditModel)

  • issue.py - Issue, IssueType

  • module.py - Module, ModuleIssue

  • cycle.py - Cycle, CycleIssue

  • metadata.py - State, Label

  • worklog.py - IssueWorkLog

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

Запуск тестов

uv run pytest

Форматирование кода

uv run ruff check --fix
uv run ruff format

Получение API ключа Plane

  1. Войдите в Plane

  2. Перейдите в Settings → API Tokens

  3. Создайте новый токен

  4. Скопируйте и сохраните в .env или используйте как переменную окружения

📦 Публикация в NPM

Если вы хотите опубликовать свой форк пакета, следуйте инструкциям в NPM_PUBLISH.md.

Лицензия

MIT

Автор

Сгенерировано на основе официального Plane MCP Server

Available Tools

49 tools
add_cycle_issuesA

Add issues to a cycle.

Args: project_id: The UUID identifier of the project containing the cycle cycle_id: The UUID identifier of the cycle to add issues to issues: Array of issue UUIDs to add to the cycle

Inputs: issues (required), cycle_id (required), project_id (required). Returns: result

add_issue_commentA

Add a comment to a specific issue.

Args: project_id: The UUID identifier of the project issue_id: The UUID identifier of the issue comment_html: The HTML content of the comment to add

Inputs: issue_id (required), project_id (required), comment_html (required). Returns: result

add_module_issuesA

Add issues to a module. Assign module to issues.

Args: project_id: The UUID identifier of the project containing the module module_id: The UUID identifier of the module to add issues to issues: Array of issue UUIDs to add to the module

Inputs: issues (required), module_id (required), project_id (required). Returns: result

create_cycleA

Create a new cycle in a project.

Args: project_id: The UUID identifier of the project name: The name of the cycle description: Optional cycle description start_date: Optional start date (YYYY-MM-DD) end_date: Optional end date (YYYY-MM-DD)

Inputs: name (required), project_id (required), end_date, start_date, +1 more. Returns: result

create_issueA

Create a new issue in a project.

Args: project_id: The UUID identifier of the project name: The title/name of the issue description: Optional HTML description of the issue state_id: Optional UUID of the issue state priority: Optional priority (urgent, high, medium, low, none) assignees: Optional list of assignee UUIDs labels: Optional list of label UUIDs

Inputs: name (required), project_id (required), labels, priority, +3 more. Returns: result

create_issue_typeA

Create a new issue type.

Args: project_id: The UUID identifier of the project name: Name of the issue type description: Description of the issue type color: Color hex code for the issue type icon: Icon identifier for the issue type

Inputs: name (required), project_id (required), icon, color, +1 more. Returns: result

create_labelA

Create a new label.

Args: project_id: The UUID identifier of the project name: Name of the label description: Description of the label color: Color hex code for the label

Inputs: name (required), project_id (required), color, description. Returns: result

create_moduleA

Create a new module in a project.

Args: project_id: The UUID identifier of the project name: The name of the module description: Optional module description start_date: Optional start date (YYYY-MM-DD) target_date: Optional target/end date (YYYY-MM-DD) lead: Optional UUID of the module lead

Inputs: name (required), project_id (required), lead, start_date, +2 more. Returns: result

create_projectA

Create a new project.

Args: name: The name of the project identifier: The identifier of the project (typically 5 uppercase characters) description: Optional project description

Inputs: name (required), identifier (required), description. Returns: result

create_stateC

Create a new state.

Args: project_id: The UUID identifier of the project name: Name of the state group: Group of the state (backlog, unstarted, started, completed, cancelled) description: Description of the state color: Color hex code for the state

Inputs: name (required), group (required), project_id (required), color, +1 more. Returns: result

create_worklogA

Create a new worklog for an issue.

Args: project_id: The UUID identifier of the project containing the issue issue_id: The UUID identifier of the issue to create worklog for duration: Duration in hours (e.g., 2.5 for 2 hours 30 minutes) description: Description of the work done started_at: Optional timestamp when work started (ISO 8601 format)

Inputs: duration (required), issue_id (required), project_id (required), description (required), +1 more. Returns: result

delete_cycleB

Delete a cycle.

Args: project_id: The UUID identifier of the project cycle_id: The UUID identifier of the cycle

Inputs: cycle_id (required), project_id (required). Returns: result

delete_cycle_issueA

Remove an issue from a cycle.

Args: project_id: The UUID identifier of the project containing the cycle cycle_id: The UUID identifier of the cycle containing the issue issue_id: The UUID identifier of the issue to remove from the cycle

Inputs: cycle_id (required), issue_id (required), project_id (required). Returns: result

delete_issueB

Delete an issue.

Args: project_id: The UUID identifier of the project issue_id: The UUID identifier of the issue to delete

Inputs: issue_id (required), project_id (required). Returns: result

delete_issue_typeB

Delete an issue type.

Args: project_id: The UUID identifier of the project issue_type_id: The UUID identifier of the issue type

Inputs: project_id (required), issue_type_id (required). Returns: result

delete_labelC

Delete a label.

Args: project_id: The UUID identifier of the project label_id: The UUID identifier of the label

Inputs: label_id (required), project_id (required). Returns: result

delete_moduleB

Delete a module.

Args: project_id: The UUID identifier of the project module_id: The UUID identifier of the module

Inputs: module_id (required), project_id (required). Returns: result

delete_module_issueB

Remove an issue from a module. Unassign module from issue.

Args: project_id: The UUID identifier of the project containing the module module_id: The UUID identifier of the module containing the issue issue_id: The UUID identifier of the issue to remove from the module

Inputs: issue_id (required), module_id (required), project_id (required). Returns: result

delete_stateB

Delete a state.

Args: project_id: The UUID identifier of the project state_id: The UUID identifier of the state

Inputs: state_id (required), project_id (required). Returns: result

delete_worklogA

Delete a worklog.

Args: project_id: The UUID identifier of the project containing the issue issue_id: The UUID identifier of the issue containing the worklog worklog_id: The UUID identifier of the worklog to delete

Inputs: issue_id (required), project_id (required), worklog_id (required). Returns: result

get_current_userA

Get information about the current authenticated user.

Inputs: no named parameters. Returns: result

get_cycleA

Get details of a specific cycle.

Args: project_id: The UUID identifier of the project cycle_id: The UUID identifier of the cycle

Inputs: cycle_id (required), project_id (required). Returns: result

get_issueB

Get details of a specific issue.

Args: project_id: The UUID identifier of the project issue_id: The UUID identifier of the issue

Inputs: issue_id (required), project_id (required). Returns: result

get_issue_commentsA

Get all comments for a specific issue.

Args: project_id: The UUID identifier of the project issue_id: The UUID identifier of the issue

Inputs: issue_id (required), project_id (required). Returns: result

get_issue_details_by_readable_idA

Get full issue details using readable ID (e.g. PROFI-48). Returns project_id, issue_id, current state, and other details needed for operations.

Args: issue_readable_id: The readable identifier of the issue (e.g., 'PROFI-48', 'ABC-123')

Inputs: issue_readable_id (required). Returns: result

get_issue_typeA

Get details of a specific issue type.

Args: project_id: The UUID identifier of the project issue_type_id: The UUID identifier of the issue type

Inputs: project_id (required), issue_type_id (required). Returns: result

get_issue_using_readable_identifierA

Get a specific issue using its readable identifier.

When issue identifier is provided as FIRST-123, ABC-123, etc. For FIRST-123: project_identifier is FIRST and issue_identifier is 123

Args: project_identifier: The readable identifier of the project (e.g., 'FIRST' for FIRST-123) issue_identifier: The issue number (e.g., '123' for FIRST-123)

Inputs: issue_identifier (required), project_identifier (required). Returns: result

get_issue_worklogsA

Get all worklogs for a specific issue.

Args: project_id: The UUID identifier of the project containing the issue issue_id: The UUID identifier of the issue to get worklogs for

Inputs: issue_id (required), project_id (required). Returns: result

get_labelA

Get details of a specific label.

Args: project_id: The UUID identifier of the project label_id: The UUID identifier of the label

Inputs: label_id (required), project_id (required). Returns: result

get_moduleB

Get details of a specific module.

Args: project_id: The UUID identifier of the project module_id: The UUID identifier of the module

Inputs: module_id (required), project_id (required). Returns: result

get_projectsA

Get all projects for the current user.

Inputs: no named parameters. Returns: result

get_stateB

Get details of a specific state.

Args: project_id: The UUID identifier of the project state_id: The UUID identifier of the state

Inputs: state_id (required), project_id (required). Returns: result

get_total_worklogsA

Get total logged time for a project.

Args: project_id: The UUID identifier of the project to get total worklogs for

Inputs: project_id (required). Returns: result

get_workspace_membersA

Get all members in the current workspace.

Inputs: no named parameters. Returns: result

list_cycle_issuesA

Get all issues for a specific cycle.

Args: project_id: The UUID identifier of the project containing the cycle cycle_id: The UUID identifier of the cycle to get issues for

Inputs: cycle_id (required), project_id (required). Returns: result

list_cyclesB

Get all cycles for a specific project.

Args: project_id: The UUID identifier of the project

Inputs: project_id (required). Returns: result

list_labelsA

List all labels for a project.

Args: project_id: The UUID identifier of the project

Inputs: project_id (required). Returns: result

list_module_issuesB

Get all issues for a specific module.

Args: project_id: The UUID identifier of the project containing the module module_id: The UUID identifier of the module to get issues for

Inputs: module_id (required), project_id (required). Returns: result

list_modulesA

Get all modules for a specific project.

Args: project_id: The UUID identifier of the project

Inputs: project_id (required). Returns: result

list_project_issuesA

Get all issues for a specific project.

Args: project_id: The UUID identifier of the project to get issues for

Inputs: project_id (required). Returns: result

list_statesA

Get all states for a specific project.

Args: project_id: The UUID identifier of the project to get states for

Inputs: project_id (required). Returns: result

transfer_cycle_issuesB

Transfer issues from one cycle to another.

Args: project_id: The UUID identifier of the project containing the cycle cycle_id: The UUID identifier of the source cycle new_cycle_id: The UUID identifier of the target cycle

Inputs: cycle_id (required), project_id (required), new_cycle_id (required). Returns: result

update_cycleC

Update an existing cycle.

Args: project_id: The UUID identifier of the project cycle_id: The UUID identifier of the cycle name: Updated cycle name description: Updated description start_date: Updated start date (YYYY-MM-DD) end_date: Updated end date (YYYY-MM-DD)

Inputs: cycle_id (required), project_id (required), name, end_date, +2 more. Returns: result

update_issueC

Update an existing issue.

Args: project_id: The UUID identifier of the project issue_id: The UUID identifier of the issue to update name: Updated issue name description: Updated HTML description state: Updated state UUID priority: Updated priority assignees: Updated list of assignee UUIDs labels: Updated list of label UUIDs

Inputs: issue_id (required), project_id (required), name, state, +4 more. Returns: result

update_issue_typeA

Update an existing issue type.

Args: project_id: The UUID identifier of the project issue_type_id: The UUID identifier of the issue type name: New name for the issue type description: New description for the issue type color: New color hex code for the issue type icon: New icon identifier for the issue type

Inputs: project_id (required), issue_type_id (required), icon, name, +2 more. Returns: result

update_labelB

Update an existing label.

Args: project_id: The UUID identifier of the project label_id: The UUID identifier of the label name: New name for the label description: New description for the label color: New color hex code for the label

Inputs: label_id (required), project_id (required), name, color, +1 more. Returns: result

update_moduleA

Update an existing module.

Args: project_id: The UUID identifier of the project module_id: The UUID identifier of the module name: Updated module name description: Updated description start_date: Updated start date (YYYY-MM-DD) target_date: Updated target date (YYYY-MM-DD) lead: Updated lead UUID status: Updated status

Inputs: module_id (required), project_id (required), lead, name, +4 more. Returns: result

update_stateB

Update an existing state.

Args: project_id: The UUID identifier of the project state_id: The UUID identifier of the state name: New name for the state group: New group for the state (backlog, unstarted, started, completed, cancelled) description: New description for the state color: New color hex code for the state

Inputs: state_id (required), project_id (required), name, color, +2 more. Returns: result

update_worklogA

Update an existing worklog.

Args: project_id: The UUID identifier of the project containing the issue issue_id: The UUID identifier of the issue containing the worklog worklog_id: The UUID identifier of the worklog to update duration: Updated duration in hours description: Updated description started_at: Updated timestamp when work started

Inputs: issue_id (required), project_id (required), worklog_id (required), duration, +2 more. Returns: result

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 49 tools

    Disambiguation3/5

    Most tools are clearly separated by resource type (labels, states, issues, etc.), but `get_issue_using_readable_identifier` and `get_issue_details_by_readable_id` overlap heavily, both retrieving issues via readable identifiers with only slight input differences. This ambiguity could cause an agent to pick the wrong one.

    Naming Consistency4/5

    The majority of tools follow a consistent verb_noun pattern (e.g., list_labels, create_issue, delete_cycle). Minor deviations like `get_issue_details_by_readable_id` and singular/plural mismatches (delete_module_issue vs add_module_issues) prevent a perfect score.

    Tool Count2/5

    With 49 tools, the server is far above the 25+ threshold, making it unwieldy for agents to discover and select tools. Even for a broad project management domain, the count feels excessive and could benefit from consolidation.

    Completeness4/5

    The tool set provides full CRUD for issues, labels, states, issue types, modules, cycles, and worklogs, covering core workflows well. Some gaps exist, such as no update/delete for projects and no single-project getter, but these are minor and workable.

    Maintenance

    ActivitySlowing
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Local MCP server for a self-hosted Plane instance that exposes tickets, cycles, modules, labels, and states as MCP tools with both read and mutation capabilities.
      24 npm
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      MCP server for Plane project management platform providing 56 tools for workspaces, projects, issues, comments, cycles, modules, and more.
      -