The task
Dodil, a cloud for applications with its own database, sign-in, models and CI, opened a brief for a Trello replacement: a board for a team of three to five people, run from Claude and ChatGPT over MCP. The terms: roles, a change log, no external OpenAI or Anthropic keys, and a structure anyone copies with one “remix” command. One link to a public repository is submitted, and the judging is by working code.
A team wants a simple board, and questions like “what is on me this week” and “what is holding the launch” are better asked in words than clicked through filters. For Dodil the task is different: show that a full application comes together on their cloud in an evening.
Why, and what the idea was
The first version followed the score sheet from the brief. The starter repository covered about a third of the core, and the main risk sat in the remix “gate”. So the core first, then MCP, then the extras: an AI checklist from a card, similar cards by meaning, a daily summary, “what is blocking the launch” along the chain, automatic overdue flags.
The second version was set by an independent review. It agreed that the three stars were not about the code: the judge could not touch anything within two minutes. The live link hit a sign-up wall, there were no demo logins, and Claude connected only after a client was approved by hand in our pool. The newspaper with the blackletter masthead read as an art project, not a platform template. And we turned out to be one of six similar entries with the same tables and 24-26 tools, so “26 tools” stopped being an argument.
Hence the plan: access first, then one end-to-end scenario, “a board from a sentence”, then the face. We deliberately dropped comments, schema migrations and the race for test counts.
How it went
| When | What happened |
|---|---|
| Day 1, morning | Brief and rules analysed, a plan. The core locally on stubs: boards, lists, cards, roles, log, 26 MCP actions, web with drag and drop, extras. 24 tests. A security self-check found 2 holes, closed, 26 tests |
| Day 1, afternoon | Dmytro signed up on Dodil and logged into the CLI. The starter remixed, its tables replaced with ours, CI deployed. Live check on the real database and models 9 of 9 |
| Day 1, afternoon | MCP checked the way Claude connects: OAuth through the pool, Dmytro’s login, 4 phrases from the brief, someone else’s board invisible. The “Index cards” design rejected, a newspaper with a night edition made instead |
| Day 1, evening | Repository public, the first entry submitted. The same day the owner gave 3 stars with no comment |
| Day 2, morning | A review by five independent advisers in the role of the owner and Dodil’s judges: each read the brief, our code and 10 public competing entries |
| Day 2, afternoon | The second version: set_up_board, a sample board, a public demo for three roles with a reset, MCP prompts and tool annotations. Three design options, Dmytro picked A. 47 tests, live check 11 of 11 |
| Day 2, evening | Code pushed, CI green, demo users created by Dmytro. The second entry submitted. The per-entrant limit of two reached |
Tools and method
Python and FastAPI, light DDD: a domain layer with the role rules, application with the shared scenarios, infrastructure with DataK3, sign-in and models, and two “doors”, web and mcp, that call the same scenarios. About 1,900 lines in app/ and 800 lines of tests.
Data in DataK3, Dodil’s cloud database over DuckDB: 7 tables from schema.sql, a change log with “was” and “is” fields. Sign-in through the appid user pool behind a gateway: a forged header around the gateway gets 401. Claude connects over OAuth with DCR and PKCE; Claude and ChatGPT have their own registered clients with no manual approval step. AI only from Dodil Models: the kimi-k2.7-code chat and jina-embeddings-v4 embeddings cached per card, no external keys in the project.
MCP: one /mcp endpoint, 28 action tools and three slash commands: /standup, /plan_my_week, /unblock. Every tool is marked “read only” or “changes or deletes”, so Claude asks before deleting. set_up_board assembles a board from a sentence: dates counted back from the launch date, “blocked by” links in place.
Runs on Ignite, deployed through Dodil Git CI on every push: test, build, deploy, remix check. An empty remix is not empty: a new copy opens a sample board with an overdue card, a blocker chain and history, and the demo has a reset button so the next judge does not see the previous one’s mess.
Result
A live site: the front page “Tell Claude the goal. Get the board.”, three demo sign-ins, owner, member and viewer, and a hint on connecting Claude. A board with drag and drop, card numbers, overdue cards with a red edge and “waits on #4”, search, “My plate”, “Overdue”, a daily summary and an activity log. Someone else’s board is invisible by number, by name and through search, the same on the page and in Claude.
Numbers: 24 tests in the first build, 27 in the first submitted entry, 47 in the second. The live check on the real DataK3 bucket and Dodil models 9 of 9, then 11 of 11. CI: test, build, deploy, remix passed. The first entry got 3 stars, and by the data we gathered the owner gave no one more: 3 stars on 7 entries out of 43.
Weak spots, plainly. A full remix into another organisation was not run: on Free one organisation has only one user pool, and the test copy failed on that limit. The connection in the Claude web app specifically is untested; the same protocol was checked with our own client and Claude Code. ChatGPT is registered as a client but was not tried live in ChatGPT.
What we do not know yet: the results. The owner chooses after the brief closes and has up to 30 days to judge. We will add it when it comes.
Mistakes and what we took from them





