A fast, keyboard-driven terminal client, MCP server, and Rust SDK for Roam Research. Navigate, edit, and search your knowledge graph without leaving the terminal — connect AI assistants via MCP — or use the SDK to build your own tools.
┌─────────────────────────────────────────────────────────┐
│ roam-tui [Graph: my-graph] Feb 24, 2026 │
├─────────────────────────────────────────────────────────┤
│ │
│ February 24, 2026 │
│ │
│ • Meeting notes with [[John]] │
│ • Discussed Q1 roadmap │
│ • Action items: ((ref-uid)) │
│ ▸ Project ideas [3 collapsed] │
│ • Read chapter 5 of **Deep Work** │
│ • Key insight: time blocking works │
│ │
│ February 23, 2026 │
│ │
│ • Finished migration to new API │
│ • {{DONE}} Review PR #42 │
│ │
├─────────────────────────────────────────────────────────┤
│ [i]edit [o]new [/]search [?]help [h/l]collapse/expand│
└─────────────────────────────────────────────────────────┘
roam-tui includes a built-in MCP server that exposes your Roam graph to AI assistants (Claude, Cursor, etc.). Connects directly to the Roam Research cloud API — no local Roam desktop app needed.
Add to your MCP client config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"roam": {
"command": "npx",
"args": ["-y", "roam-tui@latest", "--mcp"],
"env": {
"ROAM_GRAPH_NAME": "your-graph-name",
"ROAM_GRAPH_API__TOKEN": "roam-graph-token-XXXXX"
}
}
}
}Or if you have the binary installed:
roam --mcp| Tool | Description |
|---|---|
search |
Search pages by title |
search_blocks |
Full-text search inside block content |
get_page |
Get a page with all blocks |
get_block |
Get a block by UID |
get_daily_note |
Get a daily note by date |
get_backlinks |
Find blocks that reference a page |
get_block_refs |
Get outbound references from a block |
get_graph_stats |
Graph statistics (page/block counts) |
roam_query |
Run a raw Datalog query |
create_page |
Create a new page |
create_block |
Create a block under a parent |
create_block_with_children |
Create a block with nested children |
update_block |
Update block content |
delete_block |
Delete a block |
delete_page |
Delete a page |
move_block |
Move a block to another parent |
batch_write |
Execute multiple write operations |
export_page_as_markdown |
Export a page as formatted markdown |
All SDK operations are available as CLI subcommands. No subcommand launches the TUI.
roam journal add "Meeting with [[John]]" # add to today's daily note
roam journal # view today's note (JSON)
roam search "project" --blocks --limit 10 # search block content
roam get page "Books" # get a page with all blocks
roam get backlinks "Project Alpha" # find references to a page
roam get stats # graph statistics
roam export --page "Books" --format json # export page as JSON
roam query '[:find ?t :where [?e :node/title ?t]]' # raw Datalog query
roam create page "New Project" # create a page
roam create block --parent "uid" "Content" # create a block
roam batch operations.json # batch write operationsFull reference: CLI docs
Roam Research is powerful but lives in the browser. If you spend most of your day in the terminal, context switching costs add up. roam-tui gives you direct access to your graph — fast, focused, and keyboard-first.
Not a replacement for the web UI. Use roam-tui for quick capture, daily note workflows, and navigating your graph. Use the web for complex queries, graph visualization, and plugin-heavy workflows.
npx roam-tui@latest --mcpgit clone https://github.com/avelino/roam-tui
cd roam-tui
cargo install --path .- A Roam Research graph with an API token (how to get one)
- Rust 1.70+ (only for building from source)
Run roam for the first time — it creates a config file and tells you where:
roam
# → Created default config at: ~/.config/roam-tui/config.toml
# → Please edit it with your Roam graph name and API token, then run again.Add your credentials:
# ~/.config/roam-tui/config.toml
[graph]
name = "your-graph-name"
api_token = "roam-graph-token-XXXXX"Or use an environment variable:
export ROAM_GRAPH_API__TOKEN="roam-graph-token-XXXXX"Run again:
roamYour daily note loads. Start navigating.
Opens today's note on launch. Navigate to previous days with P / PageUp (vim) or scroll past the last block to auto-load older days. Jump back to today with G.
Full block editing with vim-style modal workflow:
ito edit the selected block,Escto save and exitoto create a new block belowddto delete a blockTab/Shift+Tabto indent/unindent- Undo with
u, redo withCtrl+R - Auto-pairing for
(),[],{} {{TODO}}/{{DONE}}toggle withAlt+EnterorCtrl+Enter
Blocks with children can be collapsed (h) and expanded (l). Press Enter to toggle. Collapsed blocks hide their children from navigation and display — just like the web UI.
Press / to open a search popup. Type to filter across all loaded blocks and cached references. Navigate results with arrow keys, press Enter to jump to the block.
Type (( in edit mode to open the autocomplete popup. Search for any block by content, select with Enter. References are resolved and displayed inline.
Blocks render with full Roam syntax support:
| Syntax | Rendering |
|---|---|
**bold** |
Bold text |
__italic__ |
Italic text |
~~strikethrough~~ |
Strikethrough |
^^highlight^^ |
Highlighted text |
`code` |
Inline code |
[[Page Name]] |
Page link (cyan) |
((block-uid)) |
Block reference (resolved) |
#tag |
Tag (cyan) |
{{TODO}} / {{DONE}} |
Checkbox markers |
{{embed: ((uid))}} |
Embedded block |
Fenced code blocks (```) render with syntax highlighting via tree-sitter. Supported languages: Rust, Python, JavaScript, TypeScript, Go, C, Bash, JSON, TOML, YAML, HTML, CSS, Markdown.
Press ? to see all keybindings for your current preset. Any key closes the help overlay.
API errors (rate limits, auth failures, network issues) appear as a popup overlay with a human-readable title and hint instead of raw JSON. Any key dismisses the popup.
Three built-in presets. Set with keybindings.preset in config.
| Action | vim | emacs | vscode |
|---|---|---|---|
| Move up | k / Up |
Ctrl+P / Up |
Up |
| Move down | j / Down |
Ctrl+N / Down |
Down |
| Cursor left | Left |
Left |
Left |
| Cursor right | Right |
Right |
Right |
| Collapse | h |
Ctrl+B |
Ctrl+Left |
| Expand | l |
Ctrl+F |
Ctrl+Right |
| Toggle open | Enter |
Enter |
Enter |
| Next day | N / PageDown |
Alt+N / PageDown |
Alt+Up / PageDown |
| Previous day | P / PageUp |
Alt+P / PageUp |
Alt+Down / PageUp |
| Go to today | G |
Ctrl+D |
Ctrl+D |
| Navigate back | Ctrl+O / Shift+Left / Alt+[ |
Shift+Left / Alt+[ |
Shift+Left / Alt+[ |
| Navigate forward | Shift+Right / Alt+] |
Shift+Right / Alt+] |
Shift+Right / Alt+] |
| Action | vim | emacs | vscode |
|---|---|---|---|
| Edit block | i |
Enter |
Enter |
| New block | o |
Alt+Enter |
Ctrl+Enter |
| Delete block | dd |
— | — |
| Search | / |
Ctrl+S |
Ctrl+Shift+F |
| Undo | u |
Ctrl+/ |
Ctrl+Z |
| Redo | Ctrl+R |
Ctrl+Shift+/ |
Ctrl+Shift+Z |
| Help | ? |
Ctrl+H |
F1 |
| Quick switcher | Ctrl+P |
— | Ctrl+P |
| Toggle sidebar | b |
— | Ctrl+B |
| Quit | q |
Ctrl+Q |
Ctrl+Q |
| Action | Key |
|---|---|
| Save and exit | Esc |
| Move cursor | Arrow keys, Home, End |
| Move by word | Ctrl+Left / Ctrl+Right |
| Toggle TODO | Alt+Enter or Ctrl+Enter |
| Block ref autocomplete | (( |
| Indent | Tab |
| Unindent | Shift+Tab |
Override any key in the config file:
[keybindings]
preset = "vim"
[keybindings.bindings]
quit = "Ctrl+q"
search = "Ctrl+f"Config file location: ~/.config/roam-tui/config.toml
All options with defaults:
[graph]
name = "" # required — your Roam graph name
api_token = "" # required — or set ROAM_GRAPH_API__TOKEN env var
[ui]
theme = "dark" # dark | light
sidebar_default = true # show sidebar on startup
sidebar_width_percent = 35 # sidebar width as percentage
[keybindings]
preset = "vim" # vim | emacs | vscode
# [keybindings.bindings] # override individual keys
# quit = "Ctrl+q"Environment variables override config file values. Prefix with ROAM_, use __ for nesting:
ROAM_GRAPH_NAME=my-graph
ROAM_GRAPH_API__TOKEN=roam-graph-token-XXXXXWhat's working now and what's next.
- Daily notes with multi-day navigation
- Block tree editing (create, edit, delete, indent, move)
- Collapse/expand blocks
- Undo/redo
- Full-text search across blocks
- Block reference autocomplete (
(() - Markdown + Roam syntax rendering
- Code block syntax highlighting (14 languages)
- Three keybinding presets (vim, emacs, vscode)
- Custom keybinding overrides
- Help overlay
- Optimistic UI updates (no lag on edits)
- Auto-refresh from API
- Page navigation (follow
[[links]]) - Navigation history (back/forward)
- Cursor navigation (left/right within blocks)
- User-friendly error popups (rate limits, auth, network)
- Quick switcher (fuzzy page navigation)
- Linked references / backlinks panel
- Page creation from
[[links]]and Quick Switcher - MCP server (
--mcpflag, 18 tools, npm distribution) - Export to markdown and JSON (CLI + TUI keybinding)
- Multi-block selection with batch operations (Shift+Up/Down)
- Sidebar with page references
- Unlinked references
- Light theme
- Breadcrumb display
git clone https://github.com/avelino/roam-tui
cd roam-tui
cargo test # 551 tests
cargo run # requires config with valid API tokenTests run without network access — API interactions use wiremock for mocking.
MIT — see LICENSE for details.