Tun's Random Thoughts
BlogProfilePhoto Gallery
All Projects
sTOobyDOo

In Progress

sTOobyDOo

View on GitHubLive Site
Tech Stack
TypeScript

sTOobyDOo

A collaborative, MCP-enabled todo app for families and teams.

Built with Next.js, TypeScript, Prisma, and LibSQL.

License: MPL-2.0 Next.js 16 TypeScript Prisma 6 MCP

Features · Quick start · Configuration · MCP · Deployment

sTOobyDOo combines a multi-user family task manager with a first-class AI integration surface. Organize shared and private lists, nest subtasks, assign work to family members, and receive push or email notifications — while any MCP-compatible AI assistant (Claude, Cursor, and others) can manage the same tasks through natural language using permission-scoped tokens.

Features

Area What is included
Families and members One family instance with multiple members, admin roles, and per-member private lists.
Lists Named lists with descriptions and colors, per-member sharing with edit/delete/share grants, and archiving.
Tasks Two levels of nested subtasks, descriptions, priorities (low/medium/high), due dates with optional times, scheduled reminders, assignment, completion, and soft-delete archiving.
AI integration (MCP) A Model Context Protocol server at /api/mcp exposing 17 tools over SSE and HTTP POST, authenticated by per-user tokens with granular permissions and per-list access restriction.
Notifications Pushover push and Resend email notifications for task assignment, completion, and due-date reminders. Credentials can be set globally by an admin, per member, or via environment variables.
Reminder scheduling A secret-protected /api/cron/reminders endpoint, a ready-to-use GitHub Actions workflow, and in-app polling as a no-setup fallback.
Interface Responsive App Router UI with light/dark themes via next-themes.
Deployment Zero-config Vercel deployment with automatic, data-safe database initialization against a hosted LibSQL database such as Turso.

Technology stack

Layer Technology
Application Next.js 16 App Router, React 19, TypeScript 5
Data Prisma 6, @prisma/adapter-libsql, SQLite-compatible LibSQL (local file or hosted)
Authentication NextAuth.js 4 credentials provider with JWT sessions and bcrypt password hashing
Styling Tailwind CSS 4, CSS variables, next-themes
Notifications pushover-js, Resend
AI protocol Model Context Protocol (SSE transport, protocol version 2024-11-05)
Deployment Vercel (serverless) with a hosted LibSQL database

Quick start

Prerequisites

  • Node.js 20.9 or newer
  • npm

1. Install the project

git clone https://github.com/tunwinlat/sTOobyDOo.git
cd sTOobyDOo
npm install

2. Configure the local environment

Create a .env.local file in the repository root:

DATABASE_URL="file:./dev.db"
NEXTAUTH_SECRET="replace-with-a-long-random-secret"

Generate a suitable secret with:

openssl rand -base64 32

Environment files are ignored by Git. See .env.example for the full variable reference.

3. Prepare the local database

npx prisma generate
npx prisma db push

4. Start sTOobyDOo

npm run dev

Open http://localhost:3000 and complete the setup wizard to create your family and admin account.

Configuration

Environment variables

Variable Requirement Purpose
DATABASE_URL Required Local file: URL for development, or a hosted libsql:// connection URL for deployment.
DATABASE_AUTH_TOKEN Hosted databases Authentication token for the LibSQL provider (required for remote URLs).
NEXTAUTH_SECRET Required Signs NextAuth JWT sessions. Use a strong random value.
NEXTAUTH_URL Optional Absolute application URL; auto-detected on Vercel.
CRON_SECRET Recommended Bearer secret protecting the /api/cron/reminders endpoint.
PUSHOVER_APP_TOKEN Optional Fallback Pushover application token when none is stored in family settings.
PUSHOVER_USER_KEY Optional Fallback Pushover user key when none is stored in family or member settings.
RESEND_API_KEY Optional Fallback Resend API key when none is stored in family settings.
RESEND_FROM_EMAIL Optional Sender address for Resend email notifications.

