Access and manage your Roam Research graph via its API.
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. It supports standard input/output (stdio), HTTP Stream, and Server-Sent Events (SSE) communication. (A WORK-IN-PROGRESS, personal project not officially endorsed by Roam Research)
This MCP server supports three primary communication methods:
8088
by default.8087
by default. (NOTE: ⚠️ DEPRECATED: The SSE Transport has been deprecated as of MCP specification version 2025-03-26. HTTP Stream Transport preferred.)You can install the package globally and run it:
npm install -g roam-research-mcp
roam-research-mcp
Or clone the repository and build from source:
git clone https://github.com/2b3pro/roam-research-mcp.git
cd roam-research-mcp
npm install
npm run build
npm start
To run the server with HTTP Stream or SSE support, you can either:
Use the default ports: Run npm start
after building (as shown above). The server will automatically listen on port 8088
for HTTP Stream and 8087
for SSE.
Specify custom ports: Set the HTTP_STREAM_PORT
and/or SSE_PORT
environment variables before starting the server.
HTTP_STREAM_PORT=9000 SSE_PORT=9001 npm start
Or, if using a .env
file, add HTTP_STREAM_PORT=9000
and/or SSE_PORT=9001
to it.
This project can be easily containerized using Docker. A Dockerfile
is provided at the root of the repository.
To build the Docker image, navigate to the project root and run:
docker build -t roam-research-mcp .
To run the Docker container and map the necessary ports, you must also provide the required environment variables. Use the -e
flag to pass ROAM_API_TOKEN
, ROAM_GRAPH_NAME
, and optionally MEMORIES_TAG
, HTTP_STREAM_PORT
, and SSE_PORT
:
docker run -p 3000:3000 -p 8088:8088 -p 8087:8087 \
-e ROAM_API_TOKEN="your-api-token" \
-e ROAM_GRAPH_NAME="your-graph-name" \
-e MEMORIES_TAG="#[[LLM/Memories]]" \
-e HTTP_STREAM_PORT="8088" \
-e SSE_PORT="8087" \
roam-research-mcp
Alternatively, if you have a .env
file in the project root (which is copied into the Docker image during build), you can use the --env-file
flag:
docker run -p 3000:3000 -p 8088:8088 --env-file .env roam-research-mcp
Run MCP Inspector after build using the provided npm script:
npm run inspector
The server provides powerful tools for interacting with Roam Research:
Roam_Markdown_Cheatsheet.md
for clearer guidance on nesting.roam_fetch_page_by_title
: Fetch page content by title. Returns content in the specified format.roam_create_page
: Create new pages with optional content and headings.roam_import_markdown
: Import nested markdown content under a specific block. (Internally uses roam_process_batch_actions
.)roam_add_todo
: Add a list of todo items to today's daily page. (Internally uses roam_process_batch_actions
.)roam_create_outline
: Add a structured outline to an existing page or block, with support for children_view_type
. Best for simpler, sequential outlines. For complex nesting (e.g., tables), consider roam_process_batch_actions
. If page_title_uid
and block_text_uid
are both blank, content defaults to the daily page. (Internally uses roam_process_batch_actions
.)roam_search_block_refs
: Search for block references within a page or across the entire graph.roam_search_hierarchy
: Search for parent or child blocks in the block hierarchy.roam_find_pages_modified_today
: Find pages that have been modified today (since midnight).roam_search_by_text
: Search for blocks containing specific text.roam_search_by_status
: Search for blocks with a specific status (TODO/DONE) across all pages or within a specific page.roam_search_by_date
: Search for blocks or pages based on creation or modification dates.roam_search_for_tag
: Search for blocks containing a specific tag and optionally filter by blocks that also contain another tag nearby.roam_remember
: Add a memory or piece of information to remember. (Internally uses roam_process_batch_actions
.)roam_recall
: Retrieve all stored memories.roam_datomic_query
: Execute a custom Datomic query on the Roam graph for advanced data retrieval beyond the available search tools.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. (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
.)Deprecated Tools:
The following tools have been deprecated as of v.0.30.0
in favor of the more powerful and flexible roam_process_batch_actions
:
roam_create_block
: Use roam_process_batch_actions
with the create-block
action.roam_update_block
: Use roam_process_batch_actions
with the update-block
action.roam_update_multiple_blocks
: Use roam_process_batch_actions
with multiple update-block
actions.Pre-computation and Context Loading:
✅ Before attempting any Roam operations, it is highly recommended to load the Roam Markdown Cheatsheet
resource into your context. This ensures you have immediate access to the correct Roam-flavored Markdown syntax, including details for tables, block references, and other special formatting. Example prompt: "Read the Roam cheatsheet first. Then, … "
Identifying Pages and Blocks for Manipulation: To ensure accurate operations, always strive to identify target pages and blocks using their Unique Identifiers (UIDs) whenever possible. While some tools accept case-sensitive text titles or content, UIDs provide unambiguous references, reducing the risk of errors due to ambiguity or changes in text.
roam_fetch_page_by_title
to retrieve a page's UID if you only have its title. Example: "Read the page titled 'Trip to Las Vegas'"roam_search_by_text
, roam_search_for_tag
, or roam_fetch_page_by_title
(with raw format) to find the block and obtain its UID. If the block exists on a page that has already been read, then a search isn't necessary.Case-Sensitivity: Be aware that text-based inputs (e.g., page titles, block content for search) are generally case-sensitive in Roam. Always match the exact casing of the text as it appears in your graph.
Iterative Refinement and Verification: For complex operations, especially those involving nested structures or multiple changes, it is often beneficial to break down the task into smaller, verifiable steps. After each significant tool call, consider fetching the affected content to verify the changes before proceeding.
Understanding Tool Nuances:
Familiarize yourself with the specific behaviors and limitations of each tool. For instance, roam_create_outline
is best for sequential outlines, while roam_process_batch_actions
offers granular control for complex structures like tables. Refer to the individual tool descriptions for detailed usage notes.
When making changes to your Roam graph, precision in your requests is crucial for achieving desired outcomes.
Specificity in Requests:
Some tools allow for identifying blocks or pages by their text content (e.g., parent_string
, title
). While convenient, using Unique Identifiers (UIDs) is always preferred for accuracy and reliability. Text-based matching can be prone to errors if there are multiple blocks with similar content or if the content changes. Tools are designed to work best when provided with explicit UIDs where available.
Example of Specificity:
Instead of:
"parent_string": "My project notes"
Prefer:
"parent_uid": "((some-unique-uid))"
Caveat Regarding Heading Formatting:
Please note that while the roam_process_batch_actions
tool can set block headings (H1, H2, H3), directly removing an existing heading (i.e., reverting a heading block to a plain text block) through this tool is not currently supported by the Roam API. The heading
attribute persists its value once set, and attempting to remove it by setting heading
to 0
, null
, or omitting the property will not unset the heading.
Here are some examples of how to creatively use the Roam tool in an LLM to interact with your Roam graph, particularly leveraging roam_process_batch_actions
for complex operations.
This prompt demonstrates creating a new page and populating it with a structured outline using a single roam_process_batch_actions
call.
"Create a new Roam page titled 'Project Alpha Planning' and add the following outline:
- Overview
- Goals
- Scope
- Team Members
- John Doe
- Jane Smith
- Tasks
- Task 1
- Subtask 1.1
- Subtask 1.2
- Task 2
- Deadlines"
This example shows how to mark existing to-do items as DONE
and add a new one, all within a single batch.
"Mark 'Finish report' and 'Review presentation' as done on today's daily page, and add a new todo 'Prepare for meeting'."
This demonstrates moving a block from one location to another and simultaneously updating its content.
"Move the block 'Important note about client feedback' (from page 'Meeting Notes 2025-06-30') under the 'Action Items' section on the 'Project Alpha Planning' page, and change its content to 'Client feedback reviewed and incorporated'."
This demonstrates moving a block from one location to another and simultaneously updating its content.
"In Roam, add a new table on the page "Fruity Tables" that compares four types of fruits: apples, oranges, grapes, and dates. Choose randomly four areas to compare."
Create a Roam Research API token:
Configure the environment variables: You have two options for configuring the required environment variables:
Option 1: Using a .env file (Recommended for development)
Create a .env
file in the roam-research directory:
ROAM_API_TOKEN=your-api-token
ROAM_GRAPH_NAME=your-graph-name
MEMORIES_TAG='#[[LLM/Memories]]'
HTTP_STREAM_PORT=8088 # Or your desired port for HTTP Stream communication
SSE_PORT=8087 # Or your desired port for SSE communication
Option 2: Using MCP settings (Alternative method)
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.
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
):~/Library/Application Support/Claude/claude_desktop_config.json
):{
"mcpServers": {
"roam-research": {
"command": "node",
"args": ["/path/to/roam-research-mcp/build/index.js"],
"env": {
"ROAM_API_TOKEN": "your-api-token",
"ROAM_GRAPH_NAME": "your-graph-name",
"MEMORIES_TAG": "#[[LLM/Memories]]",
"HTTP_STREAM_PORT": "8088",
"SSE_PORT": "8087"
}
}
}
}
Note: The server will first try to load from .env file, then fall back to environment variables from MCP settings.
Build the server (make sure you're in the root directory of the MCP):
Note: Customize 'Roam_Markdown_Cheatsheet.md' with any notes and preferences specific to your graph BEFORE building.
cd roam-research-mcp
npm install
npm run build
The server provides comprehensive error handling for common scenarios:
Each error response includes:
To build the server:
npm install
npm run build
This will:
You can also use npm run watch
during development to automatically recompile when files change.
The MCP Inspector is a tool that helps test and debug MCP servers. To test the server:
# Inspect with npx:
npx @modelcontextprotocol/inspector node build/index.js
This will:
MIT License
Manage Zendesk tickets and comments, analyze tickets, draft responses, and access Help Center articles as a knowledge base.
Talk with your Apple Notes
Breaks down complex tasks into manageable pieces and stores them in structured JSON.
Access and manage Apple Notes on macOS via AppleScript.
Simple unofficial MCP server to track time via Toggl API
Interact with Quire.io projects and tasks using the Quire API, enabling AI assistants to manage your workflow.
Provides workflow validation and best practices tools for the n8n automation platform.
Manages AI agent handoffs with structured documentation and seamless task transitions.
Read, create, update and delete Google Keep notes.
An MCP extension for the Claude Desktop application that enables automation and integration.