{
  "markdown": "# Kanban AI\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=flat&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-20232A?style=flat&logo=react&logoColor=61DAFB)](https://reactjs.org/)\n\nOpen-source AI kanban for side projects. Plan with AI, manage a board in the browser, and (optionally) drive the same board from Cursor or Claude via MCP.\n\n**Try the hosted app:** [kanbanai.dev](https://kanbanai.dev) · **Docs:** [kanbanai.dev/docs](https://kanbanai.dev/docs) · **Release updates:** [kanbanai.dev/docs/release-updates](https://kanbanai.dev/docs/release-updates)\n\nMost people cloning this repo want the **local** app. That path is first below.\n\n---\n\n## Run locally (recommended)\n\nNo Supabase account, no sign-in. One SQLite database under `.local/` (gitignored). Vite serves the UI; a small local API on port **3000** handles data and OpenAI.\n\n**Requirements:** Node.js 18+, npm, and an [OpenAI API key](https://platform.openai.com/api-keys) for AI features.\n\n```bash\ngit clone https://github.com/orholam/kanban_ai.git\ncd kanban_ai/frontend\nnpm install\ncp env.local.example .env.local\n```\n\nEdit `.env.local`:\n\n```bash\nVITE_LOCAL_MODE=true\nOPENAI_API_KEY=sk-...\n```\n\nDo **not** prefix the OpenAI key with `VITE_` — that would expose it in the browser.\n\n```bash\nnpm run dev:local\n```\n\nOpen **http://localhost:5173**.\n\n### What works in local mode\n\n| Feature | Local |\n|---|---|\n| Kanban board, sprints, tasks, comments | Yes |\n| AI project builder (chat + live workspace) + board assistant | Yes (needs `OPENAI_API_KEY`) |\n| Project members (invite by email) | Yes — invite `collaborator@dev.invalid` to try (seeded) |\n| Cloud auth / account / hosted analytics / feedback | No (needs Supabase) |\n| Remote MCP (`/api/mcp`) | No — use a hosted deploy or `vercel dev` with Supabase |\n\nFirst run applies [`frontend/scripts/local-schema.sql`](frontend/scripts/local-schema.sql). Vite proxies `/api` to the local process ([`frontend/vite.config.ts`](frontend/vite.config.ts)).\n\n### Useful scripts\n\n| Command | What it does |\n|---|---|\n| `npm run dev:local` | Local SQLite API + Vite (default for contributors) |\n| `npm start` | Vite only (pair with Supabase / `vercel dev`) |\n| `npm run build` | Production build + static SEO prerender (unique HTML per public route; skip with `SKIP_PRERENDER=1`) |\n| `npm run build:no-prerender` | Faster local production build |\n\n---\n\n## Optional: Supabase (cloud auth + sync)\n\nUse this when you want real accounts, multi-device sync, or the hosted MCP server.\n\n1. In `frontend/.env.local`, set `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY`, and remove `VITE_LOCAL_MODE` (or set it to anything other than `true`).\n2. Keep `OPENAI_API_KEY` for `/api/openai`.\n3. From `frontend/`, run two terminals: `npx vercel dev --listen 3000` then `npm start`. UI: **http://localhost:5173**.\n\n### Deploy on Vercel\n\nSet `OPENAI_API_KEY` (and Supabase / MCP vars below) in the Vercel project. The OpenAI key is read only on the server — never put it in `VITE_*` client env.\n\n`frontend/vercel.json` pins `\"buildCommand\": \"npm run build\"`. Leave it there: Vercel's Vite preset otherwise runs bare `vite build` and silently skips the SEO prerender, which makes every public URL serve the homepage shell and canonical. See [`frontend/SEO_SETUP.md`](frontend/SEO_SETUP.md). AdSense recovery work (crawlable copy, ads off docs) is logged in [`docs/adsense-approval-log.md`](docs/adsense-approval-log.md).\n\n---\n\n## Ads\n\nAds are served by TinyAdz/Apitiny via the script tag at the bottom of `frontend/index.html` (site id + `data-test-mode`). Two things are easy to break:\n\n- **Ad placements.** TinyAdz auto-places inline ads by matching CSS class chains it scraped from the landing page, so any other page gets no inventory. Add `<AdSlot />` (`frontend/src/components/AdSlot.tsx`) where an ad belongs — it renders a `ta-ad-container` div that TinyAdz fills. Currently used on blog posts and both landing variants (not on docs — see [`docs/adsense-approval-log.md`](docs/adsense-approval-log.md)).\n- **The visitor-engagement gate.** TinyAdz renders nothing until it sees a window `scroll`, `mousemove`, or `touchmove`. Because every route scrolls inside a nested `overflow-y-auto` element, `window` never emits `scroll` on its own, so `frontend/src/lib/nestedScrollBridge.ts` re-broadcasts nested scrolls onto the window from `main.tsx`. Without it, visitors who only wheel-scroll see zero ads and register zero views.\n\nTo preview demo ads locally, set `data-test-mode=\"true\"` in `frontend/index.html`.\n\n---\n\n## MCP (Cursor, Claude, other agents)\n\nOn a **hosted** deployment, Kanban AI exposes a remote MCP server at `/api/mcp` with the same board operations as the web app.\n\n- **End users:** sign in → **Connect AI** (`/connect`) → copy the generated config into Cursor or Claude Desktop. Config uses a long-lived personal MCP key (`kai_…`) so you do not need to reconnect hourly.\n- **Operators:** before Connect AI can issue `kai_…` keys in production, apply `supabase/migrations/20260714120000_mcp_api_keys.sql` on the **Kanban** Supabase project (`mruhzlixrwsgwqaodviy`). Run `./scripts/apply-mcp-api-keys-migration.sh` for the SQL editor link, or `supabase db push` after linking that project.\n- **Operators:** see [`docs/MCP_REGISTRY.md`](docs/MCP_REGISTRY.md) and the env table below.\n- **Discovery:** [`/.well-known/mcp-server`](https://kanbanai.dev/.well-known/mcp-server) · OpenAPI: [`/openapi/mcp.json`](https://kanbanai.dev/openapi/mcp.json) · AI index: [`/llms.txt`](https://kanbanai.dev/llms.txt)\n\n| Variable | Purpose |\n|---|---|\n| `SUPABASE_URL` | Same as `VITE_SUPABASE_URL` |\n| `SUPABASE_ANON_KEY` | Same as `VITE_SUPABASE_ANON_KEY` |\n| `SUPABASE_SERVICE_ROLE_KEY` | MCP analytics, member invites, personal MCP keys |\n| `MCP_API_SECRET` | Shared secret for `X-MCP-API-Key` (also used to encrypt personal keys at rest) |\n| `MCP_KEY_ENCRYPTION_SECRET` | Optional dedicated secret for encrypting personal MCP keys (falls back to `MCP_API_SECRET` / service role) |\n| `OPENAI_API_KEY` | In-app AI (optional for MCP CRUD tools) |\n\n**Tools:** `list_projects`, `get_board`, `create_project`, `update_project`, `delete_project`, `create_task`, `update_task`, `delete_task`, `list_task_comments`, `add_task_comment`, `delete_task_comment`.\n\n---\n\n## Features\n\n- AI project breakdown and sprint-aware task generation\n- Drag-and-drop kanban with priorities, types, due dates, and comments\n- Mobile-first board: status tabs + single scroll list, in-flow quick-add, drawer nav, overlay AI assistant\n- In-board AI assistant (and `@kanban` replies on task threads)\n- Project members (cloud) or local seeded collaborator for sharing tests\n- Dark / light mode\n- Optional remote MCP so coding agents manage the same board\n\n## Tech stack\n\nReact 18, TypeScript, Vite, Tailwind CSS · Local: SQLite API · Hosted: Supabase + Vercel · AI: OpenAI · MCP: `mcp-handler`\n\n## Project layout\n\n```\nfrontend/\n├── api/                 # Vercel serverless (OpenAI, MCP, feedback, invites)\n├── scripts/             # Local schema, prerender, etc.\n├── src/\n│   ├── components/\n│   ├── pages/\n│   ├── lib/\n│   └── ...\n├── public/              # Static assets, llms.txt, OpenAPI, .well-known\n└── package.json\n```\n\n## Contributing\n\n1. Fork and clone\n2. Use **Run locally** above\n3. Branch, commit, open a PR\n\nIssues and ideas: [GitHub Issues](https://github.com/orholam/kanban_ai/issues)\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n",
  "bytes": 7606,
  "sha": "b46a150c3d55ec032562084986ea5cabf72606c38f93a3b07e7d1ffefd461649",
  "repo_slug": "orholam/kanban_ai",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_orholam_kanban_ai_098dcfbf/readme"
}