MCPサーバー

Local MCP

com.local-mcp/local-mcp
コミュニケーション 生産性 公開・接続可能 MCP 2026-07-28

このMCPでできること

Connects AI assistants to Mac email, calendars, reminders, notes, tasks, files, Microsoft 365, Todoist, spreadsheets, and daily briefings.

complete_omnifocus_task
Complete OmniFocus Task
Marks an OmniFocus task as complete by task ID or name. Requires confirm=true.
入力スキーマ
{'type': 'object', 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to complete; called without it, returns a preview.'}, 'task_id': {'type': 'string', 'description': 'Exact task id from list_omnifocus_tasks (preferred). Provide this OR task_name.'}, 'task_name': {'type': 'string', 'description': "Task title to match when you don't have the id."}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'completed': {'type': 'boolean'}}}
complete_reminder
Complete Reminder
Marks a reminder complete in Apple Reminders (Reminders.app). Requires confirm=true. For Microsoft To Do use todo_complete_task instead.
入力スキーマ
{'type': 'object', 'required': ['reminder_id'], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to complete'}, 'reminder_id': {'type': 'string', 'description': 'Reminder ID from list_reminders'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
configure_clients
Configure Clients
Adds Local MCP to the config of the MCP-capable AI apps installed on this Mac, from LMCP's client catalog (Claude Desktop, Claude Code, Cursor, Windsurf, VS Code, Zed, Codex / ChatGPT desktop, Jan, LM Studio, Warp, Antigravity, Cline, Roo and more) — no manual JSON editing. Read-only PREVIEW unless confirm:true. Optionally pass a single `client` id. Reports per client whether it was set up, was already set up, can't be set up automatically (and why), or isn't installed, plus the step the user must take for the change to apply (restart the app, or open a new session). Pair with list_missing_permissions for fully agent-driven setup.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'client': {'type': 'string', 'description': 'Optional: configure only this client. One of: claude-desktop, claude-code, cursor, windsurf, vscode, zed, lmstudio, warp, antigravity, cline, roo, codex, jan, opencode, goose, hermes, raycast, msty, cherry-studio. Omit to do all installed ones.'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to write the config. Without it, returns a preview of what would change.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
connect_m365_account
Connect Microsoft 365 Account
Connect your Microsoft 365 account. Call once to get a login code, then call again after you've authenticated at microsoft.com/devicelogin to confirm the connection.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
connect_todoist
Connect Todoist
Connect Todoist. For security your API token is entered directly in Local MCP's own settings window — never passed through the AI. Call this to get the instructions, or to check whether Todoist is already connected.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['ok', 'message'], 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
create_calendar_event
Create Calendar Event
Creates an event in the Mac's Calendar app (Calendar.app). Requires title, start_date, end_date. Optionally invite attendees by email (CalDAV/Exchange calendars only), or make it a repeating event with `recurrence` (daily/weekly/monthly/yearly). For Microsoft 365 use m365_create_event instead.
入力スキーマ
{'type': 'object', 'required': ['title', 'start_date', 'end_date'], 'properties': {'notes': {'type': 'string', 'description': 'Event notes (optional)'}, 'title': {'type': 'string', 'description': 'Event title'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create the event'}, 'calendar': {'type': 'string', 'description': 'Calendar name to match (optional, alternative to calendar_id)'}, 'end_date': {'type': 'string', 'description': 'ISO 8601 date or datetime, same timezone rules as start_date. For an all-day event pass a bare date (end is inclusive: same date as start = a one-day all-day event; a later date spans through that day).'}, 'location': {'type': 'string', 'description': 'Location (optional)'}, 'attendees': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of email addresses to invite (optional, CalDAV/Exchange only)'}, 'recurrence': {'type': 'string', 'description': "Make it a repeating event: 'daily', 'weekly', 'monthly', or 'yearly' (optional; omit for a one-time event)."}, 'start_date': {'type': 'string', 'description': "ISO 8601 date or datetime. With a time (2026-06-27T09:00:00) the event is timed; a time with NO timezone is read in the Mac's LOCAL zone, append Z or an offset (2026-06-27T09:00:00Z, or +02:00) to pin it to UTC/another zone. Pass a bare DATE (YYYY-MM-DD) for BOTH start_date and end_date to create an ALL-DAY event."}, 'calendar_id': {'type': 'string', 'description': 'Calendar UUID from list_calendar_names (optional, defaults to default calendar)'}, 'recurrence_count': {'type': 'integer', 'description': 'Total number of occurrences (optional). Mutually exclusive with recurrence_until; if neither is given the event repeats indefinitely.'}, 'recurrence_until': {'type': 'string', 'description': 'ISO 8601 date the repetition stops on (optional; takes precedence over recurrence_count).'}, 'recurrence_interval': {'type': 'integer', 'description': "Repeat every N periods (optional, default 1 — e.g. recurrence='weekly' + recurrence_interval=2 = every 2 weeks)."}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'end': {'type': 'string'}, 'start': {'type': 'string'}, 'title': {'type': 'string'}, 'created': {'type': 'boolean'}, 'recurrence': {'type': 'string', 'description': 'Present when the event repeats (human-readable summary)'}, 'attendees_note': {'type': 'string'}, 'attendees_requested': {'type': 'array', 'items': {'type': 'string'}}}}
create_draft
Create Draft
Saves an email to the Mail.app Drafts folder for the user to review and send manually — it never sends. Compose a new draft with `to`/`subject` and `body` or `html_body`, or save a native reply with `reply_to_message_id`, `reply_all`, and `body` or `html_body`; the response names the Drafts mailbox and subject. A reply draft's response includes `threaded`: true means the saved draft was read back and its headers reference the source message (it will appear inside the conversation); false means it saved WITHOUT threading headers (relay the warning to the user); "unconfirmed" means it could not be read back in time (e.g. Exchange sync lag). On a multi-account Mac, pass `account` (an account name from list_email_accounts) or `from` (a sender address) to place the draft in that account's Drafts; otherwise it lands in the default account. Attach files by passing `attachments` (comma-separated absolute file paths, e.g. a PDF quote) — they are attached to the saved draft. Use this for the cautious user who wants AI-composed mail but insists on sending it themselves. Requires confirm=true to actually save it — without it, returns a preview without touching Mail.app.
入力スキーマ
{'type': 'object', 'properties': {'cc': {'type': 'string', 'description': 'CC address(es), comma-separated.'}, 'to': {'type': 'string', 'description': 'Recipient address(es) for a new draft, comma-separated. Omit for a reply draft (uses reply_to_message_id).'}, 'bcc': {'type': 'string', 'description': 'BCC address(es), comma-separated.'}, 'body': {'type': 'string', 'description': 'Plain-text body of the draft.'}, 'from': {'type': 'string', 'description': "Sender address — on a multi-account Mac, selects which account's Drafts to use. Alternative to `account`."}, 'account': {'type': 'string', 'description': 'Account name (from list_email_accounts) whose Drafts folder receives the draft. Alternative to `from`.'}, 'confirm': {'type': 'boolean', 'default': 'false', 'description': 'Must be true to actually save the draft. Without it, returns a preview of the recipient/sender, subject, and that the body will be saved.'}, 'subject': {'type': 'string', 'description': 'Subject line for a new draft. Ignored for reply drafts (they inherit the original subject).'}, 'html_body': {'type': 'string', 'description': 'HTML body of the draft. Takes precedence over `body` when both are given.'}, 'reply_all': {'type': 'boolean', 'default': 'false', 'description': 'For a reply draft, include all original recipients (reply-all) instead of just the sender.'}, 'attachments': {'type': 'string', 'description': 'Files to attach, as comma-separated absolute paths (e.g. a PDF).'}, 'reply_to_message_id': {'type': 'string', 'description': 'Message id (from list_emails/search_emails) to draft a reply to, instead of a new message.'}}}
出力スキーマ
{'type': 'object', 'properties': {'to': {'type': 'string'}, 'from': {'type': 'string'}, 'kind': {'type': 'string'}, 'account': {'type': 'string'}, 'mailbox': {'type': 'string'}, 'subject': {'type': 'string'}, 'attachments': {'type': 'array', 'items': {'type': 'string'}}, 'saved_draft': {'type': 'boolean'}, 'attachments_failed': {'type': 'array', 'items': {'type': 'string'}}, 'reply_to_message_id': {'type': 'string'}}}
create_email_folder
Create Email Folder
Creates a new mailbox folder in Mail.app.
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Folder name'}, 'account': {'type': 'string', 'description': 'Account name (optional, uses default)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}}}
出力スキーマ
{'type': 'object', 'required': ['created', 'name'], 'properties': {'name': {'type': 'string'}, 'created': {'type': 'boolean'}}}
create_note
Create Note
Creates a new note in Apple Notes. The body accepts Markdown (headings, bold/italic, bullet/numbered lists, links, inline code) — it's converted to Apple Notes' native formatting. Requires confirm=true to execute.
入力スキーマ
{'type': 'object', 'required': ['name', 'body'], 'properties': {'body': {'type': 'string', 'description': "Body of the note. Accepts Markdown (headings, bold/italic, bullet and numbered lists, links, inline code), converted to Apple Notes' native formatting."}, 'name': {'type': 'string', 'description': 'Title of the new note.'}, 'folder': {'type': 'string', 'description': "Notes folder to create it in. Defaults to the account's default folder."}, 'confirm': {'type': 'boolean', 'description': 'Set to true to actually create the note. Defaults to false.'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'created': {'type': 'boolean'}}}
create_omnifocus_task
Create OmniFocus Task
Creates a new task in OmniFocus. Requires confirm=true to execute.
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'The task title.'}, 'note': {'type': 'string', 'description': 'Longer note/body for the task.'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create; called without it, returns a preview.'}, 'flagged': {'type': 'boolean', 'default': 'false', 'description': 'Create the task flagged.'}, 'project': {'type': 'string', 'description': 'Project to file the task under (name). Omit for the inbox.'}, 'due_date': {'type': 'string', 'description': 'Due date, ISO 8601 (YYYY-MM-DD or full timestamp).'}, 'defer_date': {'type': 'string', 'description': 'Defer/start date, ISO 8601 — the task stays hidden until then.'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'created': {'type': 'boolean'}}}
create_referral_invites
Create Referral Invites
Records referral invites for the colleagues a user chose to invite and returns a unique referral link per person, so the user can later see who installed or activated LMCP. It does not send anything itself — each returned link can be included in an email or message to that person. `lang` records the language the invite is written in (e.g. "es", "en").
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['recipients'], 'properties': {'lang': {'type': 'string', 'description': "ISO language of the invite you're writing (the user's conversation language, e.g. 'es', 'en'). Defaults to the Mac's language."}, 'recipients': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string', 'description': "Recipient's name"}, 'email': {'type': 'string', 'description': "Recipient's email"}}}, 'description': 'The picked recipients.'}}}
出力スキーマ
{'type': 'object', 'properties': {'next': {'type': 'string'}, 'invites': {'type': 'array', 'items': {'type': 'object', 'properties': {'link': {'type': 'string'}, 'name': {'type': 'string'}}}}}}
create_reminder
Create Reminder
Creates a reminder in Reminders.app. Without confirm=true it returns a preview of the title, due date, notes, list and priority and creates nothing. A due_date with a date but no time sets the due date without an alarm, so Reminders will not notify; include a time to get a notification.
入力スキーマ
{'type': 'object', 'required': ['title'], 'properties': {'notes': {'type': 'string', 'description': 'Notes (optional)'}, 'title': {'type': 'string', 'description': 'Reminder title'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}, 'due_date': {'type': 'string', 'description': 'ISO 8601 date (optional)'}, 'priority': {'enum': ['none', 'low', 'medium', 'high'], 'type': 'string', 'description': 'Priority: none | low | medium | high (optional)'}, 'list_name': {'type': 'string', 'description': 'Reminder list name (optional)'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
create_reminder_list
Create Reminder List
Creates a new list in Apple Reminders (Reminders.app). Requires confirm=true.
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Name for the new reminder list'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
daily_brief
Daily Brief
Returns a single morning briefing combining today's calendar events, overdue and due-today reminders, unread inbox email count + subjects, and — when a location is provided — today's weather. Perfect for starting each day: one call gives you everything on your plate.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'location': {'type': 'string', 'description': "Optional city name or 'lat,lon' to include today's weather in the brief (e.g. 'London', 'San Francisco'). Omitted if not provided."}, 'include_emails': {'type': 'boolean', 'description': 'Include unread email summary from Mail.app (default true, skipped gracefully if Mail is not running)'}}}
出力スキーマ
{'type': 'object', 'required': ['date', 'events', 'reminders', 'emails'], 'properties': {'date': {'type': 'string', 'description': "Today's date (YYYY-MM-DD)."}, 'note': {'type': 'string', 'description': 'Onboarding enrichment shown when nothing is scheduled.'}, 'emails': {'type': ['object', 'null'], 'description': 'Unread email summary (unread_count + recent_unread), or {skipped} / {error}, or null when not requested.'}, 'events': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'end': {'type': 'string'}, 'start': {'type': 'string'}, 'title': {'type': 'string'}, 'all_day': {'type': 'boolean'}, 'calendar': {'type': 'string'}, 'location': {'type': 'string'}}}, 'description': "Today's calendar events."}, 'weather': {'type': 'object', 'description': "Today's weather (current conditions + forecast), only present when a location was provided."}, 'reminders': {'type': 'array', 'items': {'type': 'object', 'properties': {'list': {'type': 'string'}, 'title': {'type': 'string'}, 'overdue': {'type': 'boolean'}, 'due_date': {'type': 'string'}, 'reminder_id': {'type': 'string'}}}, 'description': 'Reminders due today or overdue.'}, 'incomplete': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Sections that could NOT be read this time (each step has its own ceiling). An empty/absent list means every section was actually read; a section named here means its data is missing, NOT that it is empty.'}}}
delete_calendar_event
Delete Calendar Event
Deletes an event from the Mac's Calendar app (Calendar.app) by ID. Requires confirm=true. For a repeating event, pass span='future' to delete the whole series (this and all following occurrences); the default deletes only the single occurrence named by event_id. For Microsoft 365 use m365_delete_event instead.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['event_id'], 'properties': {'span': {'type': 'string', 'description': "For a recurring event: 'this' (default — only this occurrence) or 'future' (this and all following occurrences; 'all'/'series' mean the same). Any other value is refused. Ignored for non-recurring events."}, 'confirm': {'type': 'boolean', 'description': 'Must be true to delete'}, 'event_id': {'type': 'string', 'description': 'Event (or occurrence) identifier from list_calendar_events. For a recurring event this addresses exactly the occurrence that id came from — the preview names the date and scope so you can confirm before deleting.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
delete_note
Delete Note
Deletes a note from Apple Notes, by ID or exact title. Like deleting it in the app, the note goes to "Recently Deleted" and Apple purges it after 30 days — the user can still recover it there. Requires confirm=true. The result is VERIFIED: the tool re-reads the note after deleting and reports the deletion as unverified if it is still where it was, so a success here means the note is really gone from list_notes/search_notes/read_note. Find note_id with list_notes or search_notes.
破壊的操作あり
入力スキーマ
{'type': 'object', 'properties': {'confirm': {'type': 'boolean', 'description': 'Set to true to actually delete. Defaults to false, which returns a preview and deletes nothing.'}, 'note_id': {'type': 'string', 'description': "The note's id, as list_notes/search_notes report it."}, 'note_name': {'type': 'string', 'description': "Exact title, when you don't have the id. If several notes share it, the first match is deleted — prefer note_id."}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'deleted': {'type': 'boolean', 'description': 'True only when the deletion was VERIFIED by re-reading the note'}, 'in_trash': {'type': 'boolean', 'description': 'The note moved to Recently Deleted (Apple purges it after 30 days) rather than vanishing outright'}, 'verified': {'type': 'boolean', 'description': 'The note was re-read after deleting and is no longer where it was'}, 'folder_after': {'type': 'string', 'description': 'Where it ended up (present when it moved instead of vanishing)'}, 'next_actions': {'type': 'array'}, 'folder_before': {'type': 'string', 'description': 'The folder the note was in before deleting'}}}
delete_reminder
Delete Reminder
Permanently deletes a reminder in Apple Reminders (Reminders.app) by ID. Get the reminder_id from list_reminders. Requires confirm=true.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['reminder_id'], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to delete'}, 'reminder_id': {'type': 'string', 'description': 'Reminder identifier from list_reminders'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
delete_reminder_folder
Delete Reminder Folder
Deletes an Apple Reminders list AND all reminders inside it — cannot be undone. Pass the list name (or list_id from get_reminder_folders). Requires confirm=true.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'name': {'type': 'string', 'description': 'List name to delete (or pass list_id)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to delete'}, 'list_id': {'type': 'string', 'description': 'List identifier from get_reminder_folders (alternative to name)'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
disconnect_m365_account
Disconnect Microsoft 365 Account
Disconnect your Microsoft 365 account and remove stored tokens. Runs immediately, with no preview or confirm step; reconnecting requires the Microsoft sign-in flow again.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
disconnect_todoist
Disconnect Todoist
Disconnect Todoist and remove the stored API token. Runs immediately, with no preview or confirm step; reconnecting requires the user to enter a new API token.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['ok', 'message'], 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
enable_service
Enable Service
Turns a service back ON in LMCP after the user turned it off. Use it when a tool reports that its service is turned off. Services are user preferences, not failures: turning one on is always safe and reversible from the LMCP menu bar icon. For Calendar, Reminders and Contacts the OS permission is separate — this tool reports whether macOS has granted it, and where the user must be to accept the dialog (it appears on the Mac running LMCP, which over Cloud Relay may not be where the user is).
入力スキーマ
{'type': 'object', 'required': ['service'], 'properties': {'service': {'type': 'string', 'description': "Service id, e.g. 'calendar', 'reminders', 'contacts', 'mail', 'notes', 'messages', 'teams', 'slack'."}}}
excel_create
Excel Create
Creates a new Excel spreadsheet (.xlsx file) with headers and optional data rows. JSON numbers (integers and decimals) are written as numbers, so SUM() and charts work on them; JSON strings always stay text even when they look numeric ("007", "1e3", or " 42"), as do integer values longer than 10 digits because they are identifiers like a CUIT, CBU or phone number rather than quantities.
入力スキーマ
{'type': 'object', 'required': ['path', 'headers'], 'properties': {'path': {'type': 'string', 'description': 'Output path for the .xlsx file'}, 'rows': {'type': 'array', 'items': {'type': 'array', 'description': 'One row: the cell values, in column order'}, 'description': 'Array of ROW ARRAYS — each row is itself an array of cell values (optional)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}, 'headers': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Column headers'}}}
出力スキーマ
{'type': 'object', 'required': ['created', 'path', 'headers', 'rows'], 'properties': {'path': {'type': 'string', 'description': 'Path of the created .xlsx file'}, 'rows': {'type': 'integer', 'description': 'Number of data rows written'}, 'created': {'type': 'boolean', 'description': 'True when the file was created'}, 'headers': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Column headers written'}}}
excel_read
Excel Read
Reads data from an Excel spreadsheet (.xlsx file). Returns the first row as `headers` and the remaining data rows as `rows` — mirroring excel_create's `headers`/`rows` params, so a read→create round-trip needs no manual row-0 handling.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the .xlsx file'}, 'max_rows': {'type': 'integer', 'description': 'Max rows to return (default 100)'}, 'sheet_name': {'type': 'string', 'description': 'Sheet name to read (optional, reads first sheet). Matched without case. A name that no sheet has is an error listing the available ones — it never falls back to the first sheet.'}, 'force_download': {'type': 'boolean', 'description': "If the file is stored in the cloud and evicted from this Mac (dataless), request the download and wait for it instead of failing. Off by default: a download can take minutes and use metered data, so it is the caller's decision."}}}
出力スキーマ
{'type': 'object', 'required': ['sheet', 'sheets', 'headers', 'rows', 'count'], 'properties': {'rows': {'type': 'array', 'items': {'type': 'array', 'items': {}}, 'description': "Data rows AFTER the header row; numeric cells are numbers and text cells are strings — feeds straight into excel_create's `rows`"}, 'count': {'type': 'integer', 'description': 'Number of DATA rows returned (excludes the header row)'}, 'sheet': {'type': 'string', 'description': 'Name of the sheet that was read'}, 'sheets': {'type': 'array', 'items': {'type': 'string'}, 'description': 'All sheet names in the workbook'}, 'headers': {'type': 'array', 'items': {'type': 'string'}, 'description': "The first row, as column headers — mirrors excel_create's `headers` param"}, 'sparse_cells': {'type': 'array', 'items': {'type': 'object'}, 'description': "Present only when the sheet has cells far outside the table (beyond column 64): each is {row, col, value} with REAL 1-based indices. Kept out of `rows` so one stray cell can't pad every row — but never dropped."}}}
excel_write_cell
Excel Write Cell
Writes a value to a specific cell in an Excel file. Numeric-looking value strings are written as numbers only when they round-trip exactly; otherwise they stay text. Address the cell either with `cell` in A1 notation (e.g. "B2") or with `row`+`column` as 1-based integers.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path', 'value'], 'properties': {'row': {'type': 'integer', 'description': 'Row number (1-based) — use with `column`, or use `cell` instead'}, 'cell': {'type': 'string', 'description': 'Cell in A1 notation, e.g. "B2" (alternative to row+column)'}, 'path': {'type': 'string', 'description': 'Path to the .xlsx file'}, 'value': {'type': 'string', 'description': 'Value to write'}, 'column': {'type': 'integer', 'description': 'Column number (1-based) — use with `row`, or use `cell` instead'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to modify'}, 'sheet_name': {'type': 'string', 'description': 'Sheet name (default: first sheet). Matched without case. A name that no sheet has is an error listing the available ones — it never falls back to the first sheet.'}}}
出力スキーマ
{'type': 'object', 'required': ['written', 'row', 'col', 'value'], 'properties': {'col': {'type': 'integer', 'description': 'Column that was written (1-based)'}, 'row': {'type': 'integer', 'description': 'Row that was written (1-based)'}, 'sheet': {'type': 'string', 'description': 'Sheet the value actually landed in'}, 'value': {'type': 'string', 'description': 'Value written to the cell'}, 'written': {'type': 'boolean', 'description': 'True when the cell was written'}}}
file_list
File List
Lists files and folders in a local directory. Defaults to the user's home directory. Returns name, path, type (file/directory), size, and modification date for each item. Sorted: directories first, then files, both alphabetically.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the directory. Defaults to the home directory (~) if omitted.'}, 'show_hidden': {'type': 'boolean', 'description': "Include hidden files (starting with '.'). Default false."}}}
出力スキーマ
{'type': 'object', 'properties': {'dirs': {'type': 'integer'}, 'path': {'type': 'string'}, 'count': {'type': 'integer'}, 'files': {'type': 'integer'}, 'items': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string', 'description': 'file | directory'}, 'modified': {'type': 'string'}, 'extension': {'type': 'string'}, 'is_symlink': {'type': 'boolean'}, 'size_human': {'type': 'string'}}}}}}
file_read
File Read
Reads a plain text file from the local filesystem by its absolute path — the primary, default tool for reading a local text file (use this unless the file is a PDF, Word, Excel, or PowerPoint document, which have their own readers). Reads anywhere on this Mac — home, external disks, cloud drives, /tmp — with one exception: credential and identity locations (keychains, ~/.ssh, ~/.aws, browser logins, another user's home, Time Machine backups) are never read. Supports .txt, .md, .csv, .json, .xml, .log, .yaml, .toml and common code file types; auto-detects UTF-8 with Latin-1/Windows-1252 fallback. For files in OneDrive use onedrive_read_file, in Google Drive gdrive_read_file; for PDFs pdf_read, Word word_read, Excel excel_read.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file'}, 'offset': {'type': 'integer', 'description': 'Start reading at this byte offset (default 0)'}, 'max_bytes': {'type': 'integer', 'description': 'Maximum bytes to read (default 1 MB, max 10 MB)'}, 'force_download': {'type': 'boolean', 'description': "If the file is stored in the cloud and evicted from this Mac (dataless), request the download and wait for it instead of failing. Off by default: a download can take minutes and use metered data, so it is the caller's decision."}}}
出力スキーマ
{'type': 'object', 'required': ['content', 'path', 'bytes'], 'properties': {'path': {'type': 'string', 'description': 'Resolved absolute path of the file'}, 'bytes': {'type': 'integer', 'description': 'Total file size in bytes'}, 'offset': {'type': 'integer', 'description': 'Byte offset the read started at'}, 'content': {'type': 'string', 'description': 'Decoded file text content'}, 'encoding': {'type': 'string', 'description': 'Encoding used to decode (utf8 | cp1252 | latin1)'}, 'truncated': {'type': 'boolean', 'description': 'True if more content remains beyond what was returned'}}}
file_search
File Search
Searches for files and folders by name (case-insensitive, partial match) starting from a root directory. Defaults to the home directory. Returns matching items with path, type, and size.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'root': {'type': 'string', 'description': 'Root directory to search from. Defaults to home directory (~).'}, 'query': {'type': 'string', 'description': 'Filename pattern to search for (partial, case-insensitive)'}, 'file_type': {'type': 'string', 'description': "Filter by extension, e.g. 'pdf', 'docx', 'xlsx'. Omit for all types."}, 'max_results': {'type': 'integer', 'description': 'Maximum number of results to return. Default 50, max 200.'}}}
出力スキーマ
{'type': 'object', 'properties': {'root': {'type': 'string'}, 'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string', 'description': 'file | directory'}, 'modified': {'type': 'string'}, 'extension': {'type': 'string'}, 'is_symlink': {'type': 'boolean'}, 'size_human': {'type': 'string'}, 'relative_path': {'type': 'string'}}}}}}
file_write
File Write
Writes text to a local file — create, overwrite, or append. For .txt/.md/.csv/.json/.log and any plain-text or code file. (For Word use word_create, Excel excel_create, PowerPoint ppt_create.) Writes anywhere on this Mac, with two exceptions: files your machine runs by itself (shell startup files, LaunchAgents, git hooks, AI-client configs) and credential locations are never written. Overwriting an existing file requires confirm=true (the first call returns a preview instead); append=true adds to the end and never needs confirm. Missing parent folders are created.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file to write'}, 'append': {'type': 'boolean', 'description': 'Append to the end instead of overwriting (default false)'}, 'confirm': {'type': 'boolean', 'description': 'Required (true) to OVERWRITE an existing file. Not needed to create a new file or to append.'}, 'content': {'type': 'string', 'description': 'Text content to write'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
finder_list
Finder List
Lists files and folders in a directory (Spotlight-free). Lists any folder on this Mac. Credential and identity locations (keychains, ~/.ssh, browser login stores, another user's home, Time Machine backups) are refused.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to list (default: ~)'}, 'limit': {'type': 'integer', 'description': 'Max items (default 100)'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'path': {'type': 'string'}, 'count': {'type': 'integer', 'description': 'Items returned in this response.'}, 'items': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string', 'description': 'file | directory'}, 'modified': {'type': 'string'}}}}, 'total': {'type': 'integer', 'description': 'Total items when the listing was truncated.'}, 'truncated': {'type': 'boolean'}}}
finder_search
Finder Search
Searches for files by name anywhere on this Mac (uses mdfind/Spotlight); pass path= to scope it to one folder. Credential and identity locations are refused.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'path': {'type': 'string', 'description': 'Limit search to this directory (optional)'}, 'limit': {'type': 'integer', 'description': 'Max results (default 50)'}, 'query': {'type': 'string', 'description': 'Filename or content to search for'}}}
出力スキーマ
{'type': 'object', 'required': ['query', 'count', 'results'], 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'type': {'type': 'string', 'description': 'file | directory'}}}}}}
gdrive_delete_file
Gdrive Delete File
Deletes a file or an empty folder from the synced Google Drive folder — Google Drive for Desktop syncs the deletion to the cloud (the item lands in Drive's trash). Deleting a .gdoc/.gsheet/.gslides pointer removes the real Google Doc/Sheet/Slides. Never deletes a folder that still has contents. First call returns a preview of what was actually found at that path; pass confirm=true to delete.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path under a Google Drive mount (use gdrive_root / gdrive_list_files to get one)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to actually delete'}}}
出力スキーマ
{'type': 'object', 'required': ['deleted', 'path', 'type'], 'properties': {'path': {'type': 'string'}, 'type': {'type': 'string', 'description': 'What was deleted: file, folder, or google_doc_pointer'}, 'deleted': {'type': 'boolean', 'description': 'True only when the folder listing no longer shows the item'}}}
gdrive_file_info
Gdrive File Info
Metadata for a file/folder in the synced Google Drive: size, dates, type. Cheaper than listing the whole directory.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file or folder'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string'}, 'created': {'type': 'string'}, 'modified': {'type': 'string'}, 'size_human': {'type': 'string'}}}
gdrive_list_files
Gdrive List Files
Lists files and folders in a Google Drive path (the locally-synced folder). Use gdrive_root first for valid roots — 'My Drive' and 'Shared drives' live inside each mount. Returns up to `limit` entries (default 1000).
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the Google Drive folder'}, 'limit': {'type': 'integer', 'description': 'Max entries (default 1000, max 5000)'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'items': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string'}, 'modified': {'type': 'string'}}}}, 'total': {'type': 'integer'}, 'truncated': {'type': 'boolean'}}}
gdrive_read_file
Gdrive Read File
Reads a text file from the synced Google Drive folder (.txt, .md, .csv, .json, code files...). Note: native Google Docs/Sheets/Slides sync as .gdoc/.gsheet pointers, not real files — export them from Drive or read Office/PDF copies instead. Auto-detects UTF-8 with Latin-1/CP1252 fallback. For files outside Google Drive, use file_read.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file'}, 'offset': {'type': 'integer', 'description': 'Start byte offset (default 0)'}, 'encoding': {'type': 'string', 'description': "'auto' (default), 'utf8', 'latin1', 'cp1252', 'ascii', 'utf16'"}, 'max_bytes': {'type': 'integer', 'description': 'Max bytes (default 1MB, cap 10MB)'}}}
出力スキーマ
{'type': 'object', 'required': ['content', 'path', 'bytes'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path of the file'}, 'bytes': {'type': 'integer', 'description': 'Total file size in bytes'}, 'offset': {'type': 'integer', 'description': 'Byte offset the read started at'}, 'content': {'type': 'string', 'description': 'Decoded file text content'}, 'encoding': {'type': 'string', 'description': 'Encoding used to decode (utf8 | cp1252 | latin1 | ascii | utf16)'}, 'truncated': {'type': 'boolean', 'description': 'True if more content remains beyond what was returned'}, 'bytes_read': {'type': 'integer', 'description': 'Number of bytes read in this slice'}}}
gdrive_root
Gdrive Root
Lists the Google Drive folders synced on this Mac (My Drive, Shared drives, per-account mounts). Start here to get valid paths for the other gdrive_* tools. Reads the folder Google Drive for Desktop already syncs — no Google API, no OAuth.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'roots': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}}}}}}
gdrive_search_files
Gdrive Search Files
Searches the synced Google Drive folder for files by name (recursive). Returns up to max_results matches (default 50).
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'root': {'type': 'string', 'description': 'Restrict to this Drive path (optional - defaults to all mounts)'}, 'query': {'type': 'string', 'description': 'Filename pattern to search for'}, 'max_results': {'type': 'integer', 'description': 'Maximum results (default 50)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string'}}}}}}
gdrive_write_file
Gdrive Write File
Writes or overwrites a text file in the synced Google Drive folder — it uploads automatically via the official client. Overwriting an existing file requires confirm=true (the first call returns a preview instead); creating a new file needs no confirm.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path under a Google Drive mount'}, 'confirm': {'type': 'boolean', 'description': 'Required (true) to OVERWRITE an existing file. Not needed to create a new file.'}, 'content': {'type': 'string', 'description': 'Text content to write'}}}
出力スキーマ
{'type': 'object', 'required': ['written', 'path', 'bytes', 'overwrote'], 'properties': {'path': {'type': 'string'}, 'bytes': {'type': 'integer'}, 'written': {'type': 'boolean'}, 'overwrote': {'type': 'boolean'}}}
get_audit_log
Get Audit Log
Returns recent LMCP tool call history from the local audit log. Each entry shows timestamp, tool name, call source (local/cloud), success status, and duration. Useful for GDPR Article 30 compliance reporting and debugging.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'ok': {'type': 'boolean', 'description': 'Filter to successes (true) or failures (false) only (optional)'}, 'tool': {'type': 'string', 'description': 'Filter to entries for a specific tool name (optional)'}, 'limit': {'type': 'integer', 'description': 'Number of recent entries to return (default 50, max 200)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'entries': {'type': 'array', 'items': {'type': 'object', 'properties': {'ms': {'type': 'integer'}, 'ok': {'type': 'boolean'}, 'ts': {'type': 'string'}, 'tool': {'type': 'string'}, 'source': {'type': 'string'}, 'confirmed': {'type': 'boolean', 'description': 'For a gated tool (takes confirm): true = the mutation executed, false = preview only. Absent for read-only tools.'}}}}}}
get_config
Get Config
Returns the current LMCP configuration: connected integrations, feature flags and license status. Any key that looks like a secret (token, password, api_key, or a name ending in _key) comes back as `<key>_set: true/false`, never its value.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
get_contact
Get Contact
Gets a contact from the Mac's Contacts app (Contacts.app) by name or ID. Pass `name` to look up directly by name (no need to search_contacts first — if several people match it returns a compact list to choose from), or `contact_id` for an exact lookup. For Microsoft 365 use m365_get_contact instead.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'name': {'type': 'string', 'description': 'Full or partial contact name — the one-step path. Provide this OR contact_id.'}, 'contact_id': {'type': 'string', 'description': 'Exact identifier from list_contacts/search_contacts. Provide this OR name.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
get_datetime
Get Datetime
Get the current date and time of the machine where LMCP runs — with timezone and UTC offset. Call this whenever you need the real 'now' on the user's computer: before creating calendar events or reminders, resolving relative dates like 'today'/'tomorrow'/'next Friday', or timestamping. Takes no arguments.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['iso_local', 'iso_utc', 'human', 'weekday', 'timezone', 'utc_offset', 'epoch_seconds'], 'properties': {'human': {'type': 'string', 'description': 'Human-readable local date/time.'}, 'iso_utc': {'type': 'string', 'description': 'Current time in ISO 8601, UTC.'}, 'weekday': {'type': 'string'}, 'timezone': {'type': 'string', 'description': 'IANA timezone identifier.'}, 'iso_local': {'type': 'string', 'description': "Current time in ISO 8601 with the machine's local UTC offset."}, 'utc_offset': {'type': 'string', 'description': 'UTC offset like +02:00.'}, 'epoch_seconds': {'type': 'integer', 'description': 'Unix epoch seconds.'}}}
get_m365_person
Get Microsoft 365 Person
Get detailed information about a specific person in your Microsoft 365 directory by their user ID or email address. Use 'me' to get the currently authenticated user's profile.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': "User ID (GUID), email address (UPN), or 'me' for the authenticated user, e.g. 'sarah@contoso.com', 'a1b2c3d4-...', or 'me'"}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'upn': {'type': 'string'}, 'name': {'type': 'string'}, 'email': {'type': 'string'}, 'title': {'type': 'string'}, 'mobile': {'type': 'string'}, 'office': {'type': 'string'}, 'phones': {'type': 'array', 'items': {'type': 'string'}}, 'department': {'type': 'string'}}}
get_reminder_folders
Get Reminder Folders
Lists the lists (folders) in Apple Reminders (Reminders.app) on this Mac. Every answer carries as_of (when the list snapshot was read) and cache_age_seconds; if cache_age_seconds is above 0 the snapshot is that many seconds old and a list created since then may be missing — call again to force a re-read. For Microsoft To Do use todo_get_folders instead.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string', 'description': 'Present only when the snapshot is not fresh: says how old it is and what may be missing.'}, 'as_of': {'type': 'string', 'description': 'ISO 8601 UTC instant when this list snapshot was read from EventKit (not when iCloud last synced).'}, 'count': {'type': 'integer'}, 'lists': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'color': {'type': 'string'}}}}, 'cache_age_seconds': {'type': 'integer', 'description': 'Age of the snapshot. 0 means it was read fresh for this call.'}}}
get_weather
Get Weather
Gets the current weather and a short daily forecast for a location. Pass a city name ('London', 'San Francisco', 'Tokyo,JP') or 'lat,lon' coordinates. Uses Open-Meteo — no API key required. Location must be provided (there is no device-location access).
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['location'], 'properties': {'days': {'type': 'integer', 'description': 'Number of forecast days, 1-7 (default 3)'}, 'location': {'type': 'string', 'description': "City name (e.g. 'London', 'Buenos Aires', 'Tokyo,JP') or 'lat,lon' coordinates (e.g. '40.71,-74.01')"}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
list_accounts
List Accounts
Lists Mail.app email accounts WITH each account's email addresses, server_name and type. type is whatever Mail reports — imap | pop | iCloud | smtp | unknown — and Mail's scripting dictionary has NO Exchange value, so Exchange (EWS) accounts always come back as unknown, flagged with type_undetermined: true and a type_note; for those read the mailbox through the m365_* tools (or outlook_diagnose) instead of routing by type. Slower — queries Mail directly. For just the account NAMES (to pass to list_emails(account=...)), prefer list_email_accounts: it's faster (cached, no Mail lock).
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['count', 'accounts'], 'properties': {'note': {'type': 'string', 'description': "Present when some account's type could not be determined: how many, and what to do."}, 'count': {'type': 'integer'}, 'accounts': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'type': {'type': 'string', 'description': "What Mail reports: imap | pop | iCloud | smtp | unknown. Mail has no Exchange value, so an Exchange (EWS) account reports unknown — that is Mail's answer, not a failed lookup."}, 'emails': {'type': 'array', 'items': {'type': 'string'}}, 'type_note': {'type': 'string', 'description': 'Present when type_undetermined: why the type is unknowable and which tools to use for that mailbox.'}, 'server_name': {'type': 'string', 'description': 'Host Mail connects to. The evidence for an untyped account (an Exchange host looks like outlook.office365.com or an on-prem EWS host).'}, 'type_undetermined': {'type': 'boolean', 'description': 'true when Mail did not name the type (typically Exchange). Branch on this instead of matching the string "unknown".'}}}}}}
list_calendar_events
List Calendar Events
Lists events from the Mac's Calendar app (Calendar.app, local/iCloud calendars) in a date range, or reads ONE event in full via event_id. List entries preview notes (200 chars, notes_truncated flag) and cap attendees; pass event_id to get the complete notes and full roster. Defaults to today + 7 days. For a Microsoft 365 calendar use m365_list_events instead.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max number of events to return (most recent first within the range). Optional; defaults to all in range.'}, 'calendar': {'type': 'string', 'description': 'Filter by calendar name — partial, case-insensitive (optional). To pick one of several same-titled calendars, qualify it as "Account/Calendar" (e.g. "Exchange/Calendario") using the source from list_calendar_names, or pass calendar_id.'}, 'end_date': {'type': 'string', 'description': 'ISO 8601 date (YYYY-MM-DD). Defaults to start_date + 7 days.'}, 'event_id': {'type': 'string', 'description': 'Read exactly ONE event by its id (from a previous list — for a recurring event, the per-occurrence id) with FULL notes and the complete attendee roster — required before editing notes of an event whose list entry says notes_truncated. When set, all other filters are ignored.'}, 'start_date': {'type': 'string', 'description': 'ISO 8601 date (YYYY-MM-DD). Defaults to today.'}, 'calendar_id': {'type': 'string', 'description': 'Filter by a single calendar UUID from list_calendar_names (optional).'}, 'calendar_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Filter by multiple calendar UUIDs (optional).'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'events': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string', 'description': "For a recurring event, this is a per-OCCURRENCE id (distinct for each of the 3 'Gym' rows below, for example) — pass it back to update_calendar_event/delete_calendar_event to target that exact occurrence, not just the series. Stable across calls; ignore its internal shape."}, 'end': {'type': 'string'}, 'start': {'type': 'string'}, 'title': {'type': 'string'}, 'all_day': {'type': 'boolean'}, 'calendar': {'type': 'string'}, 'calendar_id': {'type': 'string'}}}}, 'end_date': {'type': 'string'}, 'start_date': {'type': 'string'}}}
list_calendar_names
List Calendar Names
Lists the calendars in the Mac's Calendar app (Calendar.app, local/iCloud). For Microsoft 365 calendars use the m365 calendar tools instead.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'calendars': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'type': {'type': 'string', 'description': 'caldav | exchange | subscription | birthday | local'}, 'color': {'type': 'string'}, 'title': {'type': 'string'}, 'source': {'type': 'string', 'description': 'Owning account (iCloud, Exchange, an email address, On My Mac). Two calendars can share a title across accounts — use this (or id) to disambiguate.'}}}}}}
list_contacts
List Contacts
Lists contacts from the macOS Contacts app. Optionally filter by group.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max contacts to return (default 100)'}, 'group_name': {'type': 'string', 'description': 'Filter by group name (optional)'}}}
出力スキーマ
{'type': 'object', 'required': ['count', 'contacts'], 'properties': {'count': {'type': 'integer'}, 'contacts': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'full_name'], 'properties': {'id': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'object', 'properties': {'label': {'type': 'string'}, 'value': {'type': 'string'}}}}, 'phones': {'type': 'array', 'items': {'type': 'object', 'properties': {'label': {'type': 'string'}, 'value': {'type': 'string'}}}}, 'company': {'type': 'string'}, 'birthday': {'type': 'string'}, 'addresses': {'type': 'array', 'items': {'type': 'object', 'properties': {'zip': {'type': 'string'}, 'city': {'type': 'string'}, 'label': {'type': 'string'}, 'state': {'type': 'string'}, 'street': {'type': 'string'}, 'country': {'type': 'string'}}}}, 'full_name': {'type': 'string'}, 'last_name': {'type': 'string'}, 'first_name': {'type': 'string'}}}}}}
list_displays
List Displays
Lists connected displays with bounds (global space, top-left origin, points), backing scale_factor, and which is main. display_id is the CGDirectDisplayID — the SAME value list_windows reports for each window's display_id, so you can map a window to its display. Stable for the session. No permission required.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
list_email_accounts
List Email Accounts
Lists all Mail.app account NAMES (fast — cached, no Mail lock). This is the preferred way to get account names: call it first to discover them, then use list_emails(account=name) to fetch messages from a specific account. If you also need each account's email addresses or type (imap/pop/iCloud), use list_accounts instead.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'tip': {'type': 'string'}, 'count': {'type': 'integer', 'description': 'Number of accounts.'}, 'accounts': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}}}, 'description': 'Mail.app accounts, by name.'}}}
list_email_folders
List Email Folders
Lists the full folder (mailbox) tree for Apple Mail (Mail.app) accounts, including nested subfolders. Use this to discover the exact folder names that move_email(target_mailbox=...) and list_emails(mailbox=...) expect. Outlook.com, Exchange, Gmail, iCloud and IMAP accounts added to Mail.app are all included. For a Graph-only Microsoft 365 mailbox not added to Mail.app, use m365_list_emails instead. Pass account=<name> (from list_email_accounts) to enumerate one account fully; without it, every account is walked which can be slow on macOS 15+. Message counts are off by default (slow on IMAP) — pass include_counts=true to add unread/total per folder (from Mail's local index when a named account resolves from disk, or Mail.app's own live count otherwise — see unread_count_note in the response either way).
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'account': {'type': 'string', 'description': 'Mail.app account whose folder tree to list (from list_email_accounts). Defaults to every account.'}, 'include_counts': {'type': 'boolean', 'default': 'false', 'description': 'Include the message count of each folder. Slower, because each folder has to be counted.'}}}
出力スキーマ
{'type': 'object', 'properties': {'accounts': {'type': 'array', 'items': {'type': 'object', 'properties': {'account': {'type': 'string'}, 'folders': {'type': 'array'}}}}, 'truncated': {'type': 'boolean'}, 'folder_count': {'type': 'integer'}, 'next_actions': {'type': 'array'}, 'account_count': {'type': 'integer'}}}
list_emails
List Emails
Use this when the user wants to see or triage their inbox on this Mac (Apple Mail — any account added to Mail.app: iCloud, Gmail, IMAP, Exchange). Lists email headers (subject, sender, date, unread); call read_email(message_id) for the full body. For a Microsoft 365 mailbox NOT added to Mail.app, use m365_list_emails. IMPORTANT: on machines with 2+ accounts, call with account=<name> (from list_email_accounts). Without it, and when the fast index can't answer, list_emails returns the account list instead of scanning all of them — scanning every account in one call has no time limit and can block Mail for other requests too (#2268). Exactly 1 account is unaffected. Supports pagination: use offset to page through results (e.g. offset=20 for page 2 with limit=20). The limit parameter is capped at 50 per call (default 20); to read more, page with offset rather than requesting a larger limit.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': '20', 'maximum': 50, 'minimum': 0, 'description': 'How many messages to return, 0-50 (0 returns none). Defaults to 20.'}, 'offset': {'type': 'integer', 'default': '0', 'minimum': 0, 'description': 'How many messages to skip before returning, for paging through a folder. Defaults to 0.'}, 'account': {'type': 'string', 'description': 'Mail.app account name (from list_email_accounts). On a Mac with 2+ accounts, passing it is much faster than letting the walk cover all of them.'}, 'mailbox': {'type': 'string', 'description': 'Folder to list, by name (see list_email_folders). Defaults to the Inbox.'}, 'unread_only': {'type': 'boolean', 'default': 'false', 'description': 'Return only unread messages. Defaults to false.'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'offset': {'type': 'integer'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'date': {'type': 'string'}, 'from': {'type': 'string'}, 'unread': {'type': 'boolean'}, 'account': {'type': 'string'}, 'subject': {'type': 'string'}}}}, 'next_actions': {'type': 'array'}}}
list_m365_people_insights
List Microsoft 365 People Insights
List the people most relevant to you in Microsoft 365 — based on your communication patterns, collaboration history, and org chart. Useful for meeting prep and contact enrichment.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Number of people to return (default 20, max 50)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'people': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'email': {'type': 'string'}, 'title': {'type': 'string'}, 'department': {'type': 'string'}}}}}}
list_message_chats
List Message Chats
Lists recent iMessage / Messages.app conversations (chat id, name, service). Start here for Messages — the chat id it returns is what read_messages / search_messages / send_message need.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max conversations (default 30)'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'chats': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'service': {'type': 'string'}, 'chat_type': {'type': 'string'}, 'last_message': {'type': 'string'}, 'last_message_at': {'type': 'string'}}}}, 'count': {'type': 'integer'}}}
list_missing_permissions
List Missing Permissions
Returns the macOS privacy (TCC) permissions Local MCP needs that are NOT granted yet, each with a one-click `open_url` that opens the exact System Settings → Privacy & Security pane. Read-only and passive (never prompts). Use it during setup or before a workflow to tell the user precisely which "Allow" clicks remain (Calendar, Contacts, Reminders, Automation for Mail/Messages/Notes/OmniFocus, Full Disk Access, Screen Recording, Accessibility) instead of failing mid-task. An installed app that is closed can't be checked and is listed under `unverified`. `all_granted: true` means nothing is left to do.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'granted': {'type': 'array', 'items': {'type': 'string'}}, 'missing': {'type': 'array', 'items': {'type': 'object'}}, 'summary': {'type': 'string'}, 'unverified': {'type': 'array', 'items': {'type': 'object'}}, 'all_granted': {'type': 'boolean'}}}
list_notes
List Notes
Lists notes from Apple Notes app. Optionally filter by folder. Paginated: `limit` is capped at 500 per call, so page with `offset` (offset=500 returns notes 501-1000) instead of asking for a bigger limit. The response carries `total` (how many notes match in all) and `has_more` (whether anything is left past this page), so you never have to guess whether you got everything — page until `has_more` is false, which is exact even when `total_is_estimated` says the count is only a lower bound. To read a WHOLE library, pass order="id" — see the order parameter.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': '50', 'description': 'Notes per page (default 50, capped at 500). To get more, page with offset.'}, 'order': {'type': 'string', 'default': 'modified', 'description': 'order: "modified" (default) sorts newest-modified first — what you want to SHOW someone, but NOT safe for paging: modification date changes, so a note edited between two calls jumps to the front and another note is pushed past your cursor and never returned. "id" sorts by the note\'s immutable store id — stable, never renumbered, new notes append at the end — so use order="id" to walk an entire library page by page: edits and insertions mid-crawl are safe with it. One case it cannot cover, because pages are addressed by offset: if a note is DELETED mid-crawl, every note after the hole shifts one slot back and the note that was on the page boundary is skipped, silently. If completeness matters, re-run the crawl and reconcile against total, or crawl while nothing is deleting notes.'}, 'folder': {'type': 'string', 'description': 'Exact name of the Notes folder to list. Leave it out to list every folder, which excludes trashed notes; naming a folder scopes to it, and naming the trash folder lists what is in the trash.'}, 'offset': {'type': 'integer', 'default': '0', 'minimum': 0, 'description': 'How many notes to skip (default 0). offset=500 with limit=500 returns notes 501-1000. An offset past the end returns an empty page with has_more=false, not an error.'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer', 'description': 'Notes in THIS page'}, 'notes': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'modified': {'type': 'string'}}}}, 'order': {'type': 'string', 'description': 'The ordering actually applied (modified | id)'}, 'total': {'type': 'integer', 'description': 'Notes matching in total, ignoring limit/offset. A LOWER BOUND, not the exact figure, when total_is_estimated is true'}, 'offset': {'type': 'integer', 'description': 'Where this page started'}, 'has_more': {'type': 'boolean', 'description': 'True when notes remain past this page — call again with offset = offset + count'}, 'next_actions': {'type': 'array'}, 'total_is_estimated': {'type': 'boolean', 'description': 'True when the exact count could not be taken (the unbounded COUNT failed, or the JXA fallback answered) — total is then only a lower bound. has_more stays exact either way: page until it is false, never until count reaches total'}}}
list_omnifocus_folders
List OmniFocus Folders
Lists folders in OmniFocus. Folders group related projects (e.g. "Work", "Personal"). Use list_omnifocus_projects to see the projects inside them.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': '100', 'description': 'Max folders to return (default 100).'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'folders': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'status': {'type': 'string'}, 'project_count': {'type': 'integer'}}}}}}
list_omnifocus_projects
List OmniFocus Projects
Lists projects in OmniFocus. Start here for OmniFocus (alongside list_omnifocus_folders) — the project name it returns feeds list_omnifocus_tasks / create_omnifocus_task / search_omnifocus_tasks.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': '100', 'description': 'Max projects to return (default 100).'}, 'include_completed': {'type': 'boolean', 'default': 'false', 'description': 'Include completed/dropped projects (default excludes them).'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'projects': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'note': {'type': 'string'}, 'status': {'type': 'string'}, 'due_date': {'type': 'string'}, 'task_count': {'type': 'integer'}}}}}}
list_omnifocus_tags
List OmniFocus Tags
Lists all tags defined in OmniFocus.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'tags': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'task_count': {'type': 'integer'}}}}, 'count': {'type': 'integer'}}}
list_omnifocus_tasks
List OmniFocus Tasks
Lists tasks from OmniFocus. Filter by project, tag, inbox, due today, or flagged status.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'tag': {'type': 'string', 'description': 'Only tasks carrying this tag.'}, 'inbox': {'type': 'boolean', 'default': 'false', 'description': 'Only unfiled inbox tasks.'}, 'limit': {'type': 'integer', 'default': '50', 'description': 'Max tasks to return (default 50).'}, 'flagged': {'type': 'boolean', 'default': 'false', 'description': 'Only flagged tasks.'}, 'project': {'type': 'string', 'description': 'Only tasks in this project (name, case-insensitive).'}, 'due_today': {'type': 'boolean', 'default': 'false', 'description': 'Only tasks due today or overdue.'}, 'include_completed': {'type': 'boolean', 'default': 'false', 'description': 'Include completed tasks (default excludes them).'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'tasks': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'note': {'type': 'string'}, 'tags': {'type': 'array', 'items': {'type': 'string'}}, 'flagged': {'type': 'boolean'}, 'project': {'type': 'string'}, 'due_date': {'type': 'string'}, 'completed': {'type': 'boolean'}, 'defer_date': {'type': 'string'}}}}}}
list_referral_candidates
List Referral Candidates
Returns the user's emailable contacts plus an invite template, for recommending LMCP to a colleague. A user would invoke this when they want to invite or recommend someone. Returns a list of candidate contacts and a message template; create_referral_invites then generates each chosen person's unique invite link.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max contacts to return (default 60)'}}}
出力スキーマ
{'type': 'object', 'properties': {'lang': {'type': 'string'}, 'count': {'type': 'integer'}, 'notes': {'type': 'string'}, 'candidates': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'email': {'type': 'string'}}}}, 'template_body': {'type': 'string'}, 'template_subject': {'type': 'string'}}}
list_reminders
List Reminders
Lists reminders from Apple Reminders (Reminders.app) on this Mac. Optionally filter by completion status or list name. For Microsoft To Do use todo_list_tasks instead.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max number of reminders to return (earliest due first). Optional; defaults to all.'}, 'completed': {'type': 'boolean', 'description': "false or omitted = incomplete (the default). true = completed. There is no 'both': ask twice if you need them."}, 'list_name': {'type': 'string', 'description': 'Filter by reminder list name (optional)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer', 'description': 'Number returned in this response.'}, 'total': {'type': 'integer', 'description': 'Total matching before the limit.'}, 'reminders': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'list': {'type': 'string'}, 'notes': {'type': 'string'}, 'title': {'type': 'string'}, 'due_date': {'type': 'string'}, 'priority': {'type': 'string', 'description': 'none | low | medium | high (omitted when none)'}, 'completed': {'type': 'boolean'}}}}}}
list_windows
List Windows
Lists on-screen windows of any app with window_id, owning app bundle id + name, title, bounds (global space, top-left, points), display_id (the CGDirectDisplayID — matches list_displays, so you can look up which display a window is on), layer (0 = normal app window; non-zero = panel/overlay/menu), and is_focused. Window TITLES require Screen Recording permission — without it this returns an explicit permission_required error rather than a title-less result. Optional app_bundle_id filter — note that Electron-style apps often own their windows from a HELPER process with a different bundle id, so a filter can come back empty while the app is plainly on screen. on_screen_only DEFAULTS TO TRUE and excludes minimized, hidden and other-Space windows; pass false to see them. include_overlays DEFAULTS TO FALSE and excludes non-zero-layer windows (Notification Center, widgets, menus); pass true to include them — use layer in the result to tell them apart from normal windows. include_minimized_state DEFAULTS TO FALSE (an extra Accessibility lookup per app, so it's opt-in); pass true to add `minimized` (true/false) to each window AND, when on_screen_only is true (the default), also bring back the minimized windows that filter would otherwise drop — WITHOUT Accessibility granted `minimized` is `null` (unknown) and no minimized windows are added back, never a guessed false, so you can find/capture a minimized window without bringing it forward first. When the result is empty this tool returns a `note` explaining which filter emptied it and what to pass instead — read it instead of concluding the app has no windows. window_id is stable within the session for later targeting.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'app_bundle_id': {'type': 'string', 'description': 'Only return windows owned by this app bundle id.'}, 'on_screen_only': {'type': 'boolean', 'description': 'Only on-screen windows (default true).'}, 'include_overlays': {'type': 'boolean', 'description': 'Include non-zero-layer windows — Notification Center, desktop widgets, menus (default false).'}, 'include_minimized_state': {'type': 'boolean', 'description': 'Add `minimized` (true/false) to each window via an Accessibility lookup; null without Accessibility granted (default false).'}}}
lmcp_doctor
LMCP Doctor
Checks everything LMCP depends on on this Mac — the AI apps connected to it, macOS permissions, each integration, and whether an LMCP update is waiting — and fixes what it safely can: it adds LMCP to installed AI apps that are missing it and repairs entries whose command no longer exists. Read-only PREVIEW unless confirm:true. Anything it can't fix (a permission, restarting an app, a config it can't edit safely, installing an update) comes back in `needs_you` with the exact step. Use it when LMCP "doesn't work" in some app.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to apply the fixes. Without it, returns what would be fixed and what needs the user.'}}}
出力スキーマ
{'type': 'object', 'required': ['mode', 'fixed', 'would_fix', 'failed', 'needs_you', 'summary'], 'properties': {'mode': {'type': 'string', 'description': 'preview | applied'}, 'fixed': {'type': 'array', 'items': {'type': 'object', 'properties': {'how': {'type': 'string'}, 'what': {'type': 'string'}}}}, 'failed': {'type': 'array', 'items': {'type': 'object', 'properties': {'how': {'type': 'string'}, 'what': {'type': 'string'}}}}, 'summary': {'type': 'string'}, 'ok_count': {'type': 'integer'}, 'needs_you': {'type': 'array', 'items': {'type': 'object', 'properties': {'how': {'type': 'string'}, 'what': {'type': 'string'}}}}, 'would_fix': {'type': 'array', 'items': {'type': 'object', 'properties': {'how': {'type': 'string'}, 'what': {'type': 'string'}}}}}}
lmcp_install_upgrade
LMCP Install Upgrade
Checks for and installs a newer LMCP version — a self-upgrade of the LMCP app itself (not editing any of your data). Installing downloads the new version and RESTARTS LMCP (the AI client briefly reconnects), so it requires confirm=true. Pass check_only=true to only report whether a newer version is available, with no download or restart.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to actually install (which restarts LMCP). Without it, returns availability + a preview.'}, 'check_only': {'type': 'boolean', 'description': 'If true, only report availability — no download, no install, no restart.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
lmcp_state
LMCP State
Returns a structured snapshot of the LMCP environment: server/tray/teams-proxy versions, detected AI client, cloud relay state, TCC permission states (Calendar/Reminders/Contacts), and a compact summary of which services (Mail/Calendar/Contacts/Teams/OneDrive/Reminders/Notes) are reachable. Fast (<500ms), passive — never prompts the user, never opens app windows, never touches the network. Call this when you need to verify the environment is healthy before attempting a tool, or to understand what's installed and accessible. If `services.scan_pending` is true, the background service scan hasn't finished yet (just after startup) and the per-service running/accounts values are placeholders — do NOT treat them as a real outage; just call the tool you need. Otherwise `services.scanned_seconds_ago` tells you how many seconds ago that scan ran (cadence ~60s): the per-service values are a snapshot, NOT a live probe. A `false`/`0`/`not available` for a service is advisory only — it can be stale (e.g. the user connected WhatsApp or opened Mail seconds ago) — so never use this tool as a preflight gate to skip or cancel a task; the actual tool call is the source of truth, just attempt it. For reporting failures, use `report_problem` instead — it captures this same snapshot plus logs and submits to the team.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'tcc': {'type': 'object', 'properties': {'calendar': {'type': 'string'}, 'contacts': {'type': 'string'}, 'reminders': {'type': 'string'}, 'mail_automation': {'type': 'string'}, 'notes_automation': {'type': 'string'}, 'messages_automation': {'type': 'string'}, 'omnifocus_automation': {'type': 'string', 'description': 'Each <app>_automation is present only if the app is installed; <app>_last_known and <app>_note may accompany it.'}, 'mail_automation_last_known': {'type': 'string', 'description': 'Present only when mail_automation is notRunning: "authorized" if the grant was confirmed before. Not a live verdict.'}}, 'description': 'TCC permission states. Automation keys (<app>_automation) are one of notDetermined | authorized | denied | notRunning.'}, 'arch': {'type': 'string'}, 'update': {'type': 'object', 'properties': {'available': {'type': 'boolean'}, 'disk_version': {'type': 'string'}, 'needs_restart': {'type': 'boolean'}, 'latest_version': {'type': 'string'}, 'process_version': {'type': 'string'}, 'versions_behind': {'type': 'integer'}}}, 'version': {'type': 'string', 'description': 'Serving (running) server version.'}, 'built_at': {'type': 'string', 'description': "UTC build timestamp (F-041). 'unknown' if unstamped."}, 'services': {'type': 'object', 'description': 'Per-domain reachability summary (mail, calendar, contacts, teams, onedrive, slack, …); shape varies by domain. May include `scan_pending: true` right after startup, meaning the per-service running/accounts values are placeholders and not yet authoritative. Once scanned, `scanned_seconds_ago` gives the age (seconds) of that background snapshot and `freshness` restates that a false/0/not-available is advisory, not a live check — never gate a task on it.'}, 'ai_client': {'type': 'string'}, 'build_sha': {'type': 'string', 'description': "Git short SHA of the build (F-041). 'unknown' if unstamped."}, 'machine_id': {'type': 'string'}, 'os_version': {'type': 'string'}, 'web_agents': {'type': 'object', 'description': 'Web (cloud-relay) clients, counts only: `count` connected (absent when unknown), `relayed_calls_since_launch`, `last_remote_call` {at, tool, ok, ago_s}.'}, 'tray_version': {'type': 'string'}, 'last_activity': {'type': 'object', 'properties': {'at': {'type': 'string'}, 'tool': {'type': 'string'}, 'ago_s': {'type': 'integer'}, 'source': {'type': 'string'}, 'last_remote': {'type': 'object', 'description': 'Last call relayed from a web client (source cloud), when there was one.'}}}, 'skill_capture': {'type': 'object', 'properties': {'ring_size': {'type': 'integer'}, 'would_fire_signatures': {'type': 'integer'}}, 'description': 'Dark-launch counters for repeated-workflow detection (user-generated skills, PR-1). would_fire_signatures = how many times a save-this-workflow nudge WOULD have fired; ring_size = entries in the recent-calls ring. PRIVACY: the ring is IN-MEMORY ONLY — never written to disk, never transmitted, cleared on restart — and argument values are PII-scrubbed on entry, so it holds the SHAPE of a workflow, not its content. No UI acts on it yet; it exists to tune thresholds. Opt out with the skill_capture_enabled config flag.'}, 'license_status': {'type': 'string', 'description': 'trial | active | expired'}, 'cloud_token_set': {'type': 'boolean'}, 'tunnel_connected': {'type': 'boolean'}, 'cloud_data_enabled': {'type': 'boolean'}}}
lmcp_upgrade_diagnostics
LMCP Upgrade Diagnostics
Returns LMCP's self-upgrade health (the LMCP app upgrading itself, not editing your data): current version, the last N app-version upgrade attempts with any errors, whether the upgrade cache dir is writable, and any stale LMCP binaries at alternate paths. Call this when the app's auto-upgrade seems stuck, or to explain why a user is on an old version.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max recent attempts to return (default 10)'}}}
出力スキーマ
{'type': 'object', 'required': ['current_version', 'running_from', 'cache_dir', 'cache_writable', 'last_success_at', 'consecutive_failures', 'binaries_found', 'recent_attempts', 'recent_attempts_count'], 'properties': {'cache_dir': {'type': 'string'}, 'running_from': {'type': 'string', 'description': 'Real path of the currently running binary.'}, 'binaries_found': {'type': 'array', 'items': {'type': 'object', 'properties': {'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'modified': {'type': 'string'}}}, 'description': 'LMCP binaries found at known alternate paths.'}, 'cache_writable': {'type': 'boolean', 'description': 'Whether the update cache dir is writable (#1 silent-failure cause).'}, 'current_version': {'type': 'string'}, 'last_success_at': {'type': 'string', 'description': 'ISO 8601 timestamp of last successful update, empty if none.'}, 'recent_attempts': {'type': 'array', 'items': {'type': 'object', 'properties': {'to': {'type': 'string'}, 'from': {'type': 'string'}, 'note': {'type': 'string'}, 'error': {'type': 'string'}, 'phase': {'type': 'string'}, 'success': {'type': 'boolean'}, 'timestamp': {'type': 'string'}, 'duration_ms': {'type': 'integer'}}}, 'description': 'Recent update attempts, newest first.'}, 'consecutive_failures': {'type': 'integer'}, 'recent_attempts_count': {'type': 'integer'}}}
m365_create_event
Microsoft 365 Create Event
Create a calendar event in your Microsoft 365 / Outlook calendar.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['subject', 'start', 'end'], 'properties': {'end': {'type': 'string', 'description': "End time in ISO 8601, e.g. '2026-05-20T11:00:00'"}, 'body': {'type': 'string', 'description': 'Event description (optional)'}, 'start': {'type': 'string', 'description': "Start time in ISO 8601, e.g. '2026-05-20T10:00:00'"}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create the event'}, 'subject': {'type': 'string', 'description': 'Event title'}, 'calendar': {'type': 'string', 'description': 'Calendar name to create the event in — partial, case-insensitive match (optional). Omit to use the primary calendar.'}, 'location': {'type': 'string', 'description': 'Location (optional)'}, 'timezone': {'type': 'string', 'description': "IANA timezone, e.g. 'America/New_York' (default: UTC)"}, 'attendees': {'type': 'string', 'description': 'Comma-separated email addresses to invite (optional)'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
m365_delete_event
Microsoft 365 Delete Event
Delete a calendar event from your Microsoft 365 / Outlook calendar by its ID.
破壊的操作あり 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['id', 'confirm'], 'properties': {'id': {'type': 'string', 'description': 'Event ID from m365_list_events'}, 'confirm': {'type': 'boolean', 'description': 'Set to true to confirm deletion (required)'}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
m365_get_contact
Microsoft 365 Get Contact
Get full details of a specific Microsoft 365 contact by ID. Get the ID from m365_list_contacts or m365_search_contacts.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'Contact ID from m365_list_contacts or m365_search_contacts'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'notes': {'type': 'string'}, 'title': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'string'}}, 'mobile': {'type': 'string'}, 'phones': {'type': 'array', 'items': {'type': 'string'}}, 'company': {'type': 'string'}, 'surname': {'type': 'string'}, 'given_name': {'type': 'string'}, 'home_address': {'type': 'string'}, 'business_address': {'type': 'string'}}}
m365_list_contacts
Microsoft 365 List Contacts
List contacts from your Microsoft 365 / Outlook address book.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max contacts to return (default 50, max 100)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'contacts': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'title': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'string'}}, 'mobile': {'type': 'string'}, 'phones': {'type': 'array', 'items': {'type': 'string'}}, 'company': {'type': 'string'}, 'surname': {'type': 'string'}, 'given_name': {'type': 'string'}}}}}}
m365_list_emails
Microsoft 365 List Emails
Use this when the user wants their Microsoft 365 / Outlook / Exchange inbox via the cloud — requires a connected M365 account (connect_m365_account). Returns subject, sender, date, and preview. For mail already in the Mac's Mail.app (including an Exchange account added there), use list_emails.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Number of emails to return (default 20, max 50)'}, 'folder': {'type': 'string', 'description': 'Folder name: inbox (default), sentitems, drafts, deleteditems'}, 'unread_only': {'type': 'boolean', 'description': 'If true, return only unread emails'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'emails': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'from': {'type': 'string'}, 'is_read': {'type': 'boolean'}, 'preview': {'type': 'string'}, 'subject': {'type': 'string'}, 'received': {'type': 'string'}, 'from_address': {'type': 'string'}}}}}}
m365_list_events
Microsoft 365 List Events
List upcoming calendar events from your Microsoft 365 / Outlook calendar.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'days': {'type': 'integer', 'description': 'Number of days ahead to look (default 7, max 30)'}, 'limit': {'type': 'integer', 'description': 'Max events to return (default 20, max 50)'}, 'calendar': {'type': 'string', 'description': 'Calendar name to filter by — partial, case-insensitive match (optional). Omit to use the primary calendar.'}}}
出力スキーマ
{'type': 'object', 'properties': {'days': {'type': 'integer'}, 'count': {'type': 'integer'}, 'events': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'end': {'type': 'string'}, 'start': {'type': 'string'}, 'preview': {'type': 'string'}, 'subject': {'type': 'string'}, 'location': {'type': 'string'}, 'organizer': {'type': 'string'}}}}, 'calendar': {'type': 'string'}}}
m365_read_email
Microsoft 365 Read Email
Use this when the user wants the full content of a Microsoft 365 email (message ID from m365_list_emails/m365_search_emails). Requires a connected M365 account. For a message found via list_emails/search_emails (Apple Mail), use read_email.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The email message ID from m365_list_emails or m365_search_emails'}}}
出力スキーマ
{'type': 'object', 'properties': {'cc': {'type': 'array', 'items': {'type': 'string'}}, 'id': {'type': 'string'}, 'to': {'type': 'array', 'items': {'type': 'string'}}, 'body': {'type': 'string'}, 'date': {'type': 'string'}, 'from': {'type': 'string'}, 'is_read': {'type': 'boolean'}, 'subject': {'type': 'string'}, 'from_address': {'type': 'string'}}}
m365_reply_email
Microsoft 365 Reply Email
Use this when the user wants to reply to a Microsoft 365 email (message ID from m365_list_emails). Requires a connected M365 account. Shows a preview first — set confirm=true to actually send. For replying to a message found in Apple Mail, use reply_email.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['id', 'message'], 'properties': {'id': {'type': 'string', 'description': 'Message ID to reply to (from m365_list_emails or m365_read_email)'}, 'confirm': {'type': 'boolean', 'description': 'Set to true to actually send (default: shows preview only)'}, 'message': {'type': 'string', 'description': 'Your reply text'}, 'reply_all': {'type': 'boolean', 'description': 'If true, reply to all recipients (default: false)'}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
m365_search_contacts
Microsoft 365 Search Contacts
Search contacts in your Microsoft 365 address book by name, email, or company.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': 'Search term — name, email, or company'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'contacts': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'title': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'string'}}, 'mobile': {'type': 'string'}, 'phones': {'type': 'array', 'items': {'type': 'string'}}, 'company': {'type': 'string'}, 'surname': {'type': 'string'}, 'given_name': {'type': 'string'}}}}}}
m365_search_emails
Microsoft 365 Search Emails
Use this when the user wants to find emails in their Microsoft 365 / Outlook mailbox via the cloud — requires a connected M365 account. By default searches sender, subject, AND body (Microsoft Graph's own $search default). Pass scope="metadata" to search only sender/subject (faster, no body scan), or scope="body" to search only the message body. For accounts added to the Mac's Mail.app, use search_emails.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 20, max 50)'}, 'query': {'type': 'string', 'description': "Search query, e.g. 'budget Q2', 'from:alice@contoso.com', 'subject:invoice'"}, 'scope': {'enum': ['metadata', 'body', 'all'], 'type': 'string', 'description': '"all" (default — sender+subject+body, today\'s behavior), "metadata" (sender+subject only), or "body" (body only).'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'from': {'type': 'string'}, 'is_read': {'type': 'boolean'}, 'preview': {'type': 'string'}, 'subject': {'type': 'string'}, 'received': {'type': 'string'}, 'from_address': {'type': 'string'}}}}, 'search_scope': {'type': 'string'}, 'search_backend': {'type': 'string'}, 'search_coverage': {'type': 'string'}}}
m365_send_email
Microsoft 365 Send Email
Use this when the user wants to send from their Microsoft 365 / Outlook account via the cloud — requires a connected M365 account. Shows a preview first — set confirm=true to actually send. For sending from an account configured in the Mac's Mail.app, use send_email.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['to', 'subject', 'body'], 'properties': {'cc': {'type': 'string', 'description': 'CC recipients (optional, comma-separated)'}, 'to': {'type': 'string', 'description': 'Recipient email address. For multiple, separate with commas.'}, 'body': {'type': 'string', 'description': 'Email body (plain text)'}, 'confirm': {'type': 'boolean', 'description': 'Set to true to actually send (default: shows preview only)'}, 'subject': {'type': 'string', 'description': 'Email subject'}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
media_probe
Media Probe
Reports duration_ms, width, height, fps, whether it has audio, and file size for a video/audio file. Call it before editing to reason about the footage (compute trim ranges, pick a reframe crop). No permission required.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Path to the media file.'}}}
move_email
Move Email
Moves an email to another mailbox (nested target folders are found by name). Pass account= (returned by list_emails/search_emails) so the message lookup targets one account instead of scanning all of them — without it, multi-account Macs are slow and can time out on bulk moves. If you know the folder the message is in, also pass mailbox= (the `mailbox` field from the listing) so the lookup searches it first.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['message_id', 'target_mailbox'], 'properties': {'account': {'type': 'string', 'description': 'Mail.app account the message lives in (returned alongside the id). Pass it so the message is found in the right account.'}, 'confirm': {'type': 'boolean', 'default': 'false', 'description': 'Set to true to actually move the message. Defaults to false.'}, 'mailbox': {'type': 'string', 'description': 'Folder the message is in TODAY, before the move. Passing it skips searching the other folders.'}, 'message_id': {'type': 'string', 'description': 'The message id returned by list_emails or search_emails. Accepts the bare id or the <angle-bracketed> form.'}, 'target_mailbox': {'type': 'string', 'description': 'Destination folder, by name (see list_email_folders). Nested folders are found by their own name, not by a path.'}}}
出力スキーマ
{'type': 'object', 'properties': {'to': {'type': 'string'}, 'moved': {'type': 'boolean'}, 'warning': {'type': 'string'}, 'message_id': {'type': 'string'}}}
nordvpn_diagnose
NordVPN Diagnose
Run a diagnostic check on NordVPN: installation, login state, connection status, kill switch, and supported protocols. Useful for troubleshooting.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['installed'], 'properties': {'report': {'type': 'string', 'description': 'Full formatted text report'}, 'account': {'type': 'string'}, 'running': {'type': 'boolean', 'description': 'True if the NordVPN app is running'}, 'version': {'type': 'string'}, 'connected': {'type': 'boolean', 'description': 'True if the VPN is connected'}, 'installed': {'type': 'boolean', 'description': 'True if NordVPN is installed'}, 'logged_in': {'type': 'boolean', 'description': 'True if a NordVPN account is logged in'}, 'protocols': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Supported VPN protocols'}, 'kill_switch': {'type': 'boolean', 'description': 'True if the kill switch is enabled'}, 'auto_connect': {'type': 'boolean', 'description': 'True if auto-connect / connect on demand is on'}, 'subscription': {'type': 'string'}, 'last_location': {'type': 'string'}}}
nordvpn_servers
NordVPN Servers
Get recommended NordVPN servers by country or specialty. Uses NordVPN public API (no account needed). Returns server name, hostname, country, city, load %, and supported technologies.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'properties': {'type': {'type': 'string', 'description': "Server type filter: 'standard', 'p2p', 'double_vpn', 'onion', 'dedicated_ip'. Default: standard."}, 'limit': {'type': 'integer', 'description': 'Number of servers to return (1-10). Default: 5.'}, 'country': {'type': 'string', 'description': "Country name or 2-letter code (e.g. 'US', 'United States', 'JP'). Omit for auto-recommendation."}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'servers': {'type': 'array', 'items': {'type': 'object', 'properties': {'city': {'type': 'string'}, 'load': {'type': 'integer'}, 'name': {'type': 'string'}, 'status': {'type': 'string'}, 'country': {'type': 'string'}, 'hostname': {'type': 'string'}, 'technologies': {'type': 'array', 'items': {'type': 'string'}}}}}}}
nordvpn_status
NordVPN Status
Check NordVPN connection status: connected/disconnected, auto-connect, snooze, and last known location. Does NOT open NordVPN.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'version': {'type': 'string'}, 'connected': {'type': 'boolean'}, 'installed': {'type': 'boolean'}, 'app_running': {'type': 'boolean'}, 'auto_connect': {'type': 'boolean'}, 'last_location': {'type': 'string'}, 'snoozed_until': {'type': 'string'}}}
notion_list_databases
Notion List Databases
Lists Notion databases cached on this Mac with their schema (column names and types). Use notion_read_database to get the rows.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'databases': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'properties': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'type': {'type': 'string'}}}}}}}}}
notion_list_pages
Notion List Pages
Lists Notion pages cached on this Mac (titles, last edited, hierarchy), newest first. Reads the Notion desktop app's local cache — no Notion API, no integration token. Note: only pages visited in Notion (or marked Available offline) are cached.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max pages (default 50, max 500)'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'pages': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'type': {'type': 'string'}, 'title': {'type': 'string'}, 'last_edited': {'type': 'string'}, 'parent_type': {'type': 'string'}}}}}}
notion_list_workspaces
Notion List Workspaces
Lists the Notion workspaces cached on this Mac. Start here for Notion — its output feeds notion_list_databases / notion_list_pages / notion_search. Does not return workspace members: the names and emails of third parties are not part of listing workspaces.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'workspaces': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}}}}}}
notion_open_page
Notion Open Page
Opens a Notion page in the desktop app (deep link). Accepts a page id or title. Useful to let the user view or edit a page, or to pull an uncached page into the local cache.
入力スキーマ
{'type': 'object', 'required': ['page'], 'properties': {'page': {'type': 'string', 'description': 'Page id (UUID) or title (partial, case-insensitive)'}}}
出力スキーマ
{'type': 'object', 'properties': {'title': {'type': 'string'}, 'opened': {'type': 'boolean'}, 'page_id': {'type': 'string'}}}
notion_read_database
Notion Read Database
Reads the cached rows of a Notion database with their properties mapped through the schema. Accepts the database id or name (partial match). Only locally-cached rows are returned.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['database'], 'properties': {'limit': {'type': 'integer', 'description': 'Max rows (default 50, max 500)'}, 'database': {'type': 'string', 'description': 'Database id (UUID) or name (partial, case-insensitive)'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'rows': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'properties': {'type': 'object', 'additionalProperties': {'type': 'string'}}, 'last_edited': {'type': 'string'}}}}, 'count': {'type': 'integer'}}}
notion_read_page
Notion Read Page
Reads a Notion page from the local cache and returns its content as markdown (headings, lists, to-dos, code, files, subpage links). Accepts a page id or a title (partial match). If parts of the page aren't cached yet, says so — open the page in Notion or mark it Available offline for full content.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['page'], 'properties': {'page': {'type': 'string', 'description': 'Page id (UUID) or title (partial, case-insensitive)'}, 'max_blocks': {'type': 'integer', 'description': 'Max blocks to render (default 300, max 1000)'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'note': {'type': 'string'}, 'title': {'type': 'string'}, 'last_edited': {'type': 'string'}, 'blocks_rendered': {'type': 'integer'}, 'uncached_blocks': {'type': 'integer'}, 'content_markdown': {'type': 'string'}}}
notion_search
Notion Search
Searches cached Notion content (page titles and block text) for a phrase, case-insensitive. Returns matching blocks with the page they belong to. Only locally-cached content is searched — pages never opened in Notion won't match.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 20, max 100)'}, 'query': {'type': 'string', 'description': 'Text to search for'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'text': {'type': 'string'}, 'type': {'type': 'string'}, 'page_id': {'type': 'string'}, 'block_id': {'type': 'string'}, 'page_title': {'type': 'string'}, 'last_edited': {'type': 'string'}}}}}}
onedrive_delete_file
OneDrive Delete File
Deletes a file or empty folder from OneDrive.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file or folder'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to delete'}}}
出力スキーマ
{'type': 'object', 'required': ['deleted', 'path'], 'properties': {'path': {'type': 'string'}, 'deleted': {'type': 'boolean'}}}
onedrive_file_info
OneDrive File Info
Returns metadata for a file or folder: size, modification date, type, and extension. Faster than listing the parent directory when you only need info about one item.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file or folder'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string', 'description': 'file | directory'}, 'created': {'type': 'string'}, 'modified': {'type': 'string'}, 'extension': {'type': 'string'}, 'size_human': {'type': 'string'}}}
onedrive_list_files
OneDrive List Files
Lists files and folders in a OneDrive path. Use onedrive_root to find valid paths. Returns up to `limit` entries (default 1000, max 5000); large folders are truncated with a note — narrow the path for more specific results.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the OneDrive folder'}, 'limit': {'type': 'integer', 'description': 'Max entries to return (default 1000, max 5000). Folders with more entries are truncated; the response sets truncated=true and reports the total.'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer', 'description': 'Entries returned in this response.'}, 'items': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string', 'description': 'file | directory'}, 'modified': {'type': 'string'}}}}, 'total': {'type': 'integer', 'description': 'Total entries in the folder.'}, 'truncated': {'type': 'boolean', 'description': 'True when total exceeds the limit.'}}}
onedrive_move_file
OneDrive Move File
Moves or renames a file/folder within OneDrive.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['source', 'destination'], 'properties': {'source': {'type': 'string', 'description': 'Source path'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to move'}, 'destination': {'type': 'string', 'description': 'Destination path'}}}
出力スキーマ
{'type': 'object', 'required': ['moved', 'from', 'to'], 'properties': {'to': {'type': 'string'}, 'from': {'type': 'string'}, 'moved': {'type': 'boolean'}}}
onedrive_read_file
OneDrive Read File
Reads a text file from your OneDrive synced folder. Supports .txt, .md, .csv, .json, .xml, .log and several code file types. Auto-detects UTF-8, falls back to Latin-1/Windows-1252 for legacy files (common in Latin American banking .TXT padrones). For files elsewhere on this Mac, use file_read.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file'}, 'offset': {'type': 'integer', 'description': 'Start reading at byte offset (default 0)'}, 'encoding': {'type': 'string', 'description': "Force a specific encoding: 'auto' (default), 'utf8', 'latin1', 'cp1252', 'ascii', 'utf16'"}, 'max_bytes': {'type': 'integer', 'description': 'Maximum bytes to read (default 1048576 = 1 MB, capped at 10485760 = 10 MB)'}}}
出力スキーマ
{'type': 'object', 'required': ['content', 'path', 'bytes'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path of the file'}, 'bytes': {'type': 'integer', 'description': 'Total file size in bytes'}, 'offset': {'type': 'integer', 'description': 'Byte offset the read started at'}, 'content': {'type': 'string', 'description': 'Decoded file text content'}, 'encoding': {'type': 'string', 'description': 'Encoding used to decode (utf8 | cp1252 | latin1 | ascii | utf16)'}, 'truncated': {'type': 'boolean', 'description': 'True if more content remains beyond what was returned'}, 'bytes_read': {'type': 'integer', 'description': 'Number of bytes read in this slice'}}}
onedrive_root
OneDrive Root
Lists all mounted OneDrive directories on this Mac. Start here for OneDrive — the mount paths it returns are what the other onedrive_* tools (onedrive_list_files, onedrive_read_file, onedrive_search_files) need.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'roots': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}}}}}}
onedrive_search_files
OneDrive Search Files
Searches for files by name in a OneDrive directory (recursive). Returns up to max_results matches (default 50); raise max_results or narrow the root for more.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'root': {'type': 'string', 'description': 'Root OneDrive path to search in (optional)'}, 'query': {'type': 'string', 'description': 'Filename pattern to search for'}, 'max_results': {'type': 'integer', 'description': 'Maximum results (default 50)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'size': {'type': 'integer'}, 'type': {'type': 'string', 'description': 'file | directory'}}}}}}
onedrive_set_scope
OneDrive Set Scope
Restricts LMCP's OneDrive access to a specific folder. Once set, all OneDrive tools (read, write, list, search, delete, move) only work inside the allowed folder. Pass an empty folder to remove the restriction. Changes take effect immediately.
入力スキーマ
{'type': 'object', 'required': ['root_name'], 'properties': {'folder': {'type': 'string', 'description': "Allowed folder path relative to the root (e.g. '/000-Claude Personal Agent'). Empty string removes the scope."}, 'confirm': {'type': 'boolean', 'description': 'Must be true to apply'}, 'root_name': {'type': 'string', 'description': "OneDrive root name (from onedrive_root, e.g. 'OneDrive-WPPCloud')"}}}
出力スキーマ
{'type': 'object', 'properties': {'root': {'type': 'string'}, 'access': {'type': 'string'}, 'effect': {'type': 'string'}, 'scope_set': {'type': 'boolean'}, 'scope_removed': {'type': 'boolean'}, 'allowed_folder': {'type': 'string'}}}
onedrive_write_file
OneDrive Write File
Writes text content to a file in OneDrive. Overwriting an existing file requires confirm=true (the first call returns a preview instead); creating a new file needs no confirm.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the file in OneDrive'}, 'confirm': {'type': 'boolean', 'description': 'Required (true) to OVERWRITE an existing file. Not needed to create a new file.'}, 'content': {'type': 'string', 'description': 'Text content to write'}}}
出力スキーマ
{'type': 'object', 'required': ['written', 'path', 'bytes'], 'properties': {'path': {'type': 'string'}, 'bytes': {'type': 'integer'}, 'written': {'type': 'boolean'}}}
outlook_diagnose
Outlook Diagnose
Checks which email accounts are configured in Microsoft Outlook and compares them with Mail.app. If Outlook has accounts not in Mail.app, guides the user to add them so all email tools work seamlessly.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['installed'], 'properties': {'note': {'type': 'string', 'description': 'Plain-language guidance'}, 'report': {'type': 'string', 'description': 'Full formatted text report'}, 'installed': {'type': 'boolean', 'description': 'True if Microsoft Outlook is installed'}, 'outlook_accounts': {'type': 'array', 'items': {'type': 'object', 'properties': {'email': {'type': 'string'}, 'in_mail_app': {'type': 'boolean', 'description': 'Whether this account is also configured in Mail.app'}}}}, 'mail_app_accounts': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'string'}}}}}, 'missing_from_mail_app': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Outlook account emails not present in Mail.app'}}}
pdf_read
PDF Read
Reads and extracts text from a PDF document (.pdf file). Reads the PDF's text layer only — a scanned or image-only PDF returns little or no text, since this tool does not run OCR. Reads up to 50 pages and ~100 KB of text by default (max_pages changes the page cap); when a cap truncates the result, the header says how many of the total pages were included.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the PDF file'}, 'max_pages': {'type': 'integer', 'description': 'Max pages to extract (default: all)'}, 'force_download': {'type': 'boolean', 'description': "If the file is stored in the cloud and evicted from this Mac (dataless), request the download and wait for it instead of failing. Off by default: a download can take minutes and use metered data, so it is the caller's decision."}}}
出力スキーマ
{'type': 'object', 'required': ['text', 'chars'], 'properties': {'text': {'type': 'string', 'description': 'Extracted text content'}, 'chars': {'type': 'integer', 'description': 'Number of characters in the extracted text'}, 'pages': {'type': 'integer', 'description': 'Total number of pages in the PDF'}}}
permissions_status
Permissions Status
Reports the TCC permission state (screen recording, accessibility, microphone) this app needs to capture the screen and drive other apps' UI. Call it before a capture/automation run and surface the grant hints instead of failing mid-sequence. Screen Recording / Accessibility are granted in System Settings (not a JIT dialog); the URLs open the exact pane.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
ppt_create
PowerPoint Create
Creates a PowerPoint presentation (.pptx) at `path` from an array of slides, each {title, bullets:[…]}. Requires confirm=true — called without it, returns a preview of the deck instead of writing the file. The path must be somewhere Local MCP can write; Desktop/Documents/Downloads may need a one-time Files-and-Folders grant (System Settings → Privacy & Security → Files and Folders). Returns {created, path, slides}.
入力スキーマ
{'type': 'object', 'required': ['path', 'slides'], 'properties': {'path': {'type': 'string', 'description': 'Output path for the .pptx file'}, 'slides': {'type': 'array', 'items': {'type': 'object', 'required': ['title'], 'properties': {'title': {'type': 'string', 'description': 'Slide title'}, 'bullets': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Bullet lines'}}}, 'description': 'Array of slide OBJECTS, each with a title and optional bullets'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}}}
出力スキーマ
{'type': 'object', 'required': ['created', 'path', 'slides'], 'properties': {'path': {'type': 'string', 'description': 'Path of the created .pptx file'}, 'slides': {'type': 'integer', 'description': 'Number of slides created'}, 'created': {'type': 'boolean', 'description': 'True when the file was created'}}}
ppt_read
PowerPoint Read
Reads slide text content from a PowerPoint presentation (.pptx file).
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the .pptx file'}, 'force_download': {'type': 'boolean', 'description': "If the file is stored in the cloud and evicted from this Mac (dataless), request the download and wait for it instead of failing. Off by default: a download can take minutes and use metered data, so it is the caller's decision."}}}
出力スキーマ
{'type': 'object', 'required': ['slides', 'count'], 'properties': {'count': {'type': 'integer', 'description': 'Number of slides'}, 'slides': {'type': 'array', 'items': {'type': 'object', 'properties': {'slide': {'type': 'integer', 'description': '1-based slide number'}, 'title': {'type': 'string', 'description': "The slide's title (empty if the slide has none)"}, 'bullets': {'type': 'array', 'items': {'type': 'string'}, 'description': "The slide's body paragraphs, one entry per line"}}}, 'description': 'Per-slide structured content ({slide, title, bullets[]}), mirroring ppt_create'}}}
read_email
Read Email
Use this when the user wants the full content of an email that lives in the Mac's Apple Mail (message ID from list_emails/search_emails). For a Microsoft 365 message ID from m365_list_emails, use m365_read_email. Pass account= (and mailbox= if known, both from list_emails/search_emails) so the lookup targets one account instead of scanning all of them. Call sequentially, not in parallel — concurrent calls serialize behind Mail.app's JXA lock and later calls will time out. Performance: body fetch is the primary latency source (avg 20s on slow IMAP). Pass include_body=false to skip it and get metadata-only (fast). Pass max_body_chars=N to cap the body at N chars after HTML stripping (default 30000; 0=unlimited). Response includes body_fetch_ms when fetch took >2s, body_omitted=true when skipped, body_truncated_at=N when cut. When a body isn't cached on this Mac, read_email returns metadata with body_omitted=true and body_omit_reason="not_downloaded" (iCloud/IMAP optimized storage) rather than making Mail fetch it (that can be slow and tie Mail up). If the user wants it anyway, retry with force_download=true to have Mail pull the body over IMAP now and return it (waits up to ~60s). Off by default; ignored while Mail is in a cooldown.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['message_id'], 'properties': {'account': {'type': 'string', 'description': 'Mail.app account the message lives in (returned alongside the id). Passing it skips searching the other accounts.'}, 'mailbox': {'type': 'string', 'description': 'Folder the message lives in (returned alongside the id). Passing it skips searching the other folders.'}, 'message_id': {'type': 'string', 'description': 'The message id returned by list_emails or search_emails. Accepts the bare id or the <angle-bracketed> form.'}, 'include_body': {'type': 'boolean', 'default': 'true', 'description': 'Return the message body, not just its headers.'}, 'force_download': {'type': 'boolean', 'default': 'false', 'description': 'Ask Mail to fetch the full message from the server when only part of it is cached locally. Slower, and it needs the account to be online.'}, 'max_body_chars': {'type': 'integer', 'default': '30000', 'minimum': 0, 'description': 'Cap on how many characters of the body to return. Defaults to 30000; the reply says when it truncated.'}}}
出力スキーマ
{'type': 'object', 'properties': {'cc': {'type': 'string'}, 'id': {'type': 'string'}, 'to': {'type': 'string'}, 'body': {'type': 'string'}, 'date': {'type': 'string'}, 'from': {'type': 'string'}, 'unread': {'type': 'boolean'}, 'account': {'type': 'string'}, 'mailbox': {'type': 'string'}, 'subject': {'type': 'string'}, 'body_omitted': {'type': 'boolean'}, 'body_fetch_ms': {'type': 'integer'}, 'body_truncated_at': {'type': 'integer'}}}
read_messages
Read Messages
Reads messages from an iMessage conversation by chat ID or contact name.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max messages (default 50)'}, 'chat_id': {'type': 'string', 'description': 'Chat identifier from list_message_chats'}, 'contact_name': {'type': 'string', 'description': 'Contact name substring (alternative to chat_id)'}}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'chat_id': {'type': 'string'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'date': {'type': 'string'}, 'sender': {'type': 'string'}, 'chat_id': {'type': 'string'}, 'content': {'type': 'string'}, 'from_me': {'type': 'boolean'}, 'chat_name': {'type': 'string'}}}}}}
read_note
Read Note
Reads the full content of a note by name or ID. CHECK `body_format` BEFORE WRITING THE BODY BACK. "markdown" means the note's formatting (headings, bold/italic, bullet/numbered lists, checkboxes, links, monospaced) came through as Markdown and update_note takes it back as-is — literal `*`, backticks and brackets arrive backslash-escaped so they survive the round trip. "plain_text" means the formatting could NOT be recovered and `body` is flat text: writing it back REPLACES the note's structure with flat text, so edit the note by other means (or ask the user) instead of rewriting the whole body.
読み取り専用
入力スキーマ
{'type': 'object', 'properties': {'note_id': {'type': 'string', 'description': 'Id of the note, from list_notes or search_notes. Use this or note_name.'}, 'note_name': {'type': 'string', 'description': 'Title of the note, when you do not have its id. Use this or note_id.'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'body': {'type': 'string'}, 'name': {'type': 'string'}, 'folder': {'type': 'string'}, 'modified': {'type': 'string'}, 'body_format': {'enum': ['markdown', 'plain_text'], 'type': 'string', 'description': 'What `body` actually is. "markdown": the note\'s formatting survived and update_note accepts this body back unchanged. "plain_text": the formatting could not be recovered — writing this body back flattens the note.'}}}
recipe_delete
Recipe Delete
Use this when the user wants to remove one of THEIR saved recipes/skills (the manifests under ~/.local/share/local-mcp/recipes). Destructive with a preview gate: the first call (without confirm) shows what would be deleted; call again with confirm=true to actually delete. Bundled starter recipes can't be deleted. To modify a recipe instead, recipe_save with the same name overwrites it (upsert).
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Recipe name (from recipe_list).'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to actually delete. Without it, returns a preview.'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'status': {'type': 'string', 'description': "'preview' when confirm was not set."}, 'deleted': {'type': 'boolean'}}, 'additionalProperties': True}
recipe_discover
Recipe Discover
Browses installable community SKILLS — ready-made LMCP workflows other people published (a morning brief, inbox triage, a weekly report). A user would browse them to find a ready-made workflow for a repeatable multi-app task instead of building it from scratch. Returns a list of {id, title, category, description, steps, votes}; install one with recipe_install(id).
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'properties': {'category': {'type': 'string', 'description': 'Optional filter hint shown to the user; the catalog is small so all skills are returned.'}}}
recipe_export
Recipe Export
Exports a saved SKILL (recipe) as a single portable token the user can send to someone else — paste it in a message, email, or doc. The recipient installs it with recipe_import and runs it with recipe_run. A user would export a skill to share it with a teammate (a handy brief, a report, a workflow). Returns {name, skill_token} plus the readable manifest.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Name of the saved skill to export (see recipe_list).'}}}
recipe_get
Recipe Get
Returns the full manifest of a recipe by name. recipe_not_found if unknown.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Name of the recipe, as listed by recipe_list. Returns recipe_not_found if it is unknown.'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'steps': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'params': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'description': {'type': 'string'}}, 'additionalProperties': True}
recipe_import
Recipe Import
Installs a SKILL someone shared with you — pass the skill_token from their recipe_export (or a raw recipe manifest JSON). Saves it to this Mac so recipe_run can use it. Safe: importing only stores the skill; when it's later run, any state-changing step (send/write/delete) previews first and needs confirmation. If a skill with the same name already exists, the import is saved under a non-colliding name. Returns {name, imported}.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'skill': {'type': 'string', 'description': 'A skill_token from recipe_export, or a raw recipe manifest JSON string.'}, 'skill_token': {'type': 'string', 'description': 'Alias for `skill` — the exact field name recipe_export returns.'}}}
recipe_install
Recipe Install
Installs a community SKILL by id (from recipe_discover) onto this Mac so recipe_run can use it. Safe: installing only stores the skill; when it's later run, any state-changing step (send/write/delete) previews first and needs confirmation. If a skill with the same name already exists, it's saved under a non-colliding name. Returns {name, installed}.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'integer', 'description': 'The community skill id from recipe_discover.'}}}
recipe_list
Recipe List
Lists the user's reusable SKILLS — saved recipes (an ordered sequence of LMCP tool calls with parameters), plus bundled ones — each runnable with recipe_run. Skills turn a repeated LMCP workflow into one reusable command. A user would list them to find an existing skill for a task rather than rebuilding it from scratch. Returns each skill's name, description, and steps.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'recipes': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'params': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Declared parameters (name/type/default).'}, 'description': {'type': 'string'}}}}}}
recipe_publish
Recipe Publish
Submits one of YOUR saved recipes/skills to the community moderation queue for Dario's review — this does NOT publish it. Without confirm=true it PREVIEWS the title/category/apps/workflow write-up that would be sent (nothing leaves this Mac); with confirm=true it submits and returns {status:"submitted", pending:true}. Once approved it appears on /community/skills and anyone can install it with recipe_install. `workflow` is the public write-up: it defaults to the recipe's own `description` field when that's at least 15 characters, otherwise pass one explicitly.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'apps': {'type': 'string', 'description': 'Free-text apps the recipe touches (e.g. "Mail, Calendar"), shown in the moderation queue.'}, 'name': {'type': 'string', 'description': 'Name of the saved recipe/skill to publish (see recipe_list).'}, 'title': {'type': 'string', 'description': "Shown once approved on /community/skills. Defaults to the recipe's own name."}, 'confirm': {'type': 'boolean', 'description': 'Must be true to actually submit. Without it, returns a preview — nothing is sent.'}, 'category': {'type': 'string', 'description': 'Free-text category shown in the moderation queue and, once approved, on /community/skills.'}, 'workflow': {'type': 'string', 'description': "The public write-up of what the recipe does. Defaults to the recipe's own `description` if it's at least 15 characters; required otherwise."}}}
recipe_run
Recipe Run
Executes a recipe end to end: binds params, runs each step's tool in order via the registry, persists the run (see recipe_runs), and returns each step's result plus any markers_path. Recipes with state-changing steps (write/send/delete) PREVIEW first — call again with confirm:true to execute; read-only recipes run immediately. A step that errors stops the run and is reported.
破壊的操作あり 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Name of the saved skill (recipe) to run, exactly as recipe_list reports it.'}, 'params': {'type': 'object', 'description': 'Param overrides (merged over the recipe defaults).'}, 'confirm': {'type': 'boolean', 'description': 'Set true to execute a recipe that has state-changing steps; read-only recipes ignore it.'}}}
recipe_runs
Recipe Runs
Shows the history of past recipe runs and their results (recorded by recipe_run), so you can reuse, compare, or debug an automation. Pass `name` for one recipe's runs, or omit for a compact history across all recipes. Pass `run_id` (with `name`) to get that run in full detail. Newest first.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'name': {'type': 'string', 'description': 'Recipe name; omit for runs across all recipes.'}, 'limit': {'type': 'integer', 'description': 'Max runs to return (default 20).'}, 'run_id': {'type': 'string', 'description': 'Return this one run in full detail (requires name).'}}}
出力スキーマ
{'type': 'object', 'properties': {'runs': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'count': {'type': 'integer'}, 'recipe': {'type': ['string', 'null'], 'description': 'Recipe name when scoped, null for the all-recipes history.'}}, 'additionalProperties': True}
recipe_save
Recipe Save
Saves a reusable SKILL — a named recipe (an ordered sequence of LMCP tool calls with parameters) — to this Mac so the user can re-run it anytime with recipe_run. A user would save one to turn a multi-step LMCP workflow they repeat (a morning brief, inbox triage, a weekly report, a data pull) into a single reusable command. Saved skills can be shared with other people via recipe_export. The manifest must have a name and a non-empty steps array. Returns {name}.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['manifest'], 'properties': {'manifest': {'type': 'object', 'description': 'The recipe manifest. Shape: {"name": string (required), "description": string, "params": [{"name": string, "type": "string"|"int"|"bool", "default": any}], "steps": [ ... ] (required, non-empty), "outputs": [{"kind": string}]}. A step is EITHER a tool call {"tool": <tool_name>, "args": {...}} OR a pause {"wait": {"seconds": N}} (also {"wait": N}). Any arg string may interpolate a declared param with ${name} (e.g. "limit": "${count}"); an arg that is exactly "${name}" keeps the param\'s type. Steps run in order; a later step can consume an EARLIER step\'s output with "${steps[N].result.KEY}" (0-based; supports .key and [i], e.g. "account": "${steps[0].result.accounts[0].name}"). On recipe_run a state-changing step previews first unless confirm:true.'}}}
record_marker
Record Marker
Drops a named marker into the active recording's timeline. t_ms is elapsed ms since recording start. Provide bounds (global points, top-left) to zoom toward an element, or omit for full-frame. note becomes a caption source. Returns no_active_session if nothing is recording.
入力スキーマ
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Marker name, e.g. open_tray, act2_calendar_create.'}, 'note': {'type': 'string', 'description': 'Free text → caption source.'}, 'bounds': {'type': 'object', 'description': 'Optional {x,y,w,h} global points to zoom toward.'}, 'session_id': {'type': 'string', 'description': 'Accepted and IGNORED: v1 records one session at a time, so a marker always lands on the active recording. It is here so echoing back the session_id from screen_record_start is not an error.'}}}
rename_reminder_folder
Rename Reminder Folder
Renames an existing Apple Reminders list. Pass the current list name (or list_id from get_reminder_folders) and new_name. Requires confirm=true.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['new_name'], 'properties': {'name': {'type': 'string', 'description': 'Current list name (or pass list_id)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to apply'}, 'list_id': {'type': 'string', 'description': 'List identifier from get_reminder_folders (alternative to name)'}, 'new_name': {'type': 'string', 'description': 'New name for the list'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
reply_email
Reply Email
Use this when the user wants to reply to an email that lives in the Mac's Apple Mail (message ID from list_emails/search_emails). Supports plain text or HTML body and previews before sending. To leave the reply in Drafts WITHOUT sending, pass `save_as_draft: true`: it builds the same native Mail reply (automatic quote of the original, correct thread, Reply/Reply-All recipients) and saves it instead of sending — `send` is never called on that path. `create_draft` with `reply_to_message_id` also leaves a draft, but composes it from scratch, so it has no automatic quote. For a Microsoft 365 message ID from m365_list_emails, use m365_reply_email. Pass `account` (from list_emails/search_emails results) to skip scanning other accounts and avoid timeouts on multi-account Macs.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['message_id'], 'properties': {'body': {'type': 'string', 'description': 'Plain-text reply body.'}, 'account': {'type': 'string', 'description': 'Account (from the listing) the message is in — pass it to skip scanning other accounts and avoid multi-account timeouts.'}, 'confirm': {'type': 'boolean', 'default': 'false', 'description': 'Consent gate: the first call previews the reply; call again with confirm=true to actually SEND it — or to save it when save_as_draft is set.'}, 'html_body': {'type': 'string', 'description': 'HTML reply body. Takes precedence over `body` when both are given.'}, 'reply_all': {'type': 'boolean', 'default': 'false', 'description': 'Reply to all original recipients instead of just the sender.'}, 'message_id': {'type': 'string', 'description': 'Id of the message to reply to (from list_emails/search_emails).'}, 'save_as_draft': {'type': 'boolean', 'default': 'false', 'description': "Save the native reply in Drafts instead of sending it. Keeps Mail's reply template: automatic quote of the original, the right thread, and the Reply/Reply-All recipients. Nothing is sent on this path."}}}
出力スキーマ
{'type': 'object', 'properties': {'sent': {'type': 'boolean', 'description': "False on the draft path — stated explicitly so 'no error' is never read as 'it went out'."}, 'replied': {'type': 'boolean'}, 'message_id': {'type': 'string'}, 'draft_mailbox': {'type': 'string', 'description': 'Where the draft was left, so the user knows where to look.'}, 'draft_subject': {'type': 'string', 'description': 'Subject of the draft that was created.'}, 'saved_as_draft': {'type': 'boolean', 'description': 'True when save_as_draft was used: the reply is in Drafts and nothing was sent.'}}}
report_friction
Report Friction
Send an ANONYMOUS, content-free signal when an LMCP tool fails, returns nothing useful, the user seems frustrated, or you could not accomplish what they asked. Helps the LMCP team find and fix the roughest spots. Send ONLY the category + the tool name — NEVER the user's request, message/email content, account names, or any personal data. No confirmation needed: this is anonymous (categories only) and respects the user's opt-out.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['friction_type'], 'properties': {'attempt_count': {'type': 'integer', 'description': 'How many times this was attempted (optional).'}, 'friction_type': {'enum': ['repeated_failure', 'user_frustrated', 'task_abandoned', 'workaround_needed', 'cannot_complete', 'other'], 'type': 'string', 'description': 'What kind of friction you observed.'}, 'error_category': {'enum': ['permission', 'timeout', 'empty', 'not_found', 'parse', 'wrong_result', 'missing_capability', 'crash', 'other'], 'type': 'string', 'description': 'Category of what went wrong (optional).'}, 'tool_attempted': {'type': 'string', 'description': 'Name of the LMCP tool involved (e.g. list_emails). Optional.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
report_problem
Report Problem
Sends a problem report, feature request, or integration request to the LMCP team — for when a user wants to report a bug, ask for a new capability, or request support for an app LMCP doesn't cover yet. Without confirm=true it returns a preview of the anonymous payload that would be sent (version, OS, permission status, and recent tool names / error-type codes — never arguments, messages or personal data); with confirm=true it submits and returns a case_id. type='problem' (default) reports a bug, type='feature' requests a new capability, type='integration' requests an unsupported app.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to submit the report. Without it, shows a preview.'}, 'symptom': {'type': 'string', 'description': 'Required for type=problem: what is broken, in your own words.'}, 'expected': {'type': 'string', 'description': 'What you or the user expected to happen.'}, 'description': {'type': 'string', 'description': 'Required for type=feature or integration: what the user wants.'}, 'report_type': {'type': 'string', 'description': "'problem' (default) | 'feature' | 'integration'"}, 'user_request': {'type': 'string', 'description': 'What the user originally asked the AI to do.'}, 'error_message': {'type': 'string', 'description': 'For type=problem: verbatim error string from the failed tool.'}, 'tool_attempted': {'type': 'string', 'description': 'For type=problem: name of the LMCP tool that failed.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
request_feature
Request Feature
Submits a feature request to the LMCP team — a new capability, a tool that doesn't exist yet, or an app/integration the user wishes LMCP supported. A user would invoke this when they want to ask the team for something LMCP can't do yet. Without confirm=true it returns a preview; with confirm=true it submits. The request includes the machine ID and (if set) the account email so the team can follow up — it is not anonymous.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['feature'], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to submit. Without it, shows a preview.'}, 'feature': {'type': 'string', 'description': 'What the user wants LMCP to do — a capability, tool, or integration.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
run_diagnostics
Run Diagnostics
Runs a fast health check of all LMCP integrations on this machine, including the AI apps connected to LMCP (configured, never used, broken command, blocked config). Shows what works, what doesn't, and how to fix it. Optionally submits a report to the LMCP team.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'focus': {'type': 'string', 'description': 'Integration to focus on: calendar, mail, contacts, reminders, omnifocus, outlook, notes, finder, onedrive, screen_recording, accessibility — or `clients` for the AI apps connected to LMCP (or one app id, e.g. cursor). Leave empty to check all.'}, 'submit': {'type': 'boolean', 'description': 'Send the diagnostic report to the LMCP team for analysis (default: false)'}}}
出力スキーマ
{'type': 'object', 'required': ['summary', 'ok_count', 'warn_count', 'problem_count', 'integrations'], 'properties': {'report': {'type': 'string', 'description': 'Full formatted text report'}, 'summary': {'type': 'string', 'description': 'Plain-language summary of overall health'}, 'ok_count': {'type': 'integer', 'description': 'Number of integrations working'}, 'submitted': {'type': 'boolean', 'description': 'True when the report was sent to the LMCP team'}, 'warn_count': {'type': 'integer', 'description': 'Number of integrations with warnings / not running'}, 'web_agents': {'type': 'object', 'description': 'Web (cloud-relay) clients, counts only: count (absent when unknown), relayed_calls_since_launch, last_remote_call'}, 'integrations': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'Integration tool key'}, 'label': {'type': 'string', 'description': 'Human-readable name'}, 'detail': {'type': 'string', 'description': 'What was found'}, 'status': {'type': 'string', 'description': 'ok | warning | error | permission | not_running | skip'}, 'fix_hint': {'type': 'string', 'description': 'How to fix, when applicable'}}}}, 'problem_count': {'type': 'integer', 'description': 'Number of integrations with errors or missing permissions'}}}
save_attachment
Save Attachment
Saves an attachment from an email to disk. Requires confirm=true; without it you get a preview of where the file would be written. Pass account= (and mailbox= if known, both from list_emails/search_emails) so the lookup targets one account instead of scanning all of them.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['message_id', 'attachment_name'], 'properties': {'account': {'type': 'string', 'description': 'Mail.app account the message lives in (returned alongside the id). Passing it skips searching the other accounts.'}, 'confirm': {'type': 'boolean', 'default': 'false', 'description': 'Set to true to actually write the file. Without it you get a preview of where it would be written. Defaults to false.'}, 'mailbox': {'type': 'string', 'description': 'Folder the message lives in (returned alongside the id). Passing it skips searching the other folders.'}, 'message_id': {'type': 'string', 'description': 'The message id of the email that carries the attachment, from list_emails or search_emails. Accepts the bare id or the <angle-bracketed> form.'}, 'destination': {'type': 'string', 'default': '~/Downloads', 'description': 'Folder to write the file into. Defaults to ~/Downloads.'}, 'attachment_name': {'type': 'string', 'description': 'File name of the attachment as it appears in the message.'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'saved': {'type': 'boolean'}, 'attempts': {'type': 'integer'}, 'destination': {'type': 'string'}}}
screen_record_start
Screen Record Start
Begins a screen recording (ScreenCaptureKit) of a display, window, or region. Single active session in v1 — a second start returns already_recording. Returns a session_id used by record_marker and screen_record_stop. Requires Screen Recording permission; without it returns an explicit permission_required error, never a silent no-op.
入力スキーマ
{'type': 'object', 'required': ['target'], 'properties': {'fps': {'type': 'integer', 'description': 'Frames per second (default 60).'}, 'target': {'type': 'object', 'required': ['kind'], 'properties': {'kind': {'enum': ['display', 'window', 'region'], 'type': 'string'}, 'region': {'type': 'object', 'description': 'Required if kind=region: {x,y,w,h} global points.'}, 'window_id': {'type': 'string', 'description': 'Required if kind=window.'}, 'display_id': {'type': 'string', 'description': 'Required if kind=display.'}}, 'description': 'What to capture.'}, 'output_path': {'type': 'string', 'description': 'Where to write the .mov (default: temp file, returned by stop). Missing parent folders are created.'}, 'show_cursor': {'type': 'boolean', 'description': 'Default true.'}}}
screen_record_status
Screen Record Status
Reports whether a recording is active, with the session_id, elapsed_ms, output path, and marker_count.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'session_id': {'type': 'string', 'description': 'Recording session to report on, from screen_record_start. Leave it out to report on the active recording.'}}}
screen_record_stop
Screen Record Stop
Stops the active recording, finalizes the .mov, and writes the marker timeline JSON (§6) next to it. Returns the video path, duration, resolution, marker_count and markers_path. Returns no_active_session if nothing is recording.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'session_id': {'type': 'string', 'description': 'Optional; the single active session is used if omitted.'}}}
screenshot_capture
Screenshot Capture
Captures a single frame of a display, window, or region to a PNG. Returns {path, resolution (PIXELS), scale_factor, display_id} — scale_factor is the backing scale of the display that was ACTUALLY captured (the same value list_displays reports for that display_id, by construction: both read one function), so pixels = points x scale_factor when converting a coordinate from the image to ui_click. If the display could not be determined you get scale_factor_unknown instead of a guess; resolution is always there, so you can derive the ratio yourself. Requires Screen Recording permission; without it returns an explicit permission_required, never a blank image.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['target'], 'properties': {'target': {'type': 'object', 'required': ['kind'], 'properties': {'kind': {'enum': ['display', 'window', 'window_title', 'region'], 'type': 'string'}, 'title': {'type': 'string', 'description': 'Exact window title to capture (kind:"window_title"). Enumerates ALL windows directly — including overlays/panels like Notification Center that list_windows hides unless include_overlays:true. If more than one window has this title, the frontmost one is captured and the response reports matched_windows > 1.'}, 'region': {'type': 'object', 'description': '{x,y,w,h} global points.'}, 'window_id': {'type': 'string'}, 'display_id': {'type': 'string'}}, 'description': 'What to capture. Required: {kind: "display"|"window"|"window_title"|"region"} plus display_id (see list_displays), window_id (see list_windows), title, or region {x,y,w,h} in global points.'}, 'output_path': {'type': 'string', 'description': 'Where to write the PNG (default: temp file). Missing parent folders are created.'}}}
search_contacts
Search Contacts
Searches the Mac's Contacts app (Contacts.app, local/iCloud) by name, email, or phone number. For a Microsoft 365 directory use m365_search_contacts or search_m365_directory instead.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 50)'}, 'query': {'type': 'string', 'description': 'Name, email, or phone to search for'}}}
出力スキーマ
{'type': 'object', 'required': ['query', 'count', 'contacts'], 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'contacts': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'full_name'], 'properties': {'id': {'type': 'string'}, 'emails': {'type': 'array', 'items': {'type': 'object', 'properties': {'label': {'type': 'string'}, 'value': {'type': 'string'}}}}, 'phones': {'type': 'array', 'items': {'type': 'object', 'properties': {'label': {'type': 'string'}, 'value': {'type': 'string'}}}}, 'company': {'type': 'string'}, 'birthday': {'type': 'string'}, 'addresses': {'type': 'array', 'items': {'type': 'object', 'properties': {'zip': {'type': 'string'}, 'city': {'type': 'string'}, 'label': {'type': 'string'}, 'state': {'type': 'string'}, 'street': {'type': 'string'}, 'country': {'type': 'string'}}}}, 'full_name': {'type': 'string'}, 'last_name': {'type': 'string'}, 'first_name': {'type': 'string'}}}}}}
search_emails
Search Emails
Use this when the user wants to find specific emails on this Mac (Apple Mail — any account added to Mail.app). Searches subject and sender by default; pass scope="body" or scope="all" to also search the message body (see search_coverage in the response — a body search can be partial while its local index is still building). For a Microsoft 365 mailbox NOT added to Mail.app, use m365_search_emails. IMPORTANT: on machines with 2+ accounts, call with account=<name> (from list_email_accounts). Without it, and when the fast index can't answer, search_emails returns the account list instead of scanning all of them — scanning every account in one call has no time limit and can block Mail for other requests too. Exactly 1 account is unaffected.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'default': '20', 'maximum': 100, 'minimum': 1, 'description': 'Maximum number of matches to return.'}, 'query': {'type': 'string', 'description': 'What to look for. Matched against subject and sender, or also the body when scope is "body" or "all".'}, 'scope': {'type': 'string', 'default': 'metadata', 'description': '"metadata" (default, subject+sender — fast, unchanged behavior), "body" (message body only, via a local index — see search_coverage in the response), or "all" (subject+sender+body).'}, 'account': {'type': 'string', 'description': 'Mail.app account to search (from list_email_accounts). On a Mac with 2+ accounts this is effectively required: without it, and when the fast index cannot answer, the tool returns the account list instead of scanning them all.'}, 'mailbox': {'type': 'string', 'description': 'Restrict the search to one folder, by name (see list_email_folders). Defaults to every folder of the account.'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'date': {'type': 'string'}, 'from': {'type': 'string'}, 'unread': {'type': 'boolean'}, 'account': {'type': 'string'}, 'subject': {'type': 'string'}}}}, 'warnings': {'type': 'array'}, 'next_actions': {'type': 'array'}, 'search_scope': {'type': 'string'}, 'search_backend': {'type': 'string'}, 'search_coverage': {'type': 'string'}, 'omitted_mailboxes': {'type': 'array'}}}
search_m365_directory
Search Microsoft 365 Directory
Search your organization's Microsoft 365 directory for users by name or email. Returns matching users with their title, department, and contact info.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 10, max 25)'}, 'query': {'type': 'string', 'description': "Name or email to search for, e.g. 'Sarah' or 'sarah@contoso.com'"}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'users': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'upn': {'type': 'string'}, 'name': {'type': 'string'}, 'email': {'type': 'string'}, 'title': {'type': 'string'}, 'mobile': {'type': 'string'}, 'office': {'type': 'string'}, 'phones': {'type': 'array', 'items': {'type': 'string'}}, 'department': {'type': 'string'}}}}}}
search_messages
Search Messages
Searches iMessage conversations by content, sender name, or date range.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 30)'}, 'query': {'type': 'string', 'description': 'Text to search for in message content (optional if from_sender is set)'}, 'since': {'type': 'string', 'description': "ISO8601 date — only return messages on or after this date (optional, e.g. '2026-04-10' or '2026-04-10T00:00:00Z')"}, 'until': {'type': 'string', 'description': "ISO8601 date — only return messages on or before this date (optional). Combine with 'since' to search a date range with no text query."}, 'from_sender': {'type': 'string', 'description': 'Substring of sender name/handle to filter by (optional)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'since': {'type': 'string'}, 'until': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'date': {'type': 'string'}, 'sender': {'type': 'string'}, 'chat_id': {'type': 'string'}, 'content': {'type': 'string'}, 'chat_name': {'type': 'string'}}}}, 'from_sender': {'type': 'string'}}}
search_notes
Search Notes
Searches Apple Notes by title or content. Paginated: `limit` is capped at 100 per call, so page with `offset` instead of asking for a bigger limit. The response carries `total` (how many notes match the query in all) and `has_more`, so a capped page is never mistaken for the complete answer — page until `has_more` is false, which is exact even when `total_is_estimated` says the count is only a lower bound. To walk every match, pass order="id" — see the order parameter.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'default': '20', 'description': 'Matches per page (default 20, capped at 100). To get more, page with offset.'}, 'order': {'type': 'string', 'default': 'modified', 'description': 'order: "modified" (default) sorts newest-modified first — what you want to SHOW someone, but NOT safe for paging: modification date changes, so a note edited between two calls jumps to the front and another note is pushed past your cursor and never returned. "id" sorts by the note\'s immutable store id — stable, never renumbered, new notes append at the end — so use order="id" to walk an entire library page by page: edits and insertions mid-crawl are safe with it. One case it cannot cover, because pages are addressed by offset: if a note is DELETED mid-crawl, every note after the hole shifts one slot back and the note that was on the page boundary is skipped, silently. If completeness matters, re-run the crawl and reconcile against total, or crawl while nothing is deleting notes.'}, 'query': {'type': 'string', 'description': "Text to look for. Matches a note's title or its snippet (the opening of the body), NOT the full body — a word that appears only deep inside a long note will not be found. Must not be empty."}, 'offset': {'type': 'integer', 'default': '0', 'minimum': 0, 'description': 'How many matches to skip (default 0). An offset past the end returns an empty page with has_more=false, not an error.'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer', 'description': 'Matches in THIS page'}, 'order': {'type': 'string', 'description': 'The ordering actually applied (modified | id)'}, 'query': {'type': 'string'}, 'total': {'type': 'integer', 'description': 'Matches in total, ignoring limit/offset. A LOWER BOUND, not the exact figure, when total_is_estimated is true'}, 'offset': {'type': 'integer', 'description': 'Where this page started'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'match': {'type': 'string'}, 'folder': {'type': 'string'}, 'preview': {'type': 'string'}}}}, 'has_more': {'type': 'boolean', 'description': 'True when matches remain past this page — call again with offset = offset + count'}, 'next_actions': {'type': 'array'}, 'total_is_estimated': {'type': 'boolean', 'description': 'True when the exact count could not be taken (the unbounded COUNT failed, or the JXA fallback answered) — total is then only a lower bound. has_more stays exact either way: page until it is false, never until count reaches total'}}}
search_omnifocus_tasks
Search OmniFocus Tasks
Searches OmniFocus tasks by name or note content.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'default': '30', 'description': 'Max matches to return (default 30).'}, 'query': {'type': 'string', 'description': 'Text to match against task names and notes (case-insensitive).'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'note': {'type': 'string'}, 'project': {'type': 'string'}, 'due_date': {'type': 'string'}}}}}}
send_email
Send Email
Use this when the user wants to send an email from an account configured in the Mac's Apple Mail. Composes and sends via Mail.app; supports plain text or HTML body. For sending from a Microsoft 365 account NOT added to Mail.app, use m365_send_email. Pass `from` to send from a specific configured Mail.app account instead of the default sender. Pass `attachments` as a comma-separated list of absolute file paths to attach files.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['to', 'subject'], 'properties': {'cc': {'type': 'string', 'description': 'CC address(es), comma-separated.'}, 'to': {'type': 'string', 'description': 'Recipient address(es), comma-separated for multiple.'}, 'bcc': {'type': 'string', 'description': 'BCC address(es), comma-separated.'}, 'body': {'type': 'string', 'description': 'Plain-text body. Use this OR html_body; if both are given, html_body wins.'}, 'from': {'type': 'string', 'description': "Sender address — on a multi-account Mac, selects which configured Mail.app account sends. Omit to use Mail's default account."}, 'confirm': {'type': 'boolean', 'default': 'false', 'description': 'Safety gate: the call only PREVIEWS (nothing is sent) unless confirm:true. Set true to actually send.'}, 'subject': {'type': 'string', 'description': 'Subject line.'}, 'html_body': {'type': 'string', 'description': 'HTML body. Takes precedence over `body` when both are set.'}, 'attachments': {'type': 'string', 'description': 'Files to attach, as comma-separated absolute paths (e.g. a PDF).'}}}
出力スキーマ
{'type': 'object', 'properties': {'to': {'type': 'string'}, 'from': {'type': 'string'}, 'sent': {'type': 'boolean'}, 'subject': {'type': 'string'}}}
send_message
Send Message
Sends an iMessage via the Mac's Messages.app to a recipient handle (phone number with country code, e.g. +14155551234, or an Apple ID email). This is a write operation: the first call (without confirm) returns a preview; call again with confirm=true to actually send. Direct (1:1) iMessage only — sending into an existing group chat isn't supported yet. Optionally attach files (a photo, a PDF, a vCard) via `attachments` — each is sent as its own iMessage, in order, before the text. If every attachment fails, the text is not sent either; if some succeed, the text still sends and `attachments_failed` lists what didn't go through. Requires Messages.app signed in to iMessage + Automation permission.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['to', 'text'], 'properties': {'to': {'type': 'string', 'description': 'Recipient handle: phone number with country code (+14155551234) or Apple ID email.'}, 'text': {'type': 'string', 'description': 'Message body to send.'}, 'confirm': {'type': 'boolean', 'description': 'Set true to actually send. Without it, returns a preview only.'}, 'attachments': {'type': 'string', 'description': 'Files to send, as comma-separated absolute paths (e.g. a photo or PDF). Each is sent as a separate iMessage, before the text.'}}}
出力スキーマ
{'type': 'object', 'properties': {'to': {'type': 'string'}, 'note': {'type': 'string'}, 'sent': {'type': 'boolean'}, 'text': {'type': 'string'}, 'error': {'type': 'string'}, 'preview': {'type': 'boolean'}, 'service': {'type': 'string'}, 'attachments': {'type': 'array', 'items': {'type': 'string'}}, 'attachments_failed': {'type': 'array', 'items': {'type': 'string'}}}}
setup_install
Install LMCP
Returns a personalized LMCP install link and setup steps (~30 sec to install). LMCP is a free Mac and Windows app that gives access to Mail/Calendar/Contacts/Notes/Reminders on Mac, Outlook/Teams/OneDrive/Office on Windows, and 100+ tools on the user's machine (data stays local). A user would invoke this to install LMCP or reconnect it. Pass os ("macos" or "windows" for real install steps; linux/ios/android go to a waitlist). Optional: email, step, issue.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['os'], 'properties': {'os': {'enum': ['macos', 'windows', 'linux', 'ios', 'android'], 'type': 'string', 'description': 'macos | windows | linux | ios | android. Cloud connectors must pass os (or server asks). Desktop terminal clients may omit → macOS. macOS and Windows both get real install steps. Linux/mobile → waitlist (not supported yet).'}, 'step': {'enum': ['connector', 'install', 'email', 'connecting_stuck', 'server_down'], 'type': 'string', 'description': 'If stuck: connector | install | email | connecting_stuck | server_down.'}, 'email': {'type': 'string', 'description': 'Optional. Helps Cloud Relay auto-connect after install.'}, 'issue': {'type': 'string', 'description': 'Optional tag: gatekeeper_error, dot_not_green, install_failed, etc.'}}}
出力スキーマ
{'type': 'object', 'required': ['instructions'], 'properties': {'os': {'type': 'string', 'description': 'Target operating system the instructions are for, when known.'}, 'instructions': {'type': 'string', 'description': 'Full human-readable, step-by-step install/setup text.'}, 'install_command': {'type': 'string', 'description': 'One-line terminal command to install LMCP, when applicable to this OS/step.'}}, 'description': 'Structured install/setup guidance for LMCP.', 'additionalProperties': True}
shortcuts_list
Shortcuts List
Lists the user's macOS Shortcuts (Atajos), each with its stable identifier — the id shortcuts_run and shortcuts_view expect. Pass `folder` to filter to one folder (name or identifier; "none" for shortcuts not in any folder), or `folders: true` to list folder names instead of shortcuts.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'folder': {'type': 'string', 'description': 'Filter to shortcuts in this folder (name, identifier, or "none"). Ignored when folders:true.'}, 'folders': {'type': 'boolean', 'description': 'List folder names instead of shortcuts. Default false.'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'folders': {'type': 'array', 'items': {'type': 'string'}}, 'shortcuts': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'identifier': {'type': 'string'}}}}}}
shortcuts_run
Shortcuts Run
Runs one of the user's macOS Shortcuts (Atajos) by name or identifier — the way Mac users already automate HomeKit, Focus modes, and third-party app actions the catalog doesn't cover. It runs the shortcut's OWN actions under the shortcut's own permissions, not a sandboxed subset — the same as clicking Run in the Shortcuts app. This is a write operation: the first call (confirm=false) returns a preview naming the shortcut, its identifier, and its folder, without running anything; set confirm=true to actually run it. A name that matches more than one shortcut is refused with both identifiers — call again with one of those, never guessed. A shortcut that waits on a dialog or runs long is stopped after a bounded timeout with a clear message instead of hanging this call.
破壊的操作あり 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['name_or_identifier'], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to actually run the shortcut. Without it, returns a preview.'}, 'input_text': {'type': 'string', 'description': 'Optional text input for the shortcut, passed via a temp file — omit if the shortcut takes no input.'}, 'name_or_identifier': {'type': 'string', 'description': 'Shortcut name or identifier, from shortcuts_list. An ambiguous name is refused — pass the identifier instead.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
shortcuts_view
Shortcuts View
Opens a shortcut in the Shortcuts app so the user can inspect its actions before running it with shortcuts_run. Does NOT run the shortcut. Accepts a name or identifier from shortcuts_list.
入力スキーマ
{'type': 'object', 'required': ['name_or_identifier'], 'properties': {'name_or_identifier': {'type': 'string', 'description': 'Shortcut name or identifier, from shortcuts_list.'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'opened': {'type': 'boolean'}, 'identifier': {'type': 'string'}}}
signal_compose_guidance
Signal Compose Guidance
Composes a Signal message and returns step-by-step guidance for the user to send it themselves. This tool does NOT send: Signal Desktop exposes no local send API and LMCP reads its database read-only, so it cannot transmit Signal messages. Call it when the user wants to message someone on Signal — it drafts the text and tells them how to deliver it. First call (show_send_steps=false or omitted) returns a preview; show_send_steps=true returns the send-it-yourself steps. chat_id should come from a previous signal_list_chats call — never fabricate IDs.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['chat_id', 'text'], 'properties': {'text': {'type': 'string', 'description': 'Plain-text message body'}, 'chat_id': {'type': 'string', 'description': 'Chat ID from signal_list_chats'}, 'show_send_steps': {'type': 'boolean', 'description': 'Set true to get the send-it-yourself steps. Default: preview only.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
signal_connect
Signal Connect
Connect Signal to Local MCP. Reports whether Signal Desktop is installed and signed in, and tells you exactly what to do next — install Signal, or open it and link your phone. (Signal links inside its own desktop app, so the QR is shown there, not here.) Once you're signed in, signal_list_chats / signal_read_messages work. If Signal is already connected, it just reports that.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
signal_list_chats
Signal List Chats
Lists Signal conversations (chats) with last-active timestamps. Reads from the local Signal Desktop database — no network access required. Returns chat IDs, contact names, and type (direct or group). Use the chat_id in subsequent signal_read_messages calls.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max chats to return (default 50)'}}}
出力スキーマ
{'type': 'object', 'required': ['chats'], 'properties': {'chats': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'Contact or group name'}, 'type': {'type': 'string', 'description': 'Chat type (direct or group)'}, 'chat_id': {'type': 'string', 'description': 'Chat ID for subsequent calls'}}}, 'description': 'Signal conversations'}, 'count': {'type': 'integer', 'description': 'Number of chats returned'}}}
signal_read_messages
Signal Read Messages
Reads messages from a specific Signal chat. The chat_id must come from a previous signal_list_chats call. Returns messages in chronological order with sender phone numbers and body text. Only messages cached locally by Signal Desktop are available.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['chat_id'], 'properties': {'limit': {'type': 'integer', 'description': 'Max messages to return (default 50)'}, 'chat_id': {'type': 'string', 'description': 'Chat ID from signal_list_chats'}}}
出力スキーマ
{'type': 'object', 'required': ['messages'], 'properties': {'count': {'type': 'integer', 'description': 'Number of messages returned'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'body': {'type': ['string', 'null'], 'description': 'Message body text (null for messages without text)'}, 'date': {'type': 'string', 'description': 'Timestamp'}, 'sender': {'type': ['string', 'null'], 'description': 'Sender phone number (null for messages sent by you)'}}}, 'description': 'Messages from the chat, chronological'}}}
signal_search_messages
Signal Search Messages
Full-text search across locally-cached Signal messages. Only messages Signal Desktop has stored on disk are searched — no network access required. Optionally restrict search to a specific chat_id.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results to return (default 50)'}, 'query': {'type': 'string', 'description': 'Search text (case-insensitive substring match)'}, 'chat_id': {'type': 'string', 'description': 'Optional chat ID to restrict search'}}}
出力スキーマ
{'type': 'object', 'required': ['results'], 'properties': {'count': {'type': 'integer', 'description': 'Number of results returned'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'body': {'type': ['string', 'null'], 'description': 'Message body text (null for messages without text)'}, 'date': {'type': 'string', 'description': 'Timestamp'}, 'sender': {'type': ['string', 'null'], 'description': 'Sender phone number (null for messages sent by you)'}}}, 'description': 'Matching messages'}}}
slack_list_channels
Slack List Channels
Lists channels in a Slack workspace, including public channels, private channels, and direct messages (DMs). Reads from the local IndexedDB cache — only channels that Slack Desktop has synced to disk are returned. Pass workspace_id from slack_list_workspaces to filter to a specific workspace.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max channels to return (default 200)'}, 'workspace_id': {'type': 'string', 'description': 'Workspace ID from slack_list_workspaces (optional — omit to list channels across all workspaces)'}}}
出力スキーマ
{'type': 'object', 'required': ['channels', 'count'], 'properties': {'count': {'type': 'integer', 'description': 'Number of channels returned'}, 'channels': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string', 'description': 'Channel ID'}, 'name': {'type': 'string', 'description': 'Channel name (or dm:<user> for DMs)'}, 'is_im': {'type': 'boolean', 'description': 'Whether this is a direct message'}, 'is_mpim': {'type': 'boolean', 'description': 'Whether this is a multi-person DM'}, 'purpose': {'type': 'string', 'description': 'Channel purpose/topic'}, 'is_private': {'type': 'boolean', 'description': 'Whether the channel is private'}, 'is_archived': {'type': 'boolean', 'description': 'Whether the channel is archived'}, 'workspace_id': {'type': 'string', 'description': 'Owning workspace ID'}}}, 'description': 'Channels and DMs synced to the local cache'}}}
slack_list_workspaces
Slack List Workspaces
Lists the Slack workspaces (teams) the user has connected in Slack Desktop. Start here for Slack — the workspace id it returns is what slack_list_channels / slack_read_channel_messages / slack_search_messages need. Reads from the local IndexedDB cache — no token needed. Only workspaces that have been synced to disk are returned.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['workspaces', 'count'], 'properties': {'count': {'type': 'integer', 'description': 'Number of workspaces returned'}, 'workspaces': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string', 'description': 'Workspace (team) ID'}, 'icon': {'type': 'string', 'description': 'Workspace icon URL'}, 'name': {'type': 'string', 'description': 'Workspace name'}, 'domain': {'type': 'string', 'description': 'Workspace domain'}}}, 'description': 'Connected Slack workspaces synced to the local cache'}}}
slack_read_channel_messages
Slack Read Channel Messages
Reads recent messages from a Slack channel or DM. Reads from the local IndexedDB cache — only messages that Slack Desktop has synced to disk are available (typically the last few hundred messages for active channels). channel_id must come from slack_list_channels.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['channel_id'], 'properties': {'limit': {'type': 'integer', 'description': 'Max messages to return (default 50)'}, 'channel_id': {'type': 'string', 'description': 'Channel ID from slack_list_channels'}}}
出力スキーマ
{'type': 'object', 'required': ['messages', 'count'], 'properties': {'count': {'type': 'integer', 'description': 'Number of messages returned'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'ts': {'type': 'string', 'description': 'Slack timestamp (e.g. 1234567890.123456)'}, 'sent': {'type': 'string', 'description': 'Human-readable sent datetime'}, 'text': {'type': 'string', 'description': 'Message text (truncated to 500 chars)'}, 'user': {'type': 'string', 'description': 'Sender user ID or username'}}}, 'description': 'Recent messages from the channel, oldest first'}}}
slack_search_messages
Slack Search Messages
Searches Slack messages. Optionally restrict to a specific channel_id. A hit whose `text` is the marker "[body not included in this search result]" (with `body_missing: true`) DID match — its body was lost by the reader, not empty. Read it with slack_read_channel_messages on its channel_id; never report it to the user as an empty message. Direct messages come back as an unresolved id rather than a name; slack_list_channels maps ids to names.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results to return (default 50)'}, 'query': {'type': 'string', 'description': 'Search text (case-insensitive substring match)'}, 'channel_id': {'type': 'string', 'description': 'Optional channel ID to restrict search'}}}
出力スキーマ
{'type': 'object', 'required': ['results', 'count'], 'properties': {'note': {'type': 'string', 'description': 'Present when something about the answer needs stating: bodies that did not survive the reader, unresolved channel names, or a genuine zero'}, 'count': {'type': 'integer', 'description': 'Number of results returned'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'ts': {'type': 'string', 'description': 'Slack timestamp (e.g. 1234567890.123456)'}, 'sent': {'type': 'string', 'description': 'Human-readable sent datetime'}, 'text': {'type': 'string', 'description': 'Message text (truncated to 500 chars), or an explicit marker when the body is missing — never a silent empty string'}, 'user': {'type': 'string', 'description': 'Sender user ID or username'}, 'channel_id': {'type': 'string', 'description': 'ID of the channel the message is in'}, 'body_missing': {'type': 'boolean', 'description': "True when the match's text did not survive the reader — the message exists and matched; see `note`"}, 'channel_name': {'type': 'string', 'description': 'Name of the channel (when known)'}, 'user_unresolved': {'type': 'boolean', 'description': 'True when `user` is a raw Slack id, not a name'}, 'channel_name_unresolved': {'type': 'boolean', 'description': 'True when the channel could not be resolved to a readable name'}}}, 'description': 'Matching messages, most recent first'}}}
stocks_get_chart
Stocks Get Chart
Gets historical price data for a stock symbol. Range: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['symbol'], 'properties': {'range': {'enum': ['1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max'], 'type': 'string', 'description': 'Time range (default: 1mo)'}, 'symbol': {'type': 'string', 'description': 'Ticker symbol, e.g. AAPL'}, 'interval': {'enum': ['1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1wk', '1mo', '3mo'], 'type': 'string', 'description': 'Data interval (default: 1d). Intraday (1m–90m) needs a short range.'}}}
出力スキーマ
{'type': 'object', 'properties': {'name': {'type': 'string'}, 'range': {'type': 'string'}, 'symbol': {'type': 'string'}, 'candles': {'type': 'array', 'items': {'type': 'object', 'properties': {'low': {'type': 'number'}, 'date': {'type': 'string'}, 'high': {'type': 'number'}, 'open': {'type': 'number'}, 'close': {'type': 'number'}, 'volume': {'type': 'integer'}}}}, 'currency': {'type': 'string'}, 'interval': {'type': 'string'}, 'change_pct': {'type': 'number'}, 'data_points': {'type': 'integer'}, 'current_price': {'type': 'number'}}}
stocks_get_quote
Stocks Get Quote
Gets current stock price and market data for one or more symbols (e.g. AAPL, MSFT, BTC-USD). Uses Yahoo Finance — no API key required.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['symbols'], 'properties': {'symbols': {'type': 'string', 'description': "Ticker symbols, comma-separated ('AAPL,MSFT,GOOGL') or a JSON array (['AAPL','MSFT'])"}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
stocks_search_symbol
Stocks Search Symbol
Searches for a stock ticker symbol by company name (e.g. "Apple" → AAPL). Start here for Stocks — the symbol it returns is what stocks_get_quote / stocks_get_chart need.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 10)'}, 'query': {'type': 'string', 'description': 'Company name or partial ticker to search for'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'query': {'type': 'string'}, 'results': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'type': {'type': 'string'}, 'symbol': {'type': 'string'}, 'exchange': {'type': 'string'}}}}}}
survey_respond
Survey Respond
Shows or submits the short in-product survey Local MCP assigned to this machine. Called with NO arguments it returns the pending survey and, in clients that support MCP Apps, renders it as an interactive card the user answers directly — prefer this. To submit conversational answers instead, pass `answers` keyed by each question's `id` (single/scale = one value, multiple = an array of values): call once to PREVIEW, then again with confirm=true to record. Do NOT invent answers — if no human gave them (you're running autonomously), call survey_skip instead.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'answers': {'type': 'object', 'description': 'Answers keyed by question id. Single/scale = a value; multiple = an array.', 'additionalProperties': True}, 'confirm': {'type': 'boolean', 'description': 'Set true to actually record the answers. Omit/false = preview only (nothing is stored).'}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'survey': {'type': 'object', 'description': 'The pending survey (no-args call) — rendered by the MCP Apps card.', 'additionalProperties': True}, 'message': {'type': 'string'}, 'preview': {'type': 'boolean'}}}
survey_skip
Survey Skip
Skips the short in-product survey Local MCP showed the user, for now — use this when the user doesn't want to answer right now. They won't be asked again this session.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
teams_call_history
Teams Call History
Reads Microsoft Teams call & meeting history from the Mac's local Teams cache — no Graph API, no token, no admin consent (the same local store the Teams Calls tab renders). Each call includes direction (incoming/outgoing/missed), participants (names + ids), start / answered / end times, duration, call type (1:1/group/meeting) and a stable call id. Optional since/until (YYYY-MM-DD) narrow the range — e.g. a daily collector pulls the previous day's calls.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max calls to return (default 50), newest first'}, 'since': {'type': 'string', 'description': 'Only calls on/after this date, YYYY-MM-DD (optional)'}, 'until': {'type': 'string', 'description': 'Only calls on/before this date, YYYY-MM-DD (optional)'}}}
出力スキーマ
{'type': 'object', 'properties': {'calls': {'type': 'array', 'items': {'type': 'object', 'properties': {'end': {'type': 'string'}, 'start': {'type': 'string'}, 'state': {'type': 'string'}, 'call_id': {'type': 'string'}, 'answered': {'type': 'string'}, 'call_type': {'type': 'string'}, 'direction': {'type': 'string'}, 'duration_s': {'type': 'integer'}, 'participants': {'type': 'array'}}}}, 'count': {'type': 'integer'}, 'error': {'type': 'string'}}}
teams_list_channels
Teams List Channels
Lists channels in a Microsoft Teams workspace. Returns channels that are cached in the local Teams client. If the result is empty, the channels have not been loaded into the local cache yet — ask the user to open Microsoft Teams and browse to the team's channels, then try again.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['team_id'], 'properties': {'team_id': {'type': 'string', 'description': 'Team ID from teams_list_teams'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'error': {'type': 'string'}, 'channels': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}}}}}}
teams_list_chats
Teams List Chats
Lists Microsoft Teams chats (direct messages and group chats).
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max chats to return (default 50)'}}}
出力スキーマ
{'type': 'object', 'properties': {'chats': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'type': {'type': 'string'}, 'title': {'type': 'string'}, 'last_sender': {'type': 'string'}, 'last_message': {'type': 'string'}, 'participants': {'type': 'string'}, 'last_message_at': {'type': 'string'}}}}, 'count': {'type': 'integer'}, 'error': {'type': 'string'}}}
teams_list_teams
Teams List Teams
Lists all the Microsoft Teams the user belongs to. Start here for Teams channels — the team id it returns feeds teams_list_channels / teams_read_channel_messages. (For 1:1 and group chats, list_message-style, use teams_list_chats.)
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'error': {'type': 'string'}, 'teams': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}}}}}}
teams_read_channel_messages
Teams Read Channel Messages
Reads messages from a Microsoft Teams channel (team_id and channel_id from teams_list_channels). Needs Full Disk Access to read Teams' local data; without it, returns {error, permission: true} instead of messages. Returns up to `limit` messages (default 50).
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['team_id', 'channel_id'], 'properties': {'limit': {'type': 'integer', 'description': 'Max messages (default 50)'}, 'team_id': {'type': 'string', 'description': 'Team ID'}, 'channel_id': {'type': 'string', 'description': 'Channel ID from teams_list_channels'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'error': {'type': 'string'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'body': {'type': 'string'}, 'sent': {'type': 'string'}, 'sender': {'type': 'string'}}}}}}
teams_read_chat_messages
Teams Read Chat Messages
Reads messages from a Teams chat or direct message thread (chat_id from teams_list_chats). Needs Full Disk Access to read Teams' local data; without it, returns {error, permission: true} instead of messages. Returns up to `limit` messages (default 50).
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['chat_id'], 'properties': {'limit': {'type': 'integer', 'description': 'Max messages (default 50)'}, 'chat_id': {'type': 'string', 'description': 'Chat ID from teams_list_chats'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'error': {'type': 'string'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'body': {'type': 'string'}, 'sent': {'type': 'string'}, 'sender': {'type': 'string'}}}}}}
teams_search_messages
Teams Search Messages
Searches your Microsoft Teams chat and direct-message history (all conversations at once) by text, sender name, and/or date range. Use this to find where something was discussed in Teams without knowing which chat. Returns matching messages with the chat they came from. Provide at least one of query, from_sender, since, until.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max results, newest first (default 50, max 200)'}, 'query': {'type': 'string', 'description': 'Text to find in message bodies (case-insensitive substring)'}, 'since': {'type': 'string', 'description': 'Only messages on/after this date, YYYY-MM-DD (optional)'}, 'until': {'type': 'string', 'description': 'Only messages on/before this date, YYYY-MM-DD (optional)'}, 'from_sender': {'type': 'string', 'description': 'Filter to a sender by display-name substring (optional)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'error': {'type': 'string'}, 'messages': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'body': {'type': 'string'}, 'sent': {'type': 'string'}, 'sender': {'type': 'string'}, 'chat_id': {'type': 'string'}, 'chat_name': {'type': 'string'}}}}}}
teams_send_channel_message
Teams Send Channel Message
Sends a text message to a Microsoft Teams channel via Graph API. Requires connect_m365_account with Chat.ReadWrite / ChannelMessage.Send permissions. team_id and channel_id must come from teams_list_teams / teams_list_channels. First call returns a preview; set confirm=true to send.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['team_id', 'channel_id', 'text'], 'properties': {'text': {'type': 'string', 'description': 'Plain-text message body'}, 'confirm': {'type': 'boolean', 'description': 'Set true to send; false returns preview'}, 'team_id': {'type': 'string', 'description': "Team ID from teams_list_teams, or the team's name"}, 'channel_id': {'type': 'string', 'description': "Channel ID from teams_list_channels, or the channel's name"}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
teams_send_message
Teams Send Message
Sends a text message to a Microsoft Teams chat or channel. Requires Microsoft Teams to be running and signed in (token is read fresh from Teams' local cookies on each call). The chat_id MUST come from a previous teams_list_chats call — never fabricate ids. This is a write operation: the first call returns a preview, the second call (with confirm=true) actually sends. sent:true means the message was read back from the conversation (delivery verified) — trust THAT field, not a follow-up read: teams_search_messages and teams_read_chat_messages read Teams' own local sync index, which can lag a verified send by minutes (single observed case: 3 min, #2285). A zero-result sibling read right after sending is NOT evidence the send failed. A response with status "sent_unconfirmed" means the server accepted the POST but the message could NOT be verified — tell the user to open Teams itself and check before assuming the recipient was notified.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['chat_id', 'text'], 'properties': {'text': {'type': 'string', 'description': 'Plain-text message body. Max 28000 chars. No formatting / mentions / attachments in v1.'}, 'chat_id': {'type': 'string', 'description': "Thread id from teams_list_chats (e.g. '19:<uuid>_<uuid>@unq.gbl.spaces' for 1:1, '19:<uuid>@thread.tacv2' for group)"}, 'confirm': {'type': 'boolean', 'description': 'Must be true to actually send. Without it, returns a preview without making any network call.'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
todo_complete_task
To Do Complete Task
Marks a Microsoft To Do task as complete (via Reminders sync).
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'list': {'type': 'string', 'description': 'List name to narrow search by title (optional)'}, 'title': {'type': 'string', 'description': 'Task title (partial match, alternative to task_id)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to complete'}, 'task_id': {'type': 'string', 'description': 'Task ID from todo_list_tasks'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
todo_create_task
To Do Create Task
Creates a task in Microsoft To Do (via Reminders sync). Task appears in To Do automatically once synced.
入力スキーマ
{'type': 'object', 'required': ['title'], 'properties': {'list': {'type': 'string', 'description': 'List name (from todo_get_folders). Defaults to first available list.'}, 'notes': {'type': 'string', 'description': 'Task notes (optional)'}, 'title': {'type': 'string', 'description': 'Task title'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}, 'due_date': {'type': 'string', 'description': 'Due date (YYYY-MM-DD, optional)'}, 'priority': {'type': 'integer', 'description': 'Priority: 1=high, 5=medium, 9=low (optional)'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
todo_get_folders
To Do Get Folders
Lists Microsoft To Do task lists. Requires Microsoft account in Reminders sync (System Settings → Internet Accounts → Microsoft Exchange → enable Reminders).
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'note': {'type': 'string'}, 'count': {'type': 'integer'}, 'lists': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'type': {'type': 'string', 'description': 'exchange | caldav'}, 'account': {'type': 'string'}}}}}}
todoist_complete_task
Todoist Complete Task
Mark a Todoist task complete (closes it). Pass the task_id from todoist_list_tasks.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['task_id'], 'properties': {'task_id': {'type': 'string', 'description': 'The task id to complete'}}}
出力スキーマ
{'type': 'object', 'required': ['ok', 'message'], 'properties': {'ok': {'type': 'boolean'}, 'message': {'type': 'string'}}}
todoist_create_task
Todoist Create Task
Create a Todoist task. Optionally set a project, a natural-language due date (due_string, e.g. 'tomorrow 5pm', 'every monday'), and priority (1=normal … 4=urgent).
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['content'], 'properties': {'content': {'type': 'string', 'description': 'The task text'}, 'priority': {'type': 'integer', 'description': '1 (normal) to 4 (urgent). Todoist UI p1 = 4.'}, 'due_string': {'type': 'string', 'description': "Natural-language due date, e.g. 'tomorrow 5pm', 'next monday'"}, 'project_id': {'type': 'string', 'description': 'Project to add it to (default: Inbox)'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'due': {'type': 'string'}, 'url': {'type': 'string'}, 'content': {'type': 'string'}, 'priority': {'type': 'integer'}, 'project_id': {'type': 'string'}}}
todoist_list_projects
Todoist List Projects
List your Todoist projects (id + name). Use a project's id to scope todoist_list_tasks or todoist_create_task.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'required': ['projects', 'count'], 'properties': {'count': {'type': 'integer'}, 'projects': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}}}}}}
todoist_list_tasks
Todoist List Tasks
List active (incomplete) Todoist tasks. Optionally scope to a project_id, or pass a Todoist filter (e.g. 'today', 'overdue', '#Work & p1').
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max results (default 50, max 200)'}, 'filter': {'type': 'string', 'description': "A Todoist filter query, e.g. 'today', 'overdue', 'p1'"}, 'project_id': {'type': 'string', 'description': 'Only tasks in this project (from todoist_list_projects)'}}}
出力スキーマ
{'type': 'object', 'required': ['tasks', 'count'], 'properties': {'count': {'type': 'integer'}, 'tasks': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'due': {'type': 'string'}, 'url': {'type': 'string'}, 'content': {'type': 'string'}, 'priority': {'type': 'integer'}, 'project_id': {'type': 'string'}}}}}}
todo_list_tasks
To Do List Tasks
Lists tasks from a Microsoft To Do list (or any Reminders list). Syncs via macOS Reminders.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'list': {'type': 'string', 'description': 'List name (from todo_get_folders). Leave empty to show all.'}, 'limit': {'type': 'integer', 'description': 'Max tasks to return (default 50)'}, 'include_completed': {'type': 'boolean', 'description': 'Include completed tasks (default false)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'tasks': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'due': {'type': 'string'}, 'list': {'type': 'string'}, 'notes': {'type': 'string'}, 'title': {'type': 'string'}, 'priority': {'type': 'integer'}, 'completed': {'type': 'boolean'}}}}}}
ui_click
Ui Click
Clicks an element (by element_ref, at its center) or a screen coordinate (by coords). button left|right, count 2 = double-click. Returns {clicked, at:{x,y}} — `clicked` means the click event was POSTED at those coordinates, NOT that the app acted on it: CGEvent carries no delivery confirmation, so a busy, modal or input-ignoring app reports exactly the same success. Confirm the effect with ui_wait_for_element or ui_read_tree rather than trusting `clicked`. element_disabled is returned ONLY when the app actually publishes AXEnabled=false; a control that does not publish AXEnabled at all is treated as unknown and clicked. Requires Accessibility permission.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'by': {'enum': ['element', 'coords'], 'type': 'string', 'description': 'Default element if element_ref given, else coords.'}, 'count': {'type': 'integer', 'description': '1 (default) or 2 for double-click.'}, 'button': {'enum': ['left', 'right'], 'type': 'string', 'description': 'Default left.'}, 'coords': {'type': 'object', 'description': '{x,y} in global screen points.'}, 'element_ref': {'type': 'string', 'description': "Element handle returned by ui_find_element or ui_read_tree; the click lands at that element's center. Needed when by=element, which is the default whenever element_ref is present."}}}
ui_find_element
Ui Find Element
GUI automation — control a native app's interface. Finds an element (button, field, menu…) in an app's accessibility tree by role and/or label. Scope with app_bundle_id or window_id. Returns an opaque element_ref (usable by ui_click / ui_get_element this session) plus role, label, bounds, focused, and `enabled` only when the app publishes AXEnabled (otherwise `enabled_unknown: true`, which does NOT mean disabled). found=false when the app is reachable but no element matches; app_not_found is an explicit error. Requires Accessibility permission.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'role': {'type': 'string', 'description': 'AX role, e.g. AXButton, AXMenuItem, AXTextField.'}, 'index': {'type': 'integer', 'description': 'Which match to return if several (default 0).'}, 'label': {'type': 'string', 'description': 'AX title/description to match.'}, 'match': {'enum': ['exact', 'contains'], 'type': 'string', 'description': 'Default contains.'}, 'window_id': {'type': 'string', 'description': 'Alternatively scope by a window_id from list_windows.'}, 'app_bundle_id': {'type': 'string', 'description': 'Scope the search to this app.'}}}
ui_get_element
Ui Get Element
Re-resolves a previously returned element_ref (its bounds/state may have changed). Returns role, label, bounds, focused, value, and `enabled` ONLY when the app publishes AXEnabled — that attribute is optional, so many perfectly usable controls omit it (TextEdit's text area does). When it is missing you get `enabled_unknown: true` instead; that is 'unknown', NOT disabled, and ui_click will click it. stale_element if the handle is unknown or the element no longer exists.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['element_ref'], 'properties': {'element_ref': {'type': 'string', 'description': 'Reference returned by an earlier UI call. Re-resolving it picks up bounds and state that may have changed since.'}}}
ui_keystroke
Ui Keystroke
Sends a key combination, e.g. "cmd+shift+5", "return", "cmd+,", "escape". Modifiers: cmd, shift, alt/option, ctrl, fn. The last token is the key. Returns {sent, delivery:"posted_not_confirmed"} — `sent` means the key events were POSTED, NOT that the app acted on them: CGEvent carries no delivery confirmation, and a keystroke's effect is arbitrary so nothing can be read back to prove it. Confirm the effect with ui_get_element / ui_read_tree rather than trusting `sent`. Modifiers are released after the combo, so a following ui_type is not swallowed. unknown_key if the key isn't recognized. Requires Accessibility permission.
入力スキーマ
{'type': 'object', 'required': ['keys'], 'properties': {'keys': {'type': 'string', 'description': 'e.g. cmd+shift+5, return, cmd+,'}}}
ui_menu_bar_click
Ui Menu Bar Click
Clicks a status-bar (menu bar extra / NSStatusItem) item and optionally follows a nested menu path. Best-effort via the app's AX extras menu bar; apps that render fully custom (non-AX) menus may not be reachable (fall back to ui_click at known coords). Requires Accessibility permission.
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'path': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Nested menu path, e.g. ["App","Settings…"].'}, 'label': {'type': 'string', 'description': 'Status item / menu item title.'}, 'app_bundle_id': {'type': 'string', 'description': 'Owner of the status item.'}}}
ui_read_tree
Ui Read Tree
Returns a COMPACT accessibility tree of a running native app's labeled + interactive elements (buttons, links, text fields, checkboxes, menus…) — the native equivalent of web_read's a11y mode. Use it to DISCOVER what to act on in an unfamiliar app when you don't already know an element's role/label (ui_find_element needs one up front). Each interactive node carries a `ref` you can pass straight to ui_click. Pass app_bundle_id of a running app (e.g. com.apple.finder — see list_windows); the tree is pruned to signal-bearing nodes and bounded by max_depth (default 12) and a node budget, so very large windows return partial. The app's macOS menu bar is skipped by default (it's hundreds of menu-item nodes) — pass include_menu_bar=true if you specifically need to act on menu-bar items.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'max_depth': {'type': 'integer', 'description': 'Max tree depth to descend (default 12, max 20)'}, 'window_id': {'type': 'string', 'description': "Alternative to app_bundle_id: a window id from list_windows (targets that window's app)"}, 'app_bundle_id': {'type': 'string', 'description': 'Bundle id of a RUNNING app (e.g. com.apple.finder)'}, 'include_menu_bar': {'type': 'boolean', 'description': "Include the app's macOS menu bar (hundreds of menu-item nodes). Default false."}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
ui_type
Ui Type
Types text into the focused control (or focuses element_ref first, then types). Sends real key events so validation/handlers fire. The result is VERIFIED BY READING the control back, not by the write succeeding: {typed, verified:true} means its value actually changed; input_not_applied is an explicit error meaning the events were posted and the value did NOT change (nothing was typed — usually the window is not frontmost); verified:false + verification:'unavailable' means the target publishes no readable value, so delivery could not be confirmed and you should read it back yourself. Requires Accessibility permission.
入力スキーマ
{'type': 'object', 'required': ['text'], 'properties': {'text': {'type': 'string', 'description': 'The text to type.'}, 'element_ref': {'type': 'string', 'description': 'Optional; focus this element first.'}}}
ui_wait_for_element
Ui Wait For Element
Deterministic synchronization — replaces all sleeps. Polls for an element until it reaches state (present|enabled|focused|absent) or times out. A timeout is an EXPLICIT error, never a false success. Returns {satisfied, waited_ms, element_ref?, bounds?, enabled_unknown?}. state:'enabled' is satisfied unless the app publishes AXEnabled=false; if the app publishes no AXEnabled at all the result carries enabled_unknown:true — the wait did not block, but nothing was actually verified about enabled-ness.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'role': {'type': 'string', 'description': 'Accessibility role of the element (e.g. AXButton, AXTextField).'}, 'label': {'type': 'string', 'description': 'Visible label or title of the element.'}, 'match': {'enum': ['exact', 'contains'], 'type': 'string', 'description': 'How to compare label: "exact" (default) or "contains".'}, 'state': {'enum': ['present', 'enabled', 'focused', 'absent'], 'type': 'string', 'description': 'Default present.'}, 'poll_ms': {'type': 'integer', 'description': 'Default 150.'}, 'window_id': {'type': 'string', 'description': 'Window to look in, from list_windows. Narrows the search to one window.'}, 'timeout_ms': {'type': 'integer', 'description': 'Default 5000.'}, 'app_bundle_id': {'type': 'string', 'description': 'Bundle id of the app to look in (e.g. com.apple.Safari). Narrows the search and makes it faster.'}}}
update_calendar_event
Update Calendar Event
Updates an existing event in the Mac's Calendar app (Calendar.app) by ID. Pass only the fields you want to change — unspecified fields are left as-is. Get the event_id from list_calendar_events; for a recurring event, pass the per-occurrence id from the specific row you mean, not a bare series id. For Microsoft 365 use the m365 calendar tools instead.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['event_id'], 'properties': {'span': {'type': 'string', 'description': "For recurring events: 'this' (default — only this occurrence) or 'future' (this and all following occurrences; 'all'/'series' mean the same). Any other value is refused."}, 'notes': {'type': 'string', 'description': 'New notes — pass empty string to clear (optional)'}, 'title': {'type': 'string', 'description': 'New title (optional)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to apply changes'}, 'end_date': {'type': 'string', 'description': 'New end datetime ISO 8601 (optional). Same timezone rules as start_date.'}, 'event_id': {'type': 'string', 'description': 'Event (or occurrence) identifier from list_calendar_events. For a recurring event this addresses exactly the occurrence that id came from — the preview names the date and scope so you can confirm before applying.'}, 'location': {'type': 'string', 'description': 'New location — pass empty string to clear (optional)'}, 'start_date': {'type': 'string', 'description': "New start datetime ISO 8601 (optional). No timezone = Mac's local time; append Z/offset to pin the zone."}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'end': {'type': 'string'}, 'notes': {'type': 'string'}, 'start': {'type': 'string'}, 'title': {'type': 'string'}, 'all_day': {'type': 'boolean'}, 'updated': {'type': 'boolean'}, 'calendar': {'type': 'string'}, 'location': {'type': 'string'}, 'attendees': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'role': {'type': 'string'}, 'email': {'type': 'string'}, 'is_me': {'type': 'boolean'}, 'status': {'type': 'string'}}}}, 'calendar_id': {'type': 'string'}, 'attendees_total': {'type': 'integer'}}}
update_note
Update Note
Updates an existing note in Apple Notes. Change the title and/or body (the body accepts Markdown, converted to Apple Notes' native formatting). Find note_id with list_notes or search_notes. Requires confirm=true.
破壊的操作あり
入力スキーマ
{'type': 'object', 'properties': {'body': {'type': 'string', 'description': "New body, replacing the current one. Accepts Markdown, converted to Apple Notes' native formatting. Check body_format from read_note before writing a body back."}, 'title': {'type': 'string', 'description': 'New title. Leave it out to keep the current one.'}, 'confirm': {'type': 'boolean', 'description': 'Set to true to actually apply the change. Defaults to false.'}, 'note_id': {'type': 'string', 'description': 'Id of the note to change, from list_notes or search_notes. Use this or note_name.'}, 'note_name': {'type': 'string', 'description': 'Title of the note to change, when you do not have its id. Use this or note_id.'}}}
出力スキーマ
{'type': 'object', 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'updated': {'type': 'boolean'}}}
update_reminder
Update Reminder
Updates an existing reminder in Reminders.app. Change the title, due date, notes, priority, or move it to another list (list_name). Get reminder_id from list_reminders. Requires confirm=true. IMPORTANT: moving to a list in a DIFFERENT account (e.g. iCloud ↔ Exchange) recreates the reminder, so its id changes — the response then has id_changed: true, the new id in reminder_id and the dead one in previous_reminder_id. Always take reminder_id from the response before any follow-up call.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['reminder_id'], 'properties': {'notes': {'type': 'string', 'description': 'New notes text (optional)'}, 'title': {'type': 'string', 'description': 'New title (optional)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to apply changes'}, 'due_date': {'type': 'string', 'description': 'New ISO 8601 due date. Pass empty string to clear (optional)'}, 'priority': {'enum': ['none', 'low', 'medium', 'high'], 'type': 'string', 'description': 'Priority: none | low | medium | high (optional)'}, 'list_name': {'type': 'string', 'description': 'Move the reminder to this list (a name from get_reminder_folders) (optional). Moving to a list in ANOTHER account recreates the reminder and CHANGES its id — read the new one from reminder_id in the response (id_changed: true).'}, 'reminder_id': {'type': 'string', 'description': 'Reminder identifier from list_reminders'}}}
出力スキーマ
{'type': 'object', 'properties': {'list': {'type': 'string', 'description': 'Destination list, when the update moved the reminder.'}, 'note': {'type': 'string'}, 'title': {'type': 'string'}, 'updated': {'type': 'boolean'}, 'id_changed': {'type': 'boolean', 'description': 'true when the update recreated the reminder (a move across accounts), which invalidates the id you passed in.'}, 'reminder_id': {'type': 'string', 'description': "The reminder's id AFTER the update — use this one from now on."}, 'previous_reminder_id': {'type': 'string', 'description': 'Only when id_changed: the id you passed in, which no longer exists.'}}, 'additionalProperties': True}
video_blur_region
Video Blur Region
Pixelates/blurs one or more rectangles over the video — the tool for redacting PII (an email pane, a name) before publishing a screen recording. Rects are in source pixels, top-left origin: [{x,y,w,h, start_ms?, end_ms?}] — omit the times to cover the whole clip. Great with a marker timeline's `bounds`. Returns the output path.
入力スキーマ
{'type': 'object', 'required': ['input', 'regions'], 'properties': {'input': {'type': 'string', 'description': 'Path to the source video file.'}, 'output': {'type': 'string', 'description': 'Default: <input>_blurred.mov. Missing parent folders are created.'}, 'regions': {'type': 'array', 'items': {'type': 'object'}, 'description': '[{x,y,w,h, start_ms?, end_ms?}] in source pixels (top-left).'}}}
video_concat
Video Concat
Stitches multiple videos end-to-end, in order, into one NEW file (e.g. assemble separate acts). All inputs should share a resolution for a clean result. Returns the output path + duration.
入力スキーマ
{'type': 'object', 'required': ['inputs'], 'properties': {'inputs': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Ordered list of video file paths.'}, 'output': {'type': 'string', 'description': 'Output path (default: <first-input>_joined.mov). Missing parent folders are created.'}}}
video_export_gif
Video Export Gif
Exports a video (or a [start_ms,end_ms] slice of it) to an optimized looping GIF — for README/social. fps (default 12) and width (default 640, height auto) control size. Returns the output path, frame count, and size.
入力スキーマ
{'type': 'object', 'required': ['input'], 'properties': {'fps': {'type': 'integer', 'description': 'Frames per second in the GIF (default 12).'}, 'input': {'type': 'string', 'description': 'Path to the source video.'}, 'width': {'type': 'integer', 'description': 'Output width in px, height scales to keep aspect (default 640).'}, 'end_ms': {'type': 'integer', 'description': 'Slice end (default: end of video).'}, 'output': {'type': 'string', 'description': 'Output path (default: <input>.gif). Missing parent folders are created.'}, 'start_ms': {'type': 'integer', 'description': 'Slice start (default 0).'}}}
video_reframe
Video Reframe
Crops a video to a target aspect ratio (e.g. "9:16" vertical, "1:1" square, "4:5") around a focus point — for social clips. Takes the LARGEST crop of that aspect that fits, centered on `focus` (x,y in source pixels, top-left origin; default = center) and clamped to the frame. Audio passes through. Returns the output path + new dimensions.
入力スキーマ
{'type': 'object', 'required': ['input', 'aspect'], 'properties': {'focus': {'type': 'object', 'description': '{x,y} center of interest in source pixels (top-left). Default: frame center.'}, 'input': {'type': 'string', 'description': 'Path to the source video file.'}, 'aspect': {'type': 'string', 'description': 'Target aspect "W:H", e.g. 9:16, 1:1, 4:5, 16:9.'}, 'output': {'type': 'string', 'description': 'Default: <input>_<aspect>.mov. Missing parent folders are created.'}}}
video_trim
Video Trim
Trims a video to one or more time ranges (milliseconds), concatenated in order into a NEW file — e.g. keep [{start_ms:0,end_ms:6000},{start_ms:126000,end_ms:223000}] to drop a dead segment. Audio is carried along. Returns the output path + duration. Never overwrites the input in place.
入力スキーマ
{'type': 'object', 'required': ['input', 'ranges'], 'properties': {'input': {'type': 'string', 'description': 'Path to the source video.'}, 'output': {'type': 'string', 'description': 'Output path (default: <input>_trimmed.mov). Missing parent folders are created.'}, 'ranges': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Ordered [{start_ms, end_ms}] to keep.'}}}
web_click
Web Click
Clicks an element on the current page. `target` is a CSS selector or visible text (resolved fresh each call). Clicks that SUBMIT a form preview first — call again with confirm:true to execute; plain links/buttons click directly. Returns {url, title, navigated, url_as_of}: `url_as_of` is "settled" when the page has finished changing, and "before_click" together with navigation_pending:true when the click started a navigation that had not finished — in that case url/title are the page BEFORE the click, NOT the destination, so do not read them as 'the click did nothing' and retry (the page is already changing); read the destination with web_read or wait for it with web_wait_for. `navigated:false` means the click changed no page.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['target'], 'properties': {'target': {'type': 'string', 'description': 'CSS selector or visible text of the element to click.'}, 'confirm': {'type': 'boolean', 'description': 'Required (true) to perform a click that submits a form.'}, 'session': {'type': 'string', 'description': "Session name (default 'default')."}}}
web_extract
Web Extract
Scrapes structured data from the current page. Pass `selectors` = an object mapping field names to CSS selectors (e.g. {"title":"h1","price":".price"}); returns each field's first-match text/href, null when absent.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['selectors'], 'properties': {'session': {'type': 'string', 'description': "Session name (default 'default')."}, 'selectors': {'type': 'object', 'description': 'Field name → CSS selector map.', 'additionalProperties': {'type': 'string'}}}}
出力スキーマ
{'type': 'object', 'properties': {'url': {'type': 'string'}, 'data': {'type': 'object', 'description': 'One key per requested field; first-match text/href, null when absent.', 'additionalProperties': True}, 'title': {'type': 'string'}}}
web_find
Web Find
Finds elements on the current page of a web session so you can decide what to click or type into. `query` is a CSS selector OR visible text to match. Returns up to 30 matches with tag/text/name/type/href — never a silent empty.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['query'], 'properties': {'query': {'type': 'string', 'description': "A CSS selector (e.g. 'input[name=q]') or visible text (e.g. 'Sign in')."}, 'session': {'type': 'string', 'description': "Session name (default 'default')."}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer', 'description': 'Number of matching elements (max 30 returned).'}, 'query': {'type': 'string'}, 'matches': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'description': 'Matched elements with tag/text/name/type/href.'}}}
web_login
Web Login
Opens a real browser window on the Mac for the user to sign into a website themselves (you never handle their password). After they log in, the session is saved on this Mac and reused by web_navigate/web_read/web_screenshot — they won't need to log in again. Use a stable `session` name per site (e.g. 'linkedin'). NOTE: automating sites like Instagram/LinkedIn may violate their terms — the user accepts that risk.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['url'], 'properties': {'url': {'type': 'string', 'description': "The site's login URL to open, e.g. https://www.linkedin.com/login"}, 'session': {'type': 'string', 'description': "A stable name for this login profile, e.g. 'linkedin'."}}}
web_navigate
Web Navigate
Navigates a web session to a URL (using its saved login if any) and returns the resulting URL + page title. Opens the session if it doesn't exist. CHECK `loaded` before reading: when it is false the page did not load and `message` says why — reading the session then describes a blank document, not the site. Read the page with web_read.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['url'], 'properties': {'url': {'type': 'string', 'description': 'URL to open (https).'}, 'session': {'type': 'string', 'description': "Session name (default 'default')."}, 'timeout_seconds': {'type': 'integer', 'description': 'Max seconds to wait for load (default 25).'}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean', 'description': 'True only when the requested page actually loaded.'}, 'url': {'type': 'string', 'description': "The URL the browser settled on (redirects followed). If it isn't the page you asked for, the navigation didn't deliver it."}, 'error': {'type': 'string', 'description': 'Present only on failure: nav_failed (the browser rejected the load), nav_timeout, or nav_blank (it finished on a blank document).'}, 'title': {'type': 'string', 'description': 'The resulting page title.'}, 'loaded': {'type': 'boolean', 'description': 'True only when the browser ended on a real web page. False means nothing was loaded — do NOT read the session and treat the result as page content.'}, 'message': {'type': 'string', 'description': "Present only on failure: why the page didn't load, and what to do about it."}, 'settle_rejected_by': {'type': 'string', 'description': "Present only with nav_timeout: which check ruled out 'the page arrived and WebKit just did not say so' - navigation_started (another navigation began and hung, so the visible document is the old one), other_url (it settled on a different page), or not_complete (the document never finished parsing)."}}}
web_read
Web Read
Reads the current page of a web session so you can reason over it. mode='text' (visible text, default), 'a11y' (compact accessible tree of links/buttons/fields — best for deciding what to click), or 'html' (raw DOM). Returns an explicit no_session error if the session isn't open, and no_page if it hasn't loaded a page — never a silent empty.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'mode': {'enum': ['text', 'a11y', 'html'], 'type': 'string', 'description': 'What to return (default text).'}, 'session': {'type': 'string', 'description': "Session name (default 'default')."}}}
出力スキーマ
{'type': 'object', 'properties': {'url': {'type': 'string'}, 'mode': {'type': 'string', 'description': 'The mode that was read (text/a11y/html).'}, 'title': {'type': 'string'}, 'content': {'type': 'string', 'description': 'The page content in the requested mode.'}}}
web_screenshot
Web Screenshot
Captures a PNG screenshot of the current page of a web session (returned inline so web AIs can see it). Useful to ground what the page looks like before acting.
読み取り専用 外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'session': {'type': 'string', 'description': "Session name (a named login profile, e.g. 'linkedin'). Defaults to 'default'."}}}
出力スキーマ
{'type': 'object', 'properties': {'url': {'type': 'string', 'description': 'URL of the page that was captured.'}, 'bytes': {'type': 'integer', 'description': 'PNG size in bytes (the image itself is an inline content block).'}}}
web_session_close
Web Session Close
Closes a web-automation session's window and frees it. The saved login STAYS on disk (cookies included), so web_login/web_navigate can reopen it later without signing in again — it also means closing does NOT clean up: to erase a profile you no longer want stored, use web_session_delete.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'session': {'type': 'string', 'description': "Session name (a named login profile, e.g. 'linkedin'). Defaults to 'default'."}}}
web_session_delete
Web Session Delete
Deletes a SAVED web-automation login profile: closes its window if open, erases its cookies and site data from this Mac, and removes it from web_session_list. Use it to clean up a profile that is no longer needed — web_session_close only closes the window and leaves the login (and its cookies) on disk. IRREVERSIBLE: the next web_login for that name starts from a signed-out browser. Requires confirm=true; without it you get a preview. Verify with web_session_list, which must no longer list the name.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'confirm': {'type': 'boolean', 'description': 'Must be true to actually delete. Without it, returns a preview and deletes nothing.'}, 'session': {'type': 'string', 'description': "Name of the profile to delete, as web_session_list reports it. Defaults to 'default'."}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean', 'description': 'True only when BOTH halves are done: data erased and name removed from the list'}, 'closed': {'type': 'boolean', 'description': 'Whether a live window had to be closed first'}, 'deleted': {'type': 'string', 'description': 'The profile name that was deleted'}, 'data_removed': {'type': 'boolean', 'description': 'Whether the cookies and site data were erased'}, 'name_forgotten': {'type': 'boolean', 'description': 'Whether the name was removed from web_session_list'}}}
web_session_list
Web Session List
Lists your web-automation login profiles: every SAVED login (persisted on disk, so web_login/web_navigate can reopen it without signing in again) plus which are currently OPEN. Each entry has `saved` (a persisted profile exists) and `open` (its window is live now, with url + title). Use it to check whether a login a recipe needs already exists before running it, instead of opening it and failing.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {}}
出力スキーマ
{'type': 'object', 'properties': {'sessions': {'type': 'array', 'items': {'type': 'object', 'properties': {'url': {'type': 'string', 'description': 'Current URL (only when open)'}, 'name': {'type': 'string'}, 'open': {'type': 'boolean', 'description': 'The session window is currently open'}, 'saved': {'type': 'boolean', 'description': 'A persisted login profile exists on disk for this name'}, 'title': {'type': 'string', 'description': 'Current page title (only when open)'}}}}}}
web_show
Web Show
Brings a web session's browser window to the FRONT so the USER can take over directly — solve a CAPTCHA, complete 2FA, or make a choice the AI shouldn't. Local MCP never solves CAPTCHAs itself; this hands control to the user. Pair with web_screenshot first to show them what's on the page. After they finish, tell the agent to continue — the session keeps its state.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'reason': {'type': 'string', 'description': "Short reason shown to the user, e.g. 'a CAPTCHA appeared' or 'confirm which account'."}, 'session': {'type': 'string', 'description': "Session name (default 'default')."}}}
web_type
Web Type
Types text into a form field (input/textarea) on the current page. `target` is a CSS selector or the field's visible label/placeholder. Does NOT submit — use web_click on the submit button afterwards (that step is gated). SPECIAL CASE — file inputs: if `target` resolves to an <input type="file">, `text` is instead treated as a LOCAL FILE PATH on this Mac and the file is attached (JS can't set a file input's value directly; this answers the native file panel programmatically without ever showing it).
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': ['target', 'text'], 'properties': {'text': {'type': 'string', 'description': 'The text to type. For an input[type=file], this is instead the LOCAL FILE PATH to upload.'}, 'target': {'type': 'string', 'description': 'CSS selector or visible label/placeholder of the field.'}, 'session': {'type': 'string', 'description': "Session name (default 'default')."}}}
web_wait_for
Web Wait For
Waits (polls, not a fixed sleep) until an element appears on the page, or times out. Use for SPA pages that hydrate after load. Prefer `selector` (a CSS selector, e.g. "input[name=password]"). `condition` also accepts the form "document.querySelector('...')"; any OTHER JavaScript condition runs arbitrary code on the page (same power as web_eval) and is disabled when LMCP is in read-only mode. Returns met:true/false.
外部アクセスあり
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'session': {'type': 'string', 'description': "Session name (default 'default')."}, 'selector': {'type': 'string', 'description': 'CSS selector to wait for (preferred; treated as data, never executed). e.g. .feed'}, 'condition': {'type': 'string', 'description': 'Alternative to selector: "document.querySelector(\'...\')" is accepted as-is; any other JS expression runs arbitrary code on the page (same power as web_eval).'}, 'timeout_seconds': {'type': 'integer', 'description': 'Max seconds to wait (default 15).'}}}
出力スキーマ
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'met': {'type': 'boolean', 'description': 'True if the condition became truthy before the timeout.'}, 'message': {'type': 'string', 'description': 'Present when the condition was not met.'}}}
window_focus
Window Focus
Brings a window (by window_id from list_windows) to the front and activates its app. window_not_found if it can't be resolved. Requires Accessibility permission.
入力スキーマ
{'type': 'object', 'required': ['window_id'], 'properties': {'window_id': {'type': 'string', 'description': 'Window to bring to the front, from list_windows. Returns window_not_found if it cannot be resolved.'}}}
window_set_frame
Window Set Frame
Pins a window (by window_id) to fixed bounds {x,y,w,h} in global points, so every take is framed identically across runs. Returns the actual post-constraint bounds. Requires Accessibility permission.
入力スキーマ
{'type': 'object', 'required': ['window_id', 'bounds'], 'properties': {'bounds': {'type': 'object', 'description': '{x,y,w,h} global points.'}, 'window_id': {'type': 'string', 'description': 'Window to move or resize, from list_windows.'}}}
word_append
Word Append
Appends text to the end of an existing Word (.docx) document at `path`, preserving the document's existing content and formatting. Requires confirm=true — called without it, returns a preview instead of modifying the file. Same file-access rules as word_create (Desktop/Documents/Downloads may need a Files-and-Folders grant). Returns {appended, chars_appended, path}. To create a new document use word_create; to read one use word_read.
破壊的操作あり
入力スキーマ
{'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Path to the existing .docx file'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to modify'}, 'content': {'type': 'string', 'description': 'Text to append'}}}
出力スキーマ
{'type': 'object', 'additionalProperties': True}
word_create
Word Create
Creates a new Word (.docx) document at `path` with the given text content (and an optional title rendered as the heading). Requires confirm=true — called without it, returns a preview of what will be written instead of creating the file. The path must be somewhere Local MCP can write; Desktop/Documents/Downloads may need a one-time Files-and-Folders grant (System Settings → Privacy & Security → Files and Folders). Returns {created, path}. For a OneDrive or Google Drive path use onedrive_write_file / gdrive_write_file; to append to an existing doc use word_append, to read one word_read.
入力スキーマ
{'type': 'object', 'required': ['path', 'content'], 'properties': {'path': {'type': 'string', 'description': 'Output path for the .docx file'}, 'title': {'type': 'string', 'description': 'Document title (optional)'}, 'confirm': {'type': 'boolean', 'description': 'Must be true to create'}, 'content': {'type': 'string', 'description': 'Document text content'}}}
出力スキーマ
{'type': 'object', 'required': ['created', 'path'], 'properties': {'path': {'type': 'string', 'description': 'Path of the created .docx file'}, 'created': {'type': 'boolean', 'description': 'True when the document was created'}}}
word_read
Word Read
Reads text content from a Word document (.docx file).
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['path'], 'properties': {'path': {'type': 'string', 'description': 'Absolute path to the .docx file'}, 'force_download': {'type': 'boolean', 'description': "If the file is stored in the cloud and evicted from this Mac (dataless), request the download and wait for it instead of failing. Off by default: a download can take minutes and use metered data, so it is the caller's decision."}}}
出力スキーマ
{'type': 'object', 'required': ['text', 'chars'], 'properties': {'text': {'type': 'string', 'description': 'Extracted text content'}, 'chars': {'type': 'integer', 'description': 'Number of characters in the extracted text'}}}
zoom_list_recordings
Zoom List Recordings
Lists Zoom meeting recordings saved locally on this Mac (~/Documents/Zoom), newest first: meeting name, date, and which artifacts exist (transcript, captions, saved chat, audio, video). Local recordings only — no Zoom API, no admin approval. Use zoom_read_transcript to read the text of a meeting.
読み取り専用
入力スキーマ
{'type': 'object', 'required': [], 'properties': {'limit': {'type': 'integer', 'description': 'Max recordings to return (default 20)'}}}
出力スキーマ
{'type': 'object', 'properties': {'count': {'type': 'integer'}, 'total': {'type': 'integer'}, 'recordings': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'path': {'type': 'string'}, 'files': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'size': {'type': 'integer'}}}}, 'has_chat': {'type': 'boolean'}, 'modified': {'type': 'string'}, 'has_transcript': {'type': 'boolean'}}}}}}
zoom_read_transcript
Zoom Read Transcript
Reads the text artifacts of a local Zoom recording: the transcript/captions (.vtt or closed_caption.txt, cleaned to readable 'Speaker: text' lines) and the saved in-meeting chat. Pass the recording name or path from zoom_list_recordings. Perfect for 'summarize my last meeting' or 'what did we agree on in the kickoff call'.
読み取り専用
入力スキーマ
{'type': 'object', 'required': ['recording'], 'properties': {'include': {'enum': ['all', 'transcript', 'chat'], 'type': 'string', 'description': "'all' (default), 'transcript' or 'chat'"}, 'recording': {'type': 'string', 'description': 'Recording folder name (or full path) from zoom_list_recordings. Partial name match works.'}}}
出力スキーマ
{'type': 'object', 'properties': {'chat': {'type': ['string', 'null']}, 'note': {'type': 'string'}, 'path': {'type': 'string'}, 'recording': {'type': 'string'}, 'transcript': {'type': ['string', 'null']}, 'chat_source': {'type': 'string'}, 'transcript_source': {'type': 'string'}}}
変更
word_append
2026年10月1日2:53
変更
update_reminder
2026年10月1日2:53
変更
update_note
2026年10月1日2:53
変更
update_calendar_event
2026年10月1日2:53
変更
shortcuts_run
2026年10月1日2:53
変更
save_attachment
2026年10月1日2:53
変更
rename_reminder_folder
2026年10月1日2:53
変更
recipe_save
2026年10月1日2:53
変更
recipe_run
2026年10月1日2:53
追加
recipe_publish
2026年10月1日2:53
変更
onedrive_write_file
2026年10月1日2:53
変更
gdrive_write_file
2026年10月1日2:53
変更
file_write
2026年10月1日2:53
変更
excel_write_cell
2026年10月1日2:53
変更
daily_brief
2026年10月1日2:53
変更
web_wait_for
2026年9月29日3:02
変更
web_type
2026年9月29日3:02
変更
web_screenshot
2026年9月29日3:02
変更
web_read
2026年9月29日3:02
変更
web_find
2026年9月29日3:02
変更
web_extract
2026年9月29日3:02
変更
todoist_list_tasks
2026年9月29日3:02
変更
todoist_list_projects
2026年9月29日3:02
変更
todoist_create_task
2026年9月29日3:02
変更
todoist_complete_task
2026年9月29日3:02
変更
teams_read_chat_messages
2026年9月29日3:02
変更
teams_read_channel_messages
2026年9月29日3:02
変更
survey_skip
2026年9月29日3:02
変更
survey_respond
2026年9月29日3:02
変更
stocks_search_symbol
2026年9月29日3:02