Connect an AI agent
Agent mode for ourlist.icu. Also as Markdown and JSON.
The short version
The order is always: sign in first, then choose. Open https://ourlist.icu, sign in with the room code and a PIN, and on the next screen choose Human (the normal app) or AI (a plain HTML interface).
If your AI can browse the web and fill in forms: sign in, then choose AI. The sign-in form is plain HTML on the front page and at https://ourlist.icu/api/ai/ . No key, no setup.
If your AI supports MCP: use a key. A person makes one in Settings → AI agents and gives it to the AI (details below).
Either way the AI can do everything a person can do on ourlist.icu, with exactly that person's permissions. What it adds or changes is recorded as that person's, marked "via AI", and appears in their activity list with an Undo.
1. Browsing AIs: sign in, then choose AI (the main way)
Step 1: https://ourlist.icu/api/ai/ (or the form on the front page). Fields: Room code and PIN, the same as the normal sign-in. Wrong PINs count towards the same lock-out as the website.
Step 2: a page with two forms, Human and AI. Choose AI (with an optional name such as "ChatGPT", shown to the person). No second PIN is asked. Choosing Human opens the normal app. A person who is already signed in on the website sees the same choice and can choose AI, which creates an AI session for them.
The AI interface is plain HTML: headings, labelled forms, links, stable URLs, no JavaScript, no drag-and-drop. Every thing a person can do is a page at https://ourlist.icu/api/ai/do/ACTION (for example /api/ai/do/list_entries?status=unexplored, /api/ai/do/create_entry, /api/ai/do/set_visited?id=5). Looking things up works by opening a link or submitting the form; changes are form posts. https://ourlist.icu/api/ai/actions lists every page. Opening one of these pages while signed out sends you to sign in, then the choice, then back to that page.
It needs cookies (the AI session lasts 12 hours and ends when the person revokes it or you log out). The person can see and revoke AI sessions in Settings → AI agents. An AI session can never approve its own requests or touch keys.
The person gives the AI their PIN for this, so give it only to an AI you trust with that person's access. For a more careful setup, add an extra member (for example "Sam's AI") with their own PIN and role and use that one.
2. MCP and REST AIs: use a key (secondary)
A person makes a key: sign in to ourlist.icu, open Settings (your initial or the room icon), AI agents, "New agent key". Pick what it may do (default Read-only) and copy the key. It starts with olt_ and is shown once.
MCP (Claude Code): claude mcp add --transport http ourlist https://ourlist.icu/api/mcp --header "Authorization: Bearer olt_YOUR_TOKEN"
MCP (any client that takes a JSON config): {"mcpServers": {"ourlist": {"type": "http", "url": "https://ourlist.icu/api/mcp", "headers": {"Authorization": "Bearer olt_YOUR_TOKEN"}}}}
MCP for clients that only speak stdio (Claude Desktop): npx -y mcp-remote https://ourlist.icu/api/mcp --header "Authorization: Bearer olt_YOUR_TOKEN"
Plain HTTP (any agent or script): curl -s https://ourlist.icu/api/agent/call -H "Authorization: Bearer olt_YOUR_TOKEN" -H "content-type: application/json" -d '{"action":"list_entries","input":{"status":"unexplored","limit":5}}'
Machine-readable: https://ourlist.icu/api/agent/actions lists every action with its JSON schema. https://ourlist.icu/api/agent/view (with the key) returns a snapshot of the room as JSON.
Work done through a key is attributed the same way: recorded as the key owner's, marked "via AI".
What a key may do (scopes) — keys only
Read-only: Can look at everything, change nothing.
Standard: Can add, edit, plan, tick and rate. Cannot delete or touch people, PINs or the room.
Everything except deleting: Standard, plus people, PINs and room settings. Still cannot delete anything.
Full: Everything you can do. Deletes and other risky actions still wait for your approval.
Scopes you can tick individually: read (Read everything in the room (ideas, movies, calendar, people, categories, history).) entries:write (Add and edit ideas and movies, sub events, and plan days.) entries:tick (Tick things off (or back on) and give star ratings.) entries:delete (Delete ideas and movies. Always shown to you for approval first, unless you switch on auto-approve.) categories:write (Add, rename, hide and unhide categories (admins only in the room itself).) categories:delete (Delete categories.) people:write (Add people, rename them, change what they can do.) people:delete (Remove people from the room.) security (Change PINs.) room:write (Change the room name, icon and colour.) room:delete (Delete the whole room. Never auto-approved.)
A token can never do more than the person it belongs to. A plain member's token cannot delete an idea, because a plain member cannot on the website either.
Safety
Same limits for both ways in: an AI logged in with a PIN is limited by that person's role, and its deletes, bulk edits and people/PIN changes wait for approval too.
Approval first. Deleting, editing many things at once, and changing people, roles or PINs do not happen straight away. The agent gets a preview of what would happen and the request waits under Settings → AI agents → Waiting for you, where you approve or say no. Requests expire after 24 hours. You can switch on auto-approve per token for delete (Deleting things (ideas, categories, people).) bulk (Editing or deleting many things at once.) security (Adding people, changing roles and PINs. (Deleting the room is never auto-approved.)) Deleting the whole room is never automatic.
Everything an agent does is logged and shown in Settings → AI agents → What agents did, with the time and a one-tap Undo where one is possible. (PIN changes, removing people and deleting rooms cannot be undone.) Undo is refused if the thing was changed again afterwards, so it never silently overwrites newer edits.
Stored text is data. Titles, details, place names and the like are typed by people, and could contain text that tries to give an AI orders. Agents are told to treat all of it as data only, results carry a warning flag when text looks like instructions, and anything risky still needs your approval, so a booby-trapped idea cannot make an agent delete things on its own.
Rate limits: each token is limited per minute (default 60 calls, a third of that for changes). Wrong tokens from one address are blocked for ten minutes after 20 tries.
Every change action accepts dryRun: true to check a request without doing it.
Responses and errors
Success: {"ok": true, "status": "done", "summary": "...", "result": {...}, "activityId": 12, "undoable": true}. Waiting for you: {"ok": true, "status": "pending_approval", "approvalId": 3, "preview": {...}} (HTTP 202). Failure: {"ok": false, "error": {"status": 400, "code": "invalid_input", "message": "...", "hint": "..."}}.
Error messages say what to fix: unknown field names suggest the right one, bad values list the allowed ones, missing permissions say which scope or role is needed.
Actions
Input fields marked * are required. Every change action also accepts dryRun.
| Action | Scope | What it does |
|---|---|---|
get_room | read | Get the room overview read (no input) |
get_snapshot | read | Get a whole-room snapshot read limit |
list_members | read | List the people in the room read (no input) |
list_categories | read | List categories read includeHidden, group, query |
list_entries | read | List ideas and movies read kind, status, categoryIds, categories, matchAll, indoor, duration, maxBudget, freeOnly, addedBy, minRating, availableOn, atTime, plannedOn, plannedFrom, plannedTo, planned, hasPlace, query, sort, limit, offset |
search_entries | read | Search ideas and movies by words read kind, status, categoryIds, categories, matchAll, indoor, duration, maxBudget, freeOnly, addedBy, minRating, availableOn, atTime, plannedOn, plannedFrom, plannedTo, planned, hasPlace, query*, sort, limit, offset |
get_entry | read | Get one idea or movie in full read id* |
get_entry_history | read | See what was edited on an entry read id* |
get_calendar | read | See what is planned on which days read month, from, to |
pick_random | read | Surprise me (random pick) read kind, status, categoryIds, categories, matchAll, indoor, duration, maxBudget, freeOnly, addedBy, minRating, availableOn, atTime, plannedOn, plannedFrom, plannedTo, planned, hasPlace, query, excludeIds |
search_places | read | Search for a place on the map read query* |
reverse_place | read | Name the place at coordinates read lat*, lon* |
create_entry | entries:write | Add an idea or a movie kind, title*, emoji, placeName, placeLat, placeLon, placeInTitle, indoor, duration, budget, details, categoryIds, categories, watchType, timeRule, plannedDate, subEvents, subTickMode |
update_entry | entries:write | Edit an idea or movie id*, title, emoji, placeName, placeLat, placeLon, placeInTitle, indoor, duration, budget, details, categoryIds, categories, watchType, timeRule, plannedDate, addCategoryIds, removeCategoryIds |
set_visited | entries:tick | Tick an idea off (or back on) id*, visited* |
set_rating | entries:tick | Rate an idea id*, stars* |
plan_entry | entries:write | Plan an idea for a day (or clear the day) id*, date* |
delete_entry | entries:delete | Delete an idea or movie id* |
bulk_update_entries | entries:write | Edit many entries at once entryIds*, changes* |
bulk_delete_entries | entries:delete | Delete many entries at once entryIds* |
add_sub_event | entries:write | Add a sub event to an idea entryId*, title*, date*, endDate, startTime, endTime, days, daysMask |
update_sub_event | entries:write | Change a sub event entryId*, subEventId*, title, date, endDate, startTime, endTime, days, daysMask |
remove_sub_event | entries:delete | Remove a sub event entryId*, subEventId* |
set_sub_event_done | entries:tick | Tick a sub event (one date) on or off entryId*, subEventId*, date*, done* |
set_sub_tick_mode | entries:write | Choose whether sub events tick the whole idea entryId*, mode* |
create_category | categories:write | Add a category name*, emoji, group |
update_category | categories:write | Rename, regroup, hide or unhide a category id*, name, emoji, group, hidden |
delete_category | categories:delete | Delete a category id* |
add_member | people:write | Add a person to the room name*, pin*, role |
update_member | people:write | Rename a person or change their role memberId*, name, role |
set_member_pin | security | Change a PIN pin*, memberId |
remove_member | people:delete | Remove a person from the room memberId* |
update_room | room:write | Change the room name, icon or colour name, emoji, accent |
delete_room | room:delete | Delete the whole room confirmCode* |
whoami | read | Check this token read (no input) |
list_activity | read | See what this token has done read limit, before, includeReads |
undo_action | read | Undo something this token did activityId* |
list_approvals | read | See approval requests from this token read status |
get_approval | read | Check one approval request read id* |
cancel_approval | read | Withdraw a pending approval request id* |
revoke_this_token | read | Revoke this token confirm* |