roam research mcp
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.
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.
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. (A WORK-IN-PROGRESS, personal project not officially endorsed by Roam Research)
You can install the package globally:
npm install -g 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
The server provides powerful tools for interacting with Roam Research:
Hierarchical outline creation
roam_fetch_page_by_title
: Fetch and read a page's content by title, recursively resolving block references up to 4 levels deep
roam_create_page
: Create new pages with optional contentroam_create_block
: Create new blocks in a page (defaults to today's daily page)roam_import_markdown
: Import nested markdown content under specific blocksroam_add_todo
: Add multiple todo items to today's daily page with checkbox syntaxroam_create_outline
: Create hierarchical outlines with proper nesting and structureroam_search_block_refs
: Search for block references within pages or across the graphroam_search_hierarchy
: Navigate and search through block parent-child relationshipsroam_find_pages_modified_today
: Find all pages that have been modified since midnight todayroam_search_by_text
: Search for blocks containing specific text across all pages or within a specific pageroam_update_block
: Update block content with direct text or pattern-based transformationsroam_search_by_date
: Search for blocks and pages based on creation or modification datesroam_search_for_tag
: Search for blocks containing specific tags with optional filtering by nearby tagsroam_remember
: Store and categorize memories or information with automatic taggingroam_recall
: Recall memories of blocks marked with tag MEMORIES_TAG (see below) or blocks on page title of the same nameroam_datomic_query
: Execute custom Datalog queries on the Roam graph for advanced data retrieval and analysisCreate a Roam Research API token:
Go to your graph settings
Create a new 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]]'
Option 2: Using MCP settings (Alternative method) Add the configuration to your MCP settings file:
~/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]]"
}
}
}
}
Note: The server will first try to load from .env file, then fall back to environment variables from MCP settings.
cd roam-research-mcp
npm install
npm run build
Fetch and read a page's content with resolved block references:
use_mcp_tool roam-research roam_fetch_page_by_title {
"title": "Example Page"
}
Returns the page content as markdown with:
Create a new page with optional content:
use_mcp_tool roam-research roam_create_page {
"title": "New Page",
"content": "Initial content for the page"
}
Returns the created page's UID on success.
Add a new block to a page (defaults to today's daily page if neither page_uid nor title provided):
use_mcp_tool roam-research roam_create_block {
"content": "Block content",
"page_uid": "optional-target-page-uid",
"title": "optional-target-page-title"
}
You can specify either:
page_uid
: Direct reference to target pagetitle
: Name of target page (will be created if it doesn't exist)Returns:
{
"success": true,
"block_uid": "created-block-uid",
"parent_uid": "parent-page-uid"
}
Create a hierarchical outline with proper nesting and structure:
use_mcp_tool roam-research roam_create_outline {
"outline": [
{
"text": "I. Top Level",
"level": 1
},
{
"text": "A. Second Level",
"level": 2
},
{
"text": "1. Third Level",
"level": 3
}
],
"page_title_uid": "optional-target-page",
"block_text_uid": "optional-header-text"
}
Features:
Parameters:
outline
: Array of outline items, each with:text
: Content of the outline item (required)level
: Nesting level (1-10, required)page_title_uid
: Target page title or UID (optional, defaults to today's page)block_text_uid
: Header text for the outline (optional)Returns:
{
"success": true,
"page_uid": "target-page-uid",
"parent_uid": "header-block-uid",
"created_uids": ["uid1", "uid2", ...]
}
Add one or more todo items to today's daily page:
use_mcp_tool roam-research roam_add_todo {
"todos": [
"First todo item",
"Second todo item",
"Third todo item"
]
}
Features:
{{TODO}} todo text
)Import nested markdown content under a specific block:
use_mcp_tool roam-research roam_import_markdown {
"content": "- Item 1
- Subitem A
- Subitem B
- Item 2",
"page_uid": "optional-page-uid",
"page_title": "optional-page-title",
"parent_uid": "optional-parent-block-uid",
"parent_string": "optional-exact-block-content",
"order": "first"
}
Features:
{
"success": true,
"page_uid": "target-page-uid",
"parent_uid": "parent-block-uid",
"created_uids": ["uid1", "uid2", ...]
}
Parameters:
content
: Nested markdown content to importpage_uid
: UID of the page containing the parent blockpage_title
: Title of the page containing the parent block (ignored if page_uid provided)parent_uid
: UID of the parent block to add content underparent_string
: Exact string content of the parent block (must provide either page_uid or page_title)order
: Where to add the content ("first" or "last", defaults to "first")Search for block references within pages or across the entire graph:
use_mcp_tool roam-research roam_search_block_refs {
"block_uid": "optional-block-uid",
"page_title_uid": "optional-page-title-or-uid"
}
Features:
Parameters:
block_uid
: UID of the block to find references to (optional)page_title_uid
: Title or UID of the page to search in (optional)Returns:
{
"success": true,
"matches": [
{
"block_uid": "referenced-block-uid",
"content": "Block content with ((reference))",
"page_title": "Page containing reference"
}
],
"message": "Found N block(s) referencing..."
}
Search for blocks containing specific text across all pages or within a specific page:
use_mcp_tool roam-research roam_search_by_text {
"text": "search text",
"page_title_uid": "optional-page-title-or-uid",
"case_sensitive": true
}
Features:
Parameters:
text
: The text to search for (required)page_title_uid
: Title or UID of the page to search in (optional)case_sensitive
: Whether to perform a case-sensitive search (optional, default: true to match Roam's native behavior)Returns:
{
"success": true,
"matches": [
{
"block_uid": "matching-block-uid",
"content": "Block content containing search text",
"page_title": "Page containing block"
}
],
"message": "Found N block(s) containing "search text""
}
Update a block's content using either direct text replacement or pattern-based transformations:
use_mcp_tool roam-research roam_update_block {
"block_uid": "target-block-uid",
"content": "New block content"
}
Or use pattern-based transformation:
use_mcp_tool roam-research roam_update_block {
"block_uid": "target-block-uid",
"transform_pattern": {
"find": "bPythonb",
"replace": "[[Python]]",
"global": true
}
}
Features:
Parameters:
block_uid
: UID of the block to update (required)content
: New content for the block (if using direct replacement)transform_pattern
: Pattern for transforming existing content:find
: Text or regex pattern to findreplace
: Text to replace withglobal
: Whether to replace all occurrences (default: true)Returns:
{
"success": true,
"content": "Updated block content"
}
Search for blocks containing specific tags with optional filtering by nearby tags:
use_mcp_tool roam-research roam_search_for_tag {
"primary_tag": "Project/Tasks",
"page_title_uid": "optional-page-title-or-uid",
"near_tag": "optional-secondary-tag",
"case_sensitive": true
}
Features:
Parameters:
primary_tag
: The main tag to search for (required)page_title_uid
: Title or UID of the page to search in (optional)near_tag
: Another tag to filter results by (optional)case_sensitive
: Whether to perform case-sensitive search (optional, default: true to match Roam's native behavior)Returns:
{
"success": true,
"matches": [
{
"block_uid": "matching-block-uid",
"content": "Block content containing #[[primary_tag]]",
"page_title": "Page containing block"
}
],
"message": "Found N block(s) referencing "primary_tag""
}
Store memories or important information with automatic tagging and categorization:
use_mcp_tool roam-research roam_remember {
"memory": "Important information to remember",
"categories": ["Work", "Project/Alpha"]
}
Features:
Parameters:
memory
: The information to remember (required)categories
: Optional array of categories to tag the memory withReturns:
{
"success": true,
"block_uid": "created-block-uid",
"content": "Memory content with tags"
}
Search for blocks and pages based on creation or modification dates:
use_mcp_tool roam-research roam_search_by_date {
"start_date": "2025-01-01",
"end_date": "2025-01-31",
"type": "modified",
"scope": "blocks",
"include_content": true
}
Features:
Parameters:
start_date
: Start date in ISO format (YYYY-MM-DD) (required)end_date
: End date in ISO format (YYYY-MM-DD) (optional)type
: Whether to search by 'created', 'modified', or 'both' (required)scope
: Whether to search 'blocks', 'pages', or 'both' (required)include_content
: Whether to include the content of matching blocks/pages (optional, default: true)Returns:
{
"success": true,
"matches": [
{
"uid": "block-or-page-uid",
"type": "block",
"time": 1704067200000,
"content": "Block or page content",
"page_title": "Page title (for blocks)"
}
],
"message": "Found N matches for the given date range and criteria"
}
Find all pages that have been modified since midnight today:
use_mcp_tool roam-research roam_find_pages_modified_today {}
Features:
Returns:
{
"success": true,
"pages": ["Page 1", "Page 2"],
"message": "Found 2 page(s) modified today"
}
Execute custom Datalog queries on your Roam graph for advanced data retrieval and analysis:
use_mcp_tool roam-research roam_datomic_query {
"query": "[:find (count ?p)
:where [?p :node/title]]",
"inputs": []
}
Features:
Parameters:
query
: The Datalog query to execute (required)inputs
: Optional array of input parameters for the queryReturns:
{
"success": true,
"matches": [
{
"content": "[result data]",
"block_uid": "",
"page_title": ""
}
],
"message": "Query executed successfully. Found N results."
}
Example Queries:
[:find (count ?p)
:where [?p :node/title]]
[:find ?string ?title
:where
[?b :block/string ?string]
[(clojure.string/lower-case ?string) ?lower]
[(clojure.string/includes? ?lower "search term")]
[?b :block/page ?p]
[?p :node/title ?title]]
[:find ?block_ref ?string
:in $ ?start_of_day
:where
[?b :edit/time ?time]
[(> ?time ?start_of_day)]
[?b :block/uid ?block_ref]
[?b :block/string ?string]]
See Roam_Research_Datalog_Cheatsheet.md for more query examples and syntax documentation.
Navigate and search through block parent-child relationships:
use_mcp_tool roam-research roam_search_hierarchy {
"parent_uid": "optional-parent-block-uid",
"child_uid": "optional-child-block-uid",
"page_title_uid": "optional-page-title-or-uid",
"max_depth": 3
}
Features:
Parameters:
parent_uid
: UID of the block to find children of (required if searching down)child_uid
: UID of the block to find parents of (required if searching up)page_title_uid
: Title or UID of the page to search in (optional)max_depth
: How many levels deep to search (optional, default: 1, max: 10)Returns:
{
"success": true,
"matches": [
{
"block_uid": "related-block-uid",
"content": "Block content",
"depth": 2,
"page_title": "Page containing block"
}
],
"message": "Found N block(s) as children/parents..."
}
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
[
{
"description": "Add a list of todo items as individual blocks to today's daily page in Roam. Each item becomes its own actionable block with todo status.nNOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use [alias]([[link]]) syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).",
"inputSchema": {
"properties": {
"todos": {
"description": "List of todo items to add",
"items": {
"description": "Todo item text",
"type": "string"
},
"type": "array"
}
},
"required": [
"todos"
],
"type": "object"
},
"name": "roam_add_todo"
},
{
"description": "Retrieve complete page contents by exact title, including all nested blocks and resolved block references. Use for accessing daily pages, reading and analyzing existing Roam pages.",
"inputSchema": {
"properties": {
"title": {
"description": "Title of the page. For date pages, use ordinal date formats such as January 2nd, 2025",
"type": "string"
}
},
"required": [
"title"
],
"type": "object"
},
"name": "roam_fetch_page_by_title"
},
{
"description": "Create a new standalone page in Roam with optional content using explicit nesting levels. Best for:n- Creating foundational concept pages that other pages will link to/fromn- Establishing new topic areas that need their own namespacen- Setting up reference materials or documentationn- Making permanent collections of information.",
"inputSchema": {
"properties": {
"content": {
"description": "Initial content for the page as an array of blocks with explicit nesting levels",
"items": {
"properties": {
"level": {
"description": "Indentation level (1-10, where 1 is top level)",
"maximum": 10,
"minimum": 1,
"type": "integer"
},
"text": {
"description": "Content of the block",
"type": "string"
}
},
"required": [
"text",
"level"
],
"type": "object"
},
"type": "array"
},
"title": {
"description": "Title of the new page",
"type": "string"
}
},
"required": [
"title"
],
"type": "object"
},
"name": "roam_create_page"
},
{
"description": "Add a new block to an existing Roam page. If no page specified, adds to today's daily note. Best for capturing immediate thoughts, additions to discussions, or content that doesn't warrant its own page. Can specify page by title or UID.nNOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use [alias]([[link]]) syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).",
"inputSchema": {
"properties": {
"content": {
"description": "Content of the block",
"type": "string"
},
"page_uid": {
"description": "Optional: UID of the page to add block to",
"type": "string"
},
"title": {
"description": "Optional: Title of the page to add block to (defaults to today's date if neither page_uid nor title provided)",
"type": "string"
}
},
"required": [
"content"
],
"type": "object"
},
"name": "roam_create_block"
},
{
"description": "Add a structured outline to an existing page or block (by title text or uid), with customizable nesting levels. Best for:n- Adding supplementary structured content to existing pagesn- Creating temporary or working outlines (meeting notes, brainstorms)n- Organizing thoughts or research under a specific topicn- Breaking down subtopics or components of a larger concept",
"inputSchema": {
"properties": {
"block_text_uid": {
"description": "A relevant title heading for the outline (or UID, if known) of the block under which outline content will be nested. If blank, content will be nested under the page title.",
"type": "string"
},
"outline": {
"description": "Array of outline items with block text and explicit nesting level",
"items": {
"properties": {
"level": {
"description": "Indentation level (1-10, where 1 is top level)",
"maximum": 10,
"minimum": 1,
"type": "integer"
},
"text": {
"description": "Content of the block",
"type": "string"
}
},
"required": [
"text",
"level"
],
"type": "object"
},
"type": "array"
},
"page_title_uid": {
"description": "Title (or UID if known) of the page. Leave blank to use the default daily page",
"type": "string"
}
},
"required": [
"outline"
],
"type": "object"
},
"name": "roam_create_outline"
},
{
"description": "Import nested markdown content into Roam under a specific block. Can locate the parent block by UID or by exact string match within a specific page.",
"inputSchema": {
"properties": {
"content": {
"description": "Nested markdown content to import",
"type": "string"
},
"order": {
"default": "first",
"description": "Optional: Where to add the content under the parent ("first" or "last")",
"enum": [
"first",
"last"
],
"type": "string"
},
"page_title": {
"description": "Optional: Title of the page containing the parent block (ignored if page_uid provided)",
"type": "string"
},
"page_uid": {
"description": "Optional: UID of the page containing the parent block",
"type": "string"
},
"parent_string": {
"description": "Optional: Exact string content of the parent block to add content under (must provide either page_uid or page_title)",
"type": "string"
},
"parent_uid": {
"description": "Optional: UID of the parent block to add content under",
"type": "string"
}
},
"required": [
"content"
],
"type": "object"
},
"name": "roam_import_markdown"
},
{
"description": "Search for blocks containing a specific tag and optionally filter by blocks that also contain another tag nearby. Example: Use this to search for memories that are tagged with the MEMORIES_TAG.",
"inputSchema": {
"properties": {
"near_tag": {
"description": "Optional: Another tag to filter results by - will only return blocks where both tags appear",
"type": "string"
},
"page_title_uid": {
"description": "Optional: Title or UID of the page to search in. Defaults to today's daily page if not provided",
"type": "string"
},
"primary_tag": {
"description": "The main tag to search for (without the [[ ]] brackets)",
"type": "string"
}
},
"required": [
"primary_tag"
],
"type": "object"
},
"name": "roam_search_for_tag"
},
{
"description": "Search for blocks with a specific status (TODO/DONE) across all pages or within a specific page.",
"inputSchema": {
"properties": {
"exclude": {
"description": "Optional: Comma-separated list of terms to filter results by exclusion (matches content or page title)",
"type": "string"
},
"include": {
"description": "Optional: Comma-separated list of terms to filter results by inclusion (matches content or page title)",
"type": "string"
},
"page_title_uid": {
"description": "Optional: Title or UID of the page to search in. If not provided, searches across all pages",
"type": "string"
},
"status": {
"description": "Status to search for (TODO or DONE)",
"enum": [
"TODO",
"DONE"
],
"type": "string"
}
},
"required": [
"status"
],
"type": "object"
},
"name": "roam_search_by_status"
},
{
"description": "Search for block references within a page or across the entire graph. Can search for references to a specific block or find all block references.",
"inputSchema": {
"properties": {
"block_uid": {
"description": "Optional: UID of the block to find references to",
"type": "string"
},
"page_title_uid": {
"description": "Optional: Title or UID of the page to search in. If not provided, searches across all pages",
"type": "string"
}
},
"type": "object"
},
"name": "roam_search_block_refs"
},
{
"description": "Search for parent or child blocks in the block hierarchy. Can search up or down the hierarchy from a given block.",
"inputSchema": {
"oneOf": [
{
"required": [
"parent_uid"
]
},
{
"required": [
"child_uid"
]
}
],
"properties": {
"child_uid": {
"description": "Optional: UID of the block to find parents of",
"type": "string"
},
"max_depth": {
"description": "Optional: How many levels deep to search (default: 1)",
"maximum": 10,
"minimum": 1,
"type": "integer"
},
"page_title_uid": {
"description": "Optional: Title or UID of the page to search in",
"type": "string"
},
"parent_uid": {
"description": "Optional: UID of the block to find children of",
"type": "string"
}
},
"type": "object"
},
"name": "roam_search_hierarchy"
},
{
"description": "Find pages that have been modified today (since midnight), with limit.",
"inputSchema": {
"properties": {
"max_num_pages": {
"default": 50,
"description": "Max number of pages to retrieve (default: 50)",
"type": "integer"
}
},
"type": "object"
},
"name": "roam_find_pages_modified_today"
},
{
"description": "Search for blocks containing specific text across all pages or within a specific page.",
"inputSchema": {
"properties": {
"page_title_uid": {
"description": "Optional: Title or UID of the page to search in. If not provided, searches across all pages",
"type": "string"
},
"text": {
"description": "The text to search for",
"type": "string"
}
},
"required": [
"text"
],
"type": "object"
},
"name": "roam_search_by_text"
},
{
"description": "Update a single block identified by its UID. Use this for individual block updates when you need to either replace the entire content or apply a transform pattern to modify specific parts of the content.nNOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use [alias]([[link]]) syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).",
"inputSchema": {
"oneOf": [
{
"required": [
"content"
]
},
{
"required": [
"transform_pattern"
]
}
],
"properties": {
"block_uid": {
"description": "UID of the block to update",
"type": "string"
},
"content": {
"description": "New content for the block. If not provided, transform_pattern will be used.",
"type": "string"
},
"transform_pattern": {
"description": "Pattern to transform the current content. Used if content is not provided.",
"properties": {
"find": {
"description": "Text or regex pattern to find",
"type": "string"
},
"global": {
"default": true,
"description": "Whether to replace all occurrences",
"type": "boolean"
},
"replace": {
"description": "Text to replace with",
"type": "string"
}
},
"required": [
"find",
"replace"
],
"type": "object"
}
},
"required": [
"block_uid"
],
"type": "object"
},
"name": "roam_update_block"
},
{
"description": "Efficiently update multiple blocks in a single batch operation. Use this when you need to update several blocks at once to avoid making multiple separate API calls. Each block in the batch can independently either have its content replaced or transformed using a pattern.nNOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use [alias]([[link]]) syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).",
"inputSchema": {
"properties": {
"updates": {
"description": "Array of block updates to perform",
"items": {
"oneOf": [
{
"required": [
"content"
]
},
{
"required": [
"transform"
]
}
],
"properties": {
"block_uid": {
"description": "UID of the block to update",
"type": "string"
},
"content": {
"description": "New content for the block. If not provided, transform will be used.",
"type": "string"
},
"transform": {
"description": "Pattern to transform the current content. Used if content is not provided.",
"properties": {
"find": {
"description": "Text or regex pattern to find",
"type": "string"
},
"global": {
"default": true,
"description": "Whether to replace all occurrences",
"type": "boolean"
},
"replace": {
"description": "Text to replace with",
"type": "string"
}
},
"required": [
"find",
"replace"
],
"type": "object"
}
},
"required": [
"block_uid"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"updates"
],
"type": "object"
},
"name": "roam_update_multiple_blocks"
},
{
"description": "Search for blocks or pages based on creation or modification dates. Not for daily pages with ordinal date titles.",
"inputSchema": {
"properties": {
"end_date": {
"description": "Optional: End date in ISO format (YYYY-MM-DD)",
"type": "string"
},
"include_content": {
"default": true,
"description": "Whether to include the content of matching blocks/pages",
"type": "boolean"
},
"scope": {
"description": "Whether to search blocks, pages, or both",
"enum": [
"blocks",
"pages",
"both"
],
"type": "string"
},
"start_date": {
"description": "Start date in ISO format (YYYY-MM-DD)",
"type": "string"
},
"type": {
"description": "Whether to search by creation date, modification date, or both",
"enum": [
"created",
"modified",
"both"
],
"type": "string"
}
},
"required": [
"start_date",
"type",
"scope"
],
"type": "object"
},
"name": "roam_search_by_date"
},
{
"description": "Add a memory or piece of information to remember, stored on the daily page with MEMORIES_TAG tag and optional categories. nNOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use [alias]([[link]]) syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).",
"inputSchema": {
"properties": {
"categories": {
"description": "Optional categories to tag the memory with (will be converted to Roam tags)",
"items": {
"type": "string"
},
"type": "array"
},
"memory": {
"description": "The memory detail or information to remember",
"type": "string"
}
},
"required": [
"memory"
],
"type": "object"
},
"name": "roam_remember"
},
{
"description": "Retrieve all stored memories on page titled MEMORIES_TAG, or tagged block content with the same name. Returns a combined, deduplicated list of memories. Optionally filter blcoks with a specified tag and sort by creation date.",
"inputSchema": {
"properties": {
"filter_tag": {
"description": "Include only memories with a specific filter tag. For single word tags use format "tag", for multi-word tags use format "tag word" (without brackets)",
"type": "string"
},
"sort_by": {
"default": "newest",
"description": "Sort order for memories based on creation date",
"enum": [
"newest",
"oldest"
],
"type": "string"
}
},
"type": "object"
},
"name": "roam_recall"
},
{
"description": "Execute a custom Datomic query on the Roam graph beyond the available search tools. This provides direct access to Roam's query engine for advanced data retrieval. Note: Roam graph is case-sensitive.nList of some of Roam's data model Namespaces and Attributes: ancestor (descendants), attrs (lookup), block (children, heading, open, order, page, parents, props, refs, string, text-align, uid), children (view-type), create (email, time), descendant (ancestors), edit (email, seen-by, time), entity (attrs), log (id), node (title), page (uid, title), refs (text).nPredicates (clojure.string/includes?, clojure.string/starts-with?, clojure.string/ends-with?, <, >, <=, >=, =, not=, !=).nAggregates (distinct, count, sum, max, min, avg, limit).nTips: Use :block/parents for all ancestor levels, :block/children for direct descendants only; combine clojure.string for complex matching, use distinct to deduplicate, leverage Pull patterns for hierarchies, handle case-sensitivity carefully, and chain ancestry rules for multi-level queries.",
"inputSchema": {
"properties": {
"inputs": {
"description": "Optional array of input parameters for the query",
"items": {
"type": "string"
},
"type": "array"
},
"query": {
"description": "The Datomic query to execute (in Datalog syntax)",
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
},
"name": "roam_datomic_query"
}
]