Skip to main content
Glama
waylake
by waylake

DEVONthink 3 MCP

Local, scoped MCP access to DEVONthink 3 on macOS. Search your archive, read cited text, follow references, and preview document organization from an AI assistant.

Tested on DEVONthink 3.9.18. Uses the official MCP TypeScript SDK 2.0.0 with the 2026-07-28 protocol and compatibility for 2025 clients. JavaScript source runs directly on Node.js; no build step, web server, API key, or second search index.

한국어 안내 · Design and research · Validation · Security boundaries

Already using DEVONthink 4? Its built-in MCP server is the simpler starting point. This project is for people staying on version 3. It is independent of DEVONtechnologies.

Install

Requires macOS, Node.js 22 or later, and a running, scriptable DEVONthink 3 installation. Open the databases you want to use. Allow the launching terminal or AI application to control DEVONthink in System Settings → Privacy & Security → Automation when macOS prompts.

Choose and register a client without cloning the repository:

npx -y @waylake/devonthink3-mcp@0.2.0 setup --client codex

For Pi:

npx -y @waylake/devonthink3-mcp@0.2.0 setup --client pi

For both, use --client both. Setup lists open databases by name, asks you to select their numbers or explicitly follow all open databases, and asks whether to enable writes. It saves local settings, then calls the client's own installer. Codex CLI or Pi must already be on PATH. --client pi installs pi-mcp-adapter@2.32.1 and this package through pi install; no separate MCP JSON editing is required.

Setup stores settings in ~/.config/devonthink3-mcp/config.json with owner-only permissions and preserves the previous file as config.json.bak. Existing unrelated MCP servers and Pi packages are retained. If client registration fails after settings were saved, fix the client installation and rerun setup. Keep setup output and configuration private.

Reconnect Codex or restart Pi after installation. In Pi, /reload and /mcp refresh and inspect available servers. The adapter discovers the package's pi.mcp manifest and connects lazily when needed. The package entry is named waylake_devonthink3-mcp__devonthink3 in the adapter. Pi package documentation, adapter documentation.

Explicit setup without prompts

This grants reads and writes to every database currently open and every database opened later:

npx -y @waylake/devonthink3-mcp@0.2.0 setup --client both --database-mode open --enable-writes

Restrict access to selected UUIDs instead:

npx -y @waylake/devonthink3-mcp@0.2.0 --doctor
npx -y @waylake/devonthink3-mcp@0.2.0 setup --database-uuids FIRST_UUID,SECOND_UUID --read-only

Without --client, setup saves settings only. Replace example UUIDs with values from the local doctor output. --exclude-databases UUID,UUID adds an exclusion list that overrides either scope mode; passing an empty string clears that list. Setup preserves other saved settings, including import roots. Settings changes require a client reconnect. Opening or closing databases does not require a reconnect.

Manual client installation

If you prefer the client's native commands, first run npx -y @waylake/devonthink3-mcp@0.2.0 setup to choose scope, then:

# Codex
codex mcp add devonthink3 -- npx -y @waylake/devonthink3-mcp@0.2.0

# Pi
pi install npm:pi-mcp-adapter@2.32.1
pi install npm:@waylake/devonthink3-mcp@0.2.0

The setup helper registers absolute Node and npm CLI paths for Codex so GUI launches do not depend on finding Node through a shell. The manual npx form requires Node/npm on the client's PATH. Official Codex MCP documentation.

For another local stdio MCP client:

{
  "mcpServers": {
    "devonthink3": {
      "command": "npx",
      "args": ["-y", "@waylake/devonthink3-mcp@0.2.0"]
    }
  }
}

Version pins keep the chosen server version stable. To upgrade, review the release and rerun setup from the new version. The Pi manifest intentionally executes the matching npm version through npx; the first connection may download that version into npm's cache. Subsequent connections reuse it. No repository checkout is required. Web-only remote clients need a separate local bridge; none is included.

Tools

Eight read tools are available by default. Five write tools appear when writes are enabled in setup or with DT3_ENABLE_WRITES=1.

Tool

Purpose

dt3_status

App readiness, version and configured scope

dt3_databases

Permitted open databases and their root UUIDs

dt3_selection

Permitted records in the current selection

dt3_search

Native full-text/query search in one database or group

dt3_list_group

Direct children, including records with no indexed text

dt3_get_record

Metadata, optional custom metadata, and edit revision

dt3_read_text

Bounded indexed text, extraction status and source link

dt3_related

Similarity, classification, duplicates, incoming/outgoing item references

dt3_create_record

Preview/create Markdown, plain text or a group

dt3_update_record

Preview/edit name, tags, comment, rating, flags, or plain/Markdown text

dt3_move_record

Move one document instance; preserve other replicants

dt3_replicate_record

Add a shared document instance within the same database

dt3_import_file

Import one permitted local file; retain its original

Each successful tool response has an output schema, structured data and a text rendering. Record identifiers accept UUIDs or x-devonthink-item:// links. Tool results include item_url for citations and resource_uri for MCP clients. devonthink3://record/{uuid} reads the first text chunk; devonthink3://guide describes the workflow. The research and organize prompts provide starting workflows.

Read and cite

  1. Call dt3_databases; choose relevant databases. Search each explicitly and combine evidence with database UUIDs and item links.

  2. Call dt3_search with native syntax such as name:report or tag:review.

  3. Inspect metadata; call dt3_read_text only for relevant records.

  4. Continue with next_offset until null, comparing revisions if the source changes.

  5. Cite the returned item link in the synthesis. Keep originals in DEVONthink and small, source-linked knowledge pages in Git.

