How I have Claude work with DEVONthink
There is no simple, quick-and-easy path to this. It’s taken a lot of trial and error to figure out what works. Much of what’s in here won’t directly map to how your Claude is set up, because I have heavily modified the harness which Claude Cowork runs on. I would think giving your AI this file and having a deep-dive discussion on how to implement it for you is likely the fastest path. Legally, I probably need to state that use is at your own risk and that no guarantees are implied, etc.
A quick overview to keep in mind:
Claude uses the official DEVONthink Model Context Protocol server, and does real work in my databases rather than just answering questions about them. That means it can also break things, so most of these rules exist because something went wrong (at least) once and I had to figure out how to prevent it from happening again.
I rely heavily on the baked-in features of DEVONthink that, once properly enabled, allow the LLM to use the MCP with less fear of losing data.
- Versioning: this works with files that the AI touches as well; anything modified retains its original content. This is a per-database setting that must be enabled, and I have Claude check that it’s enabled for every open database once a month (since it’s not easy to turn it off by accident).
- Trash as a real net: Claude has rules telling it to only soft-delete. For DEVONthink, this is moving to the trash. For the file system, it moves files to its own trash folder that I have to review and delete.
- Exclude from AI access: this keeps documents from being seen by the AI. I keep any files with PII set to exclude.
- Stable identifiers and item links surviving moves and renames. This one is more important than it first would seem. I originally had Claude run nightly tasks to keep up with any changes in DEVONthink, as its file map depended on knowing where items were stored. After a long series of trial-and-error attempts to optimize this, the best solution was to simply have Claude log the UUIDs for files and Groups, along with minimal metadata. However, it’s important that the AI knows when a new UUID is generated:
- duplicate_record returns a new UUID. replicate_record returns the same UUID with a second parent.
- convert_record creates a new record.
- Re-importing a file creates a second record rather than updating the first. That’s why I now have a rule to revise in place with update_record_content and never re-import.
- Anything regenerated on a schedule churns its UUID on each refresh, so those are anchored by name within their parent group instead.
- Logging: As noted above, some things are also logged in the DEVONthink log panel, though I’d like to see more for a better audit trail. Changes to metadata aren’t logged, though it would be nice if it caught these too when the AI made a change.
MCP Tools: The MCP includes many tools, and it took a while for the AI to realize the power already within it. I think we’re still finding better ways to do things, but that is pretty much the course for anything done with an LLM. I would suggest you spend an entire session exploring these with the LLM and running “what if” scenarios to find what works best.
The below is my own instruction layer sitting on top of the MCP (the Rules).
Where the rules live
I think the most important takeaway from this is the rules are not one big document. They are tiered because anything loaded into every session costs context, whether it gets used or not, but more importantly, will be ignored because the rules don’t “pop up” at the right time. I can’t really tell you how to do this on your system, because everybody’s harness will be different. You’ll need to find the best place to add these rules, but here are my tiers:
- An always-loaded instructions file holds only the decision rules: when to act, when to stop, what never to do.
- A reference file holds the mechanics: folder identifiers, per-database facts, filing tables. It gets loaded on demand, only when Claude is about to file something.
- A separate reference holds what has been learned about the MCP tools themselves, and Claude is required to read it before touching any DEVONthink tool.
- Filing a finished document is its own procedure, so that got pulled out into a reusable routine instead of being re-derived every time.
Here’s the tabular version of the mapping, which might help visualize when things happen and where the rule resides:
| Tier |
File |
When it loads |
| 1. Decision rules |
root CLAUDE.md, the DEVONthink section |
Every session, automatically |
| 2. Mechanics |
dt-reference.md |
On demand, before filing or picking a destination |
| 3. Tool learnings |
knowledge/devonthink-mcp.md |
Mandatory read before any DEVONthink call |
| ↳ escalation |
DT-MCP-CATALOG.md |
Only when the wiki page isn’t enough |
| ↳ raw evidence |
DT-MCP-SWEEP-EVIDENCE.md |
Never by default |
| 4. Filing procedure |
skills/dt-file/SKILL.md |
Invoked when a deliverable is ready to file |
| Audit trail |
DT-CHANGE-LOG.md |
Written, not read |
Some of these locations are file locations in my harness and won’t map to yours. The audit log is NOT a log of every edit. Content edits are covered by DT versioning and need no entry here. The log contains only deletions, merges, and other operations that are not recoverable via versioning or Trash.
Having multiple files matters more than you might expect. When everything lived in one file, the useful rules got buried in the mechanical ones. This is a recurring issue with LLM rules in general, and the fix often requires asking the AI why something failed or was ignored and how to prevent it.
The following goes into very specific points about each aspect of the rules. I’ll simply point out that this is what works best for me - so far - but I make no claim that it’s the best way.
The safety rules
These are built around what DEVONthink can actually recover, not around being cautious in general.
- Content edits run unattended. Versioning has them covered, so Claude does not ask permission and does not make a backup copy first. Append or insert is preferred over replace.
- Metadata changes require confirmation, for the reason above. Claude has to ask before overwriting a value that already contains values. Adding a tag is fine unattended.
- Every property write gets read back. This is the one that bit me several times. The update call silently ignores any key it does not recognize; no error, no warning, the same success response you would get if it had worked. So a success response is not evidence that anything happened. Claude has to verify with a separate read before it reports the change as done.
- Deletions and merges are still confirmed and logged to an audit file even though both are recoverable, because recovery depends on knowing it happened at all.
- Personally identifiable information gets surfaced to me, never decided by Claude. If it finds a document containing a Social Security number or an account number, it tells me which record it is and what is in it, and I decide whether to exclude it from artificial intelligence access. It does not redact, copy, or alter the record on its own. Note: there is an option to redact sensitive content in DEVONthink settings, but I turned it off because it masks only two read paths and does nothing for scanned documents.
- Outside of DEVONthink: Nothing gets deleted from the file system either. Files move to a dated trash folder that I clear myself.
The filing rules
- Claude may never create a new top-level group in any database. If something does not fit an existing folder, it stops and asks. Otherwise, you can end up with a database that has too many top-level folders because the AI will tend to create a new one instead of looking harder at what exists. This rule also helps maintain the general structure you create in your database, as it forces the AI to find an already existing location.
- Every record Claude touches gets exactly one provenance tag: claude-create, claude-import, or claude-edit. Three tags, mutually exclusive. It means I can always answer “Did Claude touch this file?”
- Authored text and external files take different paths. Markdown that Claude wrote goes in through the record creation call, which handles name, tags, and destination in one step. An external or binary file has to be imported, and import ignores the name and tags you pass it, so those get fixed afterward with a read-back. Importing by reference rather than by copy is banned outright, since the reference breaks the moment the temporary file goes away.
- Records are addressed by unique identifier, never by path. Paths change when I reorganize, and I reorganize constantly. A truncated identifier is treated as an error rather than a shortcut (something in Claude wants to truncate UUIDs, and so it needs to be aware of this, and when it finds one, it searches and updates it for the full UUID).
I also have a boundary test that Claude uses for what belongs in DEVONthink or what should stay in its filesystem. Will I ever open this to read it? If yes, it goes in DEVONthink. If it is only ever consumed by code or Claude’s own process, it stays on the file system. Source files and scripts never go in.
The retrieval rules
- Tool choice is specified by job rather than left to judgment, because the tool names are misleading. Exact name goes to lookup, keywords to search, “what do we have on this topic” to the similarity call in content mode, structure to the group tree.
- The one I wish I had found sooner is the chat call. It answers a specific question against a record with page citations, which means a hundred-page contract never has to be loaded into context at all. That single tool changed how usable the whole setup is.
- Searches always get scoped to a specific database. I have a large reference library in one database, and an unscoped keyword search will happily return medical textbooks for a contract question.
A few traps worth knowing, since none of them announce themselves:
- The default search operator matches whole words, not substrings. Searching a partial word returns zero results rather than an error.
- Negation in search queries does nothing. You get the whole database back looking like it was filtered, which is worse than an error.
- Similarity scores scale with how much text you give them. A three-word query silently returns nothing, while a full sentence works.
- Claude doesn’t like the automatic classification suggestions. This is an artifact of how much content already exists in a group, and I think Claude is expecting something more from this tool. What seems to work better is for it to run searches on key phrases and then drill down to those locations to find the best spot to file something. It doesn’t always work well, but good enough to be usable.
How it all gets applied
As previously noted, the rules are only useful if they fire when needed. Relying on a large text dump of rules in the CLAUDE.md file doesn’t work, or at least not consistently, so they have to be attached to triggers. The tool reference is a mandatory read before any DEVONthink call. Filing a finished document invokes the filing routine, rather than having the AI figure it out on the fly. A nightly maintenance pass audits for drift and reports what it finds, and a save routine checks format rules on the files it touches.
I know this is likely way more text than anyone wanted, but this is how I got Claude to work nearly flawlessly with DEVONthink.