mindin 0.14.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 (245) hide show
  1. mindin-0.14.0/.dockerignore +8 -0
  2. mindin-0.14.0/.github/workflows/ci.yml +31 -0
  3. mindin-0.14.0/.github/workflows/release.yml +171 -0
  4. mindin-0.14.0/.gitignore +11 -0
  5. mindin-0.14.0/CHANGES.md +149 -0
  6. mindin-0.14.0/Dockerfile +17 -0
  7. mindin-0.14.0/LICENSE +21 -0
  8. mindin-0.14.0/PKG-INFO +87 -0
  9. mindin-0.14.0/README.md +60 -0
  10. mindin-0.14.0/deploy/docker/.env.example +76 -0
  11. mindin-0.14.0/deploy/docker/Caddyfile +3 -0
  12. mindin-0.14.0/deploy/docker/compose.yml +33 -0
  13. mindin-0.14.0/deploy/k8s/deployment.yaml +73 -0
  14. mindin-0.14.0/deploy/k8s/ingress.yaml +23 -0
  15. mindin-0.14.0/deploy/k8s/secret.example.yaml +19 -0
  16. mindin-0.14.0/deploy/k8s/service.yaml +13 -0
  17. mindin-0.14.0/docs/README.md +57 -0
  18. mindin-0.14.0/docs/explanation/accounts-and-vaults.md +38 -0
  19. mindin-0.14.0/docs/explanation/encryption.md +29 -0
  20. mindin-0.14.0/docs/explanation/how-it-works.md +28 -0
  21. mindin-0.14.0/docs/explanation/lifecycle.md +16 -0
  22. mindin-0.14.0/docs/explanation/notes-and-layouts.md +42 -0
  23. mindin-0.14.0/docs/explanation/search.md +32 -0
  24. mindin-0.14.0/docs/explanation/shared-vaults.md +19 -0
  25. mindin-0.14.0/docs/how-to/back-up-and-rotate.md +27 -0
  26. mindin-0.14.0/docs/how-to/claude-code.md +50 -0
  27. mindin-0.14.0/docs/how-to/connect-claude-ai.md +13 -0
  28. mindin-0.14.0/docs/how-to/manage-accounts.md +45 -0
  29. mindin-0.14.0/docs/how-to/obsidian.md +17 -0
  30. mindin-0.14.0/docs/how-to/other-clients.md +54 -0
  31. mindin-0.14.0/docs/how-to/reverse-proxy.md +24 -0
  32. mindin-0.14.0/docs/how-to/sign-in-a-machine.md +42 -0
  33. mindin-0.14.0/docs/how-to/sign-in-methods.md +42 -0
  34. mindin-0.14.0/docs/how-to/support-access-and-import.md +26 -0
  35. mindin-0.14.0/docs/how-to/weekly-lint.md +16 -0
  36. mindin-0.14.0/docs/install/docker.md +86 -0
  37. mindin-0.14.0/docs/install/kubernetes.md +38 -0
  38. mindin-0.14.0/docs/install/semantic-search.md +103 -0
  39. mindin-0.14.0/docs/install/storage.md +56 -0
  40. mindin-0.14.0/docs/install/without-docker.md +36 -0
  41. mindin-0.14.0/docs/reference/agent-commands.md +75 -0
  42. mindin-0.14.0/docs/reference/command-line.md +102 -0
  43. mindin-0.14.0/docs/reference/configuration.md +127 -0
  44. mindin-0.14.0/docs/reference/device-flow.md +17 -0
  45. mindin-0.14.0/docs/reference/extensions.md +76 -0
  46. mindin-0.14.0/docs/reference/hooks.md +22 -0
  47. mindin-0.14.0/docs/reference/schema.md +97 -0
  48. mindin-0.14.0/docs/reference/tools.md +31 -0
  49. mindin-0.14.0/mindin/__init__.py +3 -0
  50. mindin-0.14.0/mindin/auth/__init__.py +268 -0
  51. mindin-0.14.0/mindin/auth/cimd.py +229 -0
  52. mindin-0.14.0/mindin/auth/database.py +107 -0
  53. mindin-0.14.0/mindin/auth/device.py +272 -0
  54. mindin-0.14.0/mindin/auth/hosted.py +705 -0
  55. mindin-0.14.0/mindin/auth/hosted_access.py +204 -0
  56. mindin-0.14.0/mindin/auth/hosted_deletion.py +142 -0
  57. mindin-0.14.0/mindin/auth/hosted_history.py +184 -0
  58. mindin-0.14.0/mindin/auth/hosted_keys.py +367 -0
  59. mindin-0.14.0/mindin/auth/hosted_layout.py +53 -0
  60. mindin-0.14.0/mindin/auth/hosted_members.py +126 -0
  61. mindin-0.14.0/mindin/auth/hosted_ready.py +76 -0
  62. mindin-0.14.0/mindin/auth/hosted_shared_pages.py +367 -0
  63. mindin-0.14.0/mindin/auth/hosted_snapshots.py +48 -0
  64. mindin-0.14.0/mindin/auth/hosted_store.py +900 -0
  65. mindin-0.14.0/mindin/auth/hosted_transfer.py +181 -0
  66. mindin-0.14.0/mindin/auth/hosted_vault_pages.py +543 -0
  67. mindin-0.14.0/mindin/auth/hosted_vaults.py +376 -0
  68. mindin-0.14.0/mindin/auth/hosted_web.py +427 -0
  69. mindin-0.14.0/mindin/auth/identities.py +299 -0
  70. mindin-0.14.0/mindin/auth/login.py +164 -0
  71. mindin-0.14.0/mindin/auth/login_email.py +140 -0
  72. mindin-0.14.0/mindin/auth/login_forwarded.py +125 -0
  73. mindin-0.14.0/mindin/auth/login_github.py +139 -0
  74. mindin-0.14.0/mindin/auth/login_oidc.py +90 -0
  75. mindin-0.14.0/mindin/auth/login_passkey.py +280 -0
  76. mindin-0.14.0/mindin/auth/pages.py +241 -0
  77. mindin-0.14.0/mindin/auth/prefix.py +25 -0
  78. mindin-0.14.0/mindin/auth/scopes.py +15 -0
  79. mindin-0.14.0/mindin/auth/upstream.py +171 -0
  80. mindin-0.14.0/mindin/backends/__init__.py +120 -0
  81. mindin-0.14.0/mindin/backends/local.py +143 -0
  82. mindin-0.14.0/mindin/backends/s3.py +177 -0
  83. mindin-0.14.0/mindin/backends/sealed.py +211 -0
  84. mindin-0.14.0/mindin/changelog.py +173 -0
  85. mindin-0.14.0/mindin/changes.py +182 -0
  86. mindin-0.14.0/mindin/cli.py +995 -0
  87. mindin-0.14.0/mindin/config.py +199 -0
  88. mindin-0.14.0/mindin/credentials.py +204 -0
  89. mindin-0.14.0/mindin/dav.py +419 -0
  90. mindin-0.14.0/mindin/embed_worker.py +410 -0
  91. mindin-0.14.0/mindin/embedding.py +403 -0
  92. mindin-0.14.0/mindin/extension_api.py +82 -0
  93. mindin-0.14.0/mindin/extensions.py +105 -0
  94. mindin-0.14.0/mindin/frontmatter.py +172 -0
  95. mindin-0.14.0/mindin/git.py +62 -0
  96. mindin-0.14.0/mindin/hooks.py +417 -0
  97. mindin-0.14.0/mindin/human.py +377 -0
  98. mindin-0.14.0/mindin/index.py +498 -0
  99. mindin-0.14.0/mindin/login.py +144 -0
  100. mindin-0.14.0/mindin/notes.py +897 -0
  101. mindin-0.14.0/mindin/places.py +281 -0
  102. mindin-0.14.0/mindin/presets.py +119 -0
  103. mindin-0.14.0/mindin/provision.py +146 -0
  104. mindin-0.14.0/mindin/proxy.py +128 -0
  105. mindin-0.14.0/mindin/remote.py +378 -0
  106. mindin-0.14.0/mindin/schema.py +598 -0
  107. mindin-0.14.0/mindin/search.py +428 -0
  108. mindin-0.14.0/mindin/server.py +544 -0
  109. mindin-0.14.0/mindin/shared.py +189 -0
  110. mindin-0.14.0/mindin/snapshot.py +147 -0
  111. mindin-0.14.0/mindin/stemming.py +77 -0
  112. mindin-0.14.0/mindin/tasks.py +260 -0
  113. mindin-0.14.0/mindin/templates/Areas.base +49 -0
  114. mindin-0.14.0/mindin/templates/Backlog.base +62 -0
  115. mindin-0.14.0/mindin/templates/Log.base +40 -0
  116. mindin-0.14.0/mindin/templates/Open tasks.base +64 -0
  117. mindin-0.14.0/mindin/templates/Resources.base +54 -0
  118. mindin-0.14.0/mindin/templates/__init__.py +0 -0
  119. mindin-0.14.0/mindin/templates/claude-md-snippet.md +22 -0
  120. mindin-0.14.0/mindin/templates/presets/custom/All notes.base +39 -0
  121. mindin-0.14.0/mindin/templates/presets/custom/schema.yml +25 -0
  122. mindin-0.14.0/mindin/templates/presets/journal/Backlog.base +62 -0
  123. mindin-0.14.0/mindin/templates/presets/journal/Days.base +29 -0
  124. mindin-0.14.0/mindin/templates/presets/journal/Log.base +40 -0
  125. mindin-0.14.0/mindin/templates/presets/journal/Open work.base +64 -0
  126. mindin-0.14.0/mindin/templates/presets/journal/Templates/Bases/Day.base +25 -0
  127. mindin-0.14.0/mindin/templates/presets/journal/Templates/Daily Note Template.md +10 -0
  128. mindin-0.14.0/mindin/templates/presets/journal/schema.yml +37 -0
  129. mindin-0.14.0/mindin/templates/presets/para/Areas.base +39 -0
  130. mindin-0.14.0/mindin/templates/presets/para/Backlog.base +62 -0
  131. mindin-0.14.0/mindin/templates/presets/para/Log.base +40 -0
  132. mindin-0.14.0/mindin/templates/presets/para/Projects.base +64 -0
  133. mindin-0.14.0/mindin/templates/presets/para/Resources.base +47 -0
  134. mindin-0.14.0/mindin/templates/presets/para/schema.yml +37 -0
  135. mindin-0.14.0/mindin/templates/presets/shared/Areas.base +49 -0
  136. mindin-0.14.0/mindin/templates/presets/shared/Resources.base +54 -0
  137. mindin-0.14.0/mindin/templates/presets/shared/schema.yml +35 -0
  138. mindin-0.14.0/mindin/templates/presets/simple/Backlog.base +62 -0
  139. mindin-0.14.0/mindin/templates/presets/simple/Categories.base +16 -0
  140. mindin-0.14.0/mindin/templates/presets/simple/Open work.base +64 -0
  141. mindin-0.14.0/mindin/templates/presets/simple/Recent.base +36 -0
  142. mindin-0.14.0/mindin/templates/presets/simple/Templates/Bases/Category.base +32 -0
  143. mindin-0.14.0/mindin/templates/presets/simple/Templates/Bases/Daily.base +25 -0
  144. mindin-0.14.0/mindin/templates/presets/simple/Templates/Category Template.md +5 -0
  145. mindin-0.14.0/mindin/templates/presets/simple/Templates/Daily Note Template.md +5 -0
  146. mindin-0.14.0/mindin/templates/presets/simple/Templates/Project Template.md +4 -0
  147. mindin-0.14.0/mindin/templates/presets/simple/schema.yml +29 -0
  148. mindin-0.14.0/mindin/templates/schema.yml +47 -0
  149. mindin-0.14.0/mindin/templates/welcome.md +41 -0
  150. mindin-0.14.0/mindin/terminal.py +110 -0
  151. mindin-0.14.0/mindin/vault.py +527 -0
  152. mindin-0.14.0/mindin/vectors.py +282 -0
  153. mindin-0.14.0/mindin/views.py +66 -0
  154. mindin-0.14.0/pyproject.toml +62 -0
  155. mindin-0.14.0/scripts/install.sh +117 -0
  156. mindin-0.14.0/scripts/release-notes.sh +42 -0
  157. mindin-0.14.0/scripts/release.sh +111 -0
  158. mindin-0.14.0/server.json +110 -0
  159. mindin-0.14.0/shim/pyproject.toml +25 -0
  160. mindin-0.14.0/tests/cimd_support.py +34 -0
  161. mindin-0.14.0/tests/conftest.py +79 -0
  162. mindin-0.14.0/tests/fake_models.py +36 -0
  163. mindin-0.14.0/tests/fixtures/hosted_schema.json +540 -0
  164. mindin-0.14.0/tests/fixtures/queries.json +453 -0
  165. mindin-0.14.0/tests/fixtures/vault/.obsidian/app.json +1 -0
  166. mindin-0.14.0/tests/fixtures/vault/.vault/schema.yml +11 -0
  167. mindin-0.14.0/tests/fixtures/vault/Archive/old-plan.md +11 -0
  168. mindin-0.14.0/tests/fixtures/vault/Archive/wrong-status.md +11 -0
  169. mindin-0.14.0/tests/fixtures/vault/Areas/orchard.md +15 -0
  170. mindin-0.14.0/tests/fixtures/vault/Areas/workshop.md +13 -0
  171. mindin-0.14.0/tests/fixtures/vault/Log/orchard-log.md +12 -0
  172. mindin-0.14.0/tests/fixtures/vault/Projects/orchard-draft.md +13 -0
  173. mindin-0.14.0/tests/fixtures/vault/Projects/orchard-fresh.md +13 -0
  174. mindin-0.14.0/tests/fixtures/vault/Projects/workshop-stale.md +12 -0
  175. mindin-0.14.0/tests/fixtures/vault/Resources/booking-trap.md +13 -0
  176. mindin-0.14.0/tests/fixtures/vault/Resources/broken-yaml.md +7 -0
  177. mindin-0.14.0/tests/fixtures/vault/Resources/no-frontmatter.md +1 -0
  178. mindin-0.14.0/tests/fixtures/vault/Resources/old-domain-howto.md +12 -0
  179. mindin-0.14.0/tests/fixtures/vault/Resources/workshop.md +11 -0
  180. mindin-0.14.0/tests/forwarded_support.py +59 -0
  181. mindin-0.14.0/tests/hosted_support.py +316 -0
  182. mindin-0.14.0/tests/login_support.py +183 -0
  183. mindin-0.14.0/tests/remote_support.py +112 -0
  184. mindin-0.14.0/tests/test_about.py +55 -0
  185. mindin-0.14.0/tests/test_auth_cimd.py +219 -0
  186. mindin-0.14.0/tests/test_auth_config.py +184 -0
  187. mindin-0.14.0/tests/test_auth_device.py +217 -0
  188. mindin-0.14.0/tests/test_auth_hosted.py +581 -0
  189. mindin-0.14.0/tests/test_auth_hosted_layout.py +141 -0
  190. mindin-0.14.0/tests/test_auth_login.py +505 -0
  191. mindin-0.14.0/tests/test_auth_prefix.py +55 -0
  192. mindin-0.14.0/tests/test_backends.py +338 -0
  193. mindin-0.14.0/tests/test_backlog.py +116 -0
  194. mindin-0.14.0/tests/test_changelog.py +167 -0
  195. mindin-0.14.0/tests/test_changes.py +127 -0
  196. mindin-0.14.0/tests/test_claims.py +259 -0
  197. mindin-0.14.0/tests/test_cli_accounts.py +97 -0
  198. mindin-0.14.0/tests/test_cli_hooks.py +612 -0
  199. mindin-0.14.0/tests/test_cli_output.py +367 -0
  200. mindin-0.14.0/tests/test_cli_safety.py +208 -0
  201. mindin-0.14.0/tests/test_cli_tasks.py +278 -0
  202. mindin-0.14.0/tests/test_dav.py +473 -0
  203. mindin-0.14.0/tests/test_embed_remote.py +158 -0
  204. mindin-0.14.0/tests/test_embed_worker.py +288 -0
  205. mindin-0.14.0/tests/test_extensions.py +204 -0
  206. mindin-0.14.0/tests/test_folders.py +77 -0
  207. mindin-0.14.0/tests/test_frontmatter.py +113 -0
  208. mindin-0.14.0/tests/test_hosted_database.py +69 -0
  209. mindin-0.14.0/tests/test_hosted_deletion.py +113 -0
  210. mindin-0.14.0/tests/test_hosted_schema.py +89 -0
  211. mindin-0.14.0/tests/test_hosted_sealing.py +434 -0
  212. mindin-0.14.0/tests/test_hosted_vaults.py +723 -0
  213. mindin-0.14.0/tests/test_index.py +188 -0
  214. mindin-0.14.0/tests/test_index_consistency.py +198 -0
  215. mindin-0.14.0/tests/test_index_snapshots.py +143 -0
  216. mindin-0.14.0/tests/test_install_script.py +118 -0
  217. mindin-0.14.0/tests/test_lint.py +103 -0
  218. mindin-0.14.0/tests/test_machine_tools.py +97 -0
  219. mindin-0.14.0/tests/test_note_age.py +13 -0
  220. mindin-0.14.0/tests/test_notes.py +297 -0
  221. mindin-0.14.0/tests/test_presets.py +394 -0
  222. mindin-0.14.0/tests/test_provision.py +46 -0
  223. mindin-0.14.0/tests/test_public_scope.py +62 -0
  224. mindin-0.14.0/tests/test_queries.py +32 -0
  225. mindin-0.14.0/tests/test_rate_limits.py +181 -0
  226. mindin-0.14.0/tests/test_ready.py +107 -0
  227. mindin-0.14.0/tests/test_remote.py +753 -0
  228. mindin-0.14.0/tests/test_rewrites.py +214 -0
  229. mindin-0.14.0/tests/test_schema_kinds.py +35 -0
  230. mindin-0.14.0/tests/test_sealed.py +297 -0
  231. mindin-0.14.0/tests/test_search.py +289 -0
  232. mindin-0.14.0/tests/test_security_content.py +252 -0
  233. mindin-0.14.0/tests/test_security_http.py +105 -0
  234. mindin-0.14.0/tests/test_security_paths.py +400 -0
  235. mindin-0.14.0/tests/test_semantic.py +523 -0
  236. mindin-0.14.0/tests/test_semantic_model.py +85 -0
  237. mindin-0.14.0/tests/test_server.py +120 -0
  238. mindin-0.14.0/tests/test_setup.py +191 -0
  239. mindin-0.14.0/tests/test_shared_instructions.py +68 -0
  240. mindin-0.14.0/tests/test_shared_vaults.py +615 -0
  241. mindin-0.14.0/tests/test_snapshot.py +110 -0
  242. mindin-0.14.0/tests/test_startup.py +77 -0
  243. mindin-0.14.0/tests/test_stateless_http.py +66 -0
  244. mindin-0.14.0/tests/test_vault_serving.py +367 -0
  245. mindin-0.14.0/uv.lock +2217 -0
