
Janosik
io.github.VitalyTolstik由 GitHub 账号 VitalyTolstik 发布v0.5.1更新于 Nov 4, 2026
Drive a Janosik Kanban board from any MCP client: ready work, leases and task specs.
概览
让 AI 客户端连接自托管的 Janosik 看板,读取并修改看板、列、卡片、检查清单和评论。
- 可以做什么
- 处理看板、列和卡片:创建、编辑、移动、归档和搜索
- 管理标签、检查清单、卡片链接、评论、活动记录和附件
- 可选工具集提供成员、邀请、分享链接和账户操作
- 写入与网页界面共用同一命令日志,因此可撤销,并实时同步给其他看板成员
- 适用场景
- 适合团队把工作放在自托管 Janosik 看板上,并希望由智能体领取待办任务、以限时租约认领卡片、维护任务说明与检查清单,或在受阻时报告而不是直接标记完成。
- 运行要求
- 需要以服务器模式运行的 Janosik 实例,以及在应用内创建的个人 API 密钥(JANOSIK_TOKEN,以 jnk_ 开头)。需设置 JANOSIK_URL 为实例地址;仅当应用不在站点根路径时才需 JANOSIK_APP_BASE。通过 npx 本地运行,需要 Node.js。
安装
在 SourceWeft 中
- 打开 控制台中的 Janosik,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
Janosik
A self-hosted Kanban board for teams and AI agents. Server mode provides accounts, shared boards and realtime sync. The UI and API share one pure reducer and a command log; the installable PWA can reopen cached pages offline.
[React] [TypeScript] [Vite] [Tailwind CSS] [NestJS] [CI] [License: AGPL-3.0]
Janosik runs in server mode in development and production. The UI applies edits optimistically, then sends them to the API as commands (
POST /boards/:id/commands); the UI and API use the sameboardReducer. Unit tests can exercise the reducer without an API. The PWA caches its app shell and assets, so previously loaded pages can reopen offline, but saving changes requires a server connection. Realtime updates use SSE and resume from?since=after a dropped connection. See ROADMAP.md §7 for the architecture history.
Repository layout — the workspaces
This is an npm workspaces monorepo with seven workspaces and one root lockfile. ui, shared and backend make up the application; brand, site, video and mcp support its design system, website, media and agent integrations. Install dependencies once with npm install from the repository root.
Why shared matters: a board mutation is written once (in the reducer), executed in the browser for instant feedback and on the server when the command arrives — so a card can never move differently in the UI and in the database. The same applies to validation and to DTO types: change a field in shared/src/admin.ts and both sides fail to compile until they agree.
Highlights
- Four board views — Kanban, Calendar (drag deadlines, "unscheduled" panel, week/month, day panel), Table (sorting, inline editing, configurable columns) and Watch (a read-only status view with a live activity feed and 20/50/100-item pages).
- Card density — a
Simplify designtoggle switches every card to a compact one-line tile (title, label dots, blocked marker, checklist progress, priority and assignee) with far fewer elements; the full face stays one click away in the card dialog. - Drag & drop — move cards within/between columns and reorder columns (
@dnd-kit), inline Trello-style "+" zones, keyboard sensor and drag overlay. - Rich card content — WYSIWYG description (MDXEditor) that is the card's document (up to 64k characters), checklists with progress badges (items up to 500 characters), due dates with overdue/soon badges, color/gradient covers, 14-color labels, and a read-only machine-readable acceptance-criteria / definition-of-done contract.
- Card & board archive — Trello-style archiving with restore (WIP-aware) and permanent delete; board archive with restore.
- Multi-boards — switcher, create/rename/archive/delete, deep links
/board/:id, global search across boards with snippets. - Search & filters — by title/description/labels, label ANY/ALL matching, due status, creation date; hotkeys
/andCtrl/Cmd+K, match counter. - WIP limits — per-column caps with counters, blocked composers/drags and toasts.
- Activity feed — per-card event history covering every board action, with relative timestamps and an "Agent" badge on entries an agent's API token caused.
- Keyboard-first — shortcut palette (
?),j/kcursor navigation,n/ccomposers,e/Enteredit. - Undo / redo — 50-step history with coalescing,
Ctrl/Cmd+Z,Ctrl/Cmd+Shift+Z,Ctrl+Y, header buttons. - PWA — installable (manifest + icons). The service worker caches the app shell and hashed assets, so previously loaded pages can reopen offline. Writes still need the API: if it is unreachable, an optimistic edit rolls back with a message. There is no persistent outbox yet, so reloading discards unsynced changes; previously loaded data remains available offline.
- Server mode — sign in to work with boards stored in PostgreSQL. The UI applies edits optimistically and sends each one through the command log (
POST /boards/:id/commands); rejected edits roll back with a message. Per-entity version checks protect typed text from a stale undo. A request already in flight can finish during a reload. The no-API local-only mode is used by unit tests; development and production builds require the API. - Realtime — a
GET /boards/:id/eventsSSE stream carries every committed command ({type, seq, action, actorId}) and the client replays foreign actions through the very same reducer. Edits appear in other browsers with no reload; a dropped stream resumes exactly where it stopped (?since=) and window focus remains the fallback. Your own commands are never applied twice, and a stale undo still refuses to clobber someone else's text. - Shared boards — a Members (N) dialog in the header: admins invite by email, switch roles (
ADMIN/MEMBER/VIEWER), bound a viewer's access with an expiry date ("access expired" badge) and remove members — the last admin can never be demoted or removed. Invitations are opt-in: the invitee gets a badge on the header bell and accepts or declines there; nothing is shared until they accept. Everyone else sees the same member list read-only, and aVIEWERgets a genuinely read-only board: no drag, no composers, no menus, no inline editors, a read-only card dialog — while the server independently answers 403 to every mutation. - Master panel — a separate
/adminarea for the platform operator: metrics, all users and boards, command log, audit trail and moderation (block a user and their sessions die instantly, revoke API tokens, archive/soft-delete a board, create accounts with a one-time password). Master accounts live outside the user table, have their own login, cookie and JWT audience, and are created only by the server CLI (npm run admin:create -w backend);OWNERcan add more masters,OPERATORcannot. Panel tables are schema-first: columns are named after Prisma fields (Board.id,BoardMember.userId,Card.columnId,Comment.authorId, …), foreign keys are shown as copyable IDs (title/email only as a caption) and search matches those IDs — a row can be traced to its parents even when names are not unique. - AI agents (MCP + skill) —
@janosik/mcpgives compatible clients (Claude, Cursor, VS Code, opencode and Codex) access to board tools through a personal API key. Thejanosikskill provides workflow guidance: claim a card under a temporary lease, keep its description, checklist and comments structured, and return blocked work with evidence. Keys can be scoped to one board, made read-only and rate-limited. Commands retain actor attribution, history and undo. See Drive it from an AI agent. - Performance — the editor and calendar load on demand; vendor libraries use separate cacheable chunks, and board rows and cards are memoized. Performance measurements and their test conditions are recorded in docs/PERF-BASELINE.md.
- Data safety — debounced saves, JSON export/import, automatic backups (20 snapshots, rotated), error boundary + toasts, input/collection limits everywhere.
- Themes & polish — dark/light with no-flash preflight, four board backgrounds, adjustable column glass,
prefers-reduced-motion, custom scrollbars. - i18n — English & Russian with type-safe keys and pluralization; 12h/24h time format toggle.
- Brand — Space Grotesk wordmark (self-hosted) + animated "Перо Яношика" feather logo.
Tech stack
Quick start
Prerequisites: Node.js 22.17+ — the repo pins 24 via .nvmrc (nvm use), and that is what CI runs. npm. Docker for server mode (PostgreSQL/Redis).
Per-OS walkthroughs (macOS, Windows 11, Linux) — both Docker and from-source, with the OS-specific gotchas — live in docs/INSTALL-BY-OS.md.
Server mode (accounts + PostgreSQL)
The dev UI is always in server mode: it calls /api/v1 (Vite proxies it to :3000), so you get a sign-in screen and npm run dev alone does not show a board. Bring the database and API up first:
Register at http://localhost:5173 (registration is open by default) — the boards then live in PostgreSQL and sync through the command log. To open the master panel at /admin, create the first master on the server (see below).
Local-only / no-API build. The app can also render with no backend — that is the in-browser mode the unit tests use (
MODE=test), with the seeded "Product Launch" board inlocalStorage. Thenpm run dev/npm run buildbuilds are not that mode: they always talk to the API and show the login screen, so "just look at the demo board, no login" is not available from the dev server.
Marketing site (Astro) — dev
The marketing site and docs live in site/ (Astro + Starlight) and run on their own dev server:
In dev the app is not served under /app/ on the site — that path belongs to the self-host image, where one server serves the site at / and the app at /app/. So the site's "Sign in" / "Create account" CTAs must be pointed at the UI dev server, otherwise they 404:
The reverse link — the in-app Help → Documentation — points at the site, so give the UI dev server VITE_SITE_URL (otherwise it opens /docs/ on the UI origin and hits the not-found page):
The self-host image sets both by serving the site at / and the app at /app/ on one origin; a split deployment (two hosts) sets PUBLIC_APP_URL and VITE_SITE_URL to the two origins — see docs/SELF-HOSTING.md.
Enabling outgoing email (optional — off by default)
Email delivery is not enabled by default. The API boots fine with no mail setup: with no SMTP transport configured it runs in log mode — every message (verification codes, email-change notices) is written to the server log instead of being sent, and registration auto-verifies so nobody is locked out. Messages are never actually delivered until you configure a transport in the master panel.
To actually send mail, open /admin → Email service (owner only), pick a preset and paste the credentials, then flip Enable delivery and hit Send test email:
- Gmail / Yandex / Mail.ru — configure the provider's SMTP settings and use an app password where the provider requires one.
- Brevo / SendGrid — transactional email services. SendGrid uses
apikeyas the username and your API key as the password. - Custom SMTP — any host / port / TLS.
Trying it out locally (Mailpit). The Mailpit (sandbox) preset sends email to a local catcher and needs no credentials. Messages appear in its web inbox instead of being sent to a real address. Start it, then open the inbox:
Self-hosting with Docker (production)
The fastest way to run Janosik is the prebuilt image: one container serves the
whole app (API under /api/v1 + the built SPA), next to PostgreSQL and
Redis. No separate web server or proxy config — SSE and cookies work on a
single origin.
Create a master (platform admin) account for the /admin panel — the CLI
is the only door, there is deliberately no HTTP endpoint for it:
Upgrade and back up:
Environment variables (see .env.example for the full annotated list):
To build the image from a checkout instead of pulling, uncomment build: .
in docker-compose.yml. For a TLS-terminating proxy in front, keep
PUBLIC_ORIGIN=https://…, set COOKIE_SECURE=true and TRUST_PROXY=1.
Full guide — TLS setup (Caddy/nginx/Traefik), backups & restore, the environment reference and troubleshooting: docs/SELF-HOSTING.md.
Master panel (platform admin)
Regular accounts are not admins — the panel at /admin belongs to the platform operator (the "master"), and there is deliberately no HTTP endpoint that can create a master: registration always creates a regular user, and no request can grant master rights. Masters live in their own table with their own login, cookie and JWT audience, so a user session can never open /admin (and a master token never works on user routes).
Creating a master account (admin:create)
The CLI is the only door: registration always creates regular users, and no API call can grant master rights. Run the commands from the repository root, with backend dependencies installed and backend/.env present (its DATABASE_URL must point at the same database the API uses).
Rules worth knowing:
- Password: 8–100 characters. There is deliberately no
--passwordflag — a password inargvleaks intopsoutput and shell history. Without a TTY and withoutADMIN_PASSWORDthe CLI refuses to run. - Role: the first master in an empty database becomes
OWNERautomatically; every later CLI master isOPERATORunless--owneris passed. Owners can add/block/reset masters right in the panel (Masters page); operators have full data access but cannot manage masters, so a stolen operator session cannot escalate. - Email is required and normalized to lowercase; creating a duplicate fails with a hint to use
admin:passwd. - Audit: every create/re-key writes an
AdminAuditLogrow (via: "cli"), visible on the panel's Audit page. - Sign in at
http://localhost:5173/admin(dev) orhttps://your-host/admin(self-hosted). Sign-out sits in the top-right corner. - What you get there: metrics with 14-day sparklines plus a runtime card (version, uptime, DB latency), all users (search, filter, create with a one-time password, block → sessions die instantly, revoke API tokens), all boards (create for an owner, archive/restore, soft-delete), all cards and comments (search + moderation), active sessions and personal API tokens (scoped to a board, read-only or rate-limited) with per-row revoke, the cross-board command log, and the audit trail of every master action. Tables follow the database schema (see Highlights) and search matches foreign-key IDs. The board content editor (
/admin/boards/:id/content) creates and renames columns and cards through the command log on behalf of the board owner, so the board UI stays consistent. - Hardening that ships with it: argon2id hashes, 5-failed-login lockout (15 min) plus rate limiting, per-entity refresh rotation with reuse detection, response shapes that never include password/token hashes, and an audit row for every login attempt and mutation.
Drive it from an AI agent (MCP + skill)
Janosik lets AI agents and people work on shared boards. The MCP server provides the tools; the skill describes a consistent workflow for using them:
@janosik/mcp— the tools. An MCP server (71 tools across 13 groups) for boards, columns, cards, labels, checklists, links, comments, activity and attachments. Optional toolsets add members, invitations, share links and account actions. Any compatible MCP client can connect with a personal API key (jnk_…). Writes use the same command log as the UI, so they can be undone and stream live to other board members.skills/janosik— workflow guidance. It tells the agent to read before writing, claim a card under a time-limited lease, keep its description, checklist and comments structured, use reservedagent:*labels, and return blocked work with evidence instead of marking it Done.
1. Get an API key
In the app: Account → API keys → create (starts with jnk_). Give each
agent its own user account and key, so the activity feed shows who did what
and revoking one key stops one agent. A key can be scoped when you create it:
restrict it to a single board, make it read-only (writes answer 403 pat_read_only) and give it its own requests-per-minute budget (over budget
answers 429) — a board-scoped, read-only key is the least-privilege choice for
an agent.
2. Add the MCP server
Works in Claude Desktop/Code, Cursor, VS Code, opencode and Codex.
JANOSIK_APP_BASE is only needed when the app is not at the site root (e.g.
/app). By default the server registers the board-work tools; member,
invitation, share and account tools are opt-in (JANOSIK_MCP_TOOLSETS), and
attachment upload/download stays off until you set JANOSIK_MCP_ALLOW_FS=1.
3. Add the skill
Drop skills/janosik/ into your harness's skills directory — Claude Code:
~/.claude/skills/, opencode: ~/.config/opencode/skills/, agent-compatible
harnesses: ~/.agents/skills/. Details in
skills/janosik/README.md. The skill needs no
configuration; it provides Janosik-specific guidance for working with cards.
What the agent does with it
The agent claims a card under an atomic lease (janosik_claim_card, released with
janosik_release_card): the server refuses a claim while another member still
holds a live lease, and the lease expires automatically if an agent stops
responding. It comments as it goes, fills the description and checklist, moves
it In Progress → Review → Done, and on a bug moves it back (to Bugs /
In Progress) with a comment describing the defect — so a reviewer sees the card
travel forward, back and forward again, with a reason at every turn. That
backward move plus the comment is the audit trail.
The skill asks the agent to leave a card another agent can continue without
prior context: description
sections (Why / Scope / Acceptance criteria / Out of scope / Verify),
a Definition of Done checklist, and typed comments (a structured kind:
status / question / blocker / evidence / handoff) so the thread is
machine-readable and filterable. It can also write the card's task contract
(janosik_set_card_task_spec sets acceptanceCriteria + definitionOfDone,
each rendered read-only in the card dialog) and tag cards with the reserved
agent:blocked / agent:needs-human / agent:verified labels. Every command
records whether a person or an agent caused it, so an agent's entries carry an
"Agent" badge in the card history.
Full guide in-repo: mcp/README.md and skills/janosik/SKILL.md.
Scripts
Root scripts cover the seven npm workspaces:
Workspace-specific extras worth knowing:
Project structure (UI workspace in detail)
Architecture (30 seconds)
- Normalized data model — a
Boardholds orderedColumn[], aRecord<string, Card>andLabel[]. Reordering = reordering id arrays. Archived cards stay in the map witharchivedAtand are dropped fromcolumn.cardIdsuntil restored. - Pure reducer in
shared—boardReducer(30+ actions) is a pure function; every action returns a new board, which makes undo/redo, coalescing and testing trivial. The backend executes the identical reducer when a command reaches the command log, so UI and server can never diverge. - One provider, three contexts —
BoardProviderowns state, debounced persistence (400 ms), per-board history, hotkeys and auto-backups. It publishes the board data, the actions (assembled once, so write-only components never re-render) and undo availability separately. Components only call typed convenience actions (addCard,moveCard, …). - Persistence is swappable — and was swapped — the
DebouncedPersistenceinterface wrapslocalStoragefor the local mode; server mode adds a fetch adapter (ui/src/api/client.ts+ui/src/store/server-sync.ts) that ships the same actions to the command log without touching the reducer or the UI (optimistic updates on top of the same actions). In server mode board data is deliberately not mirrored intolocalStorage(accounts on a shared browser must not see each other's boards). - Performance — the MDXEditor description editor and the calendar are lazy-loaded on first use; vendor libraries are split into stable chunks that the service worker caches; columns, cards, insert zones and table rows are memoized, so typing in one card re-renders only its own column (or table row) — the cost per keystroke no longer grows with the board.
See ROADMAP.md for project priorities, architecture decisions and task status.
Contributing
-
Work happens in feature branches off
main—feat/<slug>,fix/<slug>orchore/<slug>; never commit tomaindirectly. Open a PR and let CI run. -
Before pushing, make sure everything is green:
-
UI unit and component tests use Vitest + React Testing Library. Backend end-to-end tests use Jest + Supertest against PostgreSQL. Browser-level Playwright coverage is tracked in ROADMAP.md under TASK-41; it is not part of the current CI workflow yet.
-
New UI strings land in both
src/locales/enandsrc/locales/rusynchronously; colors come only from the design tokens insrc/index.css. -
Change the data model, a board operation, validation or an API contract in
@janosik/sharedfirst — bothuiandbackendcompile against it. -
The backend follows the fixed stack in
ROADMAP.md§7 (NestJS/Prisma/PostgreSQL/JWT) and its iteration order. -
By submitting a pull request you agree that your contribution is licensed under the AGPL-3.0 License, the same terms as the rest of the project.
See CONTRIBUTING.md for the full guide — dev setup, the gate commands, and the required DCO sign-off (git commit -s).
License
AGPL-3.0 © 2026 Vitali Toustsik
You may use, self-host, fork and modify the code, including commercially. See LICENSE for the full AGPL-3.0 terms. In particular, if you run a modified version as a network service, the license requires you to offer its source code to the people using that service.
Trademarks. The license covers the code, not the name. "Janosik" and the feather mark identify this project; forks are welcome but must not present themselves as the official Janosik or its hosted service — see TRADEMARK.md.
来源:README.md,提交 480786a
工具
0版本历史
5- v0.5.1最新Nov 4, 2026
- v0.5.0Nov 1, 2026
- v0.4.0Oct 31, 2026
- v0.3.0Oct 30, 2026
- v0.1.3Oct 29, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分