Skip to content
Richard Šenko

VaultBridge 1.0: Self-Hosted Obsidian API with Semantic Search

VaultBridge turns a normal Obsidian Markdown vault into a small, authenticated REST API with local semantic search—without replacing Markdown as the source of truth.

VaultBridge 1.0 architecture showing an AI client connected to an Obsidian vault and local semantic index

I built VaultBridge because I was tired of one very small problem: copying useful output from ChatGPT into Obsidian by hand.

The first version fixed that. It was a tiny FastAPI service behind my vault, built for one user and one workflow. Then the project kept growing. I wanted safer file access, a stable API, local semantic search, reproducible Docker deployment and a release that somebody other than me could actually trust.

On August 26, that experiment became VaultBridge 1.0: an open-source, self-hosted REST API for Obsidian Markdown vaults with local multilingual semantic search, Docker deployment and a documented TrueNAS SCALE setup.

The important part is not the version number. It is the transition from “this works on my NAS” to “somebody else can clone it, understand it, run it and rebuild it.” VaultBridge grew directly out of my earlier ChatGPT → Obsidian → TrueNAS workflow, but v1.0 is where the experiment became a project.

Contents


Why I built a self-hosted Obsidian API

The original goal was almost embarrassingly simple: remove the copy-paste step between an AI client and my Obsidian vault.

For a private script, that was enough. For a public project, it was not.

A reusable Obsidian API has to assume that the client can make mistakes. Paths need to stay inside the vault. Logs should not casually leak note content. Authentication has to be explicit. A semantic index needs a lifecycle instead of existing as a mysterious database file. Docker permissions need to work outside the machine where the project was developed.

That changed the architecture. What started as “a FastAPI script behind my vault” became a small application with a versioned API boundary, semantic-index lifecycle, tests, CI, release candidates, container publishing and deployment documentation.

In other words, the hard part was not making ChatGPT write a Markdown file. The hard part was making that capability predictable, constrained and boring enough to run continuously.


How VaultBridge 1.0 works

The architecture is intentionally small:

AI client / script / automation
            ↓
      HTTPS + Bearer API key
            ↓
         VaultBridge
         /         \
        ↓           ↓
 Markdown vault   Local semantic index
(source of truth) SQLite + embeddings

VaultBridge sits between a client and an ordinary Obsidian Markdown vault. The client gets a controlled API instead of direct filesystem access, while the vault remains a normal collection of .md files.

Alongside the vault, VaultBridge maintains a local semantic index used for meaning-based retrieval. That index is derived data. It can be deleted and rebuilt without changing the notes themselves.

This became one of the core design principles of the project:

The API can disappear. The semantic index can disappear. The knowledge base should still be there.


Why Markdown stays the source of truth

I did not want to build an “AI knowledge base” that quietly turns a vector database into the real owner of my notes.

The vault therefore stays exactly what Obsidian expects: a directory of Markdown files. Obsidian can open it. Syncthing can synchronize it. Git can version it. A text editor can modify it. VaultBridge is simply another controlled interface to the same files.

The semantic SQLite database is intentionally disposable. If I remove it, I lose search acceleration—not the knowledge itself.

That separation also makes the system easier to reason about. Markdown is durable and portable. The API and semantic layer are replaceable infrastructure around it.


Obsidian search is excellent when I remember the exact thing I am looking for: a filename, SQL object, identifier or phrase. My memory is usually less cooperative.

Sometimes I remember only the idea: “that note about the APEX authentication problem” or “the setup where I used local DNS with my NAS.” Literal search can miss those queries even when the relevant note is sitting in the vault.

VaultBridge 1.0 adds local multilingual semantic search on top of the Markdown vault. It uses FastEmbed / ONNX with a multilingual MiniLM embedding model, heading-aware chunks and hybrid semantic + lexical ranking.

The embeddings are generated on the machine running VaultBridge. No external embedding API is required.

The index is incremental, and background indexing prevents normal API writes from waiting for a full rebuild. Health endpoints expose whether semantic search is ready, how many notes and chunks are indexed, and whether the semantic layer is currently available.

For me, that observability was as important as the embeddings themselves. “There is a vector database somewhere” is not an operational model.


A deliberately small REST API

VaultBridge is not a generic remote filesystem API.

The stable /api/v1 surface focuses on note and search operations. Protected routes use a Bearer API key, vault-relative paths are validated, and operational health endpoints are kept separate from note access.

I deliberately resisted exposing every filesystem capability that Python could technically provide. An API should expose what its clients need—not everything the server is capable of doing.

Path containment is especially important here. The vault boundary is treated as a real security boundary rather than a string prefix that happens to work on the happy path. That includes accounting for traversal attempts and symlink behavior.

A smaller API is less exciting on a feature checklist. It is also much easier to understand, test and trust.


What shipping VaultBridge 1.0 actually required

The biggest lesson of the release was how different feature complete is from release ready.

