Skip to main content
Glama

Yet Another Simple Kanban board (yask)

This is a simple Kanban board that can track multiple projects.

The functionality will be extended later.

The MVP definition:

  • track multiple projects with completely separate state between them

  • every task has a number, starting with 1 and increasing

  • regular task types: Story, Task, Bug. Can be easily changed anytime.

  • regular task estimate: story points

  • compound task type: Epic

  • Epics can contain other epics (tree-like structure) without cycles, and also Stories, Tasks and Bugs

  • Epics cannot be estimated, they contain the sum of estimations of all contained tasks

  • Tasks state: Backlog, Todo, Planning, In progress, Review, Done, Blocked, Archived

  • Any task can be archived at any time

  • Archived tasks are not listed by default. They can be permanently deleted.

  • Blocked is a holding state for a task that cannot proceed until external input arrives (answers, a decision, missing info). It is skipped by the pipeline until the task is moved back to a normal state; moving to Blocked carries no prerequisite pull.

  • Tasks are sorted, sorting must be preserved. Order of execution is top-down.

  • Tasks can have other tasks as prerequisite

  • If task has prerequisites and is moved in the workflow, prerequisites are moved with it unless they're already past the stage

  • example: task is in Backlog, and has prereqs in Planning, Backlog and Review stages. If the task is moved from Backlog from Todo, the prerequisite that is also in Backlog is moved too. Others stay at their stages.

  • ask confirmation before changing state for multiple tasks in one action

  • Each state change is tracked with timestamp

  • Tasks can have attachments - markdown or images

Interface:

  • web interface (on local machine), configurable port, 4304 (0x10D0)

  • MCP interface for agents

Tech stack:

  • sqlite backend

  • python3

After MVP, the development of yask will dogfood itself to add more features.

Usage

Development

Everything is provided by the flake (nixpkgs 26.05). Enter the dev environment (Python with all dependencies and pytest):

nix develop

Run the test suite (538 tests covering the domain rules above):

python3 -m pytest tests -q

Full build + tests, hermetically:

nix build
nix flake check

Web UI

yask serve                # http://127.0.0.1:4304  (0x10D0)
yask serve --port 9000    # or: YASK_PORT=9000 yask serve
yask serve --data DIR     # or: YASK_DATA=DIR yask serve

The UI is vanilla ES modules (no build step). State lives in a SQLite database inside the data directory (default ~/.local/share/yask/yask.db).

The data directory is machine-private: it is created 0700 and the database file with its WAL sidecars 0600, and these modes are re-applied on every start — the DB holds the boards, attachment BLOBs, and the Telegram bot's password hashes, so other local users must not be able to read it.

The server is loopback-only by design and unauthenticated: the loopback bind is the boundary. As defense in depth it also rejects non-loopback Host headers and cross-origin Origin / Sec-Fetch-Site: cross-site requests, so a web page elsewhere cannot read or write it (CSRF, DNS rebinding). --allow-remote disables these checks.

MCP interface

yask mcp

Speaks MCP over stdio. Example client config:

{ "mcpServers": { "yask": { "command": "nix", "args": ["run", "/path/to/yask", "--", "mcp"] } } }

