roam-research-mcp 0.12.3 → 0.17.0

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
@@ -6,6 +6,8 @@
6
6
 
7
7
  A Model Context Protocol (MCP) server that provides comprehensive access to Roam Research's API functionality. This server enables AI assistants like Claude to interact with your Roam Research graph through a standardized interface.
8
8
 
9
+ <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>
10
+
9
11
  ## Installation
10
12
 
11
13
  You can install the package globally:
@@ -25,13 +27,19 @@ npm run build
25
27
 
26
28
  ## Features
27
29
 
28
- The server provides five powerful tools for interacting with Roam Research:
30
+ The server provides eleven powerful tools for interacting with Roam Research:
29
31
 
30
32
  1. `roam_fetch_page_by_title`: Fetch and read a page's content by title, recursively resolving block references up to 4 levels deep
31
33
  2. `roam_create_page`: Create new pages with optional content
32
34
  3. `roam_create_block`: Create new blocks in a page (defaults to today's daily page)
33
35
  4. `roam_import_markdown`: Import nested markdown content under specific blocks
34
36
  5. `roam_add_todo`: Add multiple todo items to today's daily page with checkbox syntax
37
+ 6. `roam_create_outline`: Create hierarchical outlines with proper nesting and structure
38
+ 7. `roam_search_block_refs`: Search for block references within pages or across the graph
39
+ 8. `roam_search_hierarchy`: Navigate and search through block parent-child relationships
40
+ 9. `find_pages_modified_today`: Find all pages that have been modified since midnight today
41
+ 10. `roam_search_by_text`: Search for blocks containing specific text across all pages or within a specific page
42
+ 11. `roam_update_block`: Update block content with direct text or pattern-based transformations
35
43
 
36
44
  ## Setup
37
45
 
@@ -158,6 +166,59 @@ Returns:
158
166
  }
