second-brain-joplin 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. second_brain_joplin-0.1.0/.editorconfig +18 -0
  2. second_brain_joplin-0.1.0/.env.example +5 -0
  3. second_brain_joplin-0.1.0/.github/ISSUE_TEMPLATE/bug.yml +32 -0
  4. second_brain_joplin-0.1.0/.github/ISSUE_TEMPLATE/epic.yml +24 -0
  5. second_brain_joplin-0.1.0/.github/ISSUE_TEMPLATE/feature.yml +27 -0
  6. second_brain_joplin-0.1.0/.github/ISSUE_TEMPLATE/spike.yml +25 -0
  7. second_brain_joplin-0.1.0/.github/ISSUE_TEMPLATE/task.yml +22 -0
  8. second_brain_joplin-0.1.0/.github/dependabot.yml +16 -0
  9. second_brain_joplin-0.1.0/.github/labeler.yml +23 -0
  10. second_brain_joplin-0.1.0/.github/project.yml +70 -0
  11. second_brain_joplin-0.1.0/.github/workflows/ci.yml +40 -0
  12. second_brain_joplin-0.1.0/.github/workflows/release.yml +30 -0
  13. second_brain_joplin-0.1.0/.gitignore +27 -0
  14. second_brain_joplin-0.1.0/.pre-commit-config.yaml +8 -0
  15. second_brain_joplin-0.1.0/.python-version +1 -0
  16. second_brain_joplin-0.1.0/CHANGELOG.md +31 -0
  17. second_brain_joplin-0.1.0/CONTRIBUTING.md +69 -0
  18. second_brain_joplin-0.1.0/LICENSE +21 -0
  19. second_brain_joplin-0.1.0/PKG-INFO +149 -0
  20. second_brain_joplin-0.1.0/README.md +120 -0
  21. second_brain_joplin-0.1.0/SECURITY.md +27 -0
  22. second_brain_joplin-0.1.0/docs/install.md +26 -0
  23. second_brain_joplin-0.1.0/docs/notebook-structure.md +29 -0
  24. second_brain_joplin-0.1.0/docs/project-management.md +79 -0
  25. second_brain_joplin-0.1.0/docs/reference/second-brain-inspiration.md +33 -0
  26. second_brain_joplin-0.1.0/docs/releasing.md +44 -0
  27. second_brain_joplin-0.1.0/pyproject.toml +72 -0
  28. second_brain_joplin-0.1.0/src/second_brain_joplin/__init__.py +3 -0
  29. second_brain_joplin-0.1.0/src/second_brain_joplin/joplin_client.py +43 -0
  30. second_brain_joplin-0.1.0/src/second_brain_joplin/server.py +82 -0
  31. second_brain_joplin-0.1.0/tests/conftest.py +17 -0
  32. second_brain_joplin-0.1.0/tests/test_cli.py +23 -0
  33. second_brain_joplin-0.1.0/tests/test_joplin_client.py +35 -0
  34. second_brain_joplin-0.1.0/tests/test_metadata.py +9 -0
  35. second_brain_joplin-0.1.0/tests/test_server.py +99 -0
  36. second_brain_joplin-0.1.0/uv.lock +1804 -0
