Goal
Connect your local org roam knowledge base to Codex CLI via an org-roam-mcp Message Control Protocol (MCP) server, so Codex can search, read, and write notes using MCP tools.
Important: there are two different “org-roam-mcp” servers
The name org-roam-mcp is currently used by different projects. The setup depends on which one you are running.
A) Emacs-backed (dcruver/org-roam-ai)
- This MCP server talks to a running Emacs via
emacsclient(NOT directly to SQLite). - It has both HTTP and stdio modes; for Codex CLI you must pass
--stdio. - Repo: https://github.com/dcruver/org-roam-ai
Which install source are you using?
There are (at least) two common ways to run it, and the required Emacs packages differ:
-
Recommended: run the latest server from GitHub (matches
org-roam-second-brain)- Run with uvx:
uvx --from git+https://github.com/yanboyang713/org-roam-ai.git#subdirectory=mcp org-roam-mcp --stdio - Emacs must have these features loaded:
org-roam-vector-search(fromorg-roam-second-brain)org-roam-second-brain(fromorg-roam-second-brain)org-roam-api(fromorg-roam-ai)
- Run with uvx:
-
Legacy: PyPI (
uvx org-roam-mcp) (older checks + different defaults)- Run with uvx:
uvx org-roam-mcp --stdio - Default server file path is often
~/emacs-server/server(override viaEMACS_SERVER_FILE). - Emacs is checked for these loaded features:
org-roam-vector-searchorg-roam-ai-assistantorg-roam-api
- Details set-up steps: org-roam-ai (Emacs-backed server; Codex via
--stdio)
- Run with uvx:
B) SQLite-backed (GitHub aserranoni/org-roam-mcp)
- Talks directly to the org-roam SQLite DB (
org-roam.db) and org files. - Does NOT require Emacs server or extra elisp packages.
- Repo: https://github.com/aserranoni/org-roam-mcp
Comparison — two different “org-roam-mcp” servers
| Topic | dcruver/org-roam-ai (PyPI org-roam-mcp) | aserranoni/org-roam-mcp (GitHub) |
|---|---|---|
| Primary goal | Semantic search + AI-assisted workflows | Direct org-roam DB/file access via SQLite |
| Backend | Emacs via emacsclient + elisp APIs | SQLite (org-roam.db) + org files |
| Needs Emacs server? | Yes (M-x server-start or emacs --daemon) | No |
| Needs extra Emacs packages? | Yes: org-roam-api plus semantic packages (org-roam-vector-search, org-roam-second-brain, etc.) | No |
| Needs embeddings service? | Yes (Ollama / Infinity / any OpenAI-compatible embeddings endpoint) | No |
| Stdio mode for Codex | Yes (must pass --stdio) | Yes (stdio server) |
| Typical tools | semantic_search, contextual_search, create_note, generate_embeddings, daily note helpers | search_nodes, get_node, get_backlinks, create_node, add_link |
| Best for | RAG/semantic retrieval, “AI assistant” workflows inside org-roam | Lightweight “query my org-roam DB/files” integration |
Prereqs
- Codex CLI installed and logged in
codex --version codex login - Org-roam database exists and is up-to-date
- In Emacs:
- Run
M-x org-roam-db-sync - (Recommended) Enable
org-roam-db-autosync-modeso the DB stays current
- Run
- In Emacs:
- Python runner for the server
- Recommended:
uv(so you can run the server withuvx) - Alternative:
pipin a virtualenv
- Recommended:
org-roam-ai (Emacs-backed server, works with Codex via --stdio)
This section fixes the common errors:
emacsclient: error accessing server file ...Required Emacs packages not loaded: ...
Start Emacs server (create the server file)
Start Emacs server once:
- In Emacs:
M-x server-start - Or from shell:
emacs --daemon
Important (why this matters):
- The MCP server (
org-roam-mcp) calls Emacs like this:emacsclient --server-file=/path/to/server -e '(...)'
- The
--server-fileoption uses a TCP auth file (not a UNIX socket). - So your Emacs server must run with:
server-use-tcpenabled- a readable/writable, secure
server-auth-dir(permissions 700)
If daemon startup fails because Emacs can’t write to /run/user/... (common in containers), or you see “can’t find socket”, force TCP mode and use a safe auth dir (example):
(with-eval-after-load 'server
;; org-roam-mcp calls `emacsclient --server-file=...` (TCP auth file),
;; so force the Emacs server to use TCP and bind locally.
(setq server-use-tcp t
server-host "127.0.0.1")
;; Ensure the auth dir exists and is secure (Emacs requires 700 permissions).
(setq server-auth-dir (expand-file-name "server/" user-emacs-directory))
(unless (file-directory-p server-auth-dir)
(make-directory server-auth-dir t))
(set-file-modes server-auth-dir #o700)
(unless (server-running-p) (server-start)))Where to put this (example for a vanilla config):
- Put the TCP/auth-dir settings in
~/.emacs.d/early-init.el(loads very early) - Ensure the server is started in
~/.emacs.d/init.el, e.g.:(require 'server) (unless (server-running-p) (server-start))
Then ensure the auth dir is private (otherwise Emacs refuses to start the server):
chmod 700 ~/.emacs.d/serverThen confirm the server file exists:
ls -la ~/.emacs.d/server/server 2>/dev/nullThen confirm you can connect using --server-file:
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(emacs-version)'Install + load the required Emacs packages
The recommended setup (current upstream) uses:
org-roam-second-brain(providesorg-roam-second-brainandorg-roam-vector-search)org-roam-api(fromorg-roam-ai)
Example setup for straight.el:
(straight-use-package
'(org-roam-second-brain
:type git
:host github
:repo "dcruver/org-roam-second-brain"))
(straight-use-package
'(org-roam-api
:type git
:host github
:repo "dcruver/org-roam-ai"
:files ("packages/org-roam-ai/org-roam-api.el")))
;; Ensure the features are actually loaded (required for org-roam-mcp startup)
(require 'org-roam-vector-search)
(require 'org-roam-second-brain)
(require 'org-roam-api)
;; Configure embeddings (required for semantic features)
;; Ollama example:
;; ollama pull nomic-embed-text
;; (setq org-roam-semantic-embedding-url "http://localhost:11434/v1"
;; org-roam-semantic-embedding-model "nomic-embed-text")
(setq org-roam-semantic-embedding-url "http://localhost:11434/v1"
org-roam-semantic-embedding-model "nomic-embed-text")Optional (recommended): generate embeddings once so semantic_search works well:
- In Emacs:
M-x org-roam-semantic-generate-all-embeddings - Or via MCP (after Codex is connected): call the
generate_embeddingstool
Optional: org-roam-second-brain “second brain” features (digest, stale projects, etc.)
- Try:
M-x sb/digest(keybindings are documented in https://github.com/dcruver/org-roam-second-brain)
Create predefined structured notes (Person / Project / Idea / Admin)
The package creates these notes directly (it does not use org-roam capture templates).
How to create them:
- Run interactively:
M-x sb/person(prompts for name + context)M-x sb/project(prompts for title + next action)M-x sb/idea(prompts for title + one-liner)M-x sb/admin(prompts for task + due date)
- Or use the default keybindings (global
C-c bprefix):C-c b p→ personC-c b P→ projectC-c b i→ ideaC-c b a→ admin
Where the files go:
- Under your
org-roam-directory(check in Emacs:M-x describe-variable RET org-roam-directory) - Default subfolders:
- people/, projects/, ideas/, admin/
- Customize the folders via
M-x customize-group RET sb RET(variablesb/directories).
What’s inside the files:
- A properties drawer including:
:ID:(org id):NODE-TYPE:person/project/idea/admin- extra fields depending on type (e.g.
:CONTEXT:,:LAST-CONTACT:,:STATUS:,:NEXT-ACTION:,:ONE-LINER:,:DUE-DATE:)
- Then headings like:
- Person: “* Follow-ups” and “* Notes”
- Project: “* Next Actions” and “* Notes”
- Idea: “* One-liner” and “* Elaboration”
- Admin: “* Notes”
Related helper commands:
M-x sb/inbox(orC-c b I): logs text to today’s daily note and auto-creates person nodes for any[[Name]]linksM-x sb/dangling(orC-c b u): shows dangling[[Name]]links you might want to convert into person nodes
Verify Emacs has them loaded:
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(featurep (quote org-roam-api))'
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(featurep (quote org-roam-second-brain))'
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(featurep (quote org-roam-vector-search))'Step-by-step (end-to-end, tested)
This is the minimal, repeatable sequence that makes the MCP server start successfully.
1) Start (or restart) the Emacs daemon
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(kill-emacs)' 2>/dev/null || true
emacs --daemon2) Verify the daemon is reachable via TCP auth file
ls -la ~/.emacs.d/server/server
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(emacs-version)'3) Verify required features are loaded
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(featurep (quote org-roam-vector-search))'
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(featurep (quote org-roam-second-brain))'
emacsclient --server-file=$HOME/.emacs.d/server/server -e '(featurep (quote org-roam-api))'4) Run the MCP server (stdio mode)
Upstream:
EMACS_SERVER_FILE=$HOME/.emacs.d/server/server \
uvx --from git+https://github.com/dcruver/org-roam-ai.git#subdirectory=mcp org-roam-mcp --stdioMy fork (replace with your repo if needed):
EMACS_SERVER_FILE=$HOME/.emacs.d/server/server \
uvx --from git+https://github.com/yanboyang713/org-roam-ai.git#subdirectory=mcp org-roam-mcp --stdioYou should see logs like:
- “All required Emacs packages are loaded”
- “Starting org-roam MCP server in stdio mode…”
5) Register the MCP server in Codex CLI
Upstream:
codex mcp add org-roam \
--env EMACS_SERVER_FILE=$HOME/.emacs.d/server/server \
-- uvx --from git+https://github.com/dcruver/org-roam-ai.git#subdirectory=mcp org-roam-mcp --stdioMy fork:
codex mcp add org-roam \
--env EMACS_SERVER_FILE=$HOME/.emacs.d/server/server \
-- uvx --from git+https://github.com/yanboyang713/org-roam-ai.git#subdirectory=mcp org-roam-mcp --stdioVerify:
codex mcp list
codex mcp get org-roamTroubleshooting (org-roam-ai MCP server)
“emacsclient: can’t find socket; have you started the server?”
- You’re connecting without
--server-file. Use:emacsclient --server-file=$HOME/.emacs.d/server/server -e '(emacs-version)' - If the file doesn’t exist, start the daemon:
emacs --daemon
“emacsclient: error accessing server file …”
- Usually means Emacs is not running in TCP mode (
server-use-tcp), or you’re pointing at the wrong file. - Ensure Emacs has:
server-use-tcp tserver-host "127.0.0.1"server-auth-dir "~/.emacs.d/server/"
“… is not a safe directory because it is accessible by others (755)”
- Fix permissions:
chmod 700 ~/.emacs.d/server
“org-roam-ui … Cannot bind server socket: Address already in use”
- That’s org-roam-ui’s webserver port being busy.
- Fix: don’t auto-enable org-roam-ui on startup; enable it manually when needed (
M-x org-roam-ui-mode), or change the port. - Example (only enable automatically in GUI, and don’t fail startup):
(use-package org-roam-ui :after org-roam :config (when (display-graphic-p) (ignore-errors (org-roam-ui-mode 1))))
aserranoni/org-roam-mcp (SQLite-backed)
Step 1 — Identify your org-roam DB and directory (SQLite-backed server only)
The MCP server needs two things:
- The org-roam SQLite DB file (often named
org-roam.db) - The org-roam directory containing your roam
.orgfiles
Find the DB file
In my case: ~/.emacs.d/org-roam.db
Check common DB locations:
ls -la ~/.emacs.d/org-roam.db ~/.config/emacs/org-roam.db ~/org-roam.db 2>/dev/nullIf you don’t see it, find it:
find ~ -maxdepth 4 -name "org-roam.db" 2>/dev/nullFind the org-roam directory
It is whatever you configured as org-roam-directory in Emacs.
Common locations: ~/org-roam/, ~/Documents/org-roam/, ~/Dropbox/org-roam/
In my case: ~/org/org-roam/references
Quick sanity check (must contain your roam org files):
ls -la ~/org-roam 2>/dev/null | headStep 2 — Run/Install the org-roam MCP server (SQLite-backed server only)
For the SQLite-backed server, install/run directly from GitHub to avoid name collisions with the PyPI org-roam-mcp (which is the Emacs-backed server).
Option A (recommended) — Run with uvx (no install)
uvx --from git+https://github.com/aserranoni/org-roam-mcp org-roam-mcpOption B — Install with pip in a virtualenv
python -m venv ~/.venvs/org-roam-mcp
source ~/.venvs/org-roam-mcp/bin/activate
pip install --upgrade pip
pip install git+https://github.com/aserranoni/org-roam-mcp
org-roam-mcpStep 3 — Register the MCP server in Codex CLI (SQLite-backed server only)
Codex can manage MCP servers via codex mcp.
Add the server (auto-detect mode)
Try this first (the server attempts to auto-detect DB + directory):
codex mcp add org-roam -- uvx --from git+https://github.com/aserranoni/org-roam-mcp org-roam-mcpAdd the server (explicit paths; recommended if auto-detect fails)
Replace the two paths with your real values:
codex mcp add org-roam \
--env ORG_ROAM_DB_PATH=/path/to/org-roam.db \
--env ORG_ROAM_DIR=/path/to/org-roam/ \
-- uvx --from git+https://github.com/aserranoni/org-roam-mcp org-roam-mcpOptional: increase result limit (default is usually 50):
codex mcp add org-roam \
--env ORG_ROAM_DB_PATH=/path/to/org-roam.db \
--env ORG_ROAM_DIR=/path/to/org-roam/ \
--env ORG_ROAM_MAX_SEARCH_RESULTS=200 \
-- uvx --from git+https://github.com/aserranoni/org-roam-mcp org-roam-mcpVerify Codex sees the server
codex mcp list
codex mcp get org-roamStep 4 — Use it in Codex
Start Codex normally:
codexThen prompt it to use the org-roam MCP tools. Examples:
- “Use the org-roam MCP tools to search for nodes about ‘kubernetes’.”
- “Show backlinks for my note titled ‘Deep Learning’.”
- “Create a new org-roam note titled ‘MCP ideas’ with tags mcp and codex.”
Troubleshooting
DB not found / empty results
- Run
M-x org-roam-db-syncin Emacs, then retry. - Ensure
ORG_ROAM_DB_PATHpoints to the correctorg-roam.db. - Ensure
ORG_ROAM_DIRis the directory that contains your roam.orgfiles (not a parent folder).
DB is stale after creating/updating notes
- Ensure org-roam auto-sync is enabled (
org-roam-db-autosync-mode). - If needed, manually run
M-x org-roam-db-syncafter file changes.
Codex doesn’t list the server
- Re-run:
codex mcp list codex mcp get org-roam - If you need to re-add:
codex mcp remove org-roam
then re-run the codex mcp add command.
Notes
- The MCP server runs locally; access is defined by the DB + directory paths you give it.
- If you have multiple org-roam databases (work/personal), consider adding multiple servers:
org-roam-personal,org-roam-workwith differentORG_ROAM_DB_PATHandORG_ROAM_DIR.
Reference List
- dcruver/org-roam-ai (Emacs-backed PyPI server): https://github.com/dcruver/org-roam-ai
- aserranoni/org-roam-mcp (SQLite-backed): https://github.com/aserranoni/org-roam-mcp
- LobeHub listing: https://lobehub.com/bg/mcp/aserranoni-org-roam-mcp