jimmitchell9 downloadsSend uncompleted tasks from the active note to your OmniFocus inbox, then mark them complete in the editor.
Send uncompleted tasks from the active Obsidian note to your OmniFocus inbox, then mark them complete in Obsidian.
Each task forwarded to OmniFocus includes a link back to its source note in Obsidian, so you can jump from OmniFocus straight to the relevant context.
- [ ] to OmniFocus.- [ ] in the note without forwarding to OmniFocus.[due:: 2026-05-10] → due date (also accepts natural language like today 1pm, tomorrow 9am, fri 3pm, next monday, in 3 days)[defer:: 2026-05-05] (or start:: / scheduled::) → defer date (same natural-language phrases supported)[flag:: true] (or a 🚩 on the line) → flag[estimate:: 30m] (or 1h, 1h30m, 90) → time estimate in minutesomnifocus_tags).#tags written on the task line.omnifocus_project).- [ ] to - [x].omnifocus:// URL scheme).- [ ] checkboxes.---
omnifocus_tags: [@work, @errand]
omnifocus_project: Apartment Hunt
---
- [ ] Email landlord about lease renewal [due:: 2026-05-15] [flag:: true] #apartment
When sent, this becomes an OmniFocus task with title "Email landlord about lease renewal", a due date of 2026-05-15, the flag set, and (if "Forward inline #tags" is enabled) the tag apartment — plus whatever default/frontmatter tags you've configured.
- [ ] Plan trip
- [ ] Book flight
- [ ] Reserve hotel
Notes: looking at June 12–18
By default, this sends a single OmniFocus task Plan trip with the nested lines as the OmniFocus note body. All four checkboxes in this block are marked complete in Obsidian after the send.
With Preserve task hierarchy enabled and a hierarchy-capable send mode (OmniAutomation or Plug-in on macOS), the same markdown produces three OmniFocus tasks: Plan trip as the parent with Book flight and Reserve hotel as real subtasks underneath. The free-text Notes: line stays attached to the parent's note. In URL scheme mode, hierarchy preservation is not possible, so the plugin falls back to the body-folding behavior and shows a Notice explaining why.
| Setting | Default | Notes |
|---|---|---|
| Default tags | (empty) | Comma-separated. Applied to every task unless frontmatter overrides. |
| Default project | (empty = inbox) | Frontmatter overrides per-note. |
| Tags frontmatter key | omnifocus_tags |
YAML key on a note that overrides the default tag list. |
| Project frontmatter key | omnifocus_project |
YAML key on a note that overrides the default project. |
Forward inline #tags |
off | When on, #tags written on a task line are appended to the OmniFocus tag list. |
| Skip OmniFocus Quick Entry | off | When on, tasks are saved straight to their destination via autosave=true instead of opening the Quick Entry window. |
| Preserve task hierarchy | off | When on, nested checkboxes become real OmniFocus subtasks (in OmniAutomation or Plug-in send mode). URL scheme mode falls back to today's body-folding with a Notice. |
Three modes are available in settings. The default (URL scheme) works everywhere with no security prompts but cannot set plannedDate or repeating rules. Tasks that need those fields are routed through OmniAutomation per-task; plain tasks always use the URL scheme.
| Mode | Platform | Prompts | plannedDate / repeat |
|---|---|---|---|
| URL scheme (default) | macOS, iOS, iPadOS | Never | Skipped (Notice lists what was dropped) |
| OmniAutomation | macOS only | Every send of a task with planned/repeat |
Supported |
| OmniFocus plug-in | macOS only | Once per script approval | Supported |
The plug-in mode ships a small companion plug-in that lives inside OmniFocus. Approval is keyed to a fixed bootstrap script, so you approve it once and subsequent sends run silently.
Requires OmniFocus Pro. Omni Automation (plug-ins and external scripts) is a Pro-only feature. The default URL-scheme send mode does not require Pro.
One-time setup:
omnifocus-plugin/omnifocus-task-sync.omnifocusjs from this repo into it. (If you use the iCloud-synced folder, the plug-in syncs to other Macs — though the plug-in send mode itself is macOS-only.)planned:: or repeat:: field. OmniFocus shows its security prompt for the bootstrap script — scroll to the bottom and click Approve. Future sends with planned/repeat run silently.If a future plugin update changes the bootstrap script, OmniFocus will prompt for re-approval the next time it runs.
If a Dataview field on a task can't be parsed (for example, [due:: sometime soon]), the field is dropped and the task is sent without it. A Notice lists what was skipped so you can fix it.
This builds the plugin from the latest commit on main and symlinks it into your vault, so a git pull + npm run build is all it takes to update.
# 1. Clone the repo wherever you keep code
git clone https://github.com/jimmitchell/tasks-to-omnifocus.git
cd tasks-to-omnifocus
# 2. Install deps and build
npm install
npm run build
# 3. Symlink into your vault's plugins folder
# Replace the path with your actual vault path.
ln -s "$(pwd)" "/path/to/YourVault/.obsidian/plugins/omnifocus-task-sync"
Then in Obsidian:
To update later: git pull && npm run build, then in Obsidian disable and re-enable the plugin (or run "Reload app without saving" from the command palette).
main.js and manifest.json from the latest release.<vault>/.obsidian/plugins/omnifocus-task-sync/ and drop both files inside.<vault>/.obsidian/plugins/omnifocus-task-sync/manifest.json exists (follow the symlink with ls -la), then quit and relaunch Obsidian (⌘Q on macOS — closing the window isn't enough).npm install
npm run dev # esbuild watch mode — rebuilds on save
npm run build # type-check + production build
If you sideloaded via the symlink above, npm run dev will keep main.js fresh; just disable + re-enable the plugin in Obsidian to load the new build.
MIT