@@ -0,0 +1,18 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+ indent_size = 4
10
+
11
+ [*.{yml,yaml,json,toml}]
12
+ indent_size = 2
13
+
14
+ [*.md]
15
+ trim_trailing_whitespace = false
16
+
17
+ [Makefile]
18
+ indent_style = tab
@@ -0,0 +1,5 @@
1
+ # Joplin Data API token — found at Tools → Options → Web Clipper in Joplin Desktop
2
+ JOPLIN_API_TOKEN=your-token-here
3
+
4
+ # Joplin API base URL — default is fine unless you changed the port
5
+ JOPLIN_BASE_URL=http://localhost:41184
@@ -0,0 +1,32 @@
1
+ name: Bug
2
+ description: An unexpected problem or incorrect behavior
3
+ labels: ["needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: What happened
9
+ validations:
10
+ required: true
11
+ - type: textarea
12
+ id: expected
13
+ attributes:
14
+ label: What was expected
15
+ validations:
16
+ required: true
17
+ - type: textarea
18
+ id: repro
19
+ attributes:
20
+ label: Steps to reproduce
21
+ validations:
22
+ required: true
23
+ - type: input
24
+ id: version
25
+ attributes:
26
+ label: Package version
27
+ placeholder: "e.g. 0.1.0"
28
+ - type: textarea
29
+ id: env
30
+ attributes:
31
+ label: Environment
32
+ placeholder: "OS, Python version, Joplin version"
@@ -0,0 +1,24 @@
1
+ name: Epic
2
+ description: A large, multi-issue initiative
3
+ labels: ["epic", "needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: goal
7
+ attributes:
8
+ label: Goal
9
+ description: What does this epic accomplish when all sub-issues are closed?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: sub-issues
14
+ attributes:
15
+ label: Sub-issues
16
+ description: List the issues that make up this epic (fill in after filing them).
17
+ placeholder: "- [ ] #1\n- [ ] #2"
18
+ - type: textarea
19
+ id: acceptance
20
+ attributes:
21
+ label: Acceptance criteria
22
+ description: How do we know this epic is done?
23
+ validations:
24
+ required: true
@@ -0,0 +1,27 @@
1
+ name: Feature
2
+ description: A request, idea, or new functionality
3
+ labels: ["needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem / motivation
9
+ description: What problem does this solve, or what need does it address?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: alternatives
20
+ attributes:
21
+ label: Alternatives considered
22
+ - type: textarea
23
+ id: acceptance
24
+ attributes:
25
+ label: Acceptance criteria
26
+ validations:
27
+ required: true
@@ -0,0 +1,25 @@
1
+ name: Spike
2
+ description: A time-boxed investigation that informs follow-on work
3
+ labels: ["needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: question
7
+ attributes:
8
+ label: Question to answer
9
+ description: What do we need to know by the end of this spike?
10
+ validations:
11
+ required: true
12
+ - type: input
13
+ id: timebox
14
+ attributes:
15
+ label: Timebox
16
+ placeholder: "e.g. 2 hours, 1 day"
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: output
21
+ attributes:
22
+ label: Expected output
23
+ description: What artifact or decision does this spike produce?
24
+ validations:
25
+ required: true
@@ -0,0 +1,22 @@
1
+ name: Task
2
+ description: A specific, well-scoped piece of work (including docs and chores)
3
+ labels: ["needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: What needs to be done
9
+ validations:
10
+ required: true
11
+ - type: textarea
12
+ id: acceptance
13
+ attributes:
14
+ label: Done when
15
+ description: Clear, verifiable definition of done.
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: notes
20
+ attributes:
21
+ label: Implementation notes
22
+ description: Relevant context, links, or constraints.
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "uv"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ labels:
8
+ - "dependencies"
9
+
10
+ - package-ecosystem: "github-actions"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "weekly"
14
+ labels:
15
+ - "dependencies"
16
+ - "github_actions"
@@ -0,0 +1,23 @@
1
+ component:joplin-api:
2
+ - src/second_brain_joplin/joplin_client.py
3
+
4
+ component:mcp:
5
+ - src/second_brain_joplin/server.py
6
+ - src/second_brain_joplin/tools.py
7
+
8
+ component:search:
9
+ - src/second_brain_joplin/search.py
10
+
11
+ component:docs:
12
+ - docs/**
13
+ - "*.md"
14
+ - "!CONTRIBUTING.md"
15
+
16
+ component:ci:
17
+ - .github/workflows/**
18
+ - .github/project.yml
19
+ - .github/labeler.yml
20
+ - pyproject.toml
21
+
22
+ component:templates:
23
+ - templates/**
@@ -0,0 +1,70 @@
1
+ # Declarative PM spec for second-brain-joplin.
2
+ # Applied manually via `gh` CLI or GitHub UI; no automated sync script at this stage.
3
+ # See docs/project-management.md for how this spec is used.
4
+
5
+ labels:
6
+ # component labels
7
+ - name: "component:joplin-api"
8
+ color: "0075ca"
9
+ description: "Joplin REST API client"
10
+ - name: "component:mcp"
11
+ color: "0075ca"
12
+ description: "MCP server and tool definitions"
13
+ - name: "component:search"
14
+ color: "0075ca"
15
+ description: "Semantic search and embeddings"
16
+ - name: "component:docs"
17
+ color: "0075ca"
18
+ description: "Documentation"
19
+ - name: "component:ci"
20
+ color: "0075ca"
21
+ description: "CI/CD and build"
22
+ - name: "component:templates"
23
+ color: "0075ca"
24
+ description: "Joplin note templates"
25
+
26
+ # phase labels
27
+ - name: "phase-0"
28
+ color: "e4e669"
29
+ description: "Bootstrap: repo scaffold, CI, package skeleton"
30
+ - name: "phase-1"
31
+ color: "e4e669"
32
+ description: "Core read MCP tools"
33
+ - name: "phase-2"
34
+ color: "e4e669"
35
+ description: "Semantic search"
36
+ - name: "phase-3"
37
+ color: "e4e669"
38
+ description: "Write workflow and publish"
39
+
40
+ # meta labels
41
+ - name: "epic"
42
+ color: "6f42c1"
43
+ description: "Multi-issue initiative"
44
+ - name: "backlog"
45
+ color: "d4c5f9"
46
+ description: "Unscheduled work"
47
+ - name: "needs-triage"
48
+ color: "e11d48"
49
+ description: "Not yet triaged"
50
+ - name: "blocked"
51
+ color: "b60205"
52
+ description: "Blocked by another issue or external dependency"
53
+ - name: "good first issue"
54
+ color: "7057ff"
55
+ description: "Good for newcomers"
56
+ - name: "help wanted"
57
+ color: "008672"
58
+ description: "Extra attention is needed"
59
+
60
+ milestones:
61
+ - title: "v0.1 — Bootstrap"
62
+ description: "Repo scaffold, CI, package skeleton"
63
+ - title: "v0.2 — Core Read Tools"
64
+ description: "All read MCP tools working against Joplin REST API"
65
+ - title: "v0.3 — Semantic Search"
66
+ description: "Embedding index and semantic search tool"
67
+ - title: "v0.4 — Write Workflow"
68
+ description: "Human-gated note creation"
69
+ - title: "v1.0 — Publish"
70
+ description: "PyPI release, full docs, Joplin note templates"
@@ -0,0 +1,40 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v7
15
+ - uses: astral-sh/setup-uv@v7
16
+ with:
17
+ enable-cache: true
18
+ - name: Install dependencies
19
+ run: uv sync
20
+ - name: Ruff check
21
+ run: uv run ruff check src tests
22
+ - name: Ruff format check
23
+ run: uv run ruff format --check src tests
24
+
25
+ test:
26
+ name: Test (Python ${{ matrix.python-version }})
27
+ runs-on: ubuntu-latest
28
+ strategy:
29
+ matrix:
30
+ python-version: ["3.11", "3.12", "3.13"]
31
+ steps:
32
+ - uses: actions/checkout@v7
33
+ - uses: astral-sh/setup-uv@v7
34
+ with:
35
+ enable-cache: true
36
+ python-version: ${{ matrix.python-version }}
37
+ - name: Install dependencies
38
+ run: uv sync
39
+ - name: Run tests
40
+ run: uv run pytest --tb=short
@@ -0,0 +1,30 @@
1
+ name: Release (PyPI)
2
+
3
+ # Builds the sdist + wheel and publishes to PyPI via an OIDC trusted publisher
4
+ # (no stored token). The trusted publisher is registered on https://pypi.org for
5
+ # the `jomkz/second-brain-joplin` repo, workflow `release.yml`, environment
6
+ # `pypi`. See docs/releasing.md.
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ build-and-publish:
15
+ name: Build and publish to PyPI
16
+ runs-on: ubuntu-latest
17
+ environment: pypi
18
+ permissions:
19
+ id-token: write # required for OIDC trusted publishing
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+ - uses: astral-sh/setup-uv@v7
23
+ with:
24
+ enable-cache: true
25
+ - name: Build sdist and wheel
26
+ run: uv build
27
+ - name: Validate metadata
28
+ run: uvx twine check dist/*
29
+ - name: Publish to PyPI
30
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,27 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ .env
9
+
10
+ # Ruff / pytest cache
11
+ .ruff_cache/
12
+ .pytest_cache/
13
+ .coverage
14
+ htmlcov/
15
+
16
+ # Embeddings / local index (generated at runtime)
17
+ .index/
18
+ *.npy
19
+ *.faiss
20
+
21
+ # macOS
22
+ .DS_Store
23
+
24
+ # Editor
25
+ .idea/
26
+ .vscode/
27
+ *.swp
@@ -0,0 +1,8 @@
1
+ # Run `uv run pre-commit install` once to enable these on every commit.
2
+ repos:
3
+ - repo: https://github.com/astral-sh/ruff-pre-commit
4
+ rev: v0.15.20
5
+ hooks:
6
+ - id: ruff
7
+ args: [--fix]
8
+ - id: ruff-format
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] — Bootstrap
10
+
11
+ Initial project skeleton — the MCP server starts and all tools are stubbed.
12
+
13
+ ### Added
14
+
15
+ - `second-brain-joplin` CLI with a `serve` subcommand and `--version`.
16
+ - FastMCP server exposing five stubbed tools (`joplin_overview`,
17
+ `joplin_search`, `joplin_read`, `joplin_recent`, `joplin_create`), each
18
+ returning a `{"status": "not implemented"}` payload.
19
+ - `JoplinClient` skeleton with a working `ping()` against the Joplin Web Clipper
20
+ REST API; remaining methods stubbed for v0.2.
21
+ - `.env` support via `python-dotenv` (`JOPLIN_API_TOKEN`, `JOPLIN_BASE_URL`).
22
+ - Test suite with `pytest` + `respx`, and a 90% coverage gate.
23
+ - uv-based toolchain, `uv.lock`, and CI (ruff lint + format check, pytest on
24
+ Python 3.11/3.12/3.13).
25
+ - PyPI release workflow via OIDC trusted publishing.
26
+ - Dependabot config; pre-commit, EditorConfig, and pinned Python version.
27
+ - Documentation: install, notebook structure (PARA), project management,
28
+ releasing runbook, security policy, and an inspiration/reference note.
29
+
30
+ [Unreleased]: https://github.com/jomkz/second-brain-joplin/compare/v0.1.0...HEAD
31
+ [0.1.0]: https://github.com/jomkz/second-brain-joplin/releases/tag/v0.1.0
@@ -0,0 +1,69 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in second-brain-joplin.
4
+
5
+ ## Development setup
6
+
7
+ We use [uv](https://docs.astral.sh/uv/) as the primary toolchain:
8
+
9
+ ```bash
10
+ git clone https://github.com/jomkz/second-brain-joplin
11
+ cd second-brain-joplin
12
+ uv sync
13
+ uv run pre-commit install # enable lint/format on commit
14
+ ```
15
+
16
+ <details>
17
+ <summary>pip fallback</summary>
18
+
19
+ ```bash
20
+ python -m venv .venv && source .venv/bin/activate
21
+ pip install -e ".[test]"
22
+ ```
23
+ </details>
24
+
25
+ ## Running tests
26
+
27
+ ```bash
28
+ uv run pytest
29
+ ```
30
+
31
+ Tests enforce a 90% coverage gate (configured in `pyproject.toml`).
32
+
33
+ ## Running the server locally
34
+
35
+ ```bash
36
+ cp .env.example .env
37
+ # Edit .env with your Joplin API token; it is loaded automatically via python-dotenv
38
+ uv run second-brain-joplin serve
39
+ ```
40
+
41
+ ## Issue triage checklist
42
+
43
+ See [docs/project-management.md](docs/project-management.md) for the full model
44
+ (issue types, labels, milestones). Every triaged issue should have:
45
+
46
+ 1. **Issue type** — Epic / Feature / Task / Spike / Bug (set via sidebar)
47
+ 2. **Milestone** — which release it targets (or `backlog` label if unscheduled)
48
+ 3. One or more **`component:*`** labels
49
+ 4. **Phase label** if applicable (`phase-0` through `phase-3`)
50
+ 5. **Parent Epic** set as a sub-issue where relevant
51
+
52
+ ## Label conventions
53
+
54
+ | Prefix | Values | Applied by |
55
+ |---|---|---|
56
+ | `component:` | `joplin-api`, `mcp`, `search`, `docs`, `ci`, `templates` | Maintainer (issues); labeler bot (PRs) |
57
+ | `phase-` | `phase-0`, `phase-1`, `phase-2`, `phase-3` | Maintainer |
58
+ | meta | `epic`, `backlog`, `needs-triage`, `blocked`, `good first issue`, `help wanted` | Maintainer |
59
+
60
+ ## Commit style
61
+
62
+ No strict convention yet — use a short imperative summary line. DCO sign-off (`git commit -s`) is encouraged but not enforced at this stage.
63
+
64
+ ## Pull requests
65
+
66
+ - Target `main`.
67
+ - Keep PRs focused — one logical change per PR.
68
+ - Add or update tests for any new behavior.
69
+ - CI must pass before merge.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jomkz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,149 @@
1
+ Metadata-Version: 2.4
2
+ Name: second-brain-joplin
3
+ Version: 0.1.0
4
+ Summary: MCP server that connects Claude Code (and other MCP clients) to your Joplin knowledge base
5
+ Project-URL: Homepage, https://github.com/jomkz/second-brain-joplin
6
+ Project-URL: Repository, https://github.com/jomkz/second-brain-joplin
7
+ Project-URL: Issues, https://github.com/jomkz/second-brain-joplin/issues
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: ai,claude,joplin,knowledge-base,mcp,second-brain
11
+ Classifier: Development Status :: 2 - Pre-Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: fastmcp>=2.0
21
+ Requires-Dist: httpx>=0.27
22
+ Requires-Dist: python-dotenv>=1.0
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
25
+ Requires-Dist: pytest-cov>=5.0; extra == 'test'
26
+ Requires-Dist: pytest>=8.0; extra == 'test'
27
+ Requires-Dist: respx>=0.21; extra == 'test'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # second-brain-joplin
31
+
32
+ An MCP server that turns your [Joplin](https://joplinapp.org/) knowledge base into searchable memory for any MCP-capable AI client — Claude Code, Cursor, and others.
33
+
34
+ Inspired by [second-brain-mcp](https://github.com/noesskeetit/second-brain-mcp) (for Obsidian). This project covers the same use case for Joplin: your AI assistant reads, searches, and files notes directly, without leaving the tool you already use.
35
+
36
+ > **Status:** Pre-alpha — MCP tools are stubbed. See the [roadmap](#roadmap) and open issues.
37
+
38
+ ---
39
+
40
+ ## How it works
41
+
42
+ Joplin Desktop exposes a local REST API on `localhost:41184` (the Web Clipper service). This server wraps that API as MCP tools, so your AI client can query and update your notes in real time — no export step, no sync lag.
43
+
44
+ ```
45
+ Claude Code / Cursor
46
+ │ MCP
47
+ ▼
48
+ second-brain-joplin (this server)
49
+ │ HTTP + token
50
+ ▼
51
+ Joplin Desktop (localhost:41184)
52
+ │
53
+ ▼
54
+ Your notes
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Prerequisites
60
+
61
+ - **Joplin Desktop** running with the Web Clipper service enabled:
62
+ **Tools → Options → Web Clipper → Enable Web Clipper Service**
63
+ - **API token** — copy it from the Web Clipper settings panel
64
+ - **Python ≥ 3.11** or [`uvx`](https://docs.astral.sh/uv/) (recommended — no install needed)
65
+
66
+ ---
67
+
68
+ ## Quickstart
69
+
70
+ ### Claude Code
71
+
72
+ ```bash
73
+ claude mcp add -s user second-brain-joplin \
74
+ -e JOPLIN_API_TOKEN=your-token-here \
75
+ -- uvx second-brain-joplin serve
76
+ ```
77
+
78
+ ### Other MCP clients
79
+
80
+ | Setting | Value |
81
+ |---|---|
82
+ | Command | `uvx second-brain-joplin serve` |
83
+ | `JOPLIN_API_TOKEN` | token from Joplin Web Clipper settings |
84
+ | `JOPLIN_BASE_URL` | `http://localhost:41184` (default) |
85
+
86
+ See [docs/install.md](docs/install.md) for per-client setup guides.
87
+
88
+ ---
89
+
90
+ ## MCP Tools
91
+
92
+ | Tool | Description | Writes? |
93
+ |---|---|---|
94
+ | `joplin_overview` | List all notebooks with note counts | No |
95
+ | `joplin_search` | Keyword search across all notes | No |
96
+ | `joplin_read` | Read a note by ID | No |
97
+ | `joplin_recent` | Notes modified in the last N days | No |
98
+ | `joplin_create` | Create a note (human-gated) | Yes |
99
+
100
+ > All tools are stubbed in v0.1. Implementation tracked in [v0.2 milestone](https://github.com/jomkz/second-brain-joplin/milestone/2).
101
+
102
+ ---
103
+
104
+ ## vs. second-brain-mcp (Obsidian)
105
+
106
+ | | [second-brain-mcp](https://github.com/noesskeetit/second-brain-mcp) | second-brain-joplin |
107
+ |---|---|---|
108
+ | Note app | Obsidian | Joplin |
109
+ | Storage | Plain `.md` files on disk | Joplin REST API |
110
+ | Requires app running | No | Yes (Joplin + Web Clipper) |
111
+ | Semantic search | Yes (bge-m3) | Planned (v0.3) |
112
+ | Write support | Human-gated | Human-gated (v0.4) |
113
+ | Install | `uvx second-brain-mcp` | `uvx second-brain-joplin` |
114
+
115
+ ---
116
+
117
+ ## Notebook structure
118
+
119
+ The [PARA method](https://fortelabs.com/blog/para/) works well with Joplin. See [docs/notebook-structure.md](docs/notebook-structure.md) for a recommended setup.
120
+
121
+ ---
122
+
123
+ ## Roadmap
124
+
125
+ | Milestone | Theme | Status |
126
+ |---|---|---|
127
+ | [v0.1 — Bootstrap](https://github.com/jomkz/second-brain-joplin/milestone/1) | Repo, CI, package skeleton | Done |
128
+ | [v0.2 — Core Read Tools](https://github.com/jomkz/second-brain-joplin/milestone/2) | All read MCP tools working | Planned |
129
+ | [v0.3 — Semantic Search](https://github.com/jomkz/second-brain-joplin/milestone/3) | Embedding index, semantic search | Planned |
130
+ | [v0.4 — Write Workflow](https://github.com/jomkz/second-brain-joplin/milestone/4) | Human-gated note creation | Planned |
131
+ | [v1.0 — Publish](https://github.com/jomkz/second-brain-joplin/milestone/5) | PyPI, full docs, templates | Planned |
132
+
133
+ ---
134
+
135
+ ## Security & privacy
136
+
137
+ This server keeps your notes local: it talks only to Joplin's Web Clipper REST API on `localhost` and runs on your own machine. Anything an MCP client can read, the connected AI can read — so apply least privilege and don't expose notebooks with credentials or other sensitive data. Note creation is planned as an explicit human-gated flow (v0.4); v0.1 does no silent writes. See [SECURITY.md](SECURITY.md) for details and how to report a vulnerability.
138
+
139
+ ---
140
+
141
+ ## Contributing
142
+
143
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Issues and PRs welcome — especially for testing against different Joplin versions and OS platforms.
144
+
145
+ ---
146
+
147
+ ## License
148
+
149
+ MIT — see [LICENSE](LICENSE).