List pages default to 25 records, capped at 100. Text chunks default to 8,000 UTF-16 code units, capped at 16,000; surrogate pairs are preserved. Search/browse order is native and not a snapshot. Concurrent imports or edits may change page membership; deduplicate by UUID when gathering an inventory.

Preview and edit

Enable writes through setup or an environment override and reconnect. The server still defaults every mutation to a preview:

{
  "uuid": "RECORD_UUID",
  "expected_revision": "REVISION_FROM_GET_RECORD",
  "request_id": "rename-project-note-001",
  "name": "Project note",
  "dry_run": true
}

Review before, destination and changes. For an authorized change, call the same tool with dry_run: false. A text preview shows its first 1,000 code units and total length. Tags replace the complete tag list. Moving requires both from_uuid and destination_uuid and operates on one document instance, within one database.

To preserve existing tags, read them first and include them in the replacement array.

A changed revision rejects the edit. The app is not transactional: multiple property updates can partially complete if an Apple Event fails. Inspect current state after any uncertain result. A timeout or cancellation stops the subprocess but cannot roll back an Apple Event already delivered.

Mutation receipts prevent exact retries from repeating a write within one server process. Reuse the same request_id only with identical arguments. Receipts are held for up to 256 writes without eviction; subsequent new writes return RECEIPT_LIMIT. Reconcile results before restarting. Receipts do not survive a restart and are not an audit log. Replays recheck access permissions.

Configuration

Without settings or environment overrides, access is denied and writes are off. Settings are read once at startup. Environment values override saved settings. An explicit DT3_DATABASE_UUIDS, including an empty value, also selects selected mode unless DT3_DATABASE_MODE is explicitly provided. The Pi package uses the default settings file and does not inherit custom DT3 environment overrides; use setup or a custom MCP entry for a separate Pi profile.

Variable

Default

Meaning

DT3_CONFIG

~/.config/devonthink3-mcp/config.json

Absolute settings-file path; an explicitly named missing file is an error

DT3_DATABASE_MODE

selected

selected allows UUIDs; explicit open follows all open databases

DT3_DATABASE_UUIDS

empty

Comma-separated permitted database UUIDs in selected mode; no wildcard

DT3_EXCLUDE_DATABASE_UUIDS

empty

Comma-separated denied database UUIDs, in both modes

DT3_ENABLE_WRITES

0

1 exposes write tools; all other non-0 values are rejected

DT3_EXCLUDE_TAGS

empty

Extra excluded tags, comma-separated; mcp-private is always excluded

DT3_IMPORT_ROOTS

[]

JSON array of absolute directories permitted for single-file imports

DT3_TIMEOUT_MS

30000

Per JXA subprocess timeout, 1,000–120,000 ms

Example import root: DT3_IMPORT_ROOTS='["/Users/you/Documents/MCP Import"]'. Imports follow real paths, reject symlink escapes, directories, and files over 100 MiB. Use DEVONthink itself for large folder imports.

Tag a document or group mcp-private to exclude it. The server checks every parent: a replicant in a private group is denied even if another instance is in a public group. Trash is excluded. Metadata, search results, direct reads, resources and writes share the same scope check.

Limits and troubleshooting

  • The server has no network listener or telemetry. The connected AI host may send returned content to its model provider. There is no automatic sensitive-text redaction; this is separate from DEVONthink 4's built-in privacy controls.

  • no_text means DEVONthink returned no plain text. It does not prove the source is empty. OCR, media transcription, archive expansion, spreadsheet formula evaluation and password recovery are outside this server.

  • Metadata-only search is separate from text reading. PDF text comes from DEVONthink's index; page count is provided, but returned chunks do not claim page-level alignment.

  • Text reads reject indexed text over five million characters. Native APIs may materialize full text or search results internally before pagination. A call scans at most 5,000 result candidates; follow next_offset, including on an empty filtered page.

  • Writes to locked or indexed records, group relocation, cross-database moves, trash operations and permanent deletion are excluded. Edit original indexed files through their source application.

  • NOT_RUNNING: open DEVONthink 3. ACCESS_DENIED: check UUID configuration and open databases. NOT_FOUND_OR_DENIED: check tags and ancestors. AUTOMATION_DENIED/AUTOMATION_FAILED: inspect macOS Automation permissions and app dialogs. CONFLICT: re-read and preview again.

  • Configured databases must remain open in the app; the server does not mount closed database packages. A permission granted to Terminal does not automatically grant it to a GUI AI host. Open that host interactively and check its own Automation entry.

  • Apple Events are serialized within one process; at most 16 calls queue. Use one server process for a given workflow. Multiple clients/processes and manual app edits are not protected by a distributed lock.

Development

npm ci --ignore-scripts
npm run check
DT3_LIVE_TEST=1 npm run test:live

Portable tests cover policy, schemas, replay, imports, queueing and both protocol eras. The opt-in live test creates a temporary synthetic database, exercises actual app operations, closes it, and removes its temporary files. It requires DEVONthink 3 and Automation permission; do not run it while relying on the current selection for another workflow.

For a durable archive structure and agent review workflow, read the knowledge organization guide.

MIT license. See design and research for upstream references and reuse decisions.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/waylake/devonthink3-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server