{
  "markdown": "# istefox-dt-mcp\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)\n[![Platform: macOS](https://img.shields.io/badge/platform-macOS-lightgrey.svg)](https://www.apple.com/macos/)\n[![Release: v0.3.0](https://img.shields.io/badge/release-v0.3.0-brightgreen.svg)](https://github.com/istefox/istefox-dt-mcp/releases/latest)\n[![Listed on Glama](https://glama.ai/mcp/servers/istefox/istefox-dt-mcp/badge)](https://glama.ai/mcp/servers/istefox/istefox-dt-mcp)\n\nMCP server for DEVONthink 4 — outcome-oriented tools, optional local RAG, privacy-first. Stack: Python 3.12 + FastMCP + ChromaDB + uv.\n\n> **0.3.0 — current release (May 2026)**. Seven MCP tools end-to-end, preview-then-apply with audit log + 3-state selective undo on both `file_document` and `bulk_apply`, `.mcpb` bundle installable in Claude Desktop. Vector RAG is opt-in experimental — see [ADR-008](docs/adr/0008-embedding-model-selection.md). For day-to-day status, see [`handoff.md`](handoff.md); for project constraints, see [`CLAUDE.md`](CLAUDE.md); for design decisions, see [`docs/adr/`](docs/adr/).\n\n---\n\n## Quick Install (3 ways)\n\n| Path | Best for | Prerequisites |\n|---|---|---|\n| **A — `.mcpb` desktop extension** (recommended) | Claude Desktop users, zero-config | Claude Desktop ≥ 0.8 |\n| **B — `pipx install`** (standalone CLI) | CLI users, other MCP hosts | Python 3.12, `pipx` |\n| **C — Source / dev install** | Contributors, debugging | `uv`, `git` |\n\n### A — `.mcpb` desktop extension (recommended)\n\nDrag-and-drop into Claude Desktop, one-click. The bundle handles its own runtime and dependencies.\n\n1. Download the latest `.mcpb` from [GitHub Releases](https://github.com/istefox/istefox-dt-mcp/releases/latest).\n2. Drag it onto the Claude Desktop window (or **Settings → Developer → Install Bundle**).\n3. On first use, macOS will ask for AppleEvents permission — click **Allow**.\n\n### B — `pipx install` (standalone CLI)\n\n```bash\npipx install git+https://github.com/istefox/istefox-dt-mcp\n```\n\nThen add to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"istefox-dt-mcp\": {\n      \"command\": \"istefox-dt-mcp\",\n      \"args\": [\"serve\"]\n    }\n  }\n}\n```\n\n### C — Source / dev install\n\n```bash\ngit clone https://github.com/istefox/istefox-dt-mcp.git\ncd istefox-dt-mcp\nuv sync --all-packages\nuv run istefox-dt-mcp doctor\n```\n\nSee [Setup](#setup) for full details (macOS permissions, install troubleshooting).\n\n![Installing istefox-dt-mcp in Claude Desktop — drag the .mcpb bundle into Settings → Extensions](docs/assets/install.gif)\n\n---\n\n## Prerequisites\n\n- **macOS 14+** (Sonoma or later)\n- **DEVONthink 4** (Pro or standard, any license) installed and running\n- **Disk space**: ~300 MB for the bundle, **+2 GB** if you enable RAG with `bge-m3`\n- **AppleEvents permission** for the terminal (pipx/dev) or for Claude Desktop (`.mcpb`) — requested automatically on first use\n\n---\n\n## What you can ask Claude\n\nExamples of natural prompts and the MCP tool each one triggers. All examples assume Claude Desktop with the connector installed and DEVONthink running.\n\n- *\"Find everything about 'antivibration mounts' from the last 2 years\"*\n  → `search` (BM25 by default; hybrid if RAG is enabled)\n- *\"What did we propose to Customer X?\"*\n  → `ask_database` (BM25 + synthesis; vector if RAG opt-in is on — see [RAG](#rag-vector-search--opt-in-experimental))\n- *\"Find documents similar to this PDF\"* (with a record selected in DT)\n  → `find_related` (DT's native See Also/Compare)\n- *\"File this attachment in `/Inbox/Triage` and tag it `urgent`\"*\n  → `file_document` with preview, shows what it will do, then commit with `confirm_token`\n- *\"Move every March PDF from the `Inbox` to `/Archive/2026`\"*\n  → `bulk_apply` (batch dry-run + per-record selective apply)\n- *\"Which databases are open in DT?\"*\n  → `list_databases` (read-only, 5-min cache)\n- *\"Dammi una panoramica di tutte le bollette del 2025 raggruppate per mese e tag\"*\n  → `summarize_topic` (retrieval + server-side clustering by date and tags)\n\nWrite tools (`file_document`, `bulk_apply`) are **dry-run by default**: the first call always returns a preview. Apply requires an explicit `confirm_token`. The returned `audit_id` enables selective `undo` via the CLI.\n\n![End-to-end demo: natural prompt in Claude → file_document preview (dry-run) → confirm → applied with audit_id](docs/assets/demo.gif)\n\n---\n\n## Privacy & security\n\nThe connector is designed **privacy-first** and **local-only**:\n\n- **Everything stays on your machine**: no data leaves it. No telemetry, no cloud embeddings, no analytics. The embedding model (if you enable RAG) runs locally via `sentence-transformers`.\n- **Append-only SQLite audit log** for **every** operation (reads included) at `~/.local/share/istefox-dt-mcp/audit.sqlite`. Default 90-day retention, configurable.\n- **Write tools always default to `dry_run=true`**, with a preview-then-apply pattern guarded by a short-TTL `confirm_token` (5 min default).\n- **Selective undo via `audit_id`**: every write op stores the before-state and is restorable with `istefox-dt-mcp undo <audit_id>`.\n- **Clean-room implementation**, **MIT license**: no code copied from GPL-licensed projects (see [Legal constraints](#legal-constraints)).\n- **Suitable for sensitive data**: contracts, invoices, personal notes, customer correspondence.\n\n---\n\n## Roadmap\n\n| Version | What | References |\n|---|---|---|\n| **0.1.0** (May 2026) | 6 MCP tools, audit + undo, `.mcpb` bundle, BM25-only retrieval by default | — |\n| **0.2.0** (May 2026) | 7th tool `summarize_topic`, 3-state drift detection on `file_document` undo, real-data VCR cassettes from a fixture DT4 DB | [ADR-005](docs/adr/0005-test-strategy-4-tier.md) |\n| **0.3.0** (May 2026) | Per-op 3-state drift detection on `bulk_apply` undo, one-shot release pipeline (auto-trigger MCP Registry publish) | — |\n| **0.4.0** (May 2026) | HTTP transport + OAuth 2.1 PKCE multi-device, scope enforcement (3 scope), per-DB consent (ConsentStore) | [ADR-006](docs/adr/0006-oauth-scope-model.md) |\n| **0.5.0+** (Q4 2026) | `create_smart_rule`, RAG benchmark cross-corpus + flip default embedding model, token refresh + key rotation | [ADR-004](docs/adr/0004-mvp-tool-scope.md), [ADR-008](docs/adr/0008-embedding-model-selection.md) |\n\nFull backlog in [`handoff.md`](handoff.md).\n\n---\n\n## Remote access via HTTP + OAuth (0.4.0)\n\nDefault deployment is **stdio** (Claude Desktop, single-user, local trust). For multi-device remote access (Claude.ai Web, mobile, etc.), 0.4.0 ships an **HTTP transport with OAuth 2.1 + PKCE**.\n\n**3-step setup:**\n\n1. **Start the server in HTTP mode** (loopback-only is the default — never expose directly to the public internet without TLS at the edge):\n\n   ```bash\n   uv run istefox-dt-mcp serve --transport http --host 127.0.0.1 --port 3000\n   ```\n\n2. **Front it with a TLS-terminating tunnel.** Cloudflare Tunnel is recommended (zero-config, no inbound port to forward):\n\n   ```bash\n   cloudflared tunnel --url http://127.0.0.1:3000 --hostname dt-mcp.example.com\n   ```\n\n3. **First connection** — the client (Claude.ai Web, mobile, …) walks the user through the OAuth consent UI:\n\n   - Client redirects user to `https://dt-mcp.example.com/oauth/authorize?...`\n   - User picks scopes (`dt:read` / `dt:write` / `dt:admin`) + databases to authorize\n   - Server mints an authorization code, redirects back with `?code=...`\n   - Client exchanges the code for a Bearer JWT at `/oauth/token`\n   - All subsequent MCP calls use `Authorization: Bearer <jwt>`\n\nTokens last 1 hour. Database creations *after* consent surface as `RECONSENT_REQUIRED` errors — the user re-authorizes the new database via the consent UI.\n\n**Security model** (see [ADR-006](docs/adr/0006-oauth-scope-model.md)):\n- 3 OAuth scopes (read / write / admin) — granular database scoping is **outside** the token (server-side ConsentStore), so newly-created DBs never get a free pass.\n- HMAC HS256 signing with a 32-byte secret persisted at `~/.local/share/istefox-dt-mcp/oauth_secret` (mode 0600). To rotate, delete the file + restart — all outstanding tokens become invalid.\n- Authorization codes are one-shot (10-min TTL) — replay attacks fail closed.\n\nstdio is unaffected: Claude Desktop continues to work without auth, exactly as before.\n\n---\n\n## Troubleshooting top 5\n\n| Error | Symptom | Fix |\n|---|---|---|\n| `DT_NOT_RUNNING` | All tools fail at startup | DEVONthink isn't running — launch it (Spotlight: `DEVONthink`) |\n| `PERMISSION_DENIED` (`-1743`) | First Apple Event errors out | **System Settings → Privacy & Security → Automation** → enable the toggle for `DEVONthink` under your terminal or Claude Desktop |\n| `DATABASE_NOT_FOUND` | `file_document` or `bulk_apply` rejects the path | `destination_hint` is missing the database prefix — use `/Inbox/<group>` (with leading slash), not `/<group>` |\n| `uv binary not found` | The `.mcpb` bundle won't start on first run | `brew install uv` (or `curl -LsSf https://astral.sh/uv/install.sh \\| sh`), then disable + re-enable the extension in Claude Desktop |\n| `drift_state: hostile_drift` (on undo) | Undo refuses to roll back | The record was modified after the original apply by something other than your prior undo. Run `istefox-dt-mcp audit list --recent` for context, inspect `drift_details` in the response, then add `--force` if the rollback is still what you want. **Note:** if `drift_state: already_reverted`, the record is already back to the pre-apply state — no `--force` needed, undo returns a no-op |\n\nFor anything not listed: `uv run istefox-dt-mcp doctor` produces a full diagnostic report (DT running, permissions, cache, RAG state).\n\n---\n\n## Status\n\n**0.4.0 current release** (May 2026): all 7 tools available over both **stdio** (Claude Desktop) and **streamable HTTP** (multi-device behind Cloudflare Tunnel) with **OAuth 2.1 + PKCE** authentication, 3-scope authorization model (`dt:read`/`dt:write`/`dt:admin`), per-database consent persisted server-side (ConsentStore). **294 unit + contract tests** green plus 11 integration tests opt-in. mypy clean, smoke E2E PASS on 7 steps including the OAuth flow surface.\n\nPrevious milestones: **0.3.0** (May 2026) — per-op 3-state drift detection on `bulk_apply` undo + auto-trigger MCP Registry publish. **0.2.0** (May 2026) — `summarize_topic` tool + 3-state drift on `file_document` + real-data VCR cassettes via `record-cassette` CLI. **0.1.0** (May 2026) — first public release, 6 tools, BM25-only retrieval.\n\n---\n\n## What it does\n\nA DEVONthink 4 connector for MCP that goes beyond a 1:1 wrapper of the scripting dictionary.\n\n**The seven tools:**\n\n| Tool | Type | Notes |\n|---|---|---|\n| `list_databases` | read | Open databases, with 5-min cache |\n| `search` | read | BM25 (default) + optional vector hybrid (RRF) when RAG is enabled |\n| `find_related` | read | Wraps DT's native See Also / Compare |\n| `ask_database` | read | BM25 + synthesis (default) + optional vector retrieval |\n| `summarize_topic` | read | Retrieval + server-side clustering by date/tags/kind/location *(0.2.0)* |\n| `file_document` | write | `dry_run` by default + preview-then-apply + selective undo |\n| `bulk_apply` | write | Batch ops with `dry_run` + per-op outcomes |\n\nThe two write tools follow the preview-then-apply pattern: calling them with `dry_run=true` returns a preview plus a `preview_token` (the audit_id of the dry-run); a second call with `dry_run=false` plus `confirm_token=<preview_token>` actually applies the change. The returned `audit_id` enables selective `undo` via the CLI.\n\n**MCP Resources & Prompts** *(0.5.0)*: three read-only `dt://` resources — `dt://databases`, `dt://record/{uuid}/metadata`, `dt://record/{uuid}/text` — deterministic, bounded (≤25K token), consent-gated ([ADR-0009](docs/adr/0009-mcp-resources-prompts.md)); plus two template-only prompts, `weekly_review` and `triage_inbox`, that orchestrate the existing tools.\n\nStill on the post-MVP list: `create_smart_rule` — see [ADR-004](docs/adr/0004-mvp-tool-scope.md).\n\n---\n\n## Stack\n\n| Component | Tech | Reference |\n|---|---|---|\n| Language | Python 3.12 | [ADR-001](docs/adr/0001-stack-python-fastmcp-chromadb.md) |\n| MCP framework | FastMCP 3.x | [ADR-001](docs/adr/0001-stack-python-fastmcp-chromadb.md) |\n| Validation | Pydantic v2 | [ADR-001](docs/adr/0001-stack-python-fastmcp-chromadb.md) |\n| DT bridge | JXA-only in v1 (multi-bridge-ready abstraction) | [ADR-002](docs/adr/0002-bridge-architecture-jxa-only.md) |\n| Vector DB | ChromaDB embedded | [ADR-003](docs/adr/0003-rag-same-process.md) |\n| Embedding | `paraphrase-multilingual-MiniLM-L12-v2` (default), `BAAI/bge-m3` opt-in | [ADR-008](docs/adr/0008-embedding-model-selection.md) |\n| Cache | SQLite WAL | — |\n| Tests | pytest + 4-tier strategy | [ADR-005](docs/adr/0005-test-strategy-4-tier.md) |\n| Packaging | `uv` workspace + hatchling | — |\n| Logging | structlog (JSON to stderr) | — |\n| Distribution | `pipx` + `.mcpb` desktop extension | — |\n\nMinimum DT version: **DEVONthink 4.0**. DT3 is not supported — see [ADR-007](docs/adr/0007-dt4-only.md).\n\n---\n\n## Repository structure\n\n```\n.\n├── apps/\n│   ├── server/      MCP server (FastMCP, stdio in v1; HTTP+OAuth → v2)\n│   └── sidecar/     RAG sidecar (ChromaDB + embeddings)\n├── libs/\n│   ├── adapter/     JXA bridge + cache + errors + JXA scripts\n│   └── schemas/     Shared Pydantic v2 models (common, tools, audit, errors)\n├── tests/\n│   ├── unit/        Unit tests (202 tests)\n│   ├── contract/    VCR-style replay against real DT4 captures (8 tests)\n│   ├── integration/ Real-DT smoke + latency benchmark (7 tests, opt-in)\n│   └── benchmark/   Micro-benchmarks (opt-in)\n├── docs/\n│   └── adr/         Architecture decision records\n├── .github/workflows/   CI (Ubuntu) + Integration (macOS-14) + Release (manual) + Publish-Registry\n├── scripts/             build_mcpb.sh + smoke_e2e.sh\n├── server.json          MCP Registry manifest\n├── manifest.json        .mcpb bundle manifest\n├── pyproject.toml       uv workspace + ruff + black + mypy + pytest\n├── CLAUDE.md            Mandatory project constraints\n├── memory.md            Decisions + context\n└── handoff.md           Session-to-session handover\n```\n\n---\n\n## Setup\n\n```bash\n# Prerequisites: macOS, DEVONthink 4 installed\n\n# Install uv (if missing — alternative: brew install uv)\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Clone + sync workspace\ngit clone https://github.com/istefox/istefox-dt-mcp.git\ncd istefox-dt-mcp\nuv sync --all-packages\n```\n\n### macOS Automation permission (mandatory)\n\nDEVONthink only responds to Apple Events from apps that have explicit permission. On the first `uv run istefox-dt-mcp doctor` with DT running, macOS will show a \"X wants to control DEVONthink\" dialog: click **OK**.\n\nIf you don't see the dialog (because you clicked \"Don't Allow\" earlier):\n\n1. Open **System Settings → Privacy & Security → Automation**.\n2. Find the terminal or app you're running from (Warp, iTerm, Terminal, Claude Desktop).\n3. Enable the toggle for **DEVONthink**.\n\nTypical error when permission is denied: `PERMISSION_DENIED` with AppleScript code `-1743`. The connector intercepts it and suggests the affected app in the `recovery_hint`.\n\nIf your terminal doesn't appear in the Automation list, try `tccutil reset AppleEvents <bundle-id>` (e.g. `com.apple.Terminal`, `com.googlecode.iterm2`) and re-run the probe so macOS can prompt fresh.\n\n---\n\n## Quick start\n\n```bash\n# Lint + format check\nuv run ruff check .\nuv run black --check .\n\n# Unit + contract tests (~6s)\nuv run pytest tests/unit tests/contract -v\n\n# Tests with coverage\nuv run pytest tests/unit --cov=apps --cov=libs --cov-report=term\n\n# Integration tests against real DT (opt-in; requires DT running + AppleEvents)\nuv run pytest tests/integration -m integration --benchmark-enable -v\n\n# Micro-benchmarks (opt-in: cache + bridge overhead)\nuv run pytest tests/benchmark --benchmark-enable --benchmark-only\n\n# CLI\nuv run istefox-dt-mcp --help\nuv run istefox-dt-mcp doctor       # health check (requires DT running)\nuv run istefox-dt-mcp serve        # stdio server (for Claude Desktop)\nuv run istefox-dt-mcp audit list --recent 5   # last 5 audit entries\n\n# VCR cassette recording (developer-only, requires DT4 + fixtures-dt-mcp DB)\n# See docs/development/cassette-recording.md\nuv run istefox-dt-mcp record-cassette --tool search_bm25\nuv run istefox-dt-mcp record-cassette --all   # auto-resets DB to manifest baseline first\n```\n\n---\n\n## Testing\n\nUnit, contract, and integration tests use `pytest`. For details on capturing new VCR cassettes from a live DEVONthink instance, see [`docs/development/cassette-recording.md`](docs/development/cassette-recording.md).\n\n---\n\n## Performance tuning (env vars)\n\n| Variable | Default | Effect |\n|---|---|---|\n| `ISTEFOX_FAST_LIST_DATABASES` | `false` | If truthy (`1`/`true`/`yes`/`on`): `list_databases` skips computing `record_count` (returns `null`). Useful on databases with tens of thousands of records, where `d.contents().length` can take seconds on the first call (the 5-min cache amortizes subsequent calls). Default: count included, behavior unchanged. |\n| `ISTEFOX_PREVIEW_TTL_S` | `300` | Override TTL in seconds for `preview_token` (default 5 minutes). Valid range: 1–3600. |\n| `ISTEFOX_RAG_ENABLED` | `false` | If truthy: enables the vector RAG provider (see next section). |\n| `ISTEFOX_RAG_MODEL` | `paraphrase-multilingual-MiniLM-L12-v2` | Override the embedding model (e.g. `BAAI/bge-m3`). Only used when RAG is enabled. |\n\n**For `.mcpb` installs (Claude Desktop)**: since v0.0.22 these four variables are configurable from the Claude Desktop UI without editing files. Open **Settings → Extensions → istefox-dt-mcp → Configure** and you'll see a form with human-readable labels for each option. Edit + Save + restart the server.\n\n**For `pipx`/dev installs**: set the env vars in your shell profile (`~/.zshrc`) or in the launch command.\n\n## RAG (vector search) — opt-in **experimental**\n\n> **⚠️ Experimental**: the RAG code is complete and unit-tested, but the embedding model default has not been validated cross-corpus yet. See [ADR-008](docs/adr/0008-embedding-model-selection.md) for the criteria to flip the default to `bge-m3` in a future release (target 0.4.0+). If you enable RAG now, be aware that quality depends heavily on your corpus — feedback via GitHub issues is very welcome.\n\nThe server runs in BM25-only mode by default (zero overhead, no models to download). To enable vector search:\n\n```bash\n# 1. Enable the RAG provider (env var)\nexport ISTEFOX_RAG_ENABLED=1\n\n# 2. (Optional) Override the model — default is MiniLM-L12-v2\nexport ISTEFOX_RAG_MODEL=BAAI/bge-m3   # ~2.2 GB, higher quality\n\n# 3. Index a DT database (one-shot — automatic sync covered below)\nuv run istefox-dt-mcp reindex <your-database-name>\nuv run istefox-dt-mcp reindex <your-database-name> --limit 100   # partial test\n\n# 4. Verify the index\nuv run istefox-dt-mcp doctor\n# {... \"rag\": {\"indexed_count\": N, \"embedding_model\": \"...\"}}\n\n# 5. Start the server and use search mode=hybrid or ask_database\nuv run istefox-dt-mcp serve\n```\n\nChromaDB is embedded and persisted at `~/.local/share/istefox-dt-mcp/vectors/`. Lazy load: the model is downloaded/loaded on the first call to `search` or `ask_database` in semantic mode, not at startup.\n\n### Automatic sync (opt-in)\n\nFor real-time incremental indexing via DT4 smart rules + periodic reconciliation:\n\n```bash\n# 1. (Optional) generate a webhook token\nexport ISTEFOX_WEBHOOK_TOKEN=\"$(openssl rand -hex 16)\"\n\n# 2. Start the daemon\nuv run istefox-dt-mcp watch \\\n    --port 27205 \\\n    --databases <your-database-name> \\\n    --reconcile-interval-s 21600   # every 6h\n\n# 3. Configure the DT4 smart rule (see docs/smart-rules/sync_rag.md)\n# 4. Manual reconciliation now and then:\nuv run istefox-dt-mcp reconcile <your-database-name>\n```\n\nFor auto-start at boot: see `docs/smart-rules/sync_rag.md` §\"launchd auto-start\".\n\n---\n\n## Claude Desktop integration (dev)\n\nFor end users, see [Quick Install](#quick-install-3-ways). This section covers the dev workflow (bundle build and manual config for source installs).\n\n**Build the `.mcpb` bundle** (only requires `bash + zip + unzip`):\n\n```bash\n./scripts/build_mcpb.sh\n# Output: dist/istefox-dt-mcp-<version>.mcpb (~290 KB)\n```\n\nThe bundle uses `server.type=python` with a bash wrapper (`bundle_main.sh`) that detects `uv` across common install locations (Homebrew, cargo, pipx, mise, asdf, plus the `ISTEFOX_UV_BIN` override). Claude Desktop manages the runtime lifecycle.\n\n**Manual `claude_desktop_config.json` (source install)**:\n\n```json\n{\n  \"mcpServers\": {\n    \"istefox-dt-mcp\": {\n      \"command\": \"uv\",\n      \"args\": [\"--directory\", \"/path/to/istefox-dt-mcp\", \"run\", \"istefox-dt-mcp\", \"serve\"]\n    }\n  }\n}\n```\n\nPath: `~/Library/Application Support/Claude/claude_desktop_config.json`. Restart Claude Desktop. All six tools become available.\n\n> RAG and other options: via env vars in the process that launches `claude` (manual config) or via the **Settings → Extensions → Configure** UI for the bundle (since v0.0.22).\n\n---\n\n## Key documents\n\n| File | Contents |\n|---|---|\n| [`CLAUDE.md`](CLAUDE.md) | Mandatory project constraints (legal, MCP, DT, safety) |\n| [`memory.md`](memory.md) | Consolidated decisions + open questions + context |\n| [`handoff.md`](handoff.md) | Current state + next steps |\n| [`docs/architecture.md`](docs/architecture.md) | Layered overview of the solution |\n| [`docs/adr/`](docs/adr/) | Architecture decision records (stack, bridge, sidecar, MVP, tests, DT4, RAG model) |\n| [`docs/adr/REVIEW_ADR.md`](docs/adr/REVIEW_ADR.md) | Architecture review v1.0 (input to the formal ADRs) |\n| [`ARCH-BRIEF-DT-MCP.md`](ARCH-BRIEF-DT-MCP.md) | Original architecture brief v0.1 (historical source of truth) |\n\n![Architecture diagram of istefox-dt-mcp: MCP clients → FastMCP server → JXA adapter → DEVONthink 4, with optional RAG sidecar](docs/assets/architecture.svg)\n\n---\n\n## Legal constraints\n\n- **Clean-room implementation**: no code copied from [`dvcrn/mcp-server-devonthink`](https://github.com/dvcrn/mcp-server-devonthink) (GPL-3.0).\n- **Privacy by design**: no user data leaves the machine by default. Embeddings are generated locally; the audit log is local.\n- **Personal namespace**: `istefox` (this is a personal project, not a work project).\n\n---\n\n## Other MCP servers by istefox\n\n- **[obsidian-mcp-connector](https://github.com/istefox/obsidian-mcp-connector)** — community-continuation fork of `jacksteamdev/obsidian-mcp-tools`. In-process Streamable HTTP MCP server inside Obsidian (no native binary), 20 tools over your vault, native semantic search via Transformers.js. MIT.\n\n---\n\n## License\n\n[MIT License](LICENSE) © 2026 Stefano Ferri.\n\nYou may use, modify, and redistribute the code (including commercially) as long as you keep the copyright notice. See [`LICENSE`](LICENSE) for the full text.\n",
  "bytes": 22982,
  "sha": "f33b50d674d5845683ecc6fd3b0e1f862d50cca74a3e12363d354699b33dcb1a",
  "repo_slug": "istefox/istefox-dt-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_istefox_dt_mcp_6e69cc3e/readme"
}