Automation in DEVONthink: populate `URL` metadata fields with Obsidian's URL scheme


I index my Obsidian notes inside DEVONthink (DT) to take advantage of its algorithms to analyze the contents and suggest related documents to me. But when I’m viewing the indexed notes in DT, I often need to open it in Obsidian, which was cumbersome to do manually.

After URL schemes were released, I realized I could reduce the friction in my workflow by somehow automatically populating the URL metadata field of the indexed notes with their URL schemes. This way, jumping from DT to Obsidian simply takes a shortcut, ⌃⌘O, to launch the URL.

I managed to put together a DT Smart Rule to achieve this. It can get the job done but the implementation is less than ideal, so any suggestions are greatly appreciated.


  • url-decode-encode-cli, a npm package used for URL encoding the note titles.
    • npm is needed to install the package, so I needed to install Node.js first, although I could safely uninstall Node.js after the package was installed via npm.

Smart Rule setup

on performSmartRule(theRecords)
	tell application id "DNtp"
		repeat with theRecord in theRecords
			set currentURL to the URL of theRecord
			set encodedTitle to do shell script "(export PATH=\"/usr/local/bin:$PATH\" && printf '" & the name of theRecord & "' | url-encode)"
			set obsidianURL to "obsidian://open?vault=zettelkasten&file=" & encodedTitle
			if currentURL ≠ obsidianURL then
				set the URL of theRecord to obsidianURL
			end if
		end repeat
	end tell
end performSmartRule

How it works

  • The search scope is my only Vault, “Zettelkasten”. I configured it to Exclude Subgroups because my notes are in the Vault root and subfolders contain attachments, templates, etc.
  • The rule is triggered when the note is opened (clicked) in DT.
  • The rule will assemble the Obsidian URL scheme and check against the current URL metadata field. If they’re not the same, the URL field will be overwritten with the newly assembled URL; otherwise the field will be left untouched.
    • Because the rule assembles the URL scheme every time it’s triggered, the URL field will always be up-to-date even after the note title is changed.
    • Because the rule will not overwrite the URL field if it already contained the up-to-date URL scheme, the indexed notes won’t be modified every single time you open it.
  • Simply use the shortcut ⌃⌘O to open the URL of the selected note, which will open the note in Obsidian.


  • Depends on url-decode-encode-cli to perform encoding
  • I only use one Vault and store all notes in the root directory, so I hardcoded the vault=zettelkasten part into the AppleScript. You may need to modify the script depending on your Obsidian hierachies.

This looks really helpful - many thanks.

With regard to “implementation is less than ideal” do you mean the dependency on the npm package? It is certainly a very helpful script as is. Perhaps a way to make it simpler to install would be to use the percent encoding ability of Keyboard Maestro, as many who use both DT3 and Obsidian probably also use KM. Again that would be a nice bonus but this is very helpful as is - thanks.


Glad to be of help!

My primary dissatisfactions are 1) Dependency on the npm package, and 2) The vault name part of the URL (open?vault=zettelkasten) are hardcoded into the AppleScript due to my simple hierarchy but others may need to modify it if they have multiple Vaults and / or store notes in a folder hierarchy.

Full disclosure, this is the first Smart Rule I’ve ever built and I didn’t even know this was possible – how do you call a KM action from within a DT Smart Rule? I thought my toolset was limited to AppleScript.

That’s quite a helpful first SmartRule!

Code to call a Keyboard Maestro macro can be found under the Trigger section for any macro:


Would love to figure out how to get this to automatically generate the full Obsidian path…

Thanks, that’s so cool! KM users don’t have to use the npm package then.

I didn’t choose the full path approach because I assumed it was harder. Might still be possible though.

Would you mind walking a noobie through replacing the npm package with KM? I use KM so, that’d be ideal for my setup. Thanks for building this awesome smart rule / automation! I would love to have tighter integration between Obsidian and DEVONthink in my workflows and system.