The list app your AI can actually use. CLI v0.4.1
Four ways to connect. Pick one:
| Method | Best for | Setup time |
|---|---|---|
| CLI | OpenClaw, Grok Bot, agents with a shell, scripts | 1 minute |
| MCP server | Claude Desktop, Claude Code, Codex, Cursor, Devin Desktop, Antigravity | 2 minutes |
| REST API | Copilot Studio, Gemini and xAI function calling, your own code | 5 minutes |
| Alexa | Adding things by voice on Echo devices | 1 minute |
ChatGPT connects with an app pairing code instead of an API key: ChatGPT setup.
Step 1: Install the LystBot app (iOS / Android)
Step 2: Copy your API key from Settings β AI Agents
Step 3: Pick a way to connect below
Base URL: https://lystbot.com/api/v1
Unless stated otherwise, request and response bodies use Content-Type: application/json. Image uploads use multipart/form-data; image and thumbnail GETs return authenticated binary image responses. New lists, items and favorites need a client-generated UUID v4 as id. For reminders, id is optional on creation, generated by the server when omitted or empty. A supplied non-empty ID must be a valid UUID.
| Method | Header | Used by |
|---|---|---|
| Bearer token | Authorization: Bearer YOUR_API_KEY | AI agents, CLI, MCP server, automations |
| Bearer token with app context | Authorization: Bearer YOUR_API_KEYX-LystBot-Client: app | The mobile app from version 1.0.8 |
X-Device-UUID is legacy-only and is rejected with bearer_required after the device migrates to Bearer authentication.
Agents only need the API key. The user finds it in the app under Settings β AI Agents. Bearer responses redact member device_uuid and item created_by to null. Use is_me and role to identify your own membership and display permissions. Agents do not need the app context header.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/health | Health check (no auth) |
| GET | /api/v1/lists | Get all lists |
| POST | /api/v1/lists | Create a list |
| GET | /api/v1/lists/{id} | Get a list with items, sections and members |
| PUT | /api/v1/lists/{id} | Update a list |
| DELETE | /api/v1/lists/{id} | Delete a list |
| PUT | /api/v1/lists/reorder | Set the caller's list order |
| POST | /api/v1/lists/{id}/items | Add an item |
| PUT | /api/v1/lists/{id}/items/{itemId} | Update an item |
| DELETE | /api/v1/lists/{id}/items/{itemId} | Delete an item |
| DELETE | /api/v1/lists/{id}/items/checked | Delete all checked items |
| POST | /api/v1/lists/{id}/categories | Create a section |
| PUT | /api/v1/lists/{id}/categories/{categoryId} | Rename a section |
| PUT | /api/v1/lists/{id}/categories/reorder | Reorder sections |
| DELETE | /api/v1/lists/{id}/categories/{categoryId} | Delete a section (items move to Other) |
| POST | /api/v1/items/{itemId}/attachments/images | Attach an image |
| POST | /api/v1/items/{itemId}/attachments/urls | Attach a link |
| GET | /api/v1/items/{itemId}/attachments | List attachments |
| DELETE | /api/v1/attachments/{attachmentId} | Delete an attachment |
| POST | /api/v1/lists/{id}/share | Get a share code |
| POST | /api/v1/lists/join | Join a shared list |
| POST | /api/v1/lists/{id}/leave | Leave a shared list |
| GET | /api/v1/reminders | Get all reminders |
| POST | /api/v1/reminders | Create a reminder |
| GET | /api/v1/reminders/{id} | Get one reminder |
| PUT | /api/v1/reminders/{id} | Update a reminder |
| DELETE | /api/v1/reminders/{id} | Delete a reminder |
| GET | /api/v1/favorites | Get favorites |
| POST | /api/v1/favorites | Create a favorite |
| PUT | /api/v1/favorites/{id} | Update a favorite |
| DELETE | /api/v1/favorites/{id} | Delete a favorite |
| POST | /api/v1/favorites/{id}/use | Count a favorite as used |
| PATCH | /api/v1/agents/me | Set the agent's name and emoji |
GET /api/v1/health
No authentication required.
curl https://lystbot.com/api/v1/health
{
"status": "ok"
}
GET /api/v1/lists
curl https://lystbot.com/api/v1/lists \
-H "Authorization: Bearer YOUR_API_KEY"
{
"lists": [
{
"id": "list-uuid",
"title": "Groceries",
"type": "shopping",
"emoji": "π",
"is_shared": true,
"share_code": "ABC123",
"member_count": 2,
"item_count": 5,
"unchecked_count": 3,
"updated_at": "2026-04-14T11:00:00Z"
}
]
}
POST /api/v1/lists
curl -X POST https://lystbot.com/api/v1/lists \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "NEW_LIST_UUID", "title": "Groceries", "type": "shopping", "emoji": "π"}'
{
"id": "NEW_LIST_UUID",
"created_at": "2026-04-14T11:05:00Z"
}
id and title are required. List types: shopping, todo, packing, generic (default).
GET /api/v1/lists/{id}
curl https://lystbot.com/api/v1/lists/LIST_ID \
-H "Authorization: Bearer YOUR_API_KEY"
{
"id": "list-uuid",
"title": "Groceries",
"type": "shopping",
"emoji": "π",
"is_shared": true,
"share_code": "ABC123",
"members": [ ... ],
"bot_members": [ ... ],
"categories": [
{ "id": "cat-fruit", "name": "Fruit", "position": 0 }
],
"items": [
{
"id": "item-uuid",
"category_id": "cat-fruit",
"text": "Bananas",
"checked": false,
"quantity": 2,
"unit": null,
"position": 0,
"updated_at": "2026-04-14T10:05:00Z"
}
]
}
PUT /api/v1/lists/{id}
curl -X PUT https://lystbot.com/api/v1/lists/LIST_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Weekly Groceries", "emoji": "π", "hide_completed": false}'
DELETE /api/v1/lists/{id}
curl -X DELETE https://lystbot.com/api/v1/lists/LIST_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Returns {"success": true}.
PUT /api/v1/lists/reorder
curl -X PUT https://lystbot.com/api/v1/lists/reorder \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"order": [{"list_id": "LIST_ID_1", "position": 0}, {"list_id": "LIST_ID_2", "position": 1}]}'
Set the caller's list order. Include every current list exactly once, in array order with consecutive integer positions starting at zero. This example assumes the caller has exactly two lists; replace the IDs with the complete current set. Invalid shape returns 400, inaccessible lists 403, and an incomplete or stale set 409. Returns {"success": true}.
POST /api/v1/lists/{id}/items
curl -X POST https://lystbot.com/api/v1/lists/LIST_ID/items \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "NEW_ITEM_UUID", "text": "Flour", "quantity": 1, "unit": "500g"}'
{
"id": "NEW_ITEM_UUID"
}
id and text are required. CLI and local MCP counts are integers in 1..99. REST quantity handling depends on unit: creation validates the applicable range, while updates clamp values to it. Do not infer REST limits from CLI limits. Weights and volumes go into unit, so 250 g of flour is "unit": "250g", not "quantity": 250. Set category_id to put the item into a section; without it, the item goes to Other. A list holds up to 300 items.
PUT /api/v1/lists/{id}/items/{itemId}
Send any of text, checked, quantity, unit, position, category_id.
curl -X PUT https://lystbot.com/api/v1/lists/LIST_ID/items/ITEM_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"checked": true}'
DELETE /api/v1/lists/{id}/items/{itemId}
curl -X DELETE https://lystbot.com/api/v1/lists/LIST_ID/items/ITEM_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Returns {"success": true}. To clear all checked items at once, use DELETE /api/v1/lists/{id}/items/checked.
Sections (categories in the API) split a list into groups like Produce or Dairy. Create one with POST /lists/{id}/categories and {"id": "NEW_CATEGORY_UUID", "name": "Fruit"}. Deleting a section moves its items to Other.
Items can carry images and links: POST /items/{itemId}/attachments/images takes a multipart/form-data field file, POST /items/{itemId}/attachments/urls takes {"url": "https://...", "title": "Recipe"}. Do not set Content-Type manually for the upload; the boundary must come from the client.
Images accept JPEG, PNG or WebP up to 5 MiB. The server converts them to JPEG with a maximum long edge of 1600 px and creates thumbnails with a maximum long edge of 300 px. URL attachments accept http/https links up to 2048 bytes and optional titles up to 255 characters; links are stored without fetching or unfurling.
POST /api/v1/lists/{id}/share
curl -X POST https://lystbot.com/api/v1/lists/LIST_ID/share \
-H "Authorization: Bearer YOUR_API_KEY"
{
"share_code": "ABC123"
}
POST /api/v1/lists/join
curl -X POST https://lystbot.com/api/v1/lists/join \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"code": "ABC123"}'
{
"list_id": "list-uuid",
"title": "Groceries",
"emoji": "π",
"members": [ ... ]
}
POST /api/v1/lists/{id}/leave
curl -X POST https://lystbot.com/api/v1/lists/LIST_ID/leave \
-H "Authorization: Bearer YOUR_API_KEY"
Returns {"success": true}.
One-time or recurring reminders with a push notification. repeat is one of none, daily, weekly, biweekly, monthly, yearly. The API accepts one-time reminders ("repeat": "none") with a timestamp in the past. Replace scheduled_at with a future local date and time in the specified timezone.
curl -X POST https://lystbot.com/api/v1/reminders \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "NEW_REMINDER_UUID", "title": "Take vitamins", "scheduled_at": "2027-01-15 09:00",
"timezone": "Europe/Berlin", "repeat": "none", "is_enabled": true}'
GET /reminders lists them, PUT /reminders/{id} changes any field, DELETE /reminders/{id} deletes one.
Items the user adds often, like the milk that goes on the grocery list every week.
GET /api/v1/favorites
curl "https://lystbot.com/api/v1/favorites?type=shopping" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"favorites": [
{
"id": "fav-uuid",
"text": "Milk",
"list_type": "shopping",
"category": "Dairy",
"use_count": 12,
"updated_at": "2026-04-14T10:30:00Z"
}
]
}
POST /api/v1/favorites
curl -X POST https://lystbot.com/api/v1/favorites \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "NEW_FAVORITE_UUID", "text": "Milk", "list_type": "shopping", "category": "Dairy"}'
POST /api/v1/favorites/{id}/use
Raises use_count, which sorts favorites. It doesn't add anything to a list; add the item with POST /lists/{id}/items.
PUT /api/v1/favorites/{id} # {"text": "Oat milk", "category": "Dairy"}
DELETE /api/v1/favorites/{id} # returns {"success": true}
Sets the name and emoji other members see next to your changes in shared lists.
PATCH /api/v1/agents/me
curl -X PATCH https://lystbot.com/api/v1/agents/me \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "TARS", "signature_emoji": "π€"}'
The CLI includes an MCP server. It runs locally over stdio, so it works with any MCP client that can start a local server. A remote OAuth MCP endpoint is also available at https://lystbot.com/api/v1/mcp. The remote endpoint uses OAuth rather than the local server's API key; client compatibility and available tools differ. Listed in the official MCP Registry.
npx lystbot login YOUR_API_KEYClaude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows), then restart Claude Desktop:
{
"mcpServers": {
"lystbot": {
"command": "npx",
"args": ["lystbot", "mcp"]
}
}
}
Claude Code, Codex, Grok Build, OpenClaw:
claude mcp add lystbot -- npx lystbot mcp
codex mcp add lystbot -- npx lystbot mcp
grok mcp add lystbot -- npx lystbot mcp
openclaw mcp add lystbot -- npx lystbot mcp
Cursor, Devin Desktop, Antigravity, Cline: the same JSON as above, in .cursor/mcp.json (Cursor), ~/.config/devin/mcp_config.json (Devin Desktop, formerly Windsurf) or ~/.gemini/config/mcp_config.json (Antigravity). Cline has its own MCP settings screen.
Hermes Agent: add the server under mcp_servers in ~/.hermes/config.yaml with command npx and args ["lystbot", "mcp"]. Devin CLI: devin mcp add. CrewAI: stdio via MCPServerAdapter.
| Tool | Description |
|---|---|
list_lists | Get all lists |
get_list | Get one list with its items |
create_list | Create a list |
delete_list | Delete a list |
add_items | Add items as plain text (250g flour, 3x milk) or as {text, quantity?, unit?} |
check_item | Check off an item |
uncheck_item | Uncheck an item |
remove_item | Remove an item |
clear_checked | Remove all checked items |
share_list | Get a share code |
join_list | Join a shared list |
list_categories | List the sections of a list |
create_category | Create a section |
rename_category | Rename a section |
delete_category | Delete a section |
reorder_categories | Reorder sections |
move_item | Move an item to a section or to Other |
add_item_image | Attach an image (local path or base64) |
add_item_url | Attach a link |
list_item_attachments | List the attachments of an item |
delete_item_attachment | Delete an attachment |
list_reminders | Get all reminders |
get_reminder | Get one reminder |
create_reminder | Create a reminder |
update_reminder | Change, enable or disable a reminder |
delete_reminder | Delete a reminder |
list_lists, get_list, list_reminders, create_list, add_items, update_item, create_reminder. Use update_item to check or uncheck an item. Delete and sharing tools are unavailable.
Manage lists from the terminal, yourself or through an AI agent.
# Run directly (no install)
npx lystbot
# Or install globally
npm install -g lystbot
npx lystbot login YOUR_API_KEY
The key is stored in ~/.lystbot/config.json. For several agents on one machine, give each its own file with --config <path> or LYSTBOT_CONFIG.
# Lists
npx lystbot lists # all lists
npx lystbot create "Groceries" --type shopping --emoji "π"
npx lystbot show "Groceries" # one list with items
npx lystbot delete "Groceries" --force
# Items
npx lystbot add "Groceries" "Milk, Eggs, Bread"
npx lystbot add "Groceries" "Flour" --quantity 2 --unit "500g"
npx lystbot check "Groceries" "Milk"
npx lystbot uncheck "Groceries" "Milk"
npx lystbot remove "Groceries" "Milk"
# Sections
npx lystbot categories "Groceries"
npx lystbot category add "Groceries" "Fruit"
npx lystbot move "Groceries" "Bananas" --category "Fruit"
# Attachments
npx lystbot attach-image "Groceries" "Milk" ./photo.jpg
npx lystbot attach-url "Groceries" "Milk" "https://example.com" "Recipe"
# Reminders
npx lystbot reminders
npx lystbot remind "Take vitamins" --at "tomorrow 09:00" --timezone "Europe/Berlin"
npx lystbot reminder-update <id> --disabled
npx lystbot reminder-delete <id> --yes
# Sharing
npx lystbot share "Groceries" # get a share code
npx lystbot join ABC123 # join a shared list
# Agent name and emoji in shared lists
npx lystbot profile --name "TARS" --emoji "π€"
# JSON output (for scripts and AI agents)
npx lystbot show "Groceries" --json | jq '.items'
# MCP server mode
npx lystbot mcp
| Flag | Description |
|---|---|
--json | Output as JSON (on lists, show, categories and the reminder commands) |
--config <path> | Use a different config file |
--api <url> | Use a different API base URL |
--version | Show the version |
--help | Show help |
LystBot has an official Alexa skill. Alexa handles the wake word and speech-to-text, then forwards the spoken command to the LystBot voice endpoint. That endpoint uses the same command layer as the API, the MCP server and the CLI.
The pairing code links your (hashed) Alexa user id to your LystBot user/device. That link is the only account association LystBot creates for Alexa.
RawCommandIntent
command : AMAZON.SearchQuery # the free-form spoken command
-> LystBot voice/command endpoint
-> same command layer as API / MCP / CLI
Copy this into your agent's system prompt or context file:
You have access to the user's LystBot lists.
## MCP (preferred)
If the LystBot MCP tools are available, use them: list_lists, get_list,
create_list, add_items, check_item, uncheck_item, remove_item, share_list,
join_list, plus the category and reminder tools.
Use only tools advertised by the connected MCP server. For ChatGPT remote MCP,
use update_item with checked: true or checked: false to check or uncheck
items. Deletion, sharing and category tools are not available through this
connection.
## CLI
npx lystbot lists | show | create | add | check | uncheck | remove | share | join
## REST API
Base URL: https://lystbot.com/api/v1
Auth: Authorization: Bearer API_KEY
New lists and items need a client-generated UUID v4 as "id".
- GET /lists - All lists
- POST /lists - Create list {"id": "<uuid>", "title": "...", "type": "shopping|todo|packing|generic"}
- GET /lists/:id - One list with its items
- PUT /lists/:id - Update list {"title": "...", "emoji": "..."}
- DELETE /lists/:id - Delete list
- POST /lists/:id/items - Add item {"id": "<uuid>", "text": "...", "quantity": 1-99 (1-9999 with unit), "unit": "..."}
- PUT /lists/:id/items/:itemId - Change item {"checked": true}
- DELETE /lists/:id/items/:itemId - Remove item
- POST /lists/:id/share - Get share code
- POST /lists/join - Join list {"code": "..."}
When the user asks to add something to a list, add it.
When the user asks what's on a list, read the list first.
Tell the user what you changed.
Errors come back as JSON with a machine-readable code and a message:
{
"error": "not_found",
"message": "List not found"
}
| Status | Common codes |
|---|---|
400 | missing_fields, invalid_type, invalid_category |
401 | invalid_api_key |
403 | forbidden (not a member, or owner-only action) |
404 | not_found, invalid_code |
409 | conflict, already_member |
422 | max_items_reached (300 items per list) |
error code, not on the message text.
© 2026 TourAround UG (haftungsbeschränkt) · Privacy · Imprint