Skip to content

Self-host Plan Desk for your team

Copy page

If your team wants a shared, always-on planning server behind your own firewall and TLS — with data in a database you back up, and no dependency on a vendor’s hosted instance — self-hosting is the self-host topology. You run the same open-source server asyncdot runs; you just own the box and the database.

If you’d rather skip infrastructure entirely, use the managed instance instead — see Take a local board online.

Two supported paths — pick one:

Docker, single box:

Terminal window
export PLANDESK_AUTH_PASSWORD='choose-a-strong-password'
docker compose -f docker-compose.hosted.yml up --build

By default this persists to a local SQLite file on a Docker volume. For a durable, shared database, point it at your own libSQL/Turso database instead and apply the schema once — see Docker (self-host) for the full flow.

Cloudflare Workers + Turso:

For a public HTTPS API without running a long-lived VM, deploy to the edge — see Cloudflare Workers for the complete runbook (secrets, R2, wrangler deploy).

Either way, if you’re pointing at a remote database, you — the operator — run the schema migration once, and again on upgrades:

Terminal window
plandesk migrate --db <url> --db-token <token>

The server never auto-migrates a remote database, so a multi-replica deploy never races on the schema.

GitHub sign-in is optional but recommended for a team — without it, the dashboard falls back to token entry only. Create a GitHub OAuth App and set its callback URL to:

<your-base-url>/api/auth/callback/github

Full steps (client id/secret, Wrangler secrets): Cloudflare Workers — step 2.

There’s no dashboard “Invite member” button yet — invitations today are link-only: you create one via the API, and you deliver the claim link to your teammate by hand (Slack, email, whatever). A dashboard invite flow is a planned improvement, not yet shipped.

Bootstrapping the very first owner. On a fresh instance with no GitHub sign-in yet, mint the first owner invitation from the shell:

Terminal window
plandesk admin invite-owner --email <you@example.com>

This prints a claim link. Open it and it walks you through claiming ownership of the default organization.

Inviting a teammate once you have an owner session. This endpoint requires a signed-in owner’s browser session (not a CLI/agent token), so call it with your dashboard session cookie attached — from a script, or your browser’s dev tools:

Terminal window
curl -X POST "<your-base-url>/api/v1/orgs/<org-id>/invitations" \
-H "Content-Type: application/json" \
--cookie "<your dashboard session cookie>" \
-d '{"email": "teammate@example.com", "role": "member"}'

role is owner, admin, or member. The response includes a claimUrl — send that link to your teammate directly. No email is sent by Plan Desk.

Your teammate opens the claim link, signs in with GitHub, and accepts — they’re now a member (or whatever role you invited them as) of your organization.

A teammate signing in for the first time gets their own personal organization automatically, same as anyone else. Once they’ve accepted your invite, they switch into your team’s org using the organization switcher in the dashboard’s account menu (top right, next to their role badge) — it lists every org they belong to and lets them pick.

Each teammate, in each repo they work in:

Terminal window
plandesk login --server <your-instance-url>

Paste their own CLI token (from Settings → MCP → Generate CLI token, on the team org). Then, per repo:

Terminal window
plandesk connect --to <team-org-id> [--project <name>]

This mints that person’s agent a project-scoped key — never their owner key — written to .plandesk/token. Full grammar and the two-actor model: Take a local board online and CLI Reference.

RoleCan do
ownerEverything, including minting CLI/agent keys and inviting members
adminManage projects
memberWork with content — tasks, documents, notes