plane-local-mcp
# plane-local-mcp
MCP (Model Context Protocol) local para [Plane Community Edition](https://plane.so/) self-hosted.
Usa a API pública `/api/v1/.../issues/` (compatível com Plane CE). Útil para listar projetos, issues, estados, labels, cycles e buscar itens pelo identificador humano (`PROJECT-N`, ex.: `CKTPC-838`).
## Pré-requisitos
- Python `>= 3.10`
- [uv](https://docs.astral.sh/uv/) instalado e no `PATH`
- Instância Plane CE acessível + API key
## Instalação
```bash
git clone https://github.com/JonatanCosta/plane-local-mcp.git
cd plane-local-mcp
uv sync
```
Anote o caminho absoluto do clone (ex.: `/Users/voce/plane-local-mcp`). Ele será usado nas configs abaixo.
## Variáveis de ambiente
| Variável | Obrigatória | Descrição |
| --- | --- | --- |
| `PLANE_API_KEY` | sim | API key do Plane |
| `PLANE_WORKSPACE_SLUG` | sim | Slug do workspace |
| `PLANE_BASE_URL` | sim | URL base da instância (sem `/api`) |
Exemplo:
```bash
export PLANE_API_KEY="plane_api_..."
export PLANE_WORKSPACE_SLUG="meu-workspace"
export PLANE_BASE_URL="https://plane.exemplo.com"
```
## Cursor
Edite `~/.cursor/mcp.json` (ou Settings → MCP → Add server) e adicione:
```json
{
"mcpServers": {
"plane": {
"command": "uv",
"args": [
"run",
"--directory",
"/ABS/PATH/plane-local-mcp",
"plane-local-mcp"
],
"env": {
"PLANE_API_KEY": "plane_api_...",
"PLANE_WORKSPACE_SLUG": "meu-workspace",
"PLANE_BASE_URL": "https://plane.exemplo.com"
}
}
}
}
```
Substitua `/ABS/PATH/plane-local-mcp` pelo caminho absoluto do repositório. Reinicie o Cursor (ou recarregue os MCPs) e confira se o servidor `plane` aparece com as tools.
## Claude Desktop
1. Abra **Settings → Developer → Edit Config** (cria o arquivo se ainda não existir).
2. Edite `claude_desktop_config.json`:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"plane": {
"command": "uv",
"args": [
"run",
"--directory",
"/ABS/PATH/plane-local-mcp",
"plane-local-mcp"
],
"env": {
"PLANE_API_KEY": "plane_api_...",
"PLANE_WORKSPACE_SLUG": "meu-workspace",
"PLANE_BASE_URL": "https://plane.exemplo.com"
}
}
}
}
```
3. Feche completamente o Claude Desktop e abra de novo.
4. No chat, o ícone de ferramentas (martelo) deve listar as tools do Plane.
> Dica: se `uv` não for encontrado, use o caminho absoluto do binário (ex.: `/Users/voce/.local/bin/uv`).
## Claude Code (CLI)
```bash
claude mcp add plane --env PLANE_API_KEY=plane_api_... \
--env PLANE_WORKSPACE_SLUG=meu-workspace \
--env PLANE_BASE_URL=https://plane.exemplo.com \
-- uv run --directory /ABS/PATH/plane-local-mcp plane-local-mcp
```
Ou edite `~/.claude/settings.json` / `.claude/settings.json` com o mesmo bloco `mcpServers` do Cursor.
## Codex (CLI / IDE)
Edite `~/.codex/config.toml` (ou `.codex/config.toml` no projeto, se ele estiver trusted):
```toml
[mcp_servers.plane]
command = "uv"
args = [
"run",
"--directory",
"/ABS/PATH/plane-local-mcp",
"plane-local-mcp",
]
[mcp_servers.plane.env]
PLANE_API_KEY = "plane_api_..."
PLANE_WORKSPACE_SLUG = "meu-workspace"
PLANE_BASE_URL = "https://plane.exemplo.com"
```
Alternativa via CLI:
```bash
codex mcp add plane --env PLANE_API_KEY=plane_api_... \
--env PLANE_WORKSPACE_SLUG=meu-workspace \
--env PLANE_BASE_URL=https://plane.exemplo.com \
-- uv run --directory /ABS/PATH/plane-local-mcp plane-local-mcp
```
Em uma sessão Codex, use `/mcp` para validar que o servidor conectou.
## Tools disponíveis
| Tool | Descrição |
| --- | --- |
| `get_instance_info` | Base URL, workspace e estilo de API |
| `list_projects` | Lista projetos do workspace |
| `retrieve_project` | Projeto por UUID |
| `list_states` | Estados (colunas) do projeto |
| `list_labels` | Labels do projeto |
| `list_modules` | Modules do projeto |
| `list_cycles` | Cycles do projeto |
| `list_issues` | Issues do projeto (`/issues/`) |
| `retrieve_issue` | Issue por UUID |
| `get_issue_by_identifier` | Issue por `PROJECT-N` (ex.: `CKTPC-838`) |
| `list_issue_children` | Filhos de um épico/issue |
| `update_issue` | Edita título, descrição, prioridade e/ou status |
| `add_issue_to_cycle` | Adiciona issue a um cycle |
| `remove_issue_from_cycle` | Remove issue de um cycle |
### Exemplos de edição
```text
update_issue(identifier="CKTPC-844", name="Novo título")
update_issue(identifier="CKTPC-844", description="Texto simples da descrição")
update_issue(identifier="CKTPC-844", state_name="Em Execução")
add_issue_to_cycle(identifier="CKTPC-844", cycle_name="Payment Sprint - 23")
```
Notas:
- Descrição no Plane usa HTML (`description_html`). Se passar `description` em texto puro, o MCP converte para HTML mínimo.
- Status e cycle aceitam UUID (`state_id` / `cycle_id`) ou nome (`state_name` / `cycle_name`).
- Cycle não entra no PATCH da issue: a API exige `POST .../cycles/{id}/cycle-issues/`.
## Desenvolvimento
```bash
uv sync
uv run plane-local-mcp
```
O servidor fala MCP via **stdio**.
## Licença
MIT
TDQS
Scored across 14 tools
Each tool targets a distinct resource or action, but the pair retrieve_issue and get_issue_by_identifier both retrieve a single issue, differing only by lookup key. This minor overlap is clarified by descriptions, so most tools are unambiguous.
Names follow a verb_noun pattern with snake_case throughout, but verbs are inconsistent (list, get, retrieve, update, add, remove). This is readable but not as uniform as using the same verb for the same operation.
With 14 tools, the server covers issues, cycles, states, labels, modules, and projects without feeling bloated. This is well-scoped for a project management integration.
The surface has strong read and update coverage for issues and cycles, but notably lacks a create_issue tool or any deletion capability. Agents cannot create new issues, so the lifecycle is incomplete.