Skip to content

Plane MCP sudah live, tiga jebakan operasional ini baru terasa

Adityo Guni Waluyo

Workspace nggak bisa dihapus lewat MCP, CORS dipakai ulang sebagai CSRF, dan token API ngintip di .mcp.json.

Ringkasan

Hapus workspace nggak bisa lewat MCP, cuma bisa di UI harus ketik nama dan frasa konfirmasi biar nggak kepencet AI. CORS sama CSRF ternyata satu variabel, jadi abis edit .env harus recreate semua container bukan cuma restart proxy. Token API kesimpen plain text di .mcp.json jadi wajib di-gitignore dan mending pakai yang ada expiry.

Baru selesai pasang, saya langsung coba hal yang seharusnya paling gampang: menghapus workspace uji yang tadi dibuat untuk percobaan. Perintah dikirim, respons nihil. Workspace-nya masih di sana. Saya telusuri daftar tool satu per satu, dari 30 tools dengan 204 operasi yang diiklankan di README plane-mcp-server [1]. Nggak ada satu pun yang bisa menghapus workspace.

Dugaan pertama saya meleset. Saya kira server resmi pasti mengekspos semua operasi. Faktanya, file workspace.py di upstream cuma punya tiga action: retrieve, get_features, dan update_features [3]. Delete tidak ada.

Workspace hanya bisa dihapus lewat UI, dan itu keputusan yang benar

Workspace adalah root tenant. Semua project, work item, sampai riwayat aktivitas tergantung di situ. Menghapusnya lewat satu panggilan API yang salah ketik akan jadi bencana yang nggak bisa di-undo. Makanya jalur hapusnya sengaja dibuat berlapis di antarmuka web: buka Workspace Settings, ketik nama workspace persis (case-sensitive), lalu ketik frasa delete my workspace di kolom konfirmasi kedua. Baru tombolnya aktif.

Lapisan ini makin relevan sejak tool MCP dipanggil oleh agen AI yang bisa bersikap otonom, bukan manusia yang berpikir dua kali. Kalau delete workspace jadi satu action biasa, satu halusinasi kecil dari agen sudah cukup untuk menghapus tenant produksi. Frasa konfirmasi yang harus diketik persis itu pagernya. Ini bukan keterbatasan MCP, tapi pilihan keamanan yang masuk akal. Saya berhenti mencari jalur API setelah paham alurnya.

CORS dan CSRF ternyata satu variabel

Kebutuhan kedua muncul saat dashboard dibuka dari origin lain. Browser memblokir dengan error CORS. Solusi standar: tambahkan origin baru ke CORS_ALLOWED_ORIGINS di .env, sesuai referensi environment variables self-hosting Plane [5]. Saya lakukan, restart reverse proxy, dan errornya tetap.

Dugaan saya, CORS dan CSRF itu dua konfigurasi terpisah. Setelah baca source-nya, kenyataannya begini: CSRF_TRUSTED_ORIGINS = cors_allowed_origins [2]. Django di Plane tidak punya variabel CSRF sendiri; dia pakai ulang daftar origin yang sama.

Konsekuensi praktisnya, edit .env saja tidak cukup. Environment variable dibaca saat container start, jadi container api, worker, beat, dan migrator harus di-recreate dengan docker compose up -d --force-recreate, bukan cuma proxy yang di-restart. Cara saya memastikan fix-nya nempel: hard refresh dashboard. Kalau error CSRF masih muncul, berarti ada container yang belum ke-recreate. Sekali ini agak ribet, tapi saya terima saja: satu sumber kebenaran untuk origin lebih aman daripada dua variabel yang bisa tidak sinkron.

Token API tinggal di .mcp.json, persis di samping kode

Kunci API Plane dikirim lewat header X-API-Key, dan dokumentasi API resminya menegaskan kunci itu harus diperlakukan seperti password, plus bisa diberi tanggal kedaluwarsa sejak dibuat [4]. Realitanya, config klien Claude Code menyimpan token itu sebagai plain text di .mcp.json di root repo.

Kebiasaan yang menyelamatkan: .mcp.json masuk .gitignore, dan git status dicek sebelum setiap commit. File yang satu ini bocor berarti token workspace ikut terpublish di riwayat git. Alternatif yang saya pilih untuk Hermes: kredensial tetap di config utama yang tidak pernah ikut repo, bukan di file samping yang rawan kebayang saat git add ..

Praktik kecil yang ikut saya jalankan: token yang dipakai klien AI selalu yang punya expiry, bukan yang permanen. Kalau suatu saat file config kecopy ke tempat yang salah, dampaknya ada batas waktunya, dan rotasi tinggal buat token baru lalu ganti satu baris config.

Ketiga hal ini tidak muncul saat instalasi sukses. Semuanya baru terasa setelah server benar-benar dipakai: satu operasi yang nggak ada, satu variabel yang ternyata dua peran, satu file yang diam-diam menyimpan kredensial. Pelajarannya satu: kalau dokumentasi dan perilaku nyata beda, buka source-nya. Kode sumber jarang bohong.

Artikel terkait