Notification credentials are resolved in order: per-member settings, then family (admin) settings, then these environment-variable fallbacks. All of them can be managed from the settings UI after deployment — no environment variables are required for notifications.

Database options

Provider Use case URL format
SQLite Local development file:./dev.db
Turso (or another hosted LibSQL provider) Production libsql://<db>.turso.io

Model Context Protocol (MCP)

MCP is the differentiator of sTOobyDOo: every member can issue tokens that let AI assistants read and mutate tasks through natural language — "add 'buy milk' to the shopping list", "what is due this week?", "complete the grocery run".

Creating a token

  1. Log in to your sTOobyDOo instance.
  2. Go to Settings → MCP Tokens and click Create Token.
  3. Name the connection (for example, "Claude Desktop") and choose permissions.
  4. Copy the token; it is used as ?token=YOUR_TOKEN or a Bearer header against /api/mcp.

The endpoint speaks MCP over SSE (GET /api/mcp, protocol version 2024-11-05) and accepts plain JSON-RPC over HTTP POST for simple clients.

Claude Desktop

Claude Desktop connects to remote SSE servers through a bridge such as mcp-remote. Add to claude_desktop_config.json:

{
"mcpServers": {
"stoobydoo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://your-app.vercel.app/api/mcp?token=YOUR_TOKEN"
]
}
}
}

Cursor

Add a server in Cursor's MCP settings:

{
"mcpServers": {
"stoobydoo": {
"url": "https://your-app.vercel.app/api/mcp?token=YOUR_TOKEN"
}
}
}

Available tools (17)

List management

Tool Permission required Description
get_lists — All accessible lists with open-task counts.
get_list — A single list by ID.
get_list_tasks — Tasks in a list, including two levels of subtasks.
create_list canCreateLists Create a list with name, description, and color.
update_list canEditLists Update list name, description, or color.
delete_list canDeleteLists Permanently delete a list and its tasks.

Task queries

Tool Permission required Description
get_task — Full task details including subtasks.
get_all_open_tasks — All incomplete tasks across accessible lists.
get_archived_tasks — Archived tasks, optionally filtered by list.
search_tasks — Search tasks by title or description.

Task management

Tool Permission required Description
create_task canCreateTasks Create a task with optional parent (two-level nesting).
complete_task canCompleteTasks Mark a task completed.
uncomplete_task canEditTasks Reopen a completed task.
update_task canEditTasks Update title, description, priority, due date/time, or reminder.
delete_task canDeleteTasks Permanently delete a task.
archive_task canEditTasks Archive a completed task (soft delete).
unarchive_task canEditTasks Restore an archived task.

All task tools also operate on subtasks by ID; create_task accepts a parentId up to two levels deep (task → subtask → sub-subtask).

Default token permissions

Permission Default
canCreateTasks ✅ true
canCompleteTasks ✅ true
canEditTasks ✅ true
canDeleteTasks ❌ false
canCreateLists ❌ false
canEditLists ❌ false
canDeleteLists ❌ false
allowAllLists ✅ true (or restrict to selected lists)

Destructive permissions are opt-in, and tokens can be scoped to specific lists — a safe default for handing an assistant access to a shared household.

Reminder scheduling

Reminders fire when /api/cron/reminders is called. Three options:

Option 1: GitHub Actions (included)

The repository ships .github/workflows/reminders.yml, which calls the endpoint every five minutes.

  1. In Vercel → project → Settings → Environment Variables, add CRON_SECRET (any random string, e.g. openssl rand -base64 32) and redeploy.
  2. In GitHub → Settings → Secrets and variables → Actions, add:
  • VERCEL_URL — your deployment URL with https:// (e.g. https://your-app.vercel.app)
  • CRON_SECRET — the same value as above

The workflow uses the Production environment; ensure the secrets are available there.

