{"version":"1.0.0","mcpEndpoint":"https://achieve.vision/api/mcp","protocolVersions":["2025-06-18","2025-03-26","2024-11-05"],"tools":[{"name":"vision_overview","title":"Overview","app":null,"access":"read","description":"Start here. Returns today's date in the person's timezone, this connection's access per app, Horizon domains and categories, and a summary of what needs attention in each app the connection can read (overdue and due-today tasks, today's Loupe checklists, this week's Refract status, recent notes, team size).","inputSchema":{"type":"object","properties":{},"required":[],"additionalProperties":false},"annotations":{"title":"Overview","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"vision_search","title":"Search everything","app":null,"access":"read","description":"Search across every app this connection can read. Combines semantic (meaning-based) search over Horizon tasks and Luminate notes with keyword matching over tasks, notes, Pupil members/notes/goals, Loupe checklists/items, and Refract entries/check-ins. Returns typed hits with ids you can pass to the app-specific tools.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"What to look for. Natural language works for tasks and notes."},"apps":{"type":"array","items":{"type":"string","enum":["horizon","luminate","pupil","loupe","refract"]},"description":"Limit to these apps. Default: all readable."},"includeDone":{"type":"boolean","description":"Include completed Horizon tasks in keyword matching. Default false."},"limit":{"type":"integer","description":"Max hits (default 25).","minimum":1,"maximum":100}},"required":["query"],"additionalProperties":false},"annotations":{"title":"Search everything","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"vision_api_reference","title":"REST API reference","app":null,"access":"read","description":"Documentation for every REST route behind VISION (the same routes the web app uses), optionally filtered to one app. Use before vision_api_request when a curated tool doesn't cover what you need — e.g. timers, metric logs, recurring Horizon checklists, inbox links, Luminate annotations, Loupe folders/runs/annotations, Pupil imports, Refract follow-up questions and AI generation.","inputSchema":{"type":"object","properties":{"app":{"type":"string","enum":["horizon","luminate","pupil","loupe","refract","shared"],"description":"Only routes for this app."},"search":{"type":"string","description":"Only routes whose path or summary contains this text."}},"required":[],"additionalProperties":false},"annotations":{"title":"REST API reference","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"vision_api_request","title":"Call a REST route","app":null,"access":"write","description":"Call any VISION REST route directly, as this connection. Same scopes apply: GET needs read on the route's app, anything else needs write. Account administration, token management, and auth routes are never reachable. Request ids for new rows are client-generated: send a fresh UUID as \"id\" when creating. Responses are returned as-is (decrypted JSON). Read vision_api_reference first.","inputSchema":{"type":"object","properties":{"method":{"type":"string","enum":["GET","POST","PATCH","DELETE"],"description":"HTTP method."},"path":{"type":"string","description":"Path starting with /api/, with any query string, e.g. \"/api/loupe-checklist-runs?checklistId=abc&limit=10\"."},"body":{"type":"object","description":"JSON body for POST/PATCH.","additionalProperties":true}},"required":["method","path"],"additionalProperties":false},"annotations":{"title":"Call a REST route","readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},{"name":"horizon_list_tasks","title":"List tasks","app":"horizon","access":"read","description":"List Horizon tasks with filters. Open tasks sort by urgency (overdue/earliest due first, then importance); done tasks newest-completed first. Notes are truncated to 280 chars — use horizon_get_task for the full text.","inputSchema":{"type":"object","properties":{"status":{"type":"string","enum":["open","done","all","hidden"],"description":"Default open = what the hive shows. \"hidden\" = open subtasks stranded inside already-completed tasks (the app hides them)."},"domain":{"type":"string","description":"Domain id or label (e.g. \"work\")."},"category":{"type":"string","description":"Category id (todo, idea, event, note, storage, or a custom one)."},"parentId":{"type":"string","description":"Only subtasks of this task. Pass \"root\" for top-level tasks only."},"dueBefore":{"type":"string","description":"Due on or before this date (YYYY-MM-DD)."},"dueAfter":{"type":"string","description":"Due on or after this date (YYYY-MM-DD)."},"overdue":{"type":"boolean","description":"Only open tasks whose due date has passed."},"undated":{"type":"boolean","description":"Only tasks with no due date."},"snoozed":{"type":"string","enum":["include","exclude","only"],"description":"Snoozed tasks are deferred on purpose. Default include."},"minImportance":{"type":"integer","description":"Only importance at or above this (1-5).","minimum":1,"maximum":5},"query":{"type":"string","description":"Keyword match in title or notes."},"limit":{"type":"integer","description":"Default 100.","minimum":1,"maximum":500}},"required":[],"additionalProperties":false},"annotations":{"title":"List tasks","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"horizon_get_task","title":"Get a task","app":"horizon","access":"read","description":"One task in full: notes, its parent chain (breadcrumb), and its subtasks (open and done). Tasks absorbed into a Loupe checklist are hidden and won't be found here.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Task id."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Get a task","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"horizon_create_tasks","title":"Create tasks","app":"horizon","access":"write","description":"Create 1-50 tasks in one call. To build a task with subtasks in a single call, give the parent a \"ref\" and the children \"parentRef\". Unset fields take the person's own defaults from Preferences. Possible duplicates of existing open tasks are reported back (never blocked) — mention them to the person.","inputSchema":{"type":"object","properties":{"tasks":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Short, action-shaped title. **bold**, *italic*, __underline__, ~~strike~~ render; nothing else does."},"notes":{"type":"string","description":"Markdown notes."},"domain":{"type":"string","description":"Domain id or label."},"category":{"type":"string","description":"Category id."},"importance":{"type":"integer","description":"1 (smallest) to 5 (largest). Drives the hex size.","minimum":1,"maximum":5},"dueDate":{"type":"string","description":"Deadline, YYYY-MM-DD."},"snoozeUntil":{"type":"string","description":"Hide until then: YYYY-MM-DD (that morning) or a datetime. Capped at the due date's morning."},"parentId":{"type":"string","description":"Existing task to file this under (a subtask)."},"ref":{"type":"string","description":"Your label for this new task so later items in the same call can use it as parentRef."},"parentRef":{"type":"string","description":"The ref of an earlier task in this call to nest under."},"festers":{"type":"boolean","description":"Escalate visually the longer it sits overdue. Default from Preferences."}},"required":["title"],"additionalProperties":false},"description":"Tasks to create, in order.","maxItems":50}},"required":["tasks"],"additionalProperties":false},"annotations":{"title":"Create tasks","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"horizon_update_task","title":"Update a task","app":"horizon","access":"write","description":"Change a task. Only the fields you pass change; pass null to clear dueDate, snoozeUntil, or parentId. appendNotes adds to the end of the existing notes instead of replacing them. To complete or reopen use horizon_complete_tasks / horizon_reopen_tasks.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Task id."},"title":{"type":"string","description":"New title."},"notes":{"type":"string","description":"Replace the notes (markdown)."},"appendNotes":{"type":"string","description":"Append this to the notes on a new paragraph."},"domain":{"type":"string","description":"Domain id or label."},"category":{"type":"string","description":"Category id."},"importance":{"type":"integer","description":"1-5.","minimum":1,"maximum":5},"dueDate":{"type":["string","null"],"description":"Deadline (YYYY-MM-DD; null clears)","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"snoozeUntil":{"type":["string","null"],"description":"Hide until: YYYY-MM-DD (that morning) or a datetime; null wakes it now. Capped at the due date's morning."},"parentId":{"type":["string","null"],"description":"Move under another open task, or null to move to the top level."},"festers":{"type":"boolean","description":"Escalate visually while overdue."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Update a task","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"horizon_complete_tasks","title":"Complete tasks","app":"horizon","access":"write","description":"Mark tasks done, exactly as the app does: stops any running timer (keeping its elapsed time), ends any snooze, and credits a recurring source. A task with open subtasks is NOT completed unless cascade is true — completing it completes everything inside it, so ask the person first. Already-done tasks are reported, not an error.","inputSchema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"},"description":"Task ids.","maxItems":100},"cascade":{"type":"boolean","description":"Also complete every open subtask inside these tasks. Default false."}},"required":["ids"],"additionalProperties":false},"annotations":{"title":"Complete tasks","readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"horizon_reopen_tasks","title":"Reopen tasks","app":"horizon","access":"write","description":"Undo completion: mark done tasks open again.","inputSchema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"},"description":"Task ids.","maxItems":100}},"required":["ids"],"additionalProperties":false},"annotations":{"title":"Reopen tasks","readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"horizon_delete_task","title":"Delete a task","app":"horizon","access":"write","description":"Permanently delete a task AND every subtask inside it. There is no trash. Prefer horizon_complete_tasks unless the person asked for deletion. A task absorbed into a Loupe checklist can't be deleted here (release it in Loupe first).","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Task id."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Delete a task","readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},{"name":"horizon_create_domain","title":"Create a domain","app":"horizon","access":"write","description":"Add a Domain (a life area that colors tasks, like Work or Health).","inputSchema":{"type":"object","properties":{"label":{"type":"string","description":"Display name."},"color":{"type":"string","description":"Hex color like #60a5fa.","pattern":"^#[0-9a-fA-F]{6}$"}},"required":["label"],"additionalProperties":false},"annotations":{"title":"Create a domain","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"luminate_list_notes","title":"List notes","app":"luminate","access":"read","description":"List Luminate notes, most recently edited first, with folder paths and a short snippet. Use luminate_get_note for the full body.","inputSchema":{"type":"object","properties":{"folderId":{"type":"string","description":"Only notes directly in this folder. \"root\" = unfiled notes."},"query":{"type":"string","description":"Keyword match in title or body."},"limit":{"type":"integer","description":"Default 50.","minimum":1,"maximum":500}},"required":[],"additionalProperties":false},"annotations":{"title":"List notes","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"luminate_get_note","title":"Read a note","app":"luminate","access":"read","description":"A note's full markdown body. For an imported PDF note, the body is the PDF's extracted text. Inline images appear as long data: URIs; maxChars trims the body if you only need the start.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Note id."},"maxChars":{"type":"integer","description":"Trim the body to this many characters.","minimum":100,"maximum":2000000}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Read a note","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"luminate_create_note","title":"Create a note","app":"luminate","access":"write","description":"Create a markdown note. In this app __text__ is underline (not bold); use **text** for bold. \"- [ ] item\" lines are live checkboxes.","inputSchema":{"type":"object","properties":{"title":{"type":"string","description":"Title (max 300 chars)."},"body":{"type":"string","description":"Markdown body."},"folderId":{"type":"string","description":"Folder to file it in. Omit for unfiled."}},"required":["title"],"additionalProperties":false},"annotations":{"title":"Create a note","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"luminate_update_note","title":"Edit a note","app":"luminate","access":"write","description":"Edit a note. body replaces the whole body; appendText / prependText add to it without resending everything; folderId moves it (null = unfiled). Replacing the body of a long note you haven't read in full will lose what you didn't include — prefer append/prepend.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Note id."},"title":{"type":"string","description":"New title."},"body":{"type":"string","description":"New full body (replaces)."},"appendText":{"type":"string","description":"Added at the end, on a new paragraph."},"prependText":{"type":"string","description":"Added at the start, followed by a blank line."},"folderId":{"type":["string","null"],"description":"Move to this folder, or null for unfiled."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Edit a note","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"luminate_delete_note","title":"Delete a note","app":"luminate","access":"write","description":"Permanently delete a note (and, for a PDF note, its stored PDF and margin annotations). There is no trash.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Note id."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Delete a note","readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},{"name":"luminate_list_folders","title":"List note folders","app":"luminate","access":"read","description":"Every Luminate folder with its full path and how many notes sit directly in it.","inputSchema":{"type":"object","properties":{},"required":[],"additionalProperties":false},"annotations":{"title":"List note folders","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"luminate_create_folder","title":"Create a note folder","app":"luminate","access":"write","description":"Create a folder, optionally inside another. Folders nest without limit.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Folder name."},"parentId":{"type":"string","description":"Parent folder id; omit for top level."}},"required":["name"],"additionalProperties":false},"annotations":{"title":"Create a note folder","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"pupil_list_members","title":"List team members","app":"pupil","access":"read","description":"Everyone on the team, with open-goal counts and certifications expiring within 60 days.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Filter by name."}},"required":[],"additionalProperties":false},"annotations":{"title":"List team members","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"pupil_get_member","title":"Get a team member","app":"pupil","access":"read","description":"A member's profile plus their whole timeline — goals, certifications, dated notes, and activity — newest first, the way the Pupil page shows it.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Member id."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Get a team member","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"pupil_create_member","title":"Add a team member","app":"pupil","access":"write","description":"Add someone to the team.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Full name."},"phone":{"type":"string","description":"Phone number."},"payRate":{"type":"string","description":"Pay rate, free text (e.g. \"$22/hr\")."},"hiredDate":{"type":"string","description":"YYYY-MM-DD."}},"required":["name"],"additionalProperties":false},"annotations":{"title":"Add a team member","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"pupil_update_member","title":"Update a team member","app":"pupil","access":"write","description":"Change a member's profile fields. Pay rate and hired-date changes are logged on their timeline automatically.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Member id."},"name":{"type":"string","description":"Name."},"phone":{"type":"string","description":"Phone."},"payRate":{"type":"string","description":"Pay rate."},"hiredDate":{"type":["string","null"],"description":"Hired date (YYYY-MM-DD; null clears)","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Update a team member","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"pupil_add_note","title":"Add a note to a member","app":"pupil","access":"write","description":"Add a dated note card to a member's timeline (a conversation, an observation, feedback given).","inputSchema":{"type":"object","properties":{"memberId":{"type":"string","description":"Member id."},"body":{"type":"string","description":"The note."}},"required":["memberId","body"],"additionalProperties":false},"annotations":{"title":"Add a note to a member","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"pupil_add_goal","title":"Add a goal for a member","app":"pupil","access":"write","description":"Set a development goal for a team member.","inputSchema":{"type":"object","properties":{"memberId":{"type":"string","description":"Member id."},"text":{"type":"string","description":"The goal."},"dueDate":{"type":"string","description":"YYYY-MM-DD."}},"required":["memberId","text"],"additionalProperties":false},"annotations":{"title":"Add a goal for a member","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"pupil_update_goal","title":"Update a member goal","app":"pupil","access":"write","description":"Edit a goal or mark it done/not done.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Goal id."},"text":{"type":"string","description":"New text."},"dueDate":{"type":["string","null"],"description":"Due date (YYYY-MM-DD; null clears)","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"done":{"type":"boolean","description":"Done?"}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Update a member goal","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"pupil_record_certification","title":"Record a certification","app":"pupil","access":"write","description":"Record that a member holds a certification. The certification type is matched by name (case-insensitive) and created if it doesn't exist yet. If the member already holds it, the dates are updated instead.","inputSchema":{"type":"object","properties":{"memberId":{"type":"string","description":"Member id."},"certification":{"type":"string","description":"Certification name, e.g. \"Forklift\"."},"certifiedDate":{"type":"string","description":"YYYY-MM-DD."},"expiresDate":{"type":"string","description":"YYYY-MM-DD."}},"required":["memberId","certification"],"additionalProperties":false},"annotations":{"title":"Record a certification","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_list_checklists","title":"List checklists","app":"loupe","access":"read","description":"Every Loupe checklist with its pause point, mode, cadence, item count, and whether it's due today.","inputSchema":{"type":"object","properties":{"includeArchived":{"type":"boolean","description":"Default false."}},"required":[],"additionalProperties":false},"annotations":{"title":"List checklists","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"loupe_get_checklist","title":"Get a checklist","app":"loupe","access":"read","description":"A checklist's items in order, the evidence for the current version (runs, median duration, per-item skip rate and catches — \"caught\" is the value metric: the item surfaced a real problem), recent runs, and version history. Items with zero catches over many runs are candidates for removal; subtraction is the default posture when revising.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Checklist id."},"runs":{"type":"integer","description":"How many recent runs to include (default 10).","minimum":0,"maximum":50}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Get a checklist","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"loupe_create_checklist","title":"Create a checklist","app":"loupe","access":"write","description":"Create a checklist with its items. Good checklists are short (5-9 items, 60-90 seconds), name their pause point in the person's own words (\"Before I leave the house\"), and phrase items as challenge/response. mode: \"do_confirm\" = work from memory then verify; \"read_do\" = do each item as it's read. If the person hasn't said which, leave mode unset — the app won't run it until they choose. A non_normal checklist is for when something has already gone wrong and never has a cadence.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Checklist name."},"pausePoint":{"type":"string","description":"The moment that triggers it, in the person's words."},"mode":{"type":"string","enum":["do_confirm","read_do"],"description":"How it's flown. Omit if not chosen."},"kind":{"type":"string","enum":["normal","non_normal"],"description":"Default normal."},"cadence":{"type":"string","enum":["none","daily","weekdays","weekly","monthly"],"description":"When it comes due. Default none."},"cadenceDays":{"type":"string","description":"weekly: weekday numbers 0-6 (0=Sunday) comma-separated, e.g. \"1,4\". monthly: days of month, e.g. \"1,15\"."},"dueTime":{"type":"string","description":"Advisory local time HH:MM."},"items":{"type":"array","items":{"type":"object","properties":{"challenge":{"type":"string","description":"What to look at or do — the left side of the card (\"GEAR\")."},"response":{"type":"string","description":"The state it must be in — the right side (\"DOWN, THREE GREEN\"). May be empty."},"killer":{"type":"boolean","description":"Marks a step that is both frequently skipped and consequential when skipped. Use sparingly."},"note":{"type":"string","description":"Optional short note under the item."}},"required":["challenge"],"additionalProperties":false},"description":"Items in order.","maxItems":50}},"required":["name","items"],"additionalProperties":false},"annotations":{"title":"Create a checklist","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_update_checklist","title":"Update a checklist","app":"loupe","access":"write","description":"Change a checklist's settings (not its items). archived:true retires it without deleting its history.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Checklist id."},"name":{"type":"string","description":"Name."},"pausePoint":{"type":"string","description":"Pause point."},"mode":{"type":["string","null"],"enum":["do_confirm","read_do",null],"description":"Mode, or null for not chosen."},"kind":{"type":"string","enum":["normal","non_normal"],"description":"Kind."},"cadence":{"type":"string","enum":["none","daily","weekdays","weekly","monthly"],"description":"Cadence."},"cadenceDays":{"type":["string","null"],"description":"See loupe_create_checklist."},"dueTime":{"type":["string","null"],"description":"HH:MM or null."},"archived":{"type":"boolean","description":"Archive / unarchive."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Update a checklist","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_add_items","title":"Add checklist items","app":"loupe","access":"write","description":"Add items to a checklist, at the end or right after a given item.","inputSchema":{"type":"object","properties":{"checklistId":{"type":"string","description":"Checklist id."},"items":{"type":"array","items":{"type":"object","properties":{"challenge":{"type":"string","description":"What to look at or do — the left side of the card (\"GEAR\")."},"response":{"type":"string","description":"The state it must be in — the right side (\"DOWN, THREE GREEN\"). May be empty."},"killer":{"type":"boolean","description":"Marks a step that is both frequently skipped and consequential when skipped. Use sparingly."},"note":{"type":"string","description":"Optional short note under the item."}},"required":["challenge"],"additionalProperties":false},"description":"Items in order.","maxItems":50},"afterItemId":{"type":"string","description":"Insert after this item instead of at the end."}},"required":["checklistId","items"],"additionalProperties":false},"annotations":{"title":"Add checklist items","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_update_item","title":"Edit a checklist item","app":"loupe","access":"write","description":"Change an item's challenge, response, note, killer flag, or position. Past runs keep the wording they ran with.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Item id."},"challenge":{"type":"string","description":"Challenge."},"response":{"type":"string","description":"Response."},"note":{"type":"string","description":"Note."},"killer":{"type":"boolean","description":"Killer item flag."},"position":{"type":"integer","description":"New position (0-based).","minimum":0,"maximum":1000}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Edit a checklist item","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_remove_item","title":"Remove a checklist item","app":"loupe","access":"write","description":"Take an item off a checklist. If the item came from a Horizon task (absorbed), that task is released back to Horizon unchanged — nothing is lost. Past runs keep their record of the item.","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Item id."}},"required":["id"],"additionalProperties":false},"annotations":{"title":"Remove a checklist item","readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_cut_revision","title":"Record a revision","app":"loupe","access":"write","description":"Record a revision of a checklist: snapshots its items as they stand now, freezes the current evidence alongside, and moves the checklist to the next version — which resets the evidence for the new version. Say in the note what changed and why (\"dropped tire check: 30 runs, no catches\").","inputSchema":{"type":"object","properties":{"checklistId":{"type":"string","description":"Checklist id."},"note":{"type":"string","description":"What changed and why."}},"required":["checklistId"],"additionalProperties":false},"annotations":{"title":"Record a revision","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"loupe_absorb_tasks","title":"Move tasks onto a checklist","app":"loupe","access":"write","description":"The offload path: turn recurring Horizon tasks into items on a checklist. The tasks are hidden from Horizon — not completed, not deleted — and come back unchanged if the item is removed or the checklist deleted. Tasks that hold subtasks can't be absorbed. Needs horizon read access too, to check the tasks.","inputSchema":{"type":"object","properties":{"checklistId":{"type":"string","description":"Checklist id."},"taskIds":{"type":"array","items":{"type":"string"},"description":"Horizon task ids.","maxItems":50}},"required":["checklistId","taskIds"],"additionalProperties":false},"annotations":{"title":"Move tasks onto a checklist","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"refract_get_week","title":"Get a Refract week","app":"refract","access":"read","description":"One week of Refract: the daily check-ins, the four reflection answers (and their summaries once refracted), follow-up questions, suggested to-dos, and — for the current week — what was achieved across the suite. Weeks run Monday-Saturday; Sunday belongs to the week ending.","inputSchema":{"type":"object","properties":{"date":{"type":"string","description":"Any date in the week (YYYY-MM-DD). Default today."}},"required":[],"additionalProperties":false},"annotations":{"title":"Get a Refract week","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"refract_list_weeks","title":"List Refract weeks","app":"refract","access":"read","description":"Past weeks that have a reflection, newest first, with their one-paragraph summaries when they've been refracted.","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","description":"Default 12.","minimum":1,"maximum":200}},"required":[],"additionalProperties":false},"annotations":{"title":"List Refract weeks","readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},{"name":"refract_save_checkin","title":"Save a daily check-in","app":"refract","access":"write","description":"Answer the daily Refract check-in for a day (Monday-Saturday; each weekday has its own fixed prompt, returned here). Overwrites that day's answer if one exists. Only record words the person actually said — this is their journal.","inputSchema":{"type":"object","properties":{"answer":{"type":"string","description":"The person's answer (max 500 chars)."},"date":{"type":"string","description":"YYYY-MM-DD; default today."}},"required":["answer"],"additionalProperties":false},"annotations":{"title":"Save a daily check-in","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},{"name":"refract_write_reflection","title":"Write the weekly reflection","app":"refract","access":"write","description":"Fill in the week's four reflection prompts: worstPart (\"worst part of the week\"), bestPart, bothering (\"what's still bothering you\"), proud (\"what you're proud of\"). Only available once the week has closed (from its Sunday on), and not on a locked (refracted) week. Only pass fields the person gave you; omitted fields are left alone. Record their words, not your paraphrase.","inputSchema":{"type":"object","properties":{"date":{"type":"string","description":"Any date in the week; default today."},"worstPart":{"type":"string","description":"Worst part of the week."},"bestPart":{"type":"string","description":"Best part of the week."},"bothering":{"type":"string","description":"What's still bothering them."},"proud":{"type":"string","description":"What they're proud of."}},"required":[],"additionalProperties":false},"annotations":{"title":"Write the weekly reflection","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}}],"prompts":[{"name":"plan_my_day","title":"Plan my day","description":"Look at what's due, overdue, and on today's checklists, and propose a realistic plan.","arguments":[{"name":"hours","description":"Hours available today","required":false}]},{"name":"triage_horizon","title":"Triage Horizon","description":"Find stale, duplicate, and undated tasks and suggest cleanups.","arguments":[]},{"name":"weekly_review","title":"Weekly review","description":"Walk through the week: what got done, what slipped, what to carry forward.","arguments":[]},{"name":"checklist_from_tasks","title":"Turn chores into a checklist","description":"Spot recurring self-imposed tasks and propose a Loupe checklist to hold them.","arguments":[]}]}