kgoedecke/doop: a multiplayer design canvas where AI agents edit frames over MCP
The open-source alternative to Paper.design. A multiplayer design canvas where humans and AI agents design together, live. MCP built in.
At a glance
- What is it?
- Doop is an AGPL-3.0 TypeScript canvas that renders real HTML in sandboxed frames and lets Claude Code or any MCP client edit it live. It installs with bun or one Docker command, and it is not the right tool if you want a stable API.
- Who is it for?
- Adopt doop if you already drive Claude Code or another MCP client and want its edits to land on a canvas other people can watch, and if AGPL-3.0 fits how you ship. Skip it if you need a frozen API, a hosted SLA, or a design file you can hand to a client.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap doop fills: agent output that lands on a shared canvas
Most AI design tools work as a private loop. You prompt, you wait, you get a result in a chat panel, and nobody else can see the intermediate steps. Doop takes the opposite position. The README describes it as "a multiplayer design canvas for humans and AI agents", and the unit of work is a Canvas at the path /c/<id> holding Frames, which the README says are artboards that render real HTML in sandboxed iframes. People edit in the browser. Agents edit through a built-in MCP server, and their changes stream in live. Cursors, presence, per-frame editing indicators and an activity feed are all part of the same surface.
The audience is narrow but specific. It is for teams who already run an MCP client such as Claude Code and want the agent's edits to be visible to reviewers while they happen, not pasted in afterwards. It is also for people who want the whole thing on their own machine: the README states that every design lives on a shareable canvas, that canvases are private by default, and that agents inherit exactly their human's access. That last point matters more than it sounds. An agent connected over MCP acts as the person who approved the OAuth flow, so there is no separate agent permission model to reason about.
Canvas, frames and the WebSocket room: how the pieces fit
The architecture visible in the repository is a two-process dev setup glued together by ports. package.json defines the dev script as concurrently running a server process and Vite. The README states that the web app listens on http://localhost:4300, while the API, WebSocket and MCP server listen on http://localhost:4400, with the web port proxying /api, /ws and /mcp to the backend. In production there is a single server on port 4400 serving everything, which is also the port docker-compose.yml publishes.
Real-time state travels over one WebSocket room per canvas, according to the README's description of live cursors, presence, frame editing indicators, undo/redo, comments pinned to elements and the activity feed. Frames are not images or vector documents. They render HTML inside sandboxed iframes, which is the design decision that makes the whole agent story possible: an agent produces markup, and the canvas shows the rendered result rather than a picture of it.
Persistence is Postgres through drizzle-orm. The default is not a Postgres server at all. The README says data persists to an embedded Postgres (PGlite) in data/pg, and .env.example confirms that an unset DATABASE_URL means PGlite, described there as fine for local dev and single-instance self-hosting with a persistent volume, with a real Postgres recommended in any serious deployment. Both paths go through the same code, which is a reasonable way to keep local setup free of external services. The trade-off is that the embedded database is a single-writer arrangement tied to one instance, so horizontal scaling is not on the table until you set DATABASE_URL.
Installing doop and connecting Claude Code over MCP
The README's quickstart assumes bun, and bun.lock is the only lockfile in the repository. Clone, install, run:
git clone https://github.com/kgoedecke/doop && cd doop
bun install
bun run devAfter that command, the README says the web app is at http://localhost:4300 and the API, WebSocket and MCP server at http://localhost:4400. No configuration is required for this path, because the embedded Postgres in data/pg takes over and optional integrations stay off until their variables are set.
If you would rather run the production build in Docker, docker-compose.yml defines a doop service plus a postgres:16-alpine database. The README gives the command with a generated auth secret:
BETTER_AUTH_SECRET=$(openssl rand -hex 32) docker compose up -d # app + Postgres on :4400The compose file defaults BETTER_AUTH_SECRET to a placeholder and warns against it in production, so generating the value is the point of that command rather than a formality.
Connecting an agent is one command. The README gives this example for Claude Code:
claude mcp add --transport http doop http://localhost:4300/mcpWhat you should see, per the README, is the standard MCP OAuth flow: a browser window opens, you approve, and the agent then works as you. Ask it to design something on your canvas id and the edits stream into a frame while other people on the canvas watch. The first canvas after signup also runs a welcome performance, which the README says is scripted in server/demo.ts and replayed through the same machinery real agents use, so it runs with no key at all.
The Doop Agent, its key requirements and the free-task ceiling
There are two kinds of agent in doop, and conflating them causes most of the confusion. Agents you connect yourself over MCP need no server-side key. The built-in Doop Agent is different: it lives in the server, picks work up on its own from board cards, @mentions on element comments or task feedback, and is paid for by whoever runs the instance.
The README states the server pays for the free tier on Anthropic by default, via ANTHROPIC_API_KEY, and that the same key gates the guideline distiller in server/distill.ts, which proposes durable style rules from your canvas. The free tier can run on Azure OpenAI instead when credits or compliance rules live there, through DOOP_AGENT_PROVIDER=azure plus the endpoint, key and deployment variables. The distiller stays on Anthropic either way and, in the README's words, quietly turns off without a key.
Past the free tasks, users connect their own model account. The README is explicit that a connected account takes over from the very next task and that the free tier is a trial rather than a balance to spend down. RESIDENT_TASK_LIMIT sets how many free tasks a user gets. Roles are defined in shared/agents.ts, and the README says a card can be routed through several specialists in order: UX, copy, brand, accessibility. Whether that routing produces anything useful depends entirely on the model behind it, and the number of free tasks is a server setting, not a product guarantee.
Where doop is the wrong tool
Version numbers are the first honest signal. The repository sits at 0.4.0, with v0.3.0 and a desktop-v0.2.0 release appearing within a day of each other in September 2026, and the last push was on 2026-09-10. That is a project moving quickly, which for adopters means interfaces and behaviours can shift between minor versions. If you need a frozen API to build against, doop is not that yet.
The second limitation is structural. Frames render HTML in sandboxed iframes. If your deliverable is a Figma file, a Sketch document, or anything a client expects to open in a proprietary editor, doop produces none of that. It produces canvases on a server you run. Export paths are not documented in the README, so treat interchange with other design tools as unverified rather than assumed.
The third is operational. The embedded PGlite database is described in .env.example as suitable for local dev and single-instance self-hosting, and the file recommends a real Postgres in any serious deployment. There is no documented multi-instance story for the WebSocket room either, so a horizontally scaled deployment is not something the documentation claims to support. Finally, production requires BETTER_AUTH_SECRET, and .env.example notes that admin promotion requires SMTP in production because an address only identifies someone once verified. If you self-host without a mailer, signup is open and admin promotion is disabled, which the boot log is said to report.
How doop differs from Paper.design and from plain MCP tooling
The README positions doop as the open-source alternative to Paper.design, and the difference is mostly one of control. Paper.design is a hosted product; doop is AGPL-3.0 source you run yourself, with a hosted version at doop.design for people who prefer not to. Running it yourself means you hold the database, the frames and the auth secret, and it also means you own the upgrade work.
The more interesting comparison is against using an MCP client with nothing underneath it. Claude Code and similar clients can already write files and run commands. What they lack is a shared, live surface where a second person can see the edit as it happens and comment on a specific element. Doop supplies that surface and nothing else: it is not a code editor, not a deployment pipeline and not a component library. If your team works solo and never reviews in the browser, the multiplayer layer is dead weight and a plain MCP filesystem setup will be simpler. The built-in Doop Agent is the second differentiator, since it runs server-side without a connected client, but it depends on an API key and a task limit that the operator configures.
Licence and upgrade cost under AGPL-3.0
package.json declares the licence as AGPL-3.0-only, and the repository carries both LICENSE and a CLA.md. The AGPL is the part that shapes adoption. It is a copyleft licence with a network clause, which in practice means that if you modify doop and let users interact with it over a network, you take on source-distribution obligations that permissive licences do not impose. Whether that matters depends on whether you are running doop internally or offering it to others as part of a service. That is a question for your own counsel, not for this article.
The upgrade cost is real but bounded. Release tooling is present (release-please-config.json, .release-please-manifest.json, CHANGELOG.md), so version history is tracked rather than improvised. The repository also ships a doc-lint script and husky hooks, which suggests the maintainers care about consistency. None of that removes the need to read the changelog before pulling, given how close together the 0.3.0 and 0.4.0 releases landed. If you self-host the Docker path, remember that the Dockerfile installs Chromium for the get_frame_screenshot tool and sets CHROME_PATH and CHROME_NO_SANDBOX, so your image is not small and your container runs a browser.
Editorial conclusion
Adopt doop if you already drive Claude Code or another MCP client and want its edits to land on a canvas other people can watch, and if AGPL-3.0 fits how you ship. Skip it if you need a frozen API, a hosted SLA, or a design file you can hand to a client. Before committing, run bun run dev and confirm that the MCP OAuth flow at http://localhost:4300/mcp completes in your browser, then read .env.example for the variables your deployment will need.
Frequently asked questions
What is doop?
Doop is an open-source multiplayer design canvas where humans and AI agents design together, described in its README as the open-source alternative to Paper.design. Designs live on a Canvas at /c/<id> holding Frames that render real HTML in sandboxed iframes, and agents edit through a built-in MCP server.
How do I install doop locally?
The README's quickstart is to clone the repository, run bun install, then bun run dev, which starts the web app on http://localhost:4300 and the API, WebSocket and MCP server on http://localhost:4400. No configuration is needed because data persists to an embedded Postgres (PGlite) in data/pg.
Does doop need an Anthropic API key?
Only for the built-in Doop Agent and the guideline distiller. The README states that agents you connect yourself over MCP need no key, and that the first-canvas welcome performance is scripted in server/demo.ts and runs without any configuration.
Can I self-host doop with Docker?
Yes. docker-compose.yml defines a doop service and a postgres:16-alpine database, and the README gives the command BETTER_AUTH_SECRET=$(openssl rand -hex 32) docker compose up -d, which serves the app on port 4400. The compose file defaults BETTER_AUTH_SECRET to a placeholder and warns against using it in production.
What licence does doop use?
The repository declares AGPL-3.0-only in package.json and ships a LICENSE file. The AGPL includes a network clause, so if you modify doop and let users interact with it over a network, source-distribution obligations apply.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kgoedecke-doop)