dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Joplin notes plugin for DeepSeek Harness: search, read and (opt-in) edit notes via the local Web Clipper API. Zero runtime dependencies.
Joplin notes plugin for DeepSeek Harness — let the agent read and write your local Joplin notes: search, full-text read, create, notebook management, backlinks. Read-only by default, zero runtime dependencies.
English · 简体中文 · 日本語 · 한국어
node:http / node:fs) — no Python, no uv, no long-running sidecar, no build step.Work/ProjectA, ids, or unique titles; ambiguity is reported instead of guessed.engine.41184);Only Joplin desktop's Web Clipper data API is supported. Joplin Cloud and the mobile apps expose different APIs and do not work.
plugin_manager(action: "install_bundle", target: "dsh-joplin")or:
dsh plugin --profile <profile> add dsh-joplinHave DSH install the repository into your profile directly:
plugin_manager(action: "install_bundle", target: "github:ddssh/dsh-joplin")git clone https://github.com/ddssh/dsh-joplin.gitThen pass that directory as target to install_bundle, or:
dsh plugin --profile <profile> add /absolute/path/to/dsh-joplinThe joplin_* tools are registered after install. This is a pure Host plugin with no client half, so a restart is usually unnecessary — but restarting is required after editing the plugin's JS (Node caches imported modules).
Settings are resolved from three layers, highest priority first, and the first non-empty value wins:
Priority · Source · Notes 1 · ~/.dsh/joplin.json · Recommended: takes effect immediately, keeps the token out of your profile YAML 2 · Env vars JOPLIN_TOKEN, JOPLIN_BASE_URL, JOPLIN_TIMEOUT_MS, JOPLIN_DEFAULT_NOTEBOOK, JOPLIN_ALLOW_CREATE / JOPLIN_ALLOW_UPDATE / JOPLIN_ALLOW_DELETE · Requires a Harness restart 3 · Plugin config (Settings / cordis.patch.yml in the profile) · baseUrl, token, timeoutMs, defaultNotebook, allowCreate, allowUpdate, allowDelete
Minimal setup:
cat > ~/.dsh/joplin.json <<'JSON'
{
"token": "your-web-clipper-token",
"baseUrl": "http://127.0.0.1:41184"
}
JSON
chmod 600 ~/.dsh/joplin.jsonOptional fields: defaultNotebook (where new notes go, e.g. Work/ProjectA), timeoutMs, and allowCreate / allowUpdate / allowDelete.
Once configured, call joplin_status first: it reports which layer the token came from, whether the service is reachable, and how many notebooks exist.
Tool · What it does · Default permission joplin_status · Diagnostics: token source, connectivity, notebook count, recent updates · read-only joplin_list_notebooks · Notebook tree with full paths and ids · read-only joplin_search_notes · Keyword search with snippets; empty query + notebook lists that notebook · read-only joplin_get_note · Full note: body, notebook, tags, internal links · read-only joplin_find_linked_notes · Outgoing and back links via internal links :/ · read-only joplin_create_note · Create a note (optionally in a notebook, optionally a todo) · allowCreate (on) joplin_create_notebook · Create a notebook or sub-notebook · allowCreate (on) joplin_import_markdown · Import a local .md file as a note · allowCreate (on) joplin_update_note · Change title/body/notebook/todo, only the fields you pass · allowUpdate (off) + user_confirmed joplin_delete_note · Delete; to trash by default, permanent with permanent: true · allowDelete (off) + user_confirmed
Notebook arguments accept a 32-character id, a unique title, or a full path (Work/ProjectA); ambiguous input raises an error listing the candidates.
Capability · Setting · Default Create notes / notebooks / import Markdown · allowCreate · on Modify existing notes (title/body/notebook/todo) · allowUpdate · off Delete notes · allowDelete · off
user_confirmed: true, meaning the user explicitly asked for that note in this turn.{ "token": "…", "allowUpdate": true }baseUrl (default http://127.0.0.1:41184), no uploads, no telemetry.JOPLIN_NOTES) requiring note bodies and snippets to stay away from web search, the browser, subagents, and other tools.Both were reproduced on Joplin desktop 3.7.18; the plugin works around them:
GET /search?query=… may never return, while title: search, /folders, and /notes stay fast.The plugin falls back to a local scan after 8 seconds (about 13 ms for 260 notes) and skips the stuck endpoint for 10 minutes; mode: "local" forces the local scan.
U+FFFD appears per 16 KB of body text (client-independent; reproducible with Python as well).The plugin ASCII-escapes every outbound JSON payload (\uXXXX) and reads the note back after writing; a mismatch raises WRITE_VERIFY_FAILED instead of silently corrupting the note.
npm test # starts an in-memory mock Joplin and exercises all 10 toolsThe smoke test covers notebook tree/path resolution, keyword search, listing notes by notebook, full-text read, outgoing/back links, create/update/delete, sub-notebook creation, Markdown import, the three configuration layers, the permission gates (update/delete refused by default without touching disk, user_confirmed validation), search failure fallback, and ASCII escaping.
dsh-joplin/
├── package.json # bundle manifest: dsh.bundle.patch / icon / locale
├── cordis.patch.yml # inserts the Host plugin row (id: dsh-joplin)
├── index.js # Config (schemastery) + apply: tools and prompt rules
├── joplin-tools.js # settings resolution, notebook resolution, search/link graph, tool definitions
├── joplin-client.js # node:http client (timeouts, error translation, ASCII escaping)
├── icon.svg / locale/ # plugin card presentation
└── test/ # mock Joplin server + smoke testThe capability set follows dweigend/joplin-mcp-server (Python + FastMCP). This plugin is a native Node rewrite for DSH: it keeps CRUD, the notebook tree, Markdown import, and backlinks, and adds permission gates, search fallback, and write verification, while fixing the original's notebook-path degradation when the API returns a flat list.