Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - blackstorm/mdbrain: Publish your 🔗🌳digital garden with 🧠 mdbrain · GitHub
Skip to content

Repository files navigation

Mdbrain

LicenseReleaseGitHub Stars

English | 简体中文

Mdbrain is a complete self-hosted solution for publishing Obsidian notes as websites.

It supports multiple vaults, automatic incremental publishing, link parsing, and backlink display—designed to deliver a seamless publishing experience for digital gardens, blogs, documentation, and tutorial sites.

Built with Clojure and HTMX for a simple, fast, and maintainable architecture.

Why Mdbrain

  • Truly self-hosted — No SaaS or third-party platform dependencies; you own your data
  • Obsidian-native — Full support for internal links, backlinks, and wiki-style references
  • Developer-friendly — Flexible integration with local storage or S3-compatible backends
  • One-click publishing — Publish your existing vault to a live site in seconds

Features

  • Fully self-hosted with complete control over deployment and data
  • Support for multiple independent vaults
  • Incremental and full publish modes for efficient publishing
  • Native support for Obsidian notes and related assets
  • Automatic parsing of internal links and backlinks
  • Built-in custom domain support with automatic HTTPS
  • Compatibility with local storage and S3-compatible object storage
  • Customizable site logo and HTML templates

Quickstart

One command to try it out:

docker run -d \
--name mdbrain \
--restart unless-stopped \
-p 8080:8080 \
-p 9090:9090 \
-v mdbrain:/app/data \
-e STORAGE_TYPE=local \
ghcr.io/blackstorm/mdbrain:latest
  • Public site: http://<your-server>:8080
  • Console + Publish API: http://<your-server>:9090/console (use firewall/ACLs or a private network to restrict access if needed).

Security note: the Docker image runs in ENVIRONMENT=production by default. Console sessions use Secure cookies, so accessing Console over plain HTTP can be unreliable. Prefer HTTPS for Console (for example, a reverse proxy or private network) and restrict access to port 9090 if you expose it publicly.

Production deployment (with Caddy + auto TLS):

# 1. Clone and configure
git clone https://github.com/blackstorm/mdbrain.git
cd mdbrain
cp selfhosted/.env.example selfhosted/.env
# 2. Start services
docker compose --env-file selfhosted/.env \
-f selfhosted/compose/docker-compose.caddy.yml up -d
# 3. Access Console# Direct: http://<your-server>:9090/console# Optional: put Console behind HTTPS or a private network if you need restricted access.

Then create your first admin user at /console/init, set up a vault, and install the Obsidian plugin.

Full deployment guide: selfhosted/README.md

Configuration

Mdbrain reads configuration from environment variables.

NameDescriptionDefaultRequired
STORAGE_TYPEStorage backend: local or s3localNo
DATA_PATHBase data directory/app/dataNo
CADDY_ON_DEMAND_TLS_ENABLEDEnable automatic HTTPS certificatesfalseNo
S3_ENDPOINTS3 endpoint URLYes (S3)
S3_ACCESS_KEYS3 access keyYes (S3)
S3_SECRET_KEYS3 secret keyYes (S3)
S3_BUCKETS3 bucket namemdbrainNo
S3_PUBLIC_URLPublic URL for browser asset loadingYes (S3)

Full reference: selfhosted/README.md

FAQ

What storage backends are supported?

Local filesystem storage and any S3-compatible object storage (AWS S3, MinIO, RustFS, Cloudflare R2, etc.).

Does it support backlinks?

Yes. Mdbrain automatically parses Obsidian internal links ([[note]]) and displays backlinks on each published page.

How are images and attachments handled?

All assets referenced in your notes are uploaded alongside your content and served from the same domain or S3 storage.

Can I use my own domain for each vault?

Yes. Each vault can have its own custom domain with automatic HTTPS via Caddy's on-demand TLS.

Development

Prerequisites: Java 25 (Temurin), Clojure CLI, Node.js 25, pnpm, Make.

make install
make dev
  • Frontend: http://localhost:8080
  • Console: http://localhost:9090/console

Releases

Docker image

  • Image: ghcr.io/blackstorm/mdbrain
  • Tags: latest, X.Y.Z, edge (main branch)

Obsidian plugin

Download mdbrain-plugin.zip from GitHub Releases and extract to .obsidian/plugins/mdbrain/.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

  • Server (server/): AGPL-3.0-or-later
  • Obsidian plugin (obsidian-plugin/): MIT
  • Deployment configs (selfhosted/): MIT

See THIRD_PARTY_NOTICES.md for third-party licenses.

About

Publish your 🔗🌳digital garden with 🧠 mdbrain

Topics

Resources

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages