Doramagic Project Pack · Human Manual
second-brain-joplin
MCP server that turns your Joplin knowledge base into searchable memory for Claude Code and other MCP clients
Project Overview and System Architecture
Related topics: MCP Tools Reference, Installation, Deployment, and PyPI Release
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: MCP Tools Reference, Installation, Deployment, and PyPI Release
Project Overview and System Architecture
Purpose and Scope
second-brain-joplin is a Model Context Protocol (MCP) server that exposes a local Joplin knowledge base to any MCP-capable AI client — Claude Code, Cursor, and similar tools. Source: README.md. It is the Joplin counterpart to second-brain-mcp, which targets Obsidian. Source: README.md.
The project is currently at v0.1.0 (bootstrap) — the package installs, the server starts, and all five MCP tools are registered, but each one returns a {"status": "not implemented"} payload while the underlying JoplinClient methods (except ping()) remain stubbed. Source: src/second_brain_joplin/__init__.py:3, src/second_brain_joplin/server.py:34-58. Real implementations are tracked in the v0.2 milestone and tracked as issues #5–#8 and #10 in the repository. Source: src/second_brain_joplin/server.py:32.
High-Level Architecture
The runtime topology is a three-tier, fully local chain. The AI client never touches the Joplin REST API directly; it speaks MCP to this server, which then forwards requests to Joplin over HTTP on localhost. Source: README.md.
flowchart LR
A["MCP client<br/>(Claude Code / Cursor)"]
B["second-brain-joplin<br/>FastMCP server (stdio)"]
C["Joplin Desktop<br/>Web Clipper REST API<br/>http://localhost:41184"]
D[("Joplin notes<br/>& notebooks")]
A -- "MCP / stdio" --> B
B -- "HTTP + token<br/>(python-dotenv)" --> C
C --> DCore Components
| File | Role |
|---|---|
src/second_brain_joplin/__init__.py | Package metadata; exposes __version__ = "0.1.0". Source: src/second_brain_joplin/__init__.py:3 |
src/second_brain_joplin/server.py | FastMCP server factory, argparse CLI (serve subcommand + --version), lazy JoplinClient singleton, and the five @mcp.tool() registrations. Source: src/second_brain_joplin/server.py:16, 21-28, 34-58, 60-74 |
src/second_brain_joplin/joplin_client.py | Thin httpx.AsyncClient-based wrapper around the Joplin Data API. Only ping() is implemented; the rest raise NotImplementedError. Source: src/second_brain_joplin/joplin_client.py:6-23 |
.env.example | Documented template for JOPLIN_API_TOKEN and JOPLIN_BASE_URL. Source: .env.example |
The _get_client() helper in server.py instantiates JoplinClient on first use and caches it as a module-level singleton — it reads the token and base URL from the environment at that point. Source: src/second_brain_joplin/server.py:19-28.
Registered MCP Tools (v0.1 stubs)
All five are @mcp.tool()-decorated async functions that short-circuit before reaching JoplinClient. Source: src/second_brain_joplin/server.py:34-58.
joplin_overview()— list notebooks with note counts (issue #5).joplin_search(query: str)— keyword search (issue #6).joplin_read(note_id: str)— fetch a note's full body (issue #7).joplin_recent(days: int = 7)— recently modified notes (issue #8).joplin_create(title: str, body: str, notebook_id: str)— human-gated write, planned for v0.4 (issue #10).
Configuration and Environment
Configuration is environment-only, loaded by python-dotenv at startup so a local .env "just works". Source: src/second_brain_joplin/server.py:8, 65.
| Variable | Default | Source |
|---|---|---|
JOPLIN_API_TOKEN | *(none, required)* | README.md, src/second_brain_joplin/server.py:22 |
JOPLIN_BASE_URL | http://localhost:41184 | README.md, src/second_brain_joplin/server.py:23 |
Prerequisites are intentionally minimal: Joplin Desktop with the Web Clipper service enabled, the token copied from the Web Clipper settings, and either Python ≥ 3.11 or uvx for zero-install execution. Source: README.md.
Development Workflow and CI/CD
The toolchain is uv-managed and the source of truth for tooling versions is .pre-commit-config.yaml. Source: CONTRIBUTING.md.
- Local loop —
uv sync→uv run pre-commit install→uv run pytest; ruff lint/format runs viauvx pre-commit run --all-files, mypy viauv run mypy src. Source: CONTRIBUTING.md. - Coverage gate — 90% coverage is enforced in the CI command, not in
addopts, so partial test runs do not falsely fail. Source: CONTRIBUTING.md, CHANGELOG.md. - Reusable checks workflow —
.github/workflows/checks.ymlcentralizes lint, type-check, the Python 3.11/3.12/3.13 test matrix, and a packaging build +twine checksmoke test; bothci.yml(push/PR) andrelease.yml(publish) call it. Source: CHANGELOG.md, CONTRIBUTING.md. - Type checking — mypy is a required gate (currently pragmatic; tightening to
strictis tracked in issue #19). Source: CHANGELOG.md.
Security and Privacy Posture
The server is local-only: it never sends notes to a third party, the Joplin API token is read from the environment, and writes are explicitly out of scope in v0.1. Source: SECURITY.md. Note creation is deliberately deferred to a human-gated flow in v0.4 so that "no writes happen without your confirmation". Source: SECURITY.md, README.md. The community already notes the need to enforce component-label automation via actions/labeler (issue #18) and to ship a v1.0 release pipeline (issue #12), both of which sit on the v1.0 milestone. Source: community context, issues #11, #12, #18.
Roadmap and Status
| Milestone | Theme | Status |
|---|---|---|
| v0.1 — Bootstrap | Repo, CI, package skeleton, stubbed tools | Shipped |
| v0.2 — Core Read Tools | joplin_overview, joplin_search, joplin_read, joplin_recent implemented | Planned |
| v0.3 — Semantic Search | Embedding index + joplin_semantic_search (issue #9) | Planned |
| v0.4 — Write Workflow | Human-gated joplin_create (issue #10) | Planned |
| v1.0 — Publish | OIDC-trusted PyPI release, full docs, PARA templates (issues #11, #12) | Planned |
Source: README.md, community context, issues #9, #10, #11.
See Also
- README.md — quickstart, MCP tools table, and prerequisites.
- CHANGELOG.md — full change history for the v0.1 release and unreleased CI/typing work.
- CONTRIBUTING.md — local dev setup, CI mechanics, and label conventions.
- SECURITY.md — vulnerability reporting and data-handling policy.
- src/second_brain_joplin/server.py — FastMCP tool definitions and CLI entry point.
- src/second_brain_joplin/joplin_client.py — Joplin Data API wrapper used by the tools.
- docs/install.md — per-client MCP configuration guides.
- docs/notebook-structure.md — recommended PARA notebook layout.
- docs/project-management.md — issue types, milestones, and label scheme.
Source: https://github.com/jomkz/second-brain-joplin / Human Manual
MCP Tools Reference
Related topics: Project Overview and System Architecture, Development Workflow, Testing, and CI/CD
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Project Overview and System Architecture, Development Workflow, Testing, and CI/CD
MCP Tools Reference
Overview
second-brain-joplin exposes a Model Context Protocol (MCP) server named "second-brain-joplin" that lets any MCP-capable AI client — Claude Code, Cursor, and others — read and (eventually) write to a local Joplin knowledge base through a small set of typed tools. The server is a thin FastMCP wrapper around Joplin's Web Clipper REST API on localhost:41184 (README.md).
In the current v0.1 (Bootstrap) release, all five tools are registered but stubbed — they short-circuit with a {"status": "not implemented"} payload and never call out to the (also-stubbed) JoplinClient methods (server.py). The rationale is to ship a package skeleton that boots, registers tools, and exposes a CLI (serve subcommand + --version) while real implementations land across v0.2–v0.4 (CHANGELOG.md).
Tool Registry
Five tools are defined via @mcp.tool() decorators in src/second_brain_joplin/server.py and listed in the README. The table maps each tool to its planned API call, the GitHub issue tracking its implementation, and whether it writes.
| Tool | Planned Action | Tracking Issue | Writes? |
|---|---|---|---|
joplin_overview | GET /notebooks (recurse, build tree) | #5 | No |
joplin_search | GET /search?query=<q> | #6 | No |
joplin_read | GET /notes/<id>?fields=id,title,body | #7 | No |
joplin_recent | GET /notes?order_by=updated_time&order_dir=DESC | #8 | No |
joplin_create | Human-gated note creation | #10 | Yes (gated) |
Sources: server.py, README.md.
Tool-by-Tool Reference
Each tool is an async function whose signature is part of the MCP contract that AI clients introspect. The signatures are stable even though the bodies are stubs (server.py).
`joplin_overview`
@mcp.tool()
async def joplin_overview() -> dict: ...
Returns a summary of the notebook tree — name, note count, and children — so the AI can orient before diving into individual notes (issue #5). No parameters.
`joplin_search`
@mcp.tool()
async def joplin_search(query: str) -> dict: ...
Keyword search across all notebooks via Joplin's /search endpoint. Issue #6 specifies the planned contract: required query plus an optional limit (default 10), returning matching {id, title, excerpt} records. This is the project's primary use case — letting the AI find notes by keyword (README.md, issue #6).
`joplin_read`
@mcp.tool()
async def joplin_read(note_id: str) -> dict: ...
Fetches the full markdown body of a single note. Issue #7 defines the response shape {id, title, body} and explicit handling for missing notes. Pairs naturally with joplin_search: the AI searches, picks an ID, then reads.
`joplin_recent`
@mcp.tool()
async def joplin_recent(days: int = 7) -> dict: ...
Lists notes modified within the last days days, defaulting to 7. Issue #8 frames this as "what have I been working on lately" context for the model — useful at the start of a session to ground the AI in recent work.
`joplin_create`
@mcp.tool()
async def joplin_create(title: str, body: str, notebook_id: str) -> dict: ...
The single write tool. Per issue #10, every call must pass through a human-in-the-loop confirmation (MCP prompt or similar) and requires the caller to specify the target notebook. Until v0.4 ships, this tool is also stubbed and never performs silent writes (SECURITY.md).
Stub Payload Contract
Every stubbed tool returns the same shape today:
{
"status": "not implemented",
"tool": "<tool name>",
"issue": <tracking issue number>
}
This contract is defined in server.py (one entry per tool) and exists for two reasons: (1) clients receive a typed, parseable response rather than an exception, and (2) the embedded issue field points maintainers and downstream tooling at the tracking work item. The matching JoplinClient methods (get_notebooks, get_note, search, get_recent, create_note) raise NotImplementedError if reached — but in v0.1 they are unreachable because the tools short-circuit first (joplin_client.py).
Architecture & Data Flow
The runtime architecture has three tiers: the MCP client (AI), the FastMCP server, and Joplin's local REST API. Configuration flows from environment variables (JOPLIN_API_TOKEN, JOPLIN_BASE_URL) loaded via python-dotenv (server.py).
flowchart LR
Client["MCP client<br/>(Claude Code / Cursor)"] -->|MCP stdio| Server["second-brain-joplin<br/>FastMCP server"]
Server -->|httpx + token| Joplin["Joplin Web Clipper API<br/>localhost:41184"]
Joplin --> Notes[("Your Joplin notes")]
Server -. stubbed .-> ServerOnly JoplinClient.ping() is implemented end-to-end today — it returns True when the API responds with the literal string JoplinClipperServer, and False on a httpx.ConnectError (joplin_client.py). All other client methods are stubs pending the v0.2 milestone (README.md, CHANGELOG.md).
Implementation Status & Roadmap
The tool layer is the focus of the next three milestones (README.md, CHANGELOG.md):
| Milestone | Theme | Tool Impact |
|---|---|---|
| v0.2 — Core Read Tools | Implement read tools | joplin_overview, joplin_search, joplin_read, joplin_recent become functional |
| v0.3 — Semantic Search | Embedding index (issue #9) | Adds joplin_semantic_search (bge-m3 via sentence-transformers, ChromaDB/FAISS) |
| v0.4 — Write Workflow | Human-gated creation | joplin_create ships behind a confirmation prompt |
| v1.0 — Publish | PyPI, full docs, PARA templates | Per-tool reference, configuration guide, troubleshooting (issue #11) |
Quality gates that protect the tool layer are run via the reusable checks workflow: ruff lint + format, mypy on src, pytest matrix on Python 3.11/3.12/3.13 with a 90% coverage gate, plus a packaging build/twine check/wheel smoke test (CHANGELOG.md, CONTRIBUTING.md).
Security Notes
Tools inherit the privileges of the Joplin token they are configured with. Anything an MCP client can read, the connected AI can read — so users should apply least privilege and avoid notebooks containing credentials or regulated data (SECURITY.md). v0.1 performs no writes; v0.4 will require explicit human confirmation before joplin_create reaches the API.
See Also
- README.md — project overview, quickstart, comparison vs.
second-brain-mcp - CHANGELOG.md — release notes for v0.1 and the
checksworkflow rework - SECURITY.md — vulnerability reporting and privacy model
- CONTRIBUTING.md — dev setup, CI model, label conventions
- v0.2 milestone — tracking issue for read-tool implementations (#5–#8)
- v0.4 milestone — tracking issue #10 for the write tool
Development Workflow, Testing, and CI/CD
Related topics: MCP Tools Reference, Installation, Deployment, and PyPI Release
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: MCP Tools Reference, Installation, Deployment, and PyPI Release
Development Workflow, Testing, and CI/CD
Purpose and Scope
second-brain-joplin is a pre-alpha MCP server that wraps the Joplin Web Clipper REST API as MCP tools. Its development workflow must guarantee that any merged code can (a) start the FastMCP server, (b) pass lint, type-check, and a Python test matrix, and (c) build a publishable wheel/sdist — without leaking note data to third-party services. Source: README.md:1-5, CHANGELOG.md:5-30. The project is currently at v0.1.0, with a planned v0.2 covering real tool implementations, v0.3 for semantic search, v0.4 for human-gated writes, and v1.0 for the full PyPI release. Source: src/second_brain_joplin/__init__.py:1-3, README.md:135-145.
Tooling: uv-First Bootstrap
The official toolchain is uv. New contributors run:
git clone https://github.com/jomkz/second-brain-joplin
cd second-brain-joplin
uv sync
uv run pre-commit install # enable ruff lint/format on commit
A pip fallback is documented for users without uv: create a venv, activate it, and pip install -e ".[test]". Source: CONTRIBUTING.md:5-22. The CI installs with uv sync --locked so a drift between pyproject.toml and uv.lock fails the build before tests even start. Source: CHANGELOG.md:11-15.
The server binary is a thin Python module: __version__ is exported from __init__.py, and server.py exposes an argparse CLI whose only subcommand is serve, plus a --version flag. load_dotenv() is called in main() so a .env file (modeled on .env.example) is honored before any Joplin call. Source: src/second_brain_joplin/server.py:30-65, README.md:60-78.
Testing Strategy
Tests live in tests/ and run via:
uv run pytest
uv run pytest --cov-fail-under=90 # reproduce the CI gate locally
A 90% coverage gate is enforced in CI but intentionally removed from pytest addopts, so running a subset of tests locally never spuriously fails. Source: CONTRIBUTING.md:27-32, CHANGELOG.md:27-30. The HTTP layer is tested with respx, which mocks httpx.AsyncClient calls; this is essential because JoplinClient.ping() performs an actual await client.get(...) against localhost:41184. Source: src/second_brain_joplin/joplin_client.py:11-21. The matrix covers Python 3.11, 3.12, and 3.13. Source: CONTRIBUTING.md:50-55, CHANGELOG.md:70-75.
Stubbed tools short-circuit with {"status": "not implemented", "tool": ..., "issue": <n>} payloads pointing to GitHub issues #5–#8 and #10, so tests can assert on the stub shape without exercising the unimplemented JoplinClient methods. Source: src/second_brain_joplin/server.py:40-60, src/second_brain_joplin/joplin_client.py:23-39.
Static Analysis: Lint and Types
Lint is driven by pre-commit in CI, with .pre-commit-config.yaml as the single source of truth (no more version drift with the dev group). The hooks cover ruff check + format --check plus end-of-file, trailing-whitespace, and YAML/TOML hygiene. Source: CHANGELOG.md:5-25. The local command is uvx pre-commit run --all-files. Source: CONTRIBUTING.md:36-41.
mypy is a required CI gate (uv run mypy src) with a pragmatic baseline (ignore_missing_imports, warn_unused_ignores, warn_redundant_casts) because FastMCP's untyped @mcp.tool() decorator would fail under strict = true. Source: CHANGELOG.md:17-22, pyproject.toml. Issue #19 tracks gradual tightening to strict mode once those untyped decorators are accommodated. Source: issue #19.
CI/CD Architecture
All quality gates live in one reusable workflow at .github/workflows/checks.yml — a lint job, a typecheck job, a test matrix job, and a build job that runs uv build, twine check, and a wheel smoke test. Both ci.yml (on push/PR to main) and release.yml (before publishing to PyPI) call it, so nothing merges or ships without passing the same checks. Source: CONTRIBUTING.md:46-55, CHANGELOG.md:5-15. The release job publishes the exact artifact built and tested in checks (build-once/test/publish) with skip-existing on re-runs. Source: CHANGELOG.md:7-11.
Least-privilege permissions and concurrency cancellation are configured to cancel in-flight runs on the same ref when a new commit is pushed. Source: CHANGELOG.md:13-17. PyPI publishing uses an OIDC trusted publisher; the release flow is tracked in issue #12 and milestones toward v1.0 in issue #11. Source: issue #12, issue #11. Maintainers also want an actions/labeler workflow to apply component:* labels automatically (issue #18). Source: issue #18.
flowchart LR
A[push / PR to main] --> B[ci.yml]
T[tag release] --> R[release.yml]
B --> C[checks.yml]
R --> C
C --> L1[lint: pre-commit]
C --> L2[typecheck: mypy src]
C --> L3[test matrix: py 3.11/3.12/3.13 + 90% cov]
C --> L4[build: uv build + twine check + smoke]
L4 --> P[publish to PyPI via OIDC]Local Reproduction and Best Practices
To match CI exactly, run uv sync --locked (not plain uv sync) so your environment cannot silently drift from uv.lock. Source: CHANGELOG.md:11-13. Before opening a PR, execute the same sequence CI runs:
uvx pre-commit run --all-files
uv run mypy src
uv run pytest --cov-fail-under=90
Source: CONTRIBUTING.md:36-41. PRs must target main, stay focused on one logical change, include tests, and pass the full CI. Source: CONTRIBUTING.md:84-90. Maintainers triage issues by issue type, milestone, component:* labels, optional phase-N labels, and parent epics — see the label table in CONTRIBUTING.md and the model in docs/project-management.md. Source: CONTRIBUTING.md:64-83, docs/project-management.md.
A common failure mode is the stubbed-tool surprise: when testing without a running Joplin instance, every tool returns a not implemented payload regardless of arguments. This is by design for v0.1 — implementers should look at issues #5–#8 and #10 and use respx mocks for real HTTP coverage. Source: src/second_brain_joplin/server.py:30-60, src/second_brain_joplin/joplin_client.py:23-39. Another common failure is exposing JOPLIN_API_TOKEN in version control; the env var is read at runtime and never committed. Source: SECURITY.md:12-18.
See Also
README.md— Quickstart and per-client install guidesCHANGELOG.md— Detailed release historySECURITY.md— Threat model and reporting guidelinesdocs/install.md— Per-MCP-client setup walkthroughs- Roadmap and milestone tracking on GitHub
Source: https://github.com/jomkz/second-brain-joplin / Human Manual
Installation, Deployment, and PyPI Release
Related topics: Project Overview and System Architecture, Development Workflow, Testing, and CI/CD
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Project Overview and System Architecture, Development Workflow, Testing, and CI/CD
Installation, Deployment, and PyPI Release
Overview
second-brain-joplin is a Python MCP server (__version__ = "0.1.0") that exposes a local Joplin knowledge base to any MCP-capable AI client such as Claude Code or Cursor. The server is distributed on PyPI and run via the uvx launcher; it keeps notes local by speaking only to Joplin's Web Clipper REST API on localhost:41184. The v1.0 publish milestone and the PyPI trusted-publisher work are tracked in issue #11 and issue #12 respectively.
sequenceDiagram
participant Client as MCP Client<br>(Claude Code / Cursor)
participant Srv as second-brain-joplin serve
participant Jop as Joplin Desktop<br>localhost:41184
participant Notes as Joplin Notes
Client->>Srv: stdio / MCP tool call
Srv->>Jop: HTTP GET (X = token)
Jop-->>Srv: JSON
Srv-->>Client: tool result
Jop->>Notes: local read/writeInstallation
Prerequisites
- Joplin Desktop running with the Web Clipper service enabled (toggle in *Tools → Options → Web Clipper → Enable Web Clipper Service*).
- API token copied from that same Web Clipper settings panel.
- Python ≥ 3.11 *or* the
uvxrunner (recommended — no global install needed).
Source: README.md:31-38
Recommended path: `uvx`
For Claude Code, the README documents a single registration command that injects the API token through the environment and runs the server in-process:
claude mcp add -s user second-brain-joplin \
-e JOPLIN_API_TOKEN=your-token-here \
-- uvx second-brain-joplin serve
For other MCP clients, three settings are sufficient — the serve subcommand, JOPLIN_API_TOKEN from Joplin Web Clipper, and JOPLIN_BASE_URL defaulting to http://localhost:41184. Source: README.md:42-53
Alternative path: `pip` (development)
Contributors use the bundled uv toolchain:
git clone https://github.com/jomkz/second-brain-joplin
cd second-brain-joplin
uv sync
uv run pre-commit install
A pip fallback (python -m venv .venv && pip install -e ".[test]") is documented for environments without uv. Source: CONTRIBUTING.md:9-22
Configuration and Local Run
The CLI surface is second-brain-joplin serve plus a --version flag. At startup, main() calls load_dotenv() *before* argument parsing, so a local .env file is picked up automatically; the recommended flow is cp .env.example .env, edit, then uv run second-brain-joplin serve. Source: src/second_brain_joplin/server.py:64-71; CONTRIBUTING.md:30-33
_get_client() lazily constructs the singleton JoplinClient, reading JOPLIN_API_TOKEN (defaulting to "") and JOPLIN_BASE_URL (defaulting to http://localhost:41184). The JoplinClient constructor strips a trailing slash from the base URL and stores the token in a reusable query-params dict used for every request. Source: src/second_brain_joplin/server.py:12-21; src/second_brain_joplin/joplin_client.py:11-15
CI/CD and the PyPI Release Path
Quality gates and the release pipeline share a single reusable workflow, .github/workflows/checks.yml, invoked by both ci.yml (push/PR) and release.yml (pre-publish). Releases therefore cannot ship code that has not passed the full check suite, and the release job follows a build-once/test/publish pattern — re-using the exact artifact built and tested in checks, with skip-existing on re-runs. Source: CHANGELOG.md:7-21; CONTRIBUTING.md:23-31
The checks workflow runs:
pre-commit run --all-files— single source of truth for ruff lint + format (CI invokes the *exact* same command contributors run locally).uv run mypy src— static type checking, now a required CI gate.pyteston a Python 3.11 / 3.12 / 3.13 matrix with a 90% coverage gate.- A build job that runs
uv build,twine check, and a wheel smoke test.
Source: CHANGELOG.md:9-33; CHANGELOG.md:46-50
CI also installs with uv sync --locked (a drifted uv.lock fails the run), adds least-privilege permissions and concurrency cancellation, and validates packaging on every PR. Source: CHANGELOG.md:11-21
Publication to PyPI uses an OIDC trusted publisher — no long-lived PyPI token is stored in the repo, and the project is already registered as a trusted publisher on pypi.org. Source: issue #12
Reproducing the gates locally
uv run pytest --cov-fail-under=90
uvx pre-commit run --all-files
uv run mypy src
uv build && twine check dist/*
Note that --cov-fail-under=90 was moved out of pytest addopts into the CI command specifically so partial local runs don't spuriously fail the gate. Source: CHANGELOG.md:30-33; CONTRIBUTING.md:18-31
Failure Modes and Operational Notes
- Missing token —
JoplinClientis constructed withtoken=""ifJOPLIN_API_TOKENis unset;ping()will fail at runtime rather than at import. - Joplin not running —
ping()catcheshttpx.ConnectErrorand returnsFalse, so the MCP server stays up but downstream data calls surface the connection error. - Drifted lockfile —
uv sync --lockedis a hard gate. - Coverage gate — enforced only on the full CI command, not on
pytestby default.
Source: src/second_brain_joplin/server.py:12-21; src/second_brain_joplin/joplin_client.py:17-23
Security Considerations
The server runs locally, reads the Joplin token only from the environment, and never commits it. v0.1 tools are read-oriented and stubbed; planned joplin_create writes will be explicitly human-gated before any silent write occurs. Apply least-privilege to notebooks containing credentials or regulated data — anything an MCP client can read, the connected AI can read. Source: SECURITY.md:11-21; README.md:67-74
See Also
- Tool reference —
joplin_overview,joplin_search,joplin_read,joplin_recent,joplin_create - v0.2 implementation work — milestone: Core Read Tools
- v1.0 publish epic — issue #11 (full docs, PARA templates,
uvxsmoke) and issue #12 (PyPI OIDC publish)
Source: https://github.com/jomkz/second-brain-joplin / Human Manual
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
Developers may expose sensitive permissions or credentials: Add PR labeler workflow (actions/labeler)
Developers may expose sensitive permissions or credentials: Set up CI pipeline (lint + test matrix)
Developers may fail before the first successful local run: Bootstrap second-brain-joplin (v0.1)
May increase setup, validation, or first-run risk for the user.
Doramagic Pitfall Log
Found 32 structured pitfall item(s), including 2 high/blocking item(s). Top priority: Security or permission risk - Security or permission risk requires verification.
1. Security or permission risk: Security or permission risk requires verification
- Severity: high
- Finding: Developers should check this security_permissions risk before relying on the project: Add PR labeler workflow (actions/labeler)
- User impact: Developers may expose sensitive permissions or credentials: Add PR labeler workflow (actions/labeler)
- Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Add PR labeler workflow (actions/labeler). Context: Source discussion did not expose a precise runtime context.
- Evidence: failure_mode_cluster:github_issue | https://github.com/jomkz/second-brain-joplin/issues/18
2. Security or permission risk: Security or permission risk requires verification
- Severity: high
- Finding: Developers should check this security_permissions risk before relying on the project: Set up CI pipeline (lint + test matrix)
- User impact: Developers may expose sensitive permissions or credentials: Set up CI pipeline (lint + test matrix)
- Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Set up CI pipeline (lint + test matrix). Context: Observed when using python
- Evidence: failure_mode_cluster:github_issue | https://github.com/jomkz/second-brain-joplin/issues/2
3. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Developers should check this installation risk before relying on the project: Bootstrap second-brain-joplin (v0.1)
- User impact: Developers may fail before the first successful local run: Bootstrap second-brain-joplin (v0.1)
- Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Bootstrap second-brain-joplin (v0.1). Context: Observed when using python
- Evidence: failure_mode_cluster:github_issue | https://github.com/jomkz/second-brain-joplin/issues/1
4. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/jomkz/second-brain-joplin/issues/1
5. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/jomkz/second-brain-joplin/issues/9
6. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.host_targets | https://github.com/jomkz/second-brain-joplin
7. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Developers should check this configuration risk before relying on the project: Implement core read MCP tools (v0.2)
- User impact: Developers may misconfigure credentials, environment, or host setup: Implement core read MCP tools (v0.2)
- Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Implement core read MCP tools (v0.2). Context: Source discussion did not expose a precise runtime context.
- Evidence: failure_mode_cluster:github_issue | https://github.com/jomkz/second-brain-joplin/issues/4
8. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Developers should check this configuration risk before relying on the project: Implement package skeleton and stubbed MCP server
- User impact: Developers may misconfigure credentials, environment, or host setup: Implement package skeleton and stubbed MCP server
- Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Implement package skeleton and stubbed MCP server. Context: Observed when using python
- Evidence: failure_mode_cluster:github_issue | https://github.com/jomkz/second-brain-joplin/issues/3
9. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Developers should check this configuration risk before relying on the project: PyPI publish, full docs, and Joplin templates (v1.0)
- User impact: Developers may misconfigure credentials, environment, or host setup: PyPI publish, full docs, and Joplin templates (v1.0)
- Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: PyPI publish, full docs, and Joplin templates (v1.0). Context: Observed when using windows, macos, linux
- Evidence: failure_mode_cluster:github_issue | https://github.com/jomkz/second-brain-joplin/issues/11
10. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/jomkz/second-brain-joplin/issues/19
11. Capability evidence risk: Capability evidence risk requires verification
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.assumptions | https://github.com/jomkz/second-brain-joplin
12. Runtime risk: Runtime risk requires verification
- Severity: medium
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/jomkz/second-brain-joplin/issues/7
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using second-brain-joplin with real data or production workflows.
- Implement joplin_overview tool - github / github_issue
- Implement package skeleton and stubbed MCP server - github / github_issue
- Set up CI pipeline (lint + test matrix) - github / github_issue
- Tighten mypy toward strict and cover tests/ - github / github_issue
- Add PR labeler workflow (actions/labeler) - github / github_issue
- PyPI publish, full docs, and Joplin templates (v1.0) - github / github_issue
- Bootstrap second-brain-joplin (v0.1) - github / github_issue
- Publish package to PyPI (trusted publisher) - github / github_issue
- Human-gated note creation (v0.4) - github / github_issue
- Semantic search via embedding index (v0.3) - github / github_issue
- Implement joplin_recent tool - github / github_issue
- Implement joplin_read tool - github / github_issue
Source: Project Pack community evidence and pitfall evidence