TaskPad
A Windows system-tray task manager with MCP server integration, enabling Claude Code, Claude Desktop, and claude.ai to read and write tasks via stdio or SSE.
README
TaskPad
A Windows system-tray task manager and reminder engine with deep AI and automation integration.
- System tray icon — colour-coded badge (blue / green / amber / red) with a task count
- Floating overlay — always-on-top compact task list; drag it anywhere on screen
- Reminder engine — fires desktop alerts and system sounds at the scheduled time
- MCP server — Claude Code, Claude Desktop, and claude.ai can all read and write your tasks
- REST API — JSON API on
localhost:8765for n8n, Home Assistant, or any HTTP client - Outbound webhooks — push
task.created,task.completed,reminder.fired, etc. to any URL
Table of contents
- Requirements
- Installation
- Running from source
- Tray icon guide
- Cloudflare tunnel setup
- Claude Desktop setup
- Claude Code setup
- claude.ai browser setup
- n8n integration
- REST API reference
- Outbound webhook events
- Configuration file
- Building the installer
Requirements
| Requirement | Version |
|---|---|
| Windows | 10 / 11 (64-bit) |
| Python | 3.10 or later |
| Pip packages | see requirements.txt |
TaskPad stores its data in %APPDATA%\TaskPad\ (i.e. C:\Users\<you>\AppData\Roaming\TaskPad\).
Installation
Run the installer — TaskPad-Setup-1.0.0.exe — and follow the wizard.
The wizard will:
- Copy all source files to
C:\Program Files\TaskPad\(or your chosen path). - Optionally add a desktop shortcut and a Windows autostart entry.
- Run
pip install -r requirements.txtwith the detected Python interpreter. - Ask for an optional Cloudflare tunnel URL (for Claude AI) and n8n webhook URL — you can skip these and configure them later from the tray menu.
After the installer completes, tick "Launch TaskPad now" on the final page or start it from the Start menu / desktop shortcut.
Note: If Python was not detected, install it from python.org/downloads, then open a terminal in the install folder and run:
pip install -r requirements.txt
Running from source
# Clone / copy the source, then:
pip install -r requirements.txt
python main.py
MCP stdio mode (for Claude Code / Claude Desktop):
python main.py --mcp
Tray icon guide
The tray icon colour tells you your task state at a glance:
| Colour | Meaning |
|---|---|
| Blue | No pending tasks |
| Green | Tasks exist, none due / reminded today |
| Amber | At least one reminder is scheduled for today |
| Red | Urgent task or a reminder is due within the hour |
A number badge in the top-right corner shows the count of incomplete tasks (up to 99).
Right-click menu:
| Menu item | Action |
|---|---|
| Open TaskPad | Show/hide the floating overlay |
| Add Task… | Quick-add dialog |
| Start on Boot / Stop at Boot | Toggle Windows autostart |
| Sound Settings… | Choose system sound or custom WAV |
| MCP Settings… | Set your static Cloudflare tunnel URL |
| Integration Settings… | View API key, API URL, set n8n webhook |
| MCP URL | Shows the active public MCP URL |
| Copy MCP URL | Copies it to clipboard |
| Quit | Exit the tray app |
Cloudflare tunnel setup
TaskPad exposes the MCP server on port 8766 (HTTP/SSE). To make it reachable from claude.ai or n8n on another machine you need to expose that port via a Cloudflare tunnel.
Option A — Permanent named tunnel (recommended)
This gives you a stable URL that survives restarts.
-
Create the tunnel in the Cloudflare dashboard:
- Cloudflare Zero Trust → Access → Tunnels → Create a tunnel
- Name it (e.g.
taskpad). - Under Public hostname, add a subdomain pointing to
http://localhost:8766e.g.taskpad.yourdomain.com - Install / authenticate
cloudflaredon this machine (the dashboard shows the command).
-
Tell TaskPad the stable URL:
- Right-click tray icon → MCP Settings…
- Enter
https://taskpad.yourdomain.comand save. - TaskPad will use this URL immediately (no cloudflared management needed — you run
cloudflaredseparately as a service).
-
Expose the REST API too (for n8n on another server):
- Add a second public hostname in the same tunnel:
taskpad-api.yourdomain.com→http://localhost:8765 - Use this URL as the base URL in n8n.
- Add a second public hostname in the same tunnel:
Option B — Quick ephemeral tunnel (development / testing)
If cloudflared is on your PATH or in %APPDATA%\TaskPad\cloudflared.exe, TaskPad will start a quick tunnel automatically on launch and show a tray notification with the URL. The URL changes every restart.
TaskPad will download cloudflared.exe automatically from GitHub if it is not found.
Claude Desktop setup
- Open Claude Desktop → Settings → Developer → Edit Config (
claude_desktop_config.json). - Add under
"mcpServers":
{
"mcpServers": {
"taskpad": {
"command": "python",
"args": ["C:\\Program Files\\TaskPad\\main.py", "--mcp"]
}
}
}
- Restart Claude Desktop. TaskPad should appear in the tool list.
Use
pythonwinstead ofpythonif you want to suppress the console window.
Claude Code setup
Run once in a terminal:
claude mcp add taskpad -s user -- python "C:\Program Files\TaskPad\main.py" --mcp
Verify it is registered:
claude mcp list
Claude Code will now have access to all TaskPad tools in every project.
claude.ai browser setup
claude.ai connects over HTTP/SSE (not stdio), so it needs the tunnel URL.
- Complete the Cloudflare tunnel setup to get a stable public URL.
- In claude.ai → Settings → Integrations → Add MCP server:
- URL:
https://taskpad.yourdomain.com/sse
- URL:
- Save. The TaskPad tools will appear in your claude.ai conversations.
n8n integration
TaskPad acts as both an inbound HTTP server (n8n calls it) and an outbound webhook sender (TaskPad calls n8n).
Inbound — n8n creates tasks in TaskPad
Use an HTTP Request node in n8n:
| Field | Value |
|---|---|
| Method | POST |
| URL | https://taskpad-api.yourdomain.com/webhook |
| Header | X-API-Key: <your-api-key> |
| Body | JSON (see below) |
Example body (email flagged → task with link back):
{
"title": "Follow up on invoice from Acme",
"category": "work",
"priority": "high",
"remind_at": "2026-08-01T09:00:00",
"notes": "Flagged in Outlook — needs reply by EOD",
"source_url": "https://outlook.office.com/mail/deeplink/..."
}
Find your API key: right-click tray → Integration Settings… → copy the key shown.
Outbound — TaskPad notifies n8n
- In n8n, create a Webhook node. Copy its URL.
- In TaskPad: right-click tray → Integration Settings… → paste the URL in n8n webhook URL and save.
TaskPad will POST a JSON payload to that URL for each enabled event.
REST API reference
Base URL (local): http://127.0.0.1:8765
Base URL (remote): https://taskpad-api.yourdomain.com
All endpoints except /health require the header:
X-API-Key: <your-api-key>
Interactive docs are available at http://127.0.0.1:8765/docs while TaskPad is running.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check (no auth) |
| GET | /tasks |
List tasks. Query params: category, completed |
| POST | /tasks |
Create a task |
| GET | /tasks/{id} |
Get a single task |
| PATCH | /tasks/{id} |
Update task fields |
| DELETE | /tasks/{id} |
Delete a task |
| POST | /tasks/{id}/complete |
Mark complete/incomplete. Query param: done=true/false |
| POST | /webhook |
Simplified create endpoint (same as POST /tasks, shorter schema) |
Task schema
{
"title": "string (required)",
"category": "work | personal | shared",
"task_type": "todo | reminder | both",
"priority": "urgent | high | normal | none",
"notes": "string",
"tags": ["string"],
"due_date": "YYYY-MM-DD or null",
"remind_at": "ISO datetime or null",
"repeat": "none | daily | weekdays | weekly | monthly | every_n_days",
"repeat_n": 1,
"repeat_days": [0,1,2,3,4],
"repeat_day_of_month": 1,
"enabled": true,
"source_url": "https://... or null"
}
Example — create a task with curl
curl -X POST https://taskpad-api.yourdomain.com/tasks \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Review PR #42",
"category": "work",
"priority": "high",
"remind_at": "2026-08-01T10:00:00",
"source_url": "https://github.com/your-org/your-repo/pull/42"
}'
Outbound webhook events
When a webhook URL is configured, TaskPad POSTs a JSON body to it for each event.
| Event | When it fires |
|---|---|
task.created |
Task added (via tray, MCP, or API) |
task.updated |
Task fields changed |
task.completed |
Task marked complete |
task.uncompleted |
Task marked incomplete |
task.deleted |
Task removed |
reminder.fired |
Reminder alert shown |
task.overdue |
Overdue check triggered |
Payload shape:
{
"event": "task.created",
"task_id": "abc123",
"title": "Review PR #42",
"category": "work",
"priority": "high",
"task_type": "todo",
"remind_at": "2026-08-01T10:00:00",
"due_date": null,
"completed": false,
"source_url": "https://github.com/...",
"created_at": "2026-07-28T08:00:00",
"updated_at": "2026-07-28T08:00:00"
}
Configuration file
%APPDATA%\TaskPad\config.json — created automatically on first run.
{
"api_key": "auto-generated 48-char hex key",
"mcp_public_url": "https://taskpad.yourdomain.com",
"webhook_url": "https://n8n.yourdomain.com/webhook/taskpad",
"webhook_events": [
"task.created", "task.completed", "reminder.fired", "task.overdue"
],
"sound_type": "system",
"system_sound": "SystemExclamation"
}
All settings are editable from the tray menu — direct JSON editing is not normally required.
Releasing a new version
release.ps1 handles the full release cycle in one command:
.\release.ps1 # bump patch (1.0.0 → 1.0.1), build, commit, tag, push
.\release.ps1 -Bump minor # bump minor (1.0.0 → 1.1.0)
.\release.ps1 -Bump major # bump major (1.0.0 → 2.0.0)
.\release.ps1 -Version 1.5.0 # explicit version
.\release.ps1 -NoBuild # commit + tag only, skip installer build
.\release.ps1 -NoPush # build + tag locally, do not push to remote
What it does, in order:
- Reads the current version from
version.py - Calculates the new version (or uses
-Version) - Asks for confirmation before doing anything
- Writes the new version back to
version.py - Builds the installer via
build.ps1(unless-NoBuild) git commit—chore: release v1.0.1git tag -a v1.0.1git push+git push --tags(unless-NoPushor no remote)
If the project has not been initialised as a git repo yet, the script will run git init and do an initial commit automatically.
Building the installer
Prerequisites:
- Python 3.10+ with Pillow (
pip install Pillow) - Inno Setup 6 installed
To release a new version, edit version.py:
__version__ = "1.1.0"
Then run from the project root:
.\build.ps1
Or override the version without editing the file:
.\build.ps1 -Version 1.1.0
The build script will:
- Read
version.py(or use-Versionoverride). - Generate
assets/icon.ico(all sizes from 16 to 256 px). - Compile
installer/taskpad.isswith ISCC, injecting the version. - Output
installer/output/TaskPad-Setup-<version>.exe.
The version string also appears in the tray icon tooltip (TaskPad v1.1.0).
File layout
TaskPad/
├── main.py # Entry point — tray app or --mcp mode
├── models.py # Task dataclass
├── store.py # SQLite storage + config helpers
├── scheduler.py # Reminder / overdue scheduler
├── requirements.txt
├── LICENSE.txt
├── build.ps1 # Build script (icon + Inno Setup)
├── api/
│ ├── server.py # FastAPI REST server on :8765
│ └── webhooks.py # Outbound webhook sender
├── mcp_server/
│ ├── server.py # MCP stdio server (--mcp flag)
│ ├── http_server.py # MCP HTTP/SSE server on :8766
│ └── tunnel.py # Cloudflare tunnel manager
├── ui/
│ ├── overlay.py # Floating task overlay
│ ├── alert.py # Reminder alert dialog
│ └── widgets.py # Custom PIL-based widgets
├── assets/
│ └── icon.ico # Generated by build.ps1
└── installer/
├── taskpad.iss # Inno Setup script
├── launcher.vbs # No-console launcher (wscript.exe)
├── generate_icon.py # PIL icon generator
└── write_config.py # Post-install config writer
License
MIT — see LICENSE.txt.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.