By the time VaultBridge could read, write and search notes, the interesting engineering work was only starting. Before the stable release I worked through:

  • API contract and versioning,
  • path-containment and symlink safety,
  • structured logging without sensitive request content,
  • semantic-index inspection and offline rebuild tooling,
  • Docker and TrueNAS deployment documentation,
  • CI for Python and container validation,
  • public-repository history and exposure audits,
  • release-candidate builds,
  • GitHub Container Registry publication,
  • anonymous image pulls by exact digest,
  • disposable-vault runtime smoke tests.

The stable release followed a verified v1.0.0-rc.2. I wanted the final tag to mean more than “the tests passed on my laptop.”

Publishing the project forced me to test assumptions that would have survived indefinitely in a private tool. That was probably the most valuable part of the entire v1.0 process.


Running VaultBridge with Docker and TrueNAS SCALE

My own VaultBridge instance runs on TrueNAS, so the project includes both generic Docker documentation and a TrueNAS SCALE deployment path.

A normal installation needs only a few moving parts: the VaultBridge container, a mounted Obsidian vault, writable storage for the derived semantic index and an API key.

The stable image is published through GitHub Container Registry, which means users can run the released container without building VaultBridge from source first.

For v1.0.0, the supported published runtime is Linux/amd64. I prefer making that boundary explicit instead of claiming portability that I have not actually validated.

The result is deliberately modest infrastructure: FastAPI, Markdown, SQLite and Docker. No Redis. No Celery. No external vector database. No Kubernetes cluster hiding behind the architecture diagram.


Why ChatGPT is only one VaultBridge client

ChatGPT motivated the project, but I did not want the architecture to depend on it.

A Custom GPT Action can call VaultBridge, but so can a shell script, another AI client, an agent, an automation workflow or a custom frontend. The server exposes a stable interface; the client is replaceable.

That separation matters because AI products change quickly. My knowledge base should not have to migrate every time the client does.

ChatGPT is one client. Markdown is the durable layer.

There is also an important privacy distinction. Semantic embeddings and the index stay local, but an external AI client can still receive note content that I explicitly ask VaultBridge to return. Local embeddings do not magically make every client local.


What VaultBridge 1.0 deliberately does not include

A stable release should be clear about its boundaries, not just its features.

VaultBridge v1.0.0 does not claim support for multi-architecture images, rate limiting, API-key rotation, MCP integration, filesystem watching or native Windows production deployment.

Some of those features are obvious directions for future versions. They simply were not part of the contract I was comfortable calling stable in 1.0.

I would rather ship a smaller system with explicit guarantees than add “supports everything” labels to features I have not properly validated.


What building VaultBridge taught me

The first endpoint was easy. Making the project boring in the right ways took much longer.

Release engineering, failure cases and deployment boundaries taught me more than I expected:

  • a passing unit test is not a clean-install test,
  • a Docker build is not proof that the published image actually runs,
  • a relative path is not automatically a safe path,
  • a semantic index needs lifecycle and observability, not just embeddings,
  • public Git history is part of the release surface,
  • simple architecture still needs explicit constraints.

The project also reinforced a principle I keep coming back to: use the smallest infrastructure that solves the measured problem.

For VaultBridge 1.0, FastAPI + Markdown + SQLite + Docker is enough. The goal is not to build the most impressive stack. The goal is to make an Obsidian vault safely useful to other tools without making the vault dependent on those tools.


VaultBridge FAQ

Does VaultBridge replace Obsidian?

No. The Obsidian vault remains a normal directory of Markdown files. VaultBridge adds a controlled REST API and a rebuildable semantic-search layer around those files.

Does VaultBridge send embeddings to an external API?

No external embedding API is required. VaultBridge 1.0 generates its semantic embeddings locally with FastEmbed / ONNX. An external AI client can still receive note content when you explicitly request it through the API.

Can VaultBridge run on TrueNAS SCALE?

Yes. My own deployment runs on TrueNAS, and the project documents a TrueNAS SCALE deployment path in addition to generic Docker usage.

Is VaultBridge only for ChatGPT?

No. ChatGPT was the original client, but VaultBridge is client-agnostic. Scripts, agents, automation tools and other applications can use the same REST API.

What platform does VaultBridge 1.0 support?

The published v1.0.0 runtime is supported on Linux/amd64.


Try VaultBridge

VaultBridge is open source on GitHub:

github.com/mrtrollex/VaultBridge

The stable release is available here:

VaultBridge v1.0.0

If you use Obsidian, self-host your own services or are experimenting with AI over a personal knowledge base, I would be interested to hear where this kind of API would be useful in your workflow.

And if VaultBridge solves a problem for you, a GitHub star is a simple way to help other Obsidian and self-hosting users discover the project.


Conclusion: keep the knowledge durable

VaultBridge started because I was tired of copying Markdown from one window into another.

Version 1.0 still solves that same small problem, but the boundaries are much clearer now: an authenticated REST API, local semantic search, Markdown as the source of truth and a Docker deployment I can reproduce outside my own development machine.

That is the direction I want to keep taking with the project: make the integration smarter without making the knowledge base more fragile.