@@ -0,0 +1,8 @@
1
+ .git
2
+ .venv
3
+ tests
4
+ dist
5
+ build
6
+ __pycache__
7
+ .pytest_cache
8
+ .ruff_cache
@@ -0,0 +1,31 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.11", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ - uses: astral-sh/setup-uv@v6
18
+ with:
19
+ enable-cache: true
20
+ - run: uv sync --frozen --python ${{ matrix.python-version }}
21
+ - run: uv run ruff check .
22
+ - run: uv run ruff format --check .
23
+ - run: uv run pytest -q
24
+
25
+ audit:
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v5
29
+ - uses: astral-sh/setup-uv@v6
30
+ - run: uv export --frozen --all-groups --no-emit-project --format requirements-txt > "$RUNNER_TEMP/requirements.txt"
31
+ - run: uvx pip-audit --disable-pip --require-hashes -r "$RUNNER_TEMP/requirements.txt"
@@ -0,0 +1,171 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v5
12
+ - name: The tag matches the package version
13
+ run: |
14
+ tag="${GITHUB_REF_NAME#v}"
15
+ package=$(sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml | head -1)
16
+ server=$(sed -n 's/^VERSION = "\(.*\)"/\1/p' mindin/server.py)
17
+ if [ "$package" != "$tag" ] || [ "$server" != "$tag" ]; then echo "::error::pyproject.toml says $package, server.py says $server, the tag says $tag"; exit 1; fi
18
+ former=$(sed -n 's/^version = "\(.*\)"/\1/p' shim/pyproject.toml | head -1)
19
+ pinned=$(grep -c "\"mindin\(\[semantic\]\)\?==$tag\"" shim/pyproject.toml || true)
20
+ if [ "$former" != "$tag" ] || [ "$pinned" != 2 ]; then echo "::error::shim/pyproject.toml says $former and pins mindin==$tag $pinned times, the tag says $tag"; exit 1; fi
21
+ - name: CHANGES.md says what the version brings
22
+ run: sh scripts/release-notes.sh "${GITHUB_REF_NAME#v}"
23
+ - uses: astral-sh/setup-uv@v6
24
+ - run: uv sync --frozen
25
+ - run: uv run ruff check .
26
+ - run: uv run pytest -q
27
+
28
+ pypi:
29
+ needs: [test]
30
+ runs-on: ubuntu-latest
31
+ environment: pypi
32
+ permissions:
33
+ id-token: write
34
+ contents: read
35
+ steps:
36
+ - uses: actions/checkout@v5
37
+ - uses: astral-sh/setup-uv@v6
38
+ - run: uv build --out-dir dist
39
+ - name: Build the former name, which installs mindin of the same version
40
+ run: uv build shim --out-dir dist
41
+ - uses: pypa/gh-action-pypi-publish@release/v1
42
+
43
+ ghcr:
44
+ needs: [test]
45
+ runs-on: ubuntu-latest
46
+ permissions:
47
+ contents: read
48
+ packages: write
49
+ steps:
50
+ - uses: actions/checkout@v5
51
+ - uses: docker/login-action@v3
52
+ with:
53
+ registry: ghcr.io
54
+ username: ${{ github.actor }}
55
+ password: ${{ secrets.GITHUB_TOKEN }}
56
+ - uses: docker/build-push-action@v6
57
+ with:
58
+ context: .
59
+ push: true
60
+ tags: |
61
+ ghcr.io/gronare/mindin:${{ github.ref_name }}
62
+ ghcr.io/gronare/mindin:latest
63
+ ghcr.io/gronare/notes-vault-mcp:${{ github.ref_name }}
64
+ ghcr.io/gronare/notes-vault-mcp:latest
65
+ labels: io.modelcontextprotocol.server.name=io.github.gronare/mindin
66
+ - uses: docker/build-push-action@v6
67
+ with:
68
+ context: .
69
+ push: true
70
+ build-args: EXTRAS=--extra semantic
71
+ tags: |
72
+ ghcr.io/gronare/mindin:${{ github.ref_name }}-semantic
73
+ ghcr.io/gronare/mindin:latest-semantic
74
+ ghcr.io/gronare/notes-vault-mcp:${{ github.ref_name }}-semantic
75
+ ghcr.io/gronare/notes-vault-mcp:latest-semantic
76
+ labels: io.modelcontextprotocol.server.name=io.github.gronare/mindin
77
+
78
+ registry:
79
+ needs: [pypi, ghcr]
80
+ runs-on: ubuntu-latest
81
+ permissions:
82
+ id-token: write
83
+ contents: read
84
+ steps:
85
+ - uses: actions/checkout@v5
86
+
87
+ - name: Match server.json to the tag
88
+ run: |
89
+ VERSION="${GITHUB_REF#refs/tags/v}"
90
+ jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v' server.json > server.json.tmp
91
+ mv server.json.tmp server.json
92
+
93
+ - name: Install mcp-publisher
94
+ run: |
95
+ OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
96
+ ARCH="$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"
97
+ curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_${OS}_${ARCH}.tar.gz" | tar xz mcp-publisher
98
+
99
+ - name: Log in to the MCP registry
100
+ run: ./mcp-publisher login github-oidc
101
+
102
+ - name: Publish
103
+ run: |
104
+ for attempt in 1 2 3 4 5; do
105
+ ./mcp-publisher publish && exit 0
106
+ echo "publish failed, PyPI may not have the release yet; retrying in 30s"
107
+ sleep 30
108
+ done
109
+ exit 1
110
+
111
+ plugin:
112
+ needs: [pypi]
113
+ runs-on: ubuntu-latest
114
+ steps:
115
+ - uses: actions/checkout@v5
116
+ with:
117
+ repository: gronare/claude-plugins
118
+ ref: main
119
+ ssh-key: ${{ secrets.CLAUDE_PLUGINS_DEPLOY_KEY }}
120
+
121
+ - name: Point the vault plugin at this release
122
+ run: |
123
+ VERSION="${GITHUB_REF#refs/tags/v}"
124
+ if grep -qE "(mindin|notes-vault-mcp)==${VERSION}\"" plugins/vault/.mcp.json; then
125
+ echo "the plugin already pins ${VERSION}"
126
+ exit 0
127
+ fi
128
+ sed -i -E "s/(mindin|notes-vault-mcp)==[0-9.]+/\1==${VERSION}/g" plugins/vault/.mcp.json plugins/vault/hooks/hooks.json
129
+ PLUGIN="$(jq -r '.version' plugins/vault/.claude-plugin/plugin.json | awk -F. '{print $1"."$2"."$3+1}')"
130
+ jq --arg v "$PLUGIN" '.version = $v' plugins/vault/.claude-plugin/plugin.json > plugin.json.tmp
131
+ mv plugin.json.tmp plugins/vault/.claude-plugin/plugin.json
132
+ git config user.name "mindin release"
133
+ git config user.email "release@mindin.invalid"
134
+ git add plugins/vault/.mcp.json plugins/vault/hooks/hooks.json plugins/vault/.claude-plugin/plugin.json
135
+ git commit -m "vault ${PLUGIN}: the server and the hooks pin ${VERSION}"
136
+ git push origin HEAD:main
137
+
138
+ release:
139
+ needs: [pypi, ghcr, registry, plugin]
140
+ runs-on: ubuntu-latest
141
+ permissions:
142
+ contents: write
143
+ steps:
144
+ - uses: actions/checkout@v5
145
+ with:
146
+ sparse-checkout: |
147
+ CHANGES.md
148
+ scripts/release-notes.sh
149
+ deploy/docker/compose.yml
150
+ deploy/docker/Caddyfile
151
+ deploy/docker/.env.example
152
+ scripts/install.sh
153
+ sparse-checkout-cone-mode: false
154
+ - name: The release notes, from the version's section of CHANGES.md
155
+ run: sh scripts/release-notes.sh "${GITHUB_REF_NAME#v}" > release-notes.md
156
+ - name: Publish the GitHub release with the version's notes, as latest
157
+ env:
158
+ GH_TOKEN: ${{ github.token }}
159
+ run: |
160
+ title="mindin ${GITHUB_REF_NAME#v}"
161
+ if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
162
+ gh release edit "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --notes-file release-notes.md --title "$title" --draft=false --latest
163
+ else
164
+ gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --verify-tag --notes-file release-notes.md --title "$title" --latest
165
+ fi
166
+ - name: Attach the install script and the Docker Compose files, which the install docs fetch from the latest release
167
+ env:
168
+ GH_TOKEN: ${{ github.token }}
169
+ run: |
170
+ cp deploy/docker/.env.example example.env
171
+ gh release upload "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --clobber scripts/install.sh deploy/docker/compose.yml deploy/docker/Caddyfile example.env
@@ -0,0 +1,11 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .env
5
+ *.sqlite
6
+ *.sqlite-shm
7
+ *.sqlite-wal
8
+ dist/
9
+ build/
10
+ .pytest_cache/
11
+ .ruff_cache/
@@ -0,0 +1,149 @@
1
+ # Changes
2
+
3
+ What each mindin release brings, one line per change, as you would tell someone who uses it. scripts/release.sh moves the Unreleased entries under the new version, and the GitHub release shows that version's entries.
4
+
5
+ ## Unreleased
6
+
7
+ ### What's new
8
+
9
+ ### Fixed
10
+
11
+ ## 0.14.0
12
+
13
+ ### What's new
14
+ - Renamed from notes-vault-mcp to mindin: the package, the command and the image are `mindin`. The `notes-vault-mcp` package and command keep working and run mindin, the image is published under both names, and `~/.config/notes-vault-mcp` and `~/.cache/notes-vault-mcp` move to `mindin` on the first run, so no machine is signed out or indexed again. Extensions register in the `mindin.extensions` entry point group and import from `mindin.extension_api`.
15
+ - `mindin setup` asks where the vault lives, a folder, an S3 bucket or a vault server, and saves it for every command and client on the machine; `--folder`, `--s3` and `--server` do it from a script. The environment still wins, and the Claude Code plugin's settings are read when mindin has none. `status` names which one decided in `source`.
16
+ - `curl -fsSL https://github.com/gronare/mindin/releases/latest/download/install.sh | sh` installs mindin with uv, runs `setup` and offers to add the vault to Claude Code, Codex and Cursor.
17
+ - `mindin about --json` tells a tool the name, version, contract and the commands this install has.
18
+
19
+ ### Fixed
20
+
21
+ ## 0.13.0
22
+
23
+ ### What's new
24
+ - The documentation lives in `docs/`, sorted into install guides, how-tos, reference and explanation, with a page listing every environment variable.
25
+ - `deploy/docker/` holds the Docker Compose setup, and each GitHub release carries its `compose.yml`, `Caddyfile` and `example.env`, so a server installs with two `curl` lines. Its `.env` keeps the vaults in the container's volume unless you set a bucket.
26
+ - `VAULT_HTTP_STATELESS=on` serves MCP without sessions, so a server restart drops no session a client holds.
27
+ - `notes-vault-mcp embed-worker --listen host:port` runs the model for search by meaning in a process of its own that the server reaches through `VAULT_EMBED_URL`, with `VAULT_EMBED_TOKEN` as its secret, so the server restarts fast and stays small.
28
+ - `GET /ready` answers `200` when the server is ready for requests and `503` with the names of the failing checks, for a load balancer or a readiness probe.
29
+ - `VAULT_INDEX_SNAPSHOTS=on` keeps a sealed copy of each vault's search index in storage, so a restarted or moved server restores a vault's index instead of indexing and embedding every note again. A busy vault's copy is written at most once per `VAULT_INDEX_SNAPSHOT_MINUTES` (default 10) and only when the index changed, plus once when it goes idle and once when the server stops.
30
+ - `VAULT_FORWARDED_ALLOW_IPS` names the reverse proxies, as addresses or CIDR ranges, whose `X-Forwarded-For` the server trusts, so rate limits count each real client; the limits are kept in the account store and survive a restart.
31
+ - Extensions import what they build on from `notes_vault_mcp.extension_api`; [Extensions](docs/reference/extensions.md) describes each hook.
32
+ - A vault server has one address, `/mcp`; another vault than the one picked when connecting is `/mcp?vault=<slug>`, and a slug is one lowercase word, unique among the vaults an account reaches. A new account's first vault is `notes`, and existing slugs that break the rule are rewritten on the first start.
33
+
34
+ ### Fixed
35
+ - Two writes to one note at the same moment both land: `append_file`, `set_status`, `close`, `log_append`, `write_file` and the monthly log pages write over the version they read and read again when the note changed meanwhile, two `backlog_add` calls with one title get two notes, and a new vault's first files never overwrite a file already there.
36
+ - WebDAV `PUT` honours `If-Match` and `If-None-Match: *` and answers `412` when the file changed.
37
+ - A note's age counts calendar days in local time, so a note from five days back reads "5 days" also just after midnight.
38
+ - A vault server's root address opens the account page instead of answering not found.
39
+ - The access log leaves out query strings, so sign-in and invitation links never land in it.
40
+ - An unknown vault address answers like a known one the caller cannot reach.
41
+ - WebDAV opens vaults and talks to storage off the event loop, so a slow vault never stalls other requests or `/up`.
42
+ - An edit from Obsidian over WebDAV shows in search at once instead of after up to 20 seconds.
43
+ - `close` keeps a change that lands on the note while it is being archived.
44
+
45
+ ## 0.12.0
46
+
47
+ ### What's new
48
+ - In a terminal, `search`, `backlog`, `read` and `lint` print for a person: titles first, paths whole, ages in words, colour for status, priority and kind, and rows cut at the terminal's width. In a pipe or with `--plain` they print as before; `NO_COLOR` drops the colour.
49
+ - `context` shows what a session in this repo starts with: the system note, the commits newer than it, open tasks, the backlog, traps and the last log line. `--path` reads it for another folder.
50
+ - `backlog --paths` shows each note's path, and a backlog of more than 20 ideas is grouped by priority; `--all` shows every row.
51
+ - `read --raw` prints the note exactly as stored, also in a terminal.
52
+ - `lint` in a terminal counts the findings per kind with a plain explanation, and `lint --kind <kind>` lists one kind.
53
+
54
+ ### Fixed
55
+ - The session-start hook's repo log shows only log lines, never the log note's frontmatter.
56
+
57
+ ## 0.11.0
58
+
59
+ ### What's new
60
+ - The stop hook asks the agent to save the decisions and ideas in your messages once you have written three since its last vault write, also outside a git repo; `VAULT_STOP_HOOK_PROMPTS` sets the number or turns the check `off`.
61
+ - `VAULT_STOP_HOOK_COMMITS=off` turns off the stop hook's unlogged-commit and stale-note checks and keeps the message check, for sessions whose log another tool writes.
62
+ - A vault server loads the extensions installed beside it, from the Python entry point group `notes_vault_mcp.extensions`.
63
+ - An account on a vault server owns several vaults, each with its own name, address (`/v/<slug>/mcp`), keys, connections, layout and encryption key; a key, connector or signed-in computer reaches only the vault it was made for. An existing account's vault becomes its first vault, in place, on the first start.
64
+ - `/account` lists your vaults and makes new ones; each vault has its own page to connect, see and revoke what reaches it, export, import and delete it. Who you are, ways in, support access and account deletion move to Account. A vault's layout is picked when it is made and switched on its own page.
65
+ - `login --vault <slug>` signs a machine in to one vault, and `vault use <slug> [--dir <folder>]` picks the vault for this machine or for a folder and everything below it; the hooks and the stdio server follow the folder they run in.
66
+ - A vault can be shared: its owner invites people by email, each signs in with their own account and makes their own keys and connections, and the owner removes members, hands the vault over or deletes it. A shared vault keeps only current notes (system, howto, decision, reference, trap) and refuses tasks, backlog and logs with a message the agent can act on.
67
+ - Every write, move and delete in a shared vault, through MCP or WebDAV, is kept with who made it, through what and when; its page shows each change as a diff and restores the version before it as a new change. `accounts add-vault --shared`, `members`, `add-member` and `remove-member` do the same from the shell, and `whoami` and `status --probe` show each vault's kind and role.
68
+ - Support access is granted per vault, and `support` and `accounts import` take `--vault` when the account has several. `accounts vaults`, `add-vault` and `rename-vault` manage an account's vaults from the shell.
69
+
70
+ ### Fixed
71
+
72
+ ## 0.10.3
73
+
74
+ ### What's new
75
+
76
+ ### Fixed
77
+ - claude.ai connects with its published client identity, whose metadata lists a grant the server does not use.
78
+ - A client that signs in is asked for read and write access, not only read, so a connector can write notes.
79
+
80
+ ## 0.10.2
81
+
82
+ ### What's new
83
+
84
+ ### Fixed
85
+ - Obsidian's Remotely Save syncs the vault itself over WebDAV, with its default base folder, instead of uploading a copy into a folder named after the Obsidian vault.
86
+
87
+ ## 0.10.1
88
+
89
+ ### What's new
90
+
91
+ ### Fixed
92
+ - search, backlog, lint and every other command find a vault server named in the Claude Code plugin's settings, not only the task and log commands.
93
+
94
+ ## 0.10.0
95
+
96
+ ### What's new
97
+ - The HTTP server always serves accounts, one vault each, with an /account page. This breaks older setups: the --auth flag and the bearer, builtin, oidc and forwarded modes are removed, and so are the owner and tokens commands.
98
+ - Sign in with a passkey, an email link over SMTP, GitHub, your OpenID Connect provider or a trusted proxy's signed identity header. Each method is on when its settings are present, and an account can use several.
99
+ - The provider settings are called VAULT_OIDC_ISSUER, VAULT_OIDC_CLIENT_ID, VAULT_OIDC_CLIENT_SECRET and VAULT_OIDC_SCOPES. This breaks older setups: the VAULT_HOSTED_OIDC_* names are not read.
100
+ - Registration is by invitation, or open to any verified email with VAULT_REGISTRATION=open.
101
+ - Every account's vault is encrypted in storage, file contents and names, under its own key wrapped by a master key. This breaks older setups: the server needs VAULT_HOSTED_MASTER_KEY to start, made with notes-vault-mcp master-key generate.
102
+ - Encrypted vaults are stored under new paths, so an existing plaintext vault is not read. Bring it in with notes-vault-mcp accounts import, or as a zip on /account.
103
+ - master-key status and master-key rewrap rotate the master key, with the old one in VAULT_HOSTED_MASTER_KEY_PREVIOUS.
104
+ - An account exports its vault as a zip, imports one, and deletes itself on /account. notes-vault-mcp accounts delete does the same from the shell.
105
+ - An account can allow support access for an hour, a day or a week. The support files and support read commands and accounts import refuse without it, and every access shows in the account's log.
106
+ - Layout presets: init --preset para, simple, journal or custom, each with its folders, kinds, tags and Bases views. An account picks its layout on /account and can switch later.
107
+ - A schema can nest folders and is checked when loaded. One that does not hold leaves the vault on its preset, and context, lint and the account page list each problem.
108
+ - notes-vault-mcp login signs a machine in to a vault server through the device flow, and whoami and logout go with it. With VAULT_SERVER_URL set, the stdio server, the hooks and every command work through the server.
109
+ - The Claude Code plugin offers a vault server as a third choice beside a folder and a bucket.
110
+ - New tools on a server: whoami for every connection, and claim, release and changelog for a signed-in machine. context answers JSON with format json.
111
+ - lint --write and --park-stale run through a vault server when VAULT_SERVER_URL is set, so a scheduled lint can keep a hosted vault tidy.
112
+ - snapshot --json answers a board's system and task notes, the openings of open tasks and the repo log tails in one call under an etag, and --since answers unchanged while nothing moved. log path takes --repo more than once.
113
+ - read prints one note, from the local vault or through the vault server, and --body leaves out its frontmatter.
114
+
115
+ ### Fixed
116
+ - A repo log that log_append creates is titled Log — <repo>.
117
+ - A changelog period takes whole days at both ends, so it keeps commits from early on its first day and leaves out those from early on the next period's first day.
118
+
119
+ ## 0.9.2
120
+
121
+ ### What's new
122
+ - The claim field on a task note is called kebbie. This breaks older claims: a note that carries the previous key is not read as claimed.
123
+
124
+ ### Fixed
125
+
126
+ ## 0.9.1
127
+
128
+ ### What's new
129
+ - Search by meaning on a server. A query is answered beside a running embed instead of waiting behind it, and the model stays warm while the HTTP server runs, so searches use vectors during a first sync. A server starts embedding notes without vectors as soon as it starts.
130
+ - Lower memory while embedding. VAULT_EMBED_BATCH (default 16), VAULT_EMBED_THREADS (half the usable cores, at most 4, counting a container's CPU limit) and VAULT_EMBED_MAX_TOKENS (default 256) bound the embedding process. The S3 connection pool matches the fetch workers.
131
+ - Hosted mode. --auth hosted serves one vault per account, with sign-in through an OIDC provider, invitations, an /account page and API keys. A machine can get its key through the OAuth device flow at /device. OAuth clients can identify themselves with a client ID metadata document.
132
+
133
+ ### Fixed
134
+ - WebDAV refuses writes from credentials that may only read.
135
+ - Notes written through the claude.ai connector count as touched by the session-start hook.
136
+
137
+ ## 0.9.0
138
+
139
+ ### What's new
140
+ - Search by meaning. With VAULT_SEMANTIC=on and the [semantic] extra installed, search also finds notes that match the question without sharing its words. Results say how many matched by meaning only. The default model is mpnet; set VAULT_SEMANTIC_MODEL to pick MiniLM instead.
141
+ - One embedding process is shared by every session on a machine, so several agents searching at once load the model once.
142
+ - Two images: ghcr.io/gronare/notes-vault-mcp:v0.9.0 without the model, and :v0.9.0-semantic with it.
143
+ - The README is rewritten around what the server does and how to start it.
144
+
145
+ ## 0.8.0
146
+
147
+ ### What's new
148
+ - A task note can carry a claim field naming the machine and task working on it. The server keeps the field as stored when a note is written, so an agent can claim a note without another machine overwriting the claim.
149
+ - Every release checks that the tag matches the package version before anything is published.
@@ -0,0 +1,17 @@
1
+ FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
2
+
3
+ LABEL org.opencontainers.image.source="https://github.com/gronare/mindin"
4
+ LABEL io.modelcontextprotocol.server.name="io.github.gronare/mindin"
5
+
6
+ WORKDIR /app
7
+ ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy PATH="/app/.venv/bin:$PATH"
8
+
9
+ COPY pyproject.toml uv.lock README.md ./
10
+ COPY mindin ./mindin
11
+ ARG EXTRAS=""
12
+ RUN uv sync --frozen --no-dev $EXTRAS && ln -s mindin /app/.venv/bin/notes-vault-mcp
13
+
14
+ ENV VAULT_AUTH_DIR=/data/auth VAULT_CACHE_DIR=/data/cache
15
+ VOLUME /data
16
+
17
+ ENTRYPOINT ["mindin"]
mindin-0.14.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Carl Green / Grönare
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.
mindin-0.14.0/PKG-INFO ADDED
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.5
2
+ Name: mindin
3
+ Version: 0.14.0
4
+ Summary: MCP server for a markdown notes vault on S3 or a local directory, with a SQLite index, schema-aware writes and session hooks.
5
+ Project-URL: Homepage, https://github.com/gronare/mindin
6
+ Project-URL: Repository, https://github.com/gronare/mindin
7
+ Author-email: Carl Green <carl.green@gronare.se>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: mcp,notes,obsidian,s3,vault
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
14
+ Requires-Python: >=3.11
15
+ Requires-Dist: boto3>=1.34.0
16
+ Requires-Dist: cryptography>=50.0.2
17
+ Requires-Dist: httpx2>=2.5
18
+ Requires-Dist: mcp>=2.2
19
+ Requires-Dist: pyjwt[crypto]>=2.15
20
+ Requires-Dist: pyyaml>=6.0
21
+ Requires-Dist: snowballstemmer>=3.1.1
22
+ Requires-Dist: webauthn>=3.0.1
23
+ Provides-Extra: semantic
24
+ Requires-Dist: fastembed>=0.7; extra == 'semantic'
25
+ Requires-Dist: numpy>=1.26; extra == 'semantic'
26
+ Description-Content-Type: text/markdown
27
+
28
+ <!-- mcp-name: io.github.gronare/mindin -->
29
+
30
+ # mindin
31
+
32
+ Memory for Claude and coding agents, kept as markdown notes you own, with a schema that holds and a tie to your git history.
33
+
34
+ ## Install
35
+
36
+ ```sh
37
+ curl -fsSL https://github.com/gronare/mindin/releases/latest/download/install.sh | sh
38
+ ```
39
+
40
+ It installs the `mindin` command with [uv](https://docs.astral.sh/uv/), asks where your vault lives (a folder, an S3 bucket or a vault server), and offers to add the vault to Claude Code, Codex and Cursor; it changes nothing in them without a yes. mindin was called notes-vault-mcp: the `notes-vault-mcp` package and command still work, and install and run mindin.
41
+
42
+ ### A vault server
43
+
44
+ A vault server with Docker Compose, for claude.ai, Claude Desktop, mobile and every machine you work on. You need a domain pointing at the machine, ports 80 and 443 open, and an SMTP account for sign-in links.
45
+
46
+ ```sh
47
+ mkdir notes-vault && cd notes-vault
48
+ curl -fsSL -O https://github.com/gronare/mindin/releases/latest/download/compose.yml -O https://github.com/gronare/mindin/releases/latest/download/Caddyfile
49
+ curl -fsSL -o .env https://github.com/gronare/mindin/releases/latest/download/example.env
50
+ docker compose run --rm --no-deps vault master-key generate # paste into .env, with VAULT_HOST and SMTP
51
+ docker compose up -d
52
+ docker compose exec vault mindin accounts invite you@example.com
53
+ ```
54
+
55
+ Then open `https://VAULT_HOST/account` and sign in. [Install with Docker](https://github.com/gronare/mindin/blob/main/docs/install/docker.md) walks through each step.
56
+
57
+ Without the script, on one machine: `uv tool install mindin`, then `mindin setup`.
58
+
59
+ ## Use
60
+
61
+ Add the server's address, `https://VAULT_HOST/mcp`, as a custom connector in claude.ai. Claude searches, reads and writes your notes. The same search from a shell on a [signed-in machine](https://github.com/gronare/mindin/blob/main/docs/how-to/sign-in-a-machine.md):
62
+
63
+ ```console
64
+ $ mindin search "signing in"
65
+ 1 note · archive and superseded hidden
66
+
67
+ myapp system 3 days
68
+ Areas/myapp.md
69
+ ## Sign-in Users sign in with passkeys; email links are the fallback.
70
+ ```
71
+
72
+ ## What you get
73
+
74
+ - **Notes you own.** Plain markdown in a folder or an S3 bucket; open them in Obsidian, keep them in git.
75
+ - **A schema with teeth.** Required fields, legal statuses and kinds, a tag vocabulary; a write that breaks the contract is refused. Start from PARA, a simple vault, a journal or your own layout.
76
+ - **A lifecycle.** `close` archives finished work, `backlog_add` files what was deferred, `log_append` writes one line per repo per session, `lint` reports drift.
77
+ - **Memory tied to code.** A note names the paths it describes; the session-start hook prints the commits newer than the note.
78
+ - **Search that reads your languages.** Stemming, folded diacritics, synonyms, and optional search by meaning that runs on your machine.
79
+ - **Your own vault server.** Accounts with passkeys, email links, GitHub or your identity provider, several vaults each, shared vaults, sealed in storage.
80
+
81
+ ## Documentation
82
+
83
+ [docs/](https://github.com/gronare/mindin/blob/main/docs/README.md) has the install guides, the how-tos for each client, the reference for every tool, command and setting, and how it works.
84
+
85
+ ## License
86
+
87
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,60 @@
1
+ <!-- mcp-name: io.github.gronare/mindin -->
2
+
3
+ # mindin
4
+
5
+ Memory for Claude and coding agents, kept as markdown notes you own, with a schema that holds and a tie to your git history.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ curl -fsSL https://github.com/gronare/mindin/releases/latest/download/install.sh | sh
11
+ ```
12
+
13
+ It installs the `mindin` command with [uv](https://docs.astral.sh/uv/), asks where your vault lives (a folder, an S3 bucket or a vault server), and offers to add the vault to Claude Code, Codex and Cursor; it changes nothing in them without a yes. mindin was called notes-vault-mcp: the `notes-vault-mcp` package and command still work, and install and run mindin.
14
+
15
+ ### A vault server
16
+
17
+ A vault server with Docker Compose, for claude.ai, Claude Desktop, mobile and every machine you work on. You need a domain pointing at the machine, ports 80 and 443 open, and an SMTP account for sign-in links.
18
+
19
+ ```sh
20
+ mkdir notes-vault && cd notes-vault
21
+ curl -fsSL -O https://github.com/gronare/mindin/releases/latest/download/compose.yml -O https://github.com/gronare/mindin/releases/latest/download/Caddyfile
22
+ curl -fsSL -o .env https://github.com/gronare/mindin/releases/latest/download/example.env
23
+ docker compose run --rm --no-deps vault master-key generate # paste into .env, with VAULT_HOST and SMTP
24
+ docker compose up -d
25
+ docker compose exec vault mindin accounts invite you@example.com
26
+ ```
27
+
28
+ Then open `https://VAULT_HOST/account` and sign in. [Install with Docker](https://github.com/gronare/mindin/blob/main/docs/install/docker.md) walks through each step.
29
+
30
+ Without the script, on one machine: `uv tool install mindin`, then `mindin setup`.
31
+
32
+ ## Use
33
+
34
+ Add the server's address, `https://VAULT_HOST/mcp`, as a custom connector in claude.ai. Claude searches, reads and writes your notes. The same search from a shell on a [signed-in machine](https://github.com/gronare/mindin/blob/main/docs/how-to/sign-in-a-machine.md):
35
+
36
+ ```console
37
+ $ mindin search "signing in"
38
+ 1 note · archive and superseded hidden
39
+
40
+ myapp system 3 days
41
+ Areas/myapp.md
42
+ ## Sign-in Users sign in with passkeys; email links are the fallback.
43
+ ```
44
+
45
+ ## What you get
46
+
47
+ - **Notes you own.** Plain markdown in a folder or an S3 bucket; open them in Obsidian, keep them in git.
48
+ - **A schema with teeth.** Required fields, legal statuses and kinds, a tag vocabulary; a write that breaks the contract is refused. Start from PARA, a simple vault, a journal or your own layout.
49
+ - **A lifecycle.** `close` archives finished work, `backlog_add` files what was deferred, `log_append` writes one line per repo per session, `lint` reports drift.
50
+ - **Memory tied to code.** A note names the paths it describes; the session-start hook prints the commits newer than the note.
51
+ - **Search that reads your languages.** Stemming, folded diacritics, synonyms, and optional search by meaning that runs on your machine.
52
+ - **Your own vault server.** Accounts with passkeys, email links, GitHub or your identity provider, several vaults each, shared vaults, sealed in storage.
53
+
54
+ ## Documentation
55
+
56
+ [docs/](https://github.com/gronare/mindin/blob/main/docs/README.md) has the install guides, the how-tos for each client, the reference for every tool, command and setting, and how it works.
57
+
58
+ ## License
59
+
60
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,76 @@
1
+ # mindin server settings. docs/reference/configuration.md describes every variable.
2
+
3
+ # ---- Required: edit these ----
4
+
5
+ # The domain the server answers on. Point it at this machine and open ports 80 and 443; Caddy fetches the certificate. The server's address is https://VAULT_HOST.
6
+ VAULT_HOST=vault.example.com
7
+
8
+ # Seals every vault. Make one with: docker compose run --rm --no-deps vault master-key generate
9
+ # Back it up outside this machine: without it no vault can be read.
10
+ VAULT_HOSTED_MASTER_KEY=
11
+
12
+ # At least one way to sign in. Email links are below; GitHub, an identity provider and a trusted proxy are further down.
13
+ VAULT_SMTP_HOST=smtp.example.com
14
+ VAULT_SMTP_FROM=Vault <vault@example.com>
15
+ VAULT_SMTP_USERNAME=REPLACE_ME
16
+ VAULT_SMTP_PASSWORD=REPLACE_ME
17
+ # VAULT_SMTP_SECURITY=starttls
18
+ # VAULT_SMTP_PORT=587
19
+
20
+ # ---- Storage ----
21
+
22
+ # The vaults live in the container's /data volume. To keep them in an S3 bucket instead, delete this line and fill in the S3 block.
23
+ VAULT_PATH=/data/vaults
24
+
25
+ # S3_ENDPOINT=https://s3.example.com
26
+ # S3_BUCKET=vault
27
+ # S3_ACCESS_KEY=
28
+ # S3_SECRET_KEY=
29
+ # S3_REGION=us-east-1
30
+ # S3_PREFIX=
31
+
32
+ # ---- Optional: other ways to sign in ----
33
+
34
+ # GitHub: an OAuth app with the callback https://VAULT_HOST/signin/github/callback
35
+ # VAULT_GITHUB_CLIENT_ID=
36
+ # VAULT_GITHUB_CLIENT_SECRET=
37
+
38
+ # An OpenID Connect provider: a confidential client with the callback https://VAULT_HOST/oidc/callback
39
+ # VAULT_OIDC_ISSUER=
40
+ # VAULT_OIDC_CLIENT_ID=
41
+ # VAULT_OIDC_CLIENT_SECRET=
42
+ # VAULT_OIDC_NAME=your organisation
43
+ # VAULT_OIDC_SCOPES=openid email profile
44
+
45
+ # A proxy in front that signs in people and forwards a signed identity token
46
+ # VAULT_IDENTITY_PUBLIC_KEY=
47
+ # VAULT_IDENTITY_ISSUER=
48
+ # VAULT_IDENTITY_HEADER=X-Forwarded-Identity
49
+ # VAULT_IDENTITY_TYP=
50
+ # VAULT_IDENTITY_WRITE_CLAIMS=vault:write
51
+ # VAULT_IDENTITY_READ_CLAIMS=vault:read
52
+ # VAULT_IDENTITY_NAME=your company's sign-in
53
+
54
+ # ---- Optional: accounts and access ----
55
+
56
+ # VAULT_REGISTRATION=invite
57
+ # VAULT_PASSKEYS=on
58
+ # VAULT_ALLOWED_HOSTS=
59
+ # VAULT_SUBJECT_PREFIX=users
60
+
61
+ # ---- Optional: rotating the master key ----
62
+
63
+ # VAULT_HOSTED_MASTER_KEY_PREVIOUS=
64
+
65
+ # ---- Optional: importing a vault from another bucket ----
66
+
67
+ # IMPORT_S3_ACCESS_KEY=
68
+ # IMPORT_S3_SECRET_KEY=
69
+
70
+ # ---- Optional: search by meaning ----
71
+
72
+ # docs/install/semantic-search.md turns it on with a compose.override.yml; these tune it.
73
+ # VAULT_SEMANTIC_MODEL=sentence-transformers/paraphrase-multilingual-mpnet-base-v2
74
+ # VAULT_EMBED_BATCH=16
75
+ # VAULT_EMBED_THREADS=
76
+ # VAULT_EMBED_MAX_TOKENS=256
@@ -0,0 +1,3 @@
1
+ {$VAULT_HOST} {
2
+ reverse_proxy vault:8765
3
+ }