Tools: list/create projects and tasks, set prerequisites, move/archive/ restore/delete/reorder tasks, task history, task types, attachments (list, read — images come back as viewable image blocks, markdown as text — plus a last_attachment convenience that returns the task's most recent one). Actions that would touch several tasks return requires_confirmation plus the list of affected tasks; re-invoke with confirm: true to apply.

Telegram bot

TELEGRAM_BOT_TOKEN=123:ABC yask telegram
yask telegram --data DIR    # or: YASK_DATA=DIR yask telegram

Runs the bot as a separate process: long-polls the Bot API with the token from TELEGRAM_BOT_TOKEN (get one from @BotFather) and answers /start, /help, /projects (the list of projects with their per-state task counts, sent as a rich message), /tasks [project] (the tasks in the active states — Todo, Planning, In progress and Review — grouped by project and state, sent as a rich message), /task <project> <number|title> (one task's details — state, estimate, description, prerequisites, attachments and recent history — the task found by number or by title, sent as a rich message), /backlog [project] (the tasks in the Backlog state, grouped by project, sent as a rich message), /blocked [project] (the tasks in the Blocked state, grouped by project, sent as a rich message), /attachment <project> <task> <id> (shows a task's attachment — small markdown (<16 KB) inline as a rich message (Bot API 10.1 sendRichMessage), small plain text inline as a plain message, images as a photo, larger content as a file) and /move <project> <task> <state> (moves a task to another state; a move that would pull prerequisites along asks for confirmation via inline buttons first), /describe <project> <number|title> <description> (sets — replaces — a task's description; a numeric first word resolves the task by number, otherwise the longest title prefix match does, and the remaining words become the description), /type <project> <number|title> <type> (changes a task's type — one of the board's task types, matched case-insensitively; a numeric first word resolves the task by number, otherwise the longest title prefix match does, and the remaining words name the type) and /attach <project> <number|title> (attach a file to a task: send a document or a photo to the bot captioned /attach <project> <number|title> — the bot downloads the file and attaches it; allowed types are markdown/plain text and png/jpeg/gif/webp/svg images, 10 MB max). The rich surfaces (the /projects, /tasks, /backlog and /blocked list views, the /task detail view and small markdown attachments) degrade to HTML, then plain text, if the rich send fails (or the Bot API server has no sendRichMessage); set YASK_TELEGRAM_RICH=0 to send plain text only — rich is on by default. A chat can /subscribe [project] to receive notifications about every task state change in that project, and /unsubscribe [project] to stop them — subscriptions are per chat and per project and persist across restarts; the bot detects changes by polling state_history, so latency is at most one poll interval (~30 s). More board commands are on the way. Reads the same data directory as the other subcommands.

Main menu. /start opens the main menu — an inline-keyboard hub with five h:-family buttons: Projects (the project list — the /projects view), Tasks (the active tasks of all projects — the /tasks view), Subscriptions (this chat's subscription list), Add task (the /add usage) and Help (the command reference — the /help text). The hub is one tap away from anywhere: every board view (/projects, /tasks, /task, the /add confirmation and the state-change notifications) and /help carry a "Main menu" button back to it. The menu's board buttons are auth-gated like every other inline button.

At startup the bot also registers a native command menu (the Telegram app's menu button and / command suggestions) via setMyCommands, listing the same commands.

Authentication. Board commands are password-gated. Permitted users — a Telegram chat id plus a password, stored only as a salted scrypt hash — are managed in the web UI (topbar → ✈ "Telegram bot users"), not via Telegram. A password is checked against a strength floor when it is set or rotated: at least 12 characters, using at least two of the lowercase, uppercase, digit, and symbol character classes. A user asks the bot /whoami to learn their chat id, the administrator enters it in the web UI with a password, and the user unlocks the board with /login <password>. A successful login persists across bot restarts (the session is stored in the database) and has a TTL: the stamp tracks the chat's last authenticated activity (any board command or inline-button use refreshes it), and after 24 hours without such activity the session expires and the chat must /login again — state-change notifications are not delivered while the session is expired. /logout ends the session immediately. A newly added chat must log in once, and a password change or removal from the web UI requires a fresh /login (removal revokes access immediately). Until a chat is authenticated, the board commands and all inline buttons answer with an auth-required notice and no board data, and state-change notifications are not delivered to it; /start, /help, /login, /logout and /whoami stay available to everyone.

Each permitted user can additionally be restricted to a list of visible projects (web UI → ✈ "Telegram bot users" → Projects per user). With no list set, all projects are visible; with a list, non-visible projects behave as if they do not exist for that user in every bot command, inline button and state-change notification (the regular not-found wording — a restricted user cannot tell a hidden project from a nonexistent one), and state-change notifications for a hidden project are not delivered to it. Stale subscriptions to projects that later become non-visible are left in place but inert: hidden from the subscription list, never notified.

Related MCP server: sanban

Project layout

  • yask/store.py — all domain logic (projects, numbering, epic trees, prerequisite cascade, archiving, ordering, history, attachments)

  • yask/api.py — REST API; also serves the web UI

  • yask/web/ — web UI (vanilla JS modules, no build step)

  • yask/mcp_server.py — MCP tool surface

  • yask/telegram_bot.py — Telegram bot process (Bot API client, poll loop, command dispatch)

  • yask/cli.py — yask serve / yask mcp / yask telegram

  • tests/ — pytest suite

  • flake.nix / package.nix — packaging and dev environment

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI agents to manage kanban boards with tasks, including creating boards, items, moving between columns, and searching.
    8
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to manage Kanban boards, cards, sessions, and automations through a unified MCP interface with real-time updates, supporting delegation, agent sessions, and human-in-the-loop interactions.
    AGPL 3.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to manage Kanban tasks, boards, teams, and checklists via natural language, with full CRUD operations and live updates.
    127 npm
    MIT