159
167
  ```
160
168
 
169
+ ### Create Outline
170
+
171
+ Create a hierarchical outline with proper nesting and structure:
172
+
173
+ ```typescript
174
+ use_mcp_tool roam-research roam_create_outline {
175
+ "outline": [
176
+ {
177
+ "text": "I. Top Level",
178
+ "level": 1
179
+ },
180
+ {
181
+ "text": "A. Second Level",
182
+ "level": 2
183
+ },
184
+ {
185
+ "text": "1. Third Level",
186
+ "level": 3
187
+ }
188
+ ],
189
+ "page_title_uid": "optional-target-page",
190
+ "block_text_uid": "optional-header-text"
191
+ }
192
+ ```
193
+
194
+ Features:
195
+
196
+ - Create complex outlines with up to 10 levels of nesting
197
+ - Validate outline structure and content
198
+ - Maintain proper parent-child relationships
199
+ - Optional header block for the outline
200
+ - Defaults to today's daily page if no page specified
201
+ - Efficient batch operations for creating blocks
202
+
203
+ Parameters:
204
+
205
+ - `outline`: Array of outline items, each with:
206
+ - `text`: Content of the outline item (required)
207
+ - `level`: Nesting level (1-10, required)
208
+ - `page_title_uid`: Target page title or UID (optional, defaults to today's page)
209
+ - `block_text_uid`: Header text for the outline (optional)
210
+
211
+ Returns:
212
+
213
+ ```json
214
+ {
215
+ "success": true,
216
+ "page_uid": "target-page-uid",
217
+ "parent_uid": "header-block-uid",
218
+ "created_uids": ["uid1", "uid2", ...]
219
+ }
220
+ ```
221
+
161
222
  ### Add Todo Items
162
223
 
163
224
  Add one or more todo items to today's daily page:
@@ -224,6 +285,212 @@ Parameters:
224
285
  - `parent_string`: Exact string content of the parent block (must provide either page_uid or page_title)
225
286
  - `order`: Where to add the content ("first" or "last", defaults to "first")
226
287
 
288
+ ### Search Block References
289
+
290
+ Search for block references within pages or across the entire graph:
291
+
292
+ ```typescript
293
+ use_mcp_tool roam-research roam_search_block_refs {
294
+ "block_uid": "optional-block-uid",
295
+ "page_title_uid": "optional-page-title-or-uid"
296
+ }
297
+ ```
298
+
299
+ Features:
300
+
301
+ - Find all references to a specific block
302
+ - Search for any block references within a page
303
+ - Search across the entire graph
304
+ - Supports both direct and indirect references
305
+ - Includes block content and location context
306
+
307
+ Parameters:
308
+
309
+ - `block_uid`: UID of the block to find references to (optional)
310
+ - `page_title_uid`: Title or UID of the page to search in (optional)
311
+
312
+ Returns:
313
+
314
+ ```json
315
+ {
316
+ "success": true,
317
+ "matches": [
318
+ {
319
+ "block_uid": "referenced-block-uid",
320
+ "content": "Block content with ((reference))",
321
+ "page_title": "Page containing reference"
322
+ }
323
+ ],
324
+ "message": "Found N block(s) referencing..."
325
+ }
326
+ ```
327
+
328
+ ### Search By Text
329
+
330
+ Search for blocks containing specific text across all pages or within a specific page:
331
+
332
+ ```typescript
333
+ use_mcp_tool roam-research roam_search_by_text {
334
+ "text": "search text",
335
+ "page_title_uid": "optional-page-title-or-uid",
336
+ "case_sensitive": false
337
+ }
338
+ ```
339
+
340
+ Features:
341
+
342
+ - Search for any text across all blocks in the graph
343
+ - Optional page-scoped search
344
+ - Case-sensitive or case-insensitive search
345
+ - Returns block content with page context
346
+ - Efficient text matching using Datalog queries
347
+
348
+ Parameters:
349
+
350
+ - `text`: The text to search for (required)
351
+ - `page_title_uid`: Title or UID of the page to search in (optional)
352
+ - `case_sensitive`: Whether to perform a case-sensitive search (optional, default: false)
353
+
354
+ Returns:
355
+
356
+ ```json
357
+ {
358
+ "success": true,
359
+ "matches": [
360
+ {
361
+ "block_uid": "matching-block-uid",
362
+ "content": "Block content containing search text",
363
+ "page_title": "Page containing block"
364
+ }
365
+ ],
366
+ "message": "Found N block(s) containing \"search text\""
367
+ }
368
+ ```
369
+
370
+ ### Update Block Content
371
+
372
+ Update a block's content using either direct text replacement or pattern-based transformations:
373
+
374
+ ```typescript
375
+ use_mcp_tool roam-research roam_update_block {
376
+ "block_uid": "target-block-uid",
377
+ "content": "New block content"
378
+ }
379
+ ```
380
+
381
+ Or use pattern-based transformation:
382
+
383
+ ```typescript
384
+ use_mcp_tool roam-research roam_update_block {
385
+ "block_uid": "target-block-uid",
386
+ "transform_pattern": {
387
+ "find": "\\bPython\\b",
388
+ "replace": "[[Python]]",
389
+ "global": true
390
+ }
391
+ }
392
+ ```
393
+
394
+ Features:
395
+
396
+ - Two update modes:
397
+ - Direct content replacement
398
+ - Pattern-based transformation using regex
399
+ - Verify block existence before updating
400
+ - Return updated content in response
401
+ - Support for global or single-match replacements
402
+ - Preserve block relationships and metadata
403
+
404
+ Parameters:
405
+
406
+ - `block_uid`: UID of the block to update (required)
407
+ - `content`: New content for the block (if using direct replacement)
408
+ - `transform_pattern`: Pattern for transforming existing content:
409
+ - `find`: Text or regex pattern to find
410
+ - `replace`: Text to replace with
411
+ - `global`: Whether to replace all occurrences (default: true)
412
+
413
+ Returns:
414
+
415
+ ```json
416
+ {
417
+ "success": true,
418
+ "content": "Updated block content"
419
+ }
420
+ ```
421
+
422
+ ### Find Pages Modified Today
423
+
424
+ Find all pages that have been modified since midnight today:
425
+
426
+ ```typescript
427
+ use_mcp_tool roam-research find_pages_modified_today {}
428
+ ```
429
+
430
+ Features:
431
+
432
+ - Tracks all modifications made to pages since midnight
433
+ - Detects changes at any level in the block hierarchy
434
+ - Returns unique list of modified page titles
435
+ - Includes count of modified pages
436
+ - No parameters required
437
+
438
+ Returns:
439
+
440
+ ```json
441
+ {
442
+ "success": true,
443
+ "pages": ["Page 1", "Page 2"],
444
+ "message": "Found 2 page(s) modified today"
445
+ }
446
+ ```
447
+
448
+ ### Search Block Hierarchy
449
+
450
+ Navigate and search through block parent-child relationships:
451
+
452
+ ```typescript
453
+ use_mcp_tool roam-research roam_search_hierarchy {
454
+ "parent_uid": "optional-parent-block-uid",
455
+ "child_uid": "optional-child-block-uid",
456
+ "page_title_uid": "optional-page-title-or-uid",
457
+ "max_depth": 3
458
+ }
459
+ ```
460
+
461
+ Features:
462
+
463
+ - Search up or down the block hierarchy
464
+ - Find children of a specific block
465
+ - Find parents of a specific block
466
+ - Configure search depth (1-10 levels)
467
+ - Optional page scope filtering
468
+ - Includes depth information for each result
469
+
470
+ Parameters:
471
+
472
+ - `parent_uid`: UID of the block to find children of (required if searching down)
473
+ - `child_uid`: UID of the block to find parents of (required if searching up)
474
+ - `page_title_uid`: Title or UID of the page to search in (optional)
475
+ - `max_depth`: How many levels deep to search (optional, default: 1, max: 10)
476
+
477
+ Returns:
478
+
479
+ ```json
480
+ {
481
+ "success": true,
482
+ "matches": [
483
+ {
484
+ "block_uid": "related-block-uid",
485
+ "content": "Block content",
486
+ "depth": 2,
487
+ "page_title": "Page containing block"
488
+ }
489
+ ],
490
+ "message": "Found N block(s) as children/parents..."
491
+ }
492
+ ```
493
+
227
494
  ## Error Handling
228
495
 
229
496
  The server provides comprehensive error handling for common scenarios:
@@ -240,6 +507,7 @@ The server provides comprehensive error handling for common scenarios:
240
507
  - Block not found by string match
241
508
  - Invalid markdown format
242
509
  - Missing required parameters
510
+ - Invalid outline structure or content
243
511
 
244
512
  Each error response includes:
245
513
 
@@ -259,6 +527,7 @@ The server is built with TypeScript and includes:
259
527
  - Daily page integration
260
528
  - Detailed debug logging
261
529
  - Efficient batch operations
530
+ - Hierarchical outline creation
262
531
 
263
532
  To modify or extend the server:
264
533
 
@@ -0,0 +1,44 @@
1
+ import * as dotenv from 'dotenv';
2
+ import { dirname, join } from 'path';
3
+ import { existsSync } from 'fs';
4
+ // Get the project root from the script path
5
+ const scriptPath = process.argv[1]; // Full path to the running script
6
+ const projectRoot = dirname(dirname(scriptPath)); // Go up two levels from build/index.js
7
+ // Try to load .env from project root
8
+ const envPath = join(projectRoot, '.env');
9
+ if (existsSync(envPath)) {
10
+ dotenv.config({ path: envPath });
11
+ }
12
+ // Required environment variables
13
+ const API_TOKEN = process.env.ROAM_API_TOKEN;
14
+ const GRAPH_NAME = process.env.ROAM_GRAPH_NAME;
15
+ // Validate environment variables
16
+ if (!API_TOKEN || !GRAPH_NAME) {
17
+ const missingVars = [];
18
+ if (!API_TOKEN)
19
+ missingVars.push('ROAM_API_TOKEN');
20
+ if (!GRAPH_NAME)
21
+ missingVars.push('ROAM_GRAPH_NAME');
22
+ throw new Error(`Missing required environment variables: ${missingVars.join(', ')}\n\n` +
23
+ 'Please configure these variables either:\n' +
24
+ '1. In your MCP settings file:\n' +
25
+ ' - For Cline: ~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json\n' +
26
+ ' - For Claude: ~/Library/Application Support/Claude/claude_desktop_config.json\n\n' +
27
+ ' Example configuration:\n' +
28
+ ' {\n' +
29
+ ' "mcpServers": {\n' +
30
+ ' "roam-research": {\n' +
31
+ ' "command": "node",\n' +
32
+ ' "args": ["/path/to/roam-research/build/index.js"],\n' +
33
+ ' "env": {\n' +
34
+ ' "ROAM_API_TOKEN": "your-api-token",\n' +
35
+ ' "ROAM_GRAPH_NAME": "your-graph-name"\n' +
36
+ ' }\n' +
37
+ ' }\n' +
38
+ ' }\n' +
39
+ ' }\n\n' +
40
+ '2. Or in a .env file in the roam-research directory:\n' +
41
+ ' ROAM_API_TOKEN=your-api-token\n' +
42
+ ' ROAM_GRAPH_NAME=your-graph-name');
43
+ }
44
+ export { API_TOKEN, GRAPH_NAME };