GitHub's free tier includes ~2,000 Actions minutes per month; a five-minute schedule uses ~2,160. Adjust the cron expression (for example */10 * * * *) to stay within the limit.

Option 2: External cron service

Point any scheduler (cron-job.org, UptimeRobot, and similar) at:

GET https://your-app.vercel.app/api/cron/reminders
Authorization: Bearer YOUR_CRON_SECRET

Option 3: In-app polling

The app checks for due reminders during normal use. No setup required, but delivery depends on someone opening the app.

Architecture

flowchart LR
Members[Family members] --> UI[App Router UI]
Assistants[AI assistants] --> MCP[MCP endpoint /api/mcp]
Scheduler[Cron scheduler] --> Cron[/api/cron/reminders]

UI --> API[REST route handlers]
MCP --> Tools[Permission-checked MCP tools]
API --> Services[Task, list, and notification services]
Tools --> Services
Cron --> Services

Services --> Prisma[Prisma + LibSQL adapter]
Prisma --> DB[(SQLite / hosted LibSQL)]
Services --> Push[Pushover]
Services --> Email[Resend]

Repository layout

sTOobyDOo/
├── app/                    # Next.js 16 App Router
│   ├── api/                # REST routes, MCP endpoint, cron, setup
│   ├── dashboard/          # Main dashboard
│   ├── lists/              # List views
│   ├── settings/           # User, admin, and MCP token settings
│   └── setup/              # First-run setup wizard
├── components/             # Shared UI (app shell, task items, base UI)
├── lib/                    # Auth, Prisma client, notifications, utilities
├── prisma/                 # Schema
├── scripts/                # Data-safe database initialization (ensure-db.js)
├── .github/workflows/      # Reminder scheduler (GitHub Actions)
└── middleware.ts           # Route protection

Development

Command Purpose
npm run dev Start the development server.
npm run build Create a production build.
npm run build:vercel Vercel build: Prisma generate, data-safe DB initialization, then build.
npm run db:ensure Run the safe database initialization script.
npm run db:push Synchronize the local schema with prisma db push.
npm run db:push:force Push schema with the data-loss flag.
npm run db:studio Open Prisma Studio.
npx eslint . Run ESLint.

Deployment

Deploy with Vercel

  1. Create a hosted LibSQL database (for example, with the Turso CLI):
turso db create stoobydoo
turso db show stoobydoo            # copy the libsql:// URL
turso db tokens create stoobydoo   # copy the auth token
  1. Deploy to Vercel and set DATABASE_URL, DATABASE_AUTH_TOKEN, and NEXTAUTH_SECRET. The configured build command (npm run build:vercel) generates Prisma Client and initializes the schema automatically.

  2. Complete the setup wizard on the deployed URL to create the family and admin account.

  3. Optional: set CRON_SECRET and configure the reminder scheduler (see above), and add notification credentials under settings.

Data safety

Redeploys are safe. The build runs scripts/ensure-db.js, which creates tables on the first deploy and skips destructive changes afterward — existing data is never dropped automatically. See DATA_SAFETY.md for details, and DEPLOY.md for the extended deployment guide.

Troubleshooting

Symptom Fix
"Database connection failed" Verify DATABASE_URL; ensure DATABASE_AUTH_TOKEN is set for remote URLs.
"Unauthorized" during build The Turso token is missing or expired — create a new one with turso db tokens create.
First request is slow Hosted LibSQL databases sleep when idle; the first request wakes them (5–10 seconds).
Setup wizard keeps appearing No family exists yet — complete the wizard once.

Contributing

Issues and pull requests are welcome. Keep changes focused, verify them with npm run build and npx eslint ., and describe the motivation and verification performed.

License

sTOobyDOo is licensed under the Mozilla Public License 2.0. Modifications to MPL-covered files must remain available under the MPL when distributed.

© 2026 Tun's Random Thoughts. All rights reserved.