roam-research-mcp 1.6.0 → 2.4.3

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.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
- ![](./roam-research-mcp-image.jpeg)
1
+ ![Roam Research MCP + CLI](./roam-research-mcp-header.png)
2
2
 
3
- # Roam Research MCP Server
3
+ # Roam Research MCP + CLI
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/roam-research-mcp.svg)](https://badge.fury.io/js/roam-research-mcp)
6
- [![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)
6
+ [![Project Status: Active](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
  [![GitHub](https://img.shields.io/github/license/2b3pro/roam-research-mcp)](https://github.com/2b3pro/roam-research-mcp/blob/main/LICENSE)
9
9
 
10
- A Model Context Protocol (MCP) server and standalone CLI that provides comprehensive access to Roam Research's API functionality. The MCP server enables AI assistants like Claude to interact with your Roam Research graph through a standardized interface, while the CLI (`roam`) lets you fetch, search, and import content directly from the command line. Supports standard input/output (stdio) and HTTP Stream communication. (A WORK-IN-PROGRESS, personal project not officially endorsed by Roam Research)
10
+ A Model Context Protocol (MCP) server and standalone CLI that provides comprehensive access to Roam Research's API functionality. The MCP server enables AI assistants like Claude to interact with your Roam Research graph through a standardized interface, while the CLI (`roam`) lets you fetch, search, and import content directly from the command line. Supports multi-graph configurations, write protection, standard input/output (stdio) and HTTP Stream communication. (Personal project, not officially endorsed by Roam Research)
11
11
 
12
12
  <a href="https://glama.ai/mcp/servers/fzfznyaflu"><img width="380" height="200" src="https://glama.ai/mcp/servers/fzfznyaflu/badge" alt="Roam Research MCP server" /></a>
13
13
  <a href="https://mseep.ai/app/2b3pro-roam-research-mcp"><img width="380" height="200" src="https://mseep.net/pr/2b3pro-roam-research-mcp-badge.png" alt="MseeP.ai Security Assessment Badge" /></a>
@@ -85,7 +85,9 @@ docker run -p 3000:3000 -p 8088:8088 --env-file .env roam-research-mcp
85
85
 
86
86
  ## Standalone CLI: `roam`
87
87
 
88
- A standalone command-line tool for interacting with Roam Research directly, without running the MCP server. Provides four subcommands: `get`, `search`, `save`, and `refs`.
88
+ A standalone command-line tool for interacting with Roam Research directly, without running the MCP server. Provides eight subcommands: `get`, `search`, `save`, `refs`, `update`, `batch`, `rename`, and `status`.
89
+
90
+ All content creation, update, and retrieval commands support **standard input (stdin) piping**, allowing for powerful automation workflows (e.g., `cat notes.md | roam save`, `roam search "query" | roam get`).
89
91
 
90
92
  ### Installation
91
93
 
@@ -111,7 +113,7 @@ Configure via `.env` file in the project root or set as environment variables.
111
113
 
112
114
  ---
113
115
 
114
- ### `roam get` - Fetch pages or blocks
116
+ ### `roam get` - Fetch pages, blocks, or TODOs
115
117
 
116
118
  Fetch content from Roam and output as markdown or JSON.
117
119
 
@@ -132,6 +134,18 @@ roam get "Daily Notes" --depth 2
132
134
  # Flatten hierarchy
133
135
  roam get "Daily Notes" --flat
134
136
 
137
+ # Fetch TODO items
138
+ roam get --todo
139
+
140
+ # Fetch DONE items
141
+ roam get --done
142
+
143
+ # Filter TODOs by page
144
+ roam get --todo -p "January 2nd, 2026"
145
+
146
+ # Include/exclude filter
147
+ roam get --todo -i "urgent,important" -e "someday"
148
+
135
149
  # Debug mode
136
150
  roam get "Daily Notes" --debug
137
151
  ```
@@ -141,6 +155,11 @@ roam get "Daily Notes" --debug
141
155
  - `--depth <n>` - Child levels to fetch (default: 4)
142
156
  - `--refs <n>` - Block ref expansion depth (default: 1)
143
157
  - `--flat` - Flatten hierarchy to single-level list
158
+ - `--todo` - Fetch TODO items
159
+ - `--done` - Fetch DONE items
160
+ - `-p, --page <title>` - Filter TODOs/DONEs by page title
161
+ - `-i, --include <terms>` - Include only items containing these terms (comma-separated)
162
+ - `-e, --exclude <terms>` - Exclude items containing these terms (comma-separated)
144
163
  - `--debug` - Show query metadata
145
164
 
146
165
  ---
@@ -186,9 +205,9 @@ roam search "keyword" --json
186
205
 
187
206
  ---
188
207
 
189
- ### `roam save` - Import markdown
208
+ ### `roam save` - Import markdown or create TODOs
190
209
 
191
- Import markdown content to Roam, creating or updating pages.
210
+ Import markdown content to Roam, creating or updating pages, or add TODO items.
192
211
 
193
212
  ```bash
194
213
  # From a file (title derived from filename)
@@ -211,11 +230,21 @@ roam save --title "Quick Note" << EOF
211
230
  - Item 2
212
231
  - Nested item
213
232
  EOF
233
+
234
+ # Create a TODO item on today's daily page
235
+ roam save --todo "Buy groceries"
236
+
237
+ # Create multiple TODOs from stdin (newline-separated)
238
+ echo -e "Task 1\nTask 2\nTask 3" | roam save --todo
239
+
240
+ # Pipe TODO list from file
241
+ cat todos.txt | roam save --todo
214
242
  ```
215
243
 
216
244
  **Options:**
217
245
  - `--title <title>` - Page title (defaults to filename without `.md`)
218
246
  - `--update` - Update existing page using smart diff (preserves block UIDs)
247
+ - `-t, --todo [text]` - Add a TODO item to today's daily page (text or stdin)
219
248
  - `--debug` - Show debug information
220
249
 
221
250
  **Features:**
@@ -223,6 +252,7 @@ EOF
223
252
  - Automatically links the new page from today's daily page
224
253
  - Converts standard markdown to Roam-flavored markdown
225
254
  - Smart diff mode (`--update`) preserves block UIDs for existing content
255
+ - TODO mode creates `{{[[TODO]]}}` items on the daily page
226
256
 
227
257
  ---
228
258
 
@@ -278,6 +308,103 @@ JSON output for programmatic use:
278
308
 
279
309
  ---
280
310
 
311
+ ### `roam batch` - Execute multiple operations in one API call
312
+
313
+ Execute multiple operations in a single batch API call to reduce rate limiting issues.
314
+
315
+ ```bash
316
+ # From a JSON file
317
+ roam batch commands.json
318
+
319
+ # From stdin
320
+ cat commands.json | roam batch
321
+
322
+ # Dry run (validate without executing)
323
+ roam batch --dry-run commands.json
324
+
325
+ # With debug output
326
+ roam batch --debug commands.json
327
+ ```
328
+
329
+ **Command Format:**
330
+
331
+ Input is a JSON array of command objects:
332
+
333
+ ```json
334
+ [
335
+ { "command": "create", "params": { "text": "Parent block", "parent": "pageUid", "as": "p1" } },
336
+ { "command": "create", "params": { "text": "Child block", "parent": "{{p1}}" } },
337
+ { "command": "todo", "params": { "text": "Task item" } },
338
+ { "command": "codeblock", "params": { "parent": "{{p1}}", "language": "ts", "code": "const x = 1;" } }
339
+ ]
340
+ ```
341
+
342
+ **Supported Commands:**
343
+
344
+ | Command | Description |
345
+ |---------|-------------|
346
+ | `create` | Create a block |
347
+ | `update` | Update block content |
348
+ | `delete` | Delete a block |
349
+ | `move` | Move block to new location |
350
+ | `todo` | Create TODO item |
351
+ | `table` | Create table structure |
352
+ | `outline` | Create nested outline |
353
+ | `remember` | Create tagged memory |
354
+ | `page` | Create page with content |
355
+ | `codeblock` | Create code block |
356
+
357
+ **Features:**
358
+
359
+ - Placeholder references (`{{name}}`) for cross-command dependencies
360
+ - Automatic page title → UID resolution
361
+ - Daily page auto-resolution for `todo` and `remember`
362
+ - Level-based hierarchy for `outline` command
363
+ - `--dry-run` mode for validation
364
+
365
+ **Options:**
366
+ - `--dry-run` - Validate and show planned actions without executing
367
+ - `--debug` - Show debug information
368
+ - `-g, --graph <name>` - Target graph (multi-graph mode)
369
+ - `--write-key <key>` - Write confirmation key
370
+
371
+ See [docs/batch-cli-spec.md](docs/batch-cli-spec.md) for full specification.
372
+
373
+ ---
374
+
375
+ ### `roam status` - Show available graphs
376
+
377
+ Display configured graphs and their connection status.
378
+
379
+ ```bash
380
+ # Show available graphs
381
+ roam status
382
+
383
+ # Test connectivity to all graphs
384
+ roam status --ping
385
+
386
+ # Output as JSON
387
+ roam status --json
388
+ ```
389
+
390
+ **Example Output:**
391
+
392
+ ```
393
+ Roam Research MCP v2.4.0
394
+
395
+ Graphs:
396
+ • personal (default) ✓ connected
397
+ • work [protected] ✓ connected
398
+
399
+ Write-protected graphs require --write-key flag for modifications.
400
+ ```
401
+
402
+ **Options:**
403
+ - `--ping` - Test connection to each graph
404
+ - `--json` - Output as JSON for scripting
405
+
406
+ ---
407
+
281
408
  ## To Test
282
409
 
283
410
  Run [MCP Inspector](https://github.com/modelcontextprotocol/inspector) after build using the provided npm script:
@@ -304,7 +431,7 @@ The server provides powerful tools for interacting with Roam Research:
304
431
 
305
432
  1. `roam_fetch_page_by_title`: Fetch page content by title. Returns content in the specified format.
306
433
  2. `roam_fetch_block_with_children`: Fetch a block by its UID along with its hierarchical children down to a specified depth. Automatically handles `((UID))` formatting.
307
- 3. `roam_create_page`: Create new pages with optional content and headings. **Now supports mixed content types** - content array can include both text blocks and tables in a single call using `{type: "table", headers, rows}` format. Creates a block on the daily page linking to the newly created page.
434
+ 3. `roam_create_page`: Create new pages with optional content and headings. **Now supports mixed content types** - content array can include both text blocks and tables in a single call using `{type: "table", headers, rows}` format. Automatically adds a "Processed: [[date]]" block at the end of the page linking to today's daily page.
308
435
  4. `roam_create_table`: Create a properly formatted Roam table with specified headers and rows. Abstracts Roam's complex nested table structure, validates row/column consistency, and handles empty cells automatically.
309
436
  5. `roam_import_markdown`: Import nested markdown content under a specific block. (Internally uses `roam_process_batch_actions`.)
310
437
  6. `roam_add_todo`: Add a list of todo items to today's daily page. (Internally uses `roam_process_batch_actions`.)
@@ -316,12 +443,13 @@ The server provides powerful tools for interacting with Roam Research:
316
443
  12. `roam_search_by_status`: Search for blocks with a specific status (TODO/DONE) across all pages or within a specific page.
317
444
  13. `roam_search_by_date`: Search for blocks or pages based on creation or modification dates.
318
445
  14. `roam_search_for_tag`: Search for blocks containing a specific tag and optionally filter by blocks that also contain another tag nearby or exclude blocks with a specific tag. This tool supports pagination via the `limit` and `offset` parameters.
319
- 15. `roam_remember`: Add a memory or piece of information to remember. (Internally uses `roam_process_batch_actions`.)
446
+ 15. `roam_remember`: Add a memory or piece of information to remember. Supports optional `heading` parameter to nest under a specific heading on the daily page (created if missing), or `parent_uid` to nest under a specific block. Use `include_memories_tag: false` to omit the MEMORIES_TAG. (Internally uses `roam_process_batch_actions`.)
320
447
  16. `roam_recall`: Retrieve all stored memories.
321
448
  17. `roam_datomic_query`: Execute a custom Datomic query on the Roam graph for advanced data retrieval beyond the available search tools. Now supports client-side regex filtering for enhanced post-query processing. Optimal for complex filtering (including regex), highly complex boolean logic, arbitrary sorting criteria, and proximity search.
322
449
  18. `roam_markdown_cheatsheet`: Provides the content of the Roam Markdown Cheatsheet resource, optionally concatenated with custom instructions if `CUSTOM_INSTRUCTIONS_PATH` environment variable is set.
323
450
  19. `roam_process_batch_actions`: Execute a sequence of low-level block actions (create, update, move, delete) in a single, non-transactional batch. Provides granular control for complex nesting like tables. **Now includes pre-validation** that catches errors before API execution, with structured error responses and automatic rate limit retry with exponential backoff. (Note: For actions on existing blocks or within a specific page context, it is often necessary to first obtain valid page or block UIDs using tools like `roam_fetch_page_by_title`.)
324
451
  20. `roam_update_page_markdown`: Update an existing page with new markdown content using smart diff. **Preserves block UIDs** where possible, keeping references intact across the graph. Uses three-phase matching (exact text → normalized → position fallback) to generate minimal operations. Supports `dry_run` mode to preview changes. Ideal for syncing external markdown files, AI-assisted content updates, and batch modifications without losing block references.
452
+ 21. `roam_move_block`: Move a block to a new location (different parent or position). Convenience wrapper around `roam_process_batch_actions` for single block moves. Parameters: `block_uid` (required), `parent_uid` (required), `order` (optional, defaults to "last").
325
453
 
326
454
  **Deprecated Tools**:
327
455
  The following tools have been deprecated as of `v0.36.2` in favor of the more powerful and flexible `roam_process_batch_actions`:
@@ -462,9 +590,13 @@ The tool will match existing blocks by content, update changed text, add new blo
462
590
  - Create a new token
463
591
 
464
592
  2. Configure the environment variables:
465
- You have two options for configuring the required environment variables:
466
593
 
467
- Option 1: Using a .env file (Recommended for development)
594
+ ### Single Graph Mode (Default)
595
+
596
+ For most users with one Roam graph, use the simple configuration:
597
+
598
+ **Option 1: Using a .env file (Recommended for development)**
599
+
468
600
  Create a `.env` file in the roam-research directory:
469
601
 
470
602
  ```
@@ -475,7 +607,8 @@ The tool will match existing blocks by content, update changed text, add new blo
475
607
  HTTP_STREAM_PORT=8088 # Or your desired port for HTTP Stream communication
476
608
  ```
477
609
 
478
- Option 2: Using MCP settings (Alternative method)
610
+ **Option 2: Using MCP settings (Alternative method)**
611
+
479
612
  Add the configuration to your MCP settings file. Note that you may need to update the `args` to `["/path/to/roam-research-mcp/build/index.js"]` if you are running the server directly.
480
613
 
481
614
  - For Cline (`~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`):
@@ -501,6 +634,62 @@ The tool will match existing blocks by content, update changed text, add new blo
501
634
 
502
635
  Note: The server will first try to load from .env file, then fall back to environment variables from MCP settings.
503
636
 
637
+ ---
638
+
639
+ ### Multi-Graph Mode (v2.0.0+)
640
+
641
+ For users with multiple Roam graphs, you can configure a single MCP server instance to connect to all of them. This is more token-efficient than running multiple server instances.
642
+
643
+ **Configuration:**
644
+
645
+ ```json
646
+ ROAM_GRAPHS="{\"personal\":{\"token\":\"roam-graph-token-xxx\",\"graph\":\"my-personal-graph\"},\"work\":{\"token\":\"roam-graph-token-yyy\",\"graph\":\"company-graph\",\"write_key\":\"confirm-work-write\"}}"
647
+ ROAM_DEFAULT_GRAPH=personal
648
+ ```
649
+
650
+ | Field | Required | Description |
651
+ |-------|----------|-------------|
652
+ | `token` | Yes | Roam API token for this graph |
653
+ | `graph` | Yes | Roam graph name |
654
+ | `write_key` | No | Required confirmation string for writes to non-default graphs |
655
+
656
+ **Usage in Tools:**
657
+
658
+ All tools accept optional `graph` and `write_key` parameters:
659
+
660
+ ```json
661
+ {
662
+ "title": "My Page",
663
+ "graph": "work",
664
+ "write_key": "confirm-work-write"
665
+ }
666
+ ```
667
+
668
+ - **Read operations**: Can target any graph using the `graph` parameter
669
+ - **Write operations on default graph**: Work without additional parameters
670
+ - **Write operations on non-default graphs**: Require the `write_key` if configured
671
+
672
+ **CLI Usage:**
673
+
674
+ All CLI commands support the `-g, --graph` flag:
675
+
676
+ ```bash
677
+ # Read from work graph
678
+ roam get "Meeting Notes" -g work
679
+
680
+ # Write to work graph (requires --write-key if configured)
681
+ roam save notes.md -g work --write-key "confirm-work-write"
682
+ ```
683
+
684
+ **Safety Model:**
685
+
686
+ The `write_key` serves as a confirmation gate (not a secret) to prevent accidental writes to non-default graphs. When a write is attempted without the required key, the error message reveals the expected key:
687
+
688
+ ```
689
+ Write to "work" graph requires write_key confirmation.
690
+ Provide write_key: "confirm-work-write" to proceed.
691
+ ```
692
+
504
693
  3. Build the server (make sure you're in the root directory of the MCP):
505
694
 
506
695
  Note: Customize 'Roam_Markdown_Cheatsheet.md' with any notes and preferences specific to your graph BEFORE building.