Roam Research
Roam Research MCP 서버
Roam Research의 API 기능에 대한 포괄적인 접근을 제공하는 모델 컨텍스트 프로토콜(MCP) 서버입니다. 이 서버를 통해 Claude와 같은 AI 비서가 표준화된 인터페이스를 통해 Roam Research 그래프와 상호 작용할 수 있습니다. (현재 진행 중인 개인 프로젝트이며 Roam Research의 공식 승인을 받지 않았습니다.)
설치
패키지를 글로벌하게 설치할 수 있습니다:
지엑스피1
또는 저장소를 복제하고 소스에서 빌드합니다.
git clone https://github.com/2b3pro/roam-research-mcp.git
cd roam-research-mcp
npm install
npm run buildRelated MCP server: Roam Research MCP Server
테스트하려면
빌드 후 MCP Inspector를 실행합니다.
npx @modelcontextprotocol/inspector node build/index.js특징
이 서버는 Roam Research와 상호 작용하기 위한 강력한 도구를 제공합니다.
.env 지원을 통한 환경 변수 처리
포괄적인 입력 검증
대소문자 구분 없이 페이지 제목 일치
재귀적 블록 참조 해결
마크다운 구문 분석 및 변환
일일 페이지 통합
자세한 디버그 로깅
효율적인 배치 작업
계층적 개요 생성
roam_fetch_page_by_title: 제목별로 페이지의 콘텐츠를 가져와서 읽고, 최대 4단계 깊이까지 블록 참조를 재귀적으로 확인합니다.roam_create_page: 선택적 콘텐츠로 새 페이지를 만듭니다.roam_create_block: 페이지에 새로운 블록을 생성합니다(기본값은 오늘의 일일 페이지입니다)roam_import_markdown: 특정 블록 아래에 중첩된 마크다운 콘텐츠를 가져옵니다.roam_add_todo: 체크박스 구문을 사용하여 오늘의 일일 페이지에 여러 개의 할 일 항목을 추가합니다.roam_create_outline: 적절한 중첩 및 구조를 사용하여 계층적 개요를 만듭니다.roam_search_block_refs: 페이지 내 또는 그래프 전체에서 블록 참조를 검색합니다.roam_search_hierarchy: 블록 부모-자식 관계를 탐색하고 검색합니다.roam_find_pages_modified_today: 오늘 자정 이후 수정된 모든 페이지를 찾습니다.roam_search_by_text: 모든 페이지 또는 특정 페이지 내에서 특정 텍스트가 포함된 블록을 검색합니다.roam_update_block: 직접 텍스트 또는 패턴 기반 변환으로 블록 콘텐츠 업데이트roam_search_by_date: 생성 또는 수정 날짜를 기준으로 블록 및 페이지 검색roam_search_for_tag: 근처 태그로 선택적으로 필터링하여 특정 태그가 포함된 블록을 검색합니다.roam_remember: 자동 태그 지정으로 기억이나 정보를 저장하고 분류합니다.roam_recall: MEMORIES_TAG 태그로 표시된 블록(아래 참조) 또는 같은 이름의 페이지 제목에 있는 블록의 메모리를 회수합니다.roam_datomic_query: 고급 데이터 검색 및 분석을 위해 Roam 그래프에서 사용자 정의 Datalog 쿼리를 실행합니다.
설정
Roam Research API 토큰을 생성하세요:
그래프 설정으로 이동하세요
"API 토큰" 섹션으로 이동합니다(설정 > "그래프" 탭 > "API 토큰" 섹션을 클릭하고 "+ 새 API 토큰" 버튼을 클릭합니다)
새로운 토큰을 생성하세요
환경 변수 구성: 필요한 환경 변수를 구성하는 데는 두 가지 옵션이 있습니다.
옵션 1: .env 파일 사용(개발에 권장) roam-research 디렉터리에
.env파일을 만듭니다.ROAM_API_TOKEN=your-api-token ROAM_GRAPH_NAME=your-graph-name MEMORIES_TAG='#[[LLM/Memories]]'옵션 2: MCP 설정 사용(대체 방법) MCP 설정 파일에 구성을 추가합니다.
Cline의 경우(
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json):Claude 데스크톱 앱(
~/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]]" } } } }참고: 서버는 먼저 .env 파일에서 로드를 시도한 다음 MCP 설정의 환경 변수를 사용합니다.
서버를 빌드합니다(MCP의 루트 디렉토리에 있는지 확인하세요):
cd roam-research-mcp npm install npm run build
용법
제목으로 페이지 가져오기
해결된 블록 참조로 페이지의 콘텐츠를 가져와서 읽습니다.
use_mcp_tool roam-research roam_fetch_page_by_title {
"title": "Example Page"
}다음을 사용하여 페이지 내용을 마크다운으로 반환합니다.
완전한 계층 구조
블록 참조는 재귀적으로 해결됨(최대 4단계 깊이)
중첩 수준에 대한 적절한 들여쓰기
전체 마크다운 서식
페이지 만들기
선택적인 콘텐츠로 새 페이지를 만드세요:
use_mcp_tool roam-research roam_create_page {
"title": "New Page",
"content": "Initial content for the page"
}성공시 생성된 페이지의 UID를 반환합니다.
블록 생성
페이지에 새 블록을 추가합니다(page_uid나 title이 제공되지 않으면 오늘의 일일 페이지가 기본값으로 설정됨):
use_mcp_tool roam-research roam_create_block {
"content": "Block content",
"page_uid": "optional-target-page-uid",
"title": "optional-target-page-title"
}다음 중 하나를 지정할 수 있습니다.
page_uid: 대상 페이지에 대한 직접 참조title: 대상 페이지의 이름 (존재하지 않으면 생성됩니다)둘 다 아님: 블록이 오늘의 일일 페이지에 추가됩니다.
보고:
{
"success": true,
"block_uid": "created-block-uid",
"parent_uid": "parent-page-uid"
}개요 만들기
적절한 중첩과 구조를 갖춘 계층적 개요를 만듭니다.
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"
}특징:
최대 10단계의 중첩으로 복잡한 윤곽선을 만듭니다.
개요 구조와 내용 검증
올바른 부모-자녀 관계 유지
개요에 대한 선택적 헤더 블록
페이지가 지정되지 않으면 오늘의 일일 페이지로 기본 설정됩니다.
블록 생성을 위한 효율적인 일괄 작업
매개변수:
outline: 개요 항목의 배열, 각 항목에는 다음이 포함됩니다.text: 개요 항목의 내용(필수)level: 중첩 레벨(1-10, 필수)
page_title_uid: 대상 페이지 제목 또는 UID(선택 사항, 기본값은 오늘 페이지)block_text_uid: 개요의 헤더 텍스트(선택 사항)
보고:
{
"success": true,
"page_uid": "target-page-uid",
"parent_uid": "header-block-uid",
"created_uids": ["uid1", "uid2", ...]
}할 일 항목 추가
오늘의 일일 페이지에 하나 이상의 할 일 항목을 추가하세요.
use_mcp_tool roam-research roam_add_todo {
"todos": [
"First todo item",
"Second todo item",
"Third todo item"
]
}특징:
Roam 체크박스 구문을 사용하여 할 일을 추가합니다(
{{TODO}} todo text).단일 작업에서 여러 개의 할 일 추가 지원
10개 이상의 할 일을 추가할 때 효율성을 위해 일괄 작업을 사용합니다.
오늘의 페이지가 존재하지 않으면 자동으로 오늘의 페이지를 생성합니다.
순차적으로 최상위 블록으로 할 일을 추가합니다.
중첩된 마크다운 가져오기
특정 블록 아래에 중첩된 마크다운 콘텐츠를 가져옵니다.
use_mcp_tool roam-research roam_import_markdown {
"content": "- Item 1\n - Subitem A\n - Subitem B\n- 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"
}특징:
특정 블록 아래의 콘텐츠 가져오기:
UID 또는 정확한 문자열 일치로 부모 블록 찾기
제목이나 UID로 특정 페이지 내 블록 찾기
페이지가 지정되지 않으면 오늘 페이지로 기본 설정됩니다.
콘텐츠 배치 제어:
부모 블록의 첫 번째 또는 마지막 자식으로 추가
계층 구조 유지
중첩된 콘텐츠에 대한 효율적인 일괄 작업
포괄적인 반환 값:
{ "success": true, "page_uid": "target-page-uid", "parent_uid": "parent-block-uid", "created_uids": ["uid1", "uid2", ...] }
매개변수:
content: 가져올 중첩된 마크다운 콘텐츠page_uid: 부모 블록이 포함된 페이지의 UIDpage_title: 부모 블록이 포함된 페이지의 제목(page_uid가 제공된 경우 무시됨)parent_uid: 콘텐츠를 추가할 부모 블록의 UIDparent_string: 부모 블록의 정확한 문자열 내용(page_uid 또는 page_title을 제공해야 함)order: 콘텐츠를 추가할 위치("first" 또는 "last", 기본값은 "first")
블록 참조 검색
페이지 내 또는 전체 그래프에서 블록 참조를 검색합니다.
use_mcp_tool roam-research roam_search_block_refs {
"block_uid": "optional-block-uid",
"page_title_uid": "optional-page-title-or-uid"
}특징:
특정 블록에 대한 모든 참조 찾기
페이지 내에서 블록 참조를 검색합니다.
그래프 전체에서 검색
직접 및 간접 참조를 모두 지원합니다.
블록 콘텐츠와 위치 컨텍스트가 포함됩니다.
매개변수:
block_uid: 참조를 찾을 블록의 UID(선택 사항)page_title_uid: 검색할 페이지의 제목 또는 UID(선택 사항)
보고:
{
"success": true,
"matches": [
{
"block_uid": "referenced-block-uid",
"content": "Block content with ((reference))",
"page_title": "Page containing reference"
}
],
"message": "Found N block(s) referencing..."
}텍스트로 검색
모든 페이지 또는 특정 페이지 내에서 특정 텍스트가 포함된 블록을 검색합니다.
use_mcp_tool roam-research roam_search_by_text {
"text": "search text",
"page_title_uid": "optional-page-title-or-uid",
"case_sensitive": true
}특징:
그래프의 모든 블록에서 모든 텍스트를 검색합니다.
선택적인 페이지 범위 검색
대소문자 구분 또는 대소문자 구분 안 함 검색
페이지 컨텍스트를 사용하여 블록 콘텐츠를 반환합니다.
Datalog 쿼리를 사용한 효율적인 텍스트 매칭
매개변수:
text: 검색할 텍스트(필수)page_title_uid: 검색할 페이지의 제목 또는 UID(선택 사항)case_sensitive: 대소문자 구분 검색을 수행할지 여부(선택 사항, 기본값: Roam의 기본 동작과 일치하려면 true)
보고:
{
"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\""
}블록 콘텐츠 업데이트
직접 텍스트 교체나 패턴 기반 변환을 사용하여 블록의 콘텐츠를 업데이트합니다.
use_mcp_tool roam-research roam_update_block {
"block_uid": "target-block-uid",
"content": "New block content"
}또는 패턴 기반 변환을 사용합니다.
use_mcp_tool roam-research roam_update_block {
"block_uid": "target-block-uid",
"transform_pattern": {
"find": "\\bPython\\b",
"replace": "[[Python]]",
"global": true
}
}특징:
두 가지 업데이트 모드:
직접 콘텐츠 교체
정규식을 사용한 패턴 기반 변환
업데이트하기 전에 블록 존재 여부를 확인하세요
업데이트된 콘텐츠를 응답으로 반환합니다.
글로벌 또는 단일 매치 교체 지원
블록 관계 및 메타데이터 보존
매개변수:
block_uid: 업데이트할 블록의 UID(필수)content: 블록에 대한 새 콘텐츠(직접 교체를 사용하는 경우)transform_pattern: 기존 콘텐츠를 변환하기 위한 패턴:find: 찾을 텍스트 또는 정규식 패턴replace: 바꿀 텍스트global: 모든 항목을 바꿀지 여부(기본값: true)
보고:
{
"success": true,
"content": "Updated block content"
}태그 검색
근처 태그로 선택적으로 필터링하여 특정 태그가 포함된 블록을 검색하세요.
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
}특징:
특정 태그가 포함된 블록 검색
다른 태그의 존재 여부에 따른 선택적 필터링
페이지 범위 또는 그래프 전체 검색
대소문자 구분 또는 대소문자 구분 안 함 검색
페이지 컨텍스트를 사용하여 블록 콘텐츠를 반환합니다.
Datalog 쿼리를 사용한 효율적인 태그 매칭
매개변수:
primary_tag: 검색할 주요 태그(필수)page_title_uid: 검색할 페이지의 제목 또는 UID(선택 사항)near_tag: 결과를 필터링할 또 다른 태그(선택 사항)case_sensitive: 대소문자 구분 검색을 수행할지 여부(선택 사항, 기본값: Roam의 기본 동작과 일치하려면 true)
보고:
{
"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\""
}정보 기억하기
자동 태그 지정 및 분류를 통해 추억이나 중요한 정보를 저장하세요.
use_mcp_tool roam-research roam_remember {
"memory": "Important information to remember",
"categories": ["Work", "Project/Alpha"]
}특징:
#[[LLM/Memories]] 태그로 정보를 저장합니다.
조직을 위한 선택적 카테고리 태그 추가
오늘의 일일 페이지에 자동으로 추가됩니다
메모리당 여러 카테고리 지원
roam_search_for_tag를 사용하여 쉽게 검색
기억의 연대순을 유지합니다
매개변수:
memory: 기억할 정보 (필수)categories: 메모리에 태그를 지정할 카테고리의 선택적 배열
보고:
{
"success": true,
"block_uid": "created-block-uid",
"content": "Memory content with tags"
}날짜로 검색
생성 또는 수정 날짜를 기준으로 블록 및 페이지 검색:
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
}특징:
생성 날짜, 수정 날짜 또는 둘 다로 검색
블록, 페이지 또는 둘 다 필터링
시작 및 종료 날짜가 포함된 선택적 날짜 범위
결과에 블록/페이지 콘텐츠 포함 또는 제외
타임스탬프별로 결과 정렬
Datalog 쿼리를 사용한 효율적인 날짜 기반 필터링
매개변수:
start_date: ISO 형식(YYYY-MM-DD)의 시작 날짜(필수)end_date: ISO 형식(YYYY-MM-DD)의 종료 날짜(선택 사항)type: '생성됨', '수정됨', '둘 다'로 검색할지 여부 (필수)scope: '블록', '페이지' 또는 '둘 다'를 검색할지 여부(필수)include_content: 일치하는 블록/페이지의 콘텐츠를 포함할지 여부(선택 사항, 기본값: true)
보고:
{
"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"
}오늘 수정된 페이지 찾기
오늘 자정 이후 수정된 모든 페이지를 찾으세요:
use_mcp_tool roam-research roam_find_pages_modified_today {}특징:
자정 이후 페이지에 적용된 모든 수정 사항을 추적합니다.
블록 계층의 모든 레벨에서 변경 사항을 감지합니다.
수정된 페이지 제목의 고유한 목록을 반환합니다.
수정된 페이지 수 포함
매개변수가 필요하지 않습니다
보고:
{
"success": true,
"pages": ["Page 1", "Page 2"],
"message": "Found 2 page(s) modified today"
}데이터 쿼리 실행
고급 데이터 검색 및 분석을 위해 Roam 그래프에서 사용자 정의 Datalog 쿼리를 실행하세요.
use_mcp_tool roam-research roam_datomic_query {
"query": "[:find (count ?p)\n :where [?p :node/title]]",
"inputs": []
}특징:
Roam의 쿼리 엔진에 직접 액세스
모든 Datalog 쿼리 기능 지원:
복잡한 패턴 매칭
집계 함수(count, sum, max, min, avg, distinct)
문자열 연산(includes?, starts-with?, ends-with?)
논리 연산(<, >, <=, >=, =, not=)
재귀 쿼리에 대한 규칙
대소문자 구분 및 대소문자 구분 안 함 검색 기능
그래프 전체에 걸친 효율적인 쿼리
매개변수:
query: 실행할 Datalog 쿼리(필수)inputs: 쿼리에 대한 입력 매개변수의 선택적 배열
보고:
{
"success": true,
"matches": [
{
"content": "[result data]",
"block_uid": "",
"page_title": ""
}
],
"message": "Query executed successfully. Found N results."
}예시 쿼리:
모든 페이지 수 세기:
[: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]]더 많은 쿼리 예제와 구문 설명서는 Roam_Research_Datalog_Cheatsheet.md를 참조하세요.
검색 블록 계층 구조
블록 부모-자식 관계를 탐색하고 검색합니다.
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
}특징:
블록 계층을 위아래로 검색
특정 블록의 자식 찾기
특정 블록의 부모 찾기
검색 깊이 구성(1~10단계)
선택적 페이지 범위 필터링
각 결과에 대한 심층 정보가 포함되어 있습니다.
매개변수:
parent_uid: 자식을 찾을 블록의 UID(아래로 검색하는 경우 필수)child_uid: 부모를 찾을 블록의 UID(위로 검색하는 경우 필수)page_title_uid: 검색할 페이지의 제목 또는 UID(선택 사항)max_depth: 검색할 깊이 수준(선택 사항, 기본값: 1, 최대: 10)
보고:
{
"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..."
}오류 처리
서버는 일반적인 시나리오에 대한 포괄적인 오류 처리를 제공합니다.
구성 오류:
API 토큰 또는 그래프 이름이 없습니다.
잘못된 환경 변수
API 오류:
인증 실패
잘못된 요청
실패한 작업
도구별 오류:
페이지를 찾을 수 없습니다(대소문자 구분 없이 검색)
문자열 일치로 블록을 찾을 수 없습니다.
잘못된 마크다운 형식
필수 매개변수가 없습니다
잘못된 개요 구조 또는 내용
각 오류 응답에는 다음이 포함됩니다.
표준 MCP 오류 코드
자세한 오류 메시지
해당되는 경우 해결을 위한 제안
개발
건물
서버를 빌드하려면:
npm install
npm run build이렇게 하면:
필요한 모든 종속성을 설치하세요
TypeScript를 JavaScript로 컴파일
출력 파일을 실행 가능하게 만들기
개발 중에 npm run watch 사용하면 파일이 변경되면 자동으로 다시 컴파일할 수도 있습니다.
MCP Inspector로 테스트
MCP Inspector는 MCP 서버를 테스트하고 디버깅하는 데 도움이 되는 도구입니다. 서버를 테스트하려면 다음을 수행하세요.
# Inspect with npx:
npx @modelcontextprotocol/inspector node build/index.js이렇게 하면:
서버를 검사기 모드로 시작합니다.
다음에 대한 대화형 인터페이스를 제공합니다.
사용 가능한 도구 및 리소스 나열
사용자 정의 매개변수로 도구 실행
도구 응답 및 오류 처리 보기
특허
MIT 라이센스
Available Tools
25 toolsroam_add_todoA
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. NOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use alias syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| todos | Yes | List of todo items to add | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
Output Schema
| Name | Required | Description |
|---|---|---|
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnly=false, and the description adds that each item becomes an 'actionable block with todo status', and provides markdown linking rules. This is useful behavioral context beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main purpose is stated in a single, direct sentence. The markdown note and IMPORTANT prerequisite are structured with labels and are relevant to correct use. It is slightly long, but each part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values don't need to be explained. The description covers the action, the effect on blocks, markdown syntax details, and the required prerequisite call to roam_get_guidelines, making it complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all three parameters with 100% coverage, so the baseline is 3. The description adds valuable markdown syntax guidance for the 'todos' parameter text, such as [[link]] and #[[multiple words]], which increases the score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Add') and resource ('today's daily page'), and clearly states that each item becomes an 'individual block' with todo status. This distinguishes it from sibling tools like roam_create_outline or roam_import_markdown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use: adding todos to today's daily page. It also gives an explicit prerequisite: call roam_get_guidelines and load the Roam Markdown Cheatsheet before use. It doesn't explicitly mention alternatives or when not to use, so a 4 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_create_outlineA
Add a structured outline to an existing page or block (by title text or uid), with customizable nesting levels. To create a new page with an outline, use the roam_create_page tool instead. The outline parameter defines new blocks to be created. To nest content under an existing block, provide its UID or exact text in block_text_uid, and ensure the outline array contains only the child blocks with levels relative to that parent. Including the parent block's text in the outline array will create a duplicate block. Best for:
Adding supplementary structured content to existing pages
Creating temporary or working outlines (meeting notes, brainstorms)
Organizing thoughts or research under a specific topic
Breaking down subtopics or components of a larger concept Best for simpler, contiguous hierarchical content. For complex nesting (e.g., tables) or granular control over block placement, consider
roam_process_batch_actionsinstead. API Usage Note: This tool performs verification queries after creation. For large outlines (10+ items) or when rate limits are a concern, consider usingroam_process_batch_actionsinstead to minimize API calls.
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| order | No | Insertion position for the first level-1 block relative to existing page/block children. Accepts "first", "last", or a non-negative integer (0-indexed). Default: "last". | |
| outline | Yes | Array of outline items with block text and explicit nesting level. Must be a valid hierarchy: the first item must be level 1, and subsequent levels cannot increase by more than 1 at a time (e.g., a level 3 cannot follow a level 1). | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| block_text_uid | No | The text content or UID of the block to nest the outline under (UID is preferred for accuracy). If blank, content is nested directly under the page (or the default daily page if page_title_uid is also blank). | |
| page_title_uid | No | Title or UID of the page (UID is preferred for accuracy). Leave blank to use the default daily page. |
Output Schema
| Name | Required | Description |
|---|---|---|
| success | Yes | |
| page_uid | Yes | |
| parent_uid | Yes | Block the outline was nested under |
| created_blocks | Yes | The created block tree. Objects, not UID strings. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations (which are all false) by disclosing that the tool 'performs verification queries after creation' and warns about the risk of duplicate blocks if the parent block's text is included in the outline array. It also clarifies that the outline parameter defines new blocks, which is key behavioral context. However, it does not mention idempotency failure behavior or partial-failure details, so it is not fully exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than strictly necessary but well-structured with a clear opening sentence, bulleted 'Best for' list, and a separate API Usage Note. Each section adds value without redundancy, and the most essential information is front-loaded. It earns a 4 rather than 5 due to its length, though it remains focused.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, nested outline structure), the description is remarkably complete. It covers purpose, usage alternatives, API rate-limit implications, common use cases, and even a prerequisite instruction (call roam_get_guidelines). The existence of an output schema further reduces the need to describe return values, so there are no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage of parameter descriptions, so the baseline is 3. The description adds meaningful semantic nuances beyond the schema, particularly for the `outline` parameter: it explains that levels are relative to the parent block, and warns against including the parent block's text. This extra guidance helps prevent common usage errors.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Add a structured outline to an existing page or block (by title text or uid), with customizable nesting levels.' It distinguishes itself from the sibling tool `roam_create_page` by explicitly noting that tool should be used for creating new pages with outlines. The verb-resource pairing is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool vs alternatives: 'To create a new page with an outline, use the `roam_create_page` tool instead' and 'For complex nesting (e.g., tables) or granular control over block placement, consider `roam_process_batch_actions` instead.' It also includes a 'Best for' list and a clear exclusion criterion, making the decision process straightforward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_create_pageA
Create a new standalone page in Roam with optional content, including structured outlines and tables, using explicit nesting levels and headings (H1-H3). This is the preferred method for creating a new page with an outline in a single step. Best for:
Creating foundational concept pages that other pages will link to/from
Establishing new topic areas that need their own namespace
Setting up reference materials or documentation
Making permanent collections of information
Creating pages with mixed text and table content in one call. Efficiency Tip: This tool batches page and content creation efficiently. For adding content to existing pages, use
roam_process_batch_actionsinstead.
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| title | Yes | Title of the new page | |
| content | No | Initial content for the page as an array of content items. Each item can be a text block or a table. Text blocks use {text, level, heading?}. Tables use {type: "table", headers, rows}. Items are processed in order. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
Output Schema
| Name | Required | Description |
|---|---|---|
| success | Yes | |
| page_uid | Yes | UID of the created page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate a write operation (readOnlyHint=false) and no idempotency/destructive hints. The description adds context beyond annotations by explaining the tool 'batches page and content creation efficiently' and requiring the user to consult guidelines beforehand. However, it does not disclose edge-case behaviors such as what happens if the page already exists, which would be useful for a creation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening sentence, a 'Best for' list, an efficiency tip, and an important prerequisite note. It is slightly longer than necessary (the best-for list has some overlap), but every section earns its place and it is front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (nested content arrays, table support, headings) and the detailed input schema, the description provides sufficient context: it explains the structure of content, highlights the ability to mix text and tables, and gives usage boundaries. It could mention conflict behavior for existing pages, but overall it is quite complete for a creation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% parameter description coverage, so the schema carries the burden. The description restates general capabilities (outlines, tables, headings) but does not add specific parameter-level semantics beyond what the schema already explains. Thus the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Create a new standalone page in Roam with optional content, including structured outlines and tables, using explicit nesting levels and headings (H1-H3).' It also distinguishes itself from siblings by noting it is 'the preferred method for creating a new page with an outline in a single step' and contrasts with roam_process_batch_actions for adding content to existing pages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance through a 'Best for:' list covering foundational pages, new namespaces, reference materials, and permanent collections. It also gives an exclusion: 'For adding content to existing pages, use roam_process_batch_actions instead,' and includes a prerequisite instruction to call roam_get_guidelines and load the Markdown Cheatsheet before using.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_create_tableA
Create a table in Roam with specified headers and rows. This tool abstracts the complex nested structure that Roam tables require, making it much easier to create properly formatted tables.
Why use this tool:
Roam tables require precise nested block structures that are error-prone to create manually
Automatically handles the {{[[table]]}} container and nested column structure
Validates row/column consistency before execution
Converts empty cells to spaces (required by Roam)
Example: A table with headers ["", "Column A", "Column B"] and rows [{label: "Row 1", cells: ["A1", "B1"]}] creates a 2x3 table.
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | Yes | Data rows for the table. Each row has a label (first column) and cells (remaining columns). | |
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| order | No | Optional: Position under the parent. Can be a number (0-based) or "first"/"last". Defaults to "last". | last |
| headers | Yes | Column headers for the table. The first header is typically empty (for the row label column). Example: ["", "Option A", "Option B"] | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| parent_uid | Yes | The UID of the parent block or page where the table should be created. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present only when success is false. |
| success | Yes | |
| uid_map | No | Placeholder name → generated UID. Present only on success. |
| table_uid | No | |
| actions_attempted | No | |
| validation_passed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate a write operation (readOnlyHint: false) but provide limited safety info. The description adds valuable context: it automatically handles the {{[[table]]}} container, validates row/column consistency, and converts empty cells to spaces. It also mentions the session prerequisite, giving the agent important operational details beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core action. The 'Why use this tool' bullets are concise and purposeful, the example is helpful, and the IMPORTANT note is relevant. No sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 params), the description provides purpose, rationale, an example, and a prerequisite. The output schema exists, so return-value details are not necessary. It lacks explicit edge-case handling but is complete enough for an agent to use effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description's example adds a concrete illustration of how headers and rows map to a table, but it does not add significant new semantics beyond what the schema provides. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create a table in Roam with specified headers and rows,' which is a specific verb+resource statement that clearly distinguishes this tool from siblings like roam_create_outline or roam_create_page. It also explains the tool abstracts Roam's complex nested table structure, reinforcing its unique purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Why use this tool' section explicitly states when this tool is beneficial (avoiding error-prone manual creation, handling table containers, validating consistency). It also provides a clear prerequisite: call roam_get_guidelines and load the Markdown Cheatsheet before use. However, it does not explicitly name alternatives or state when not to use it, though the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_datomic_queryARead-onlyIdempotent
Execute a custom Datomic query on the Roam graph for advanced data retrieval beyond the available search tools. This provides direct access to Roam's query engine. Note: Roam graph is case-sensitive.
Optimal Use Cases for roam_datomic_query:
Advanced Filtering (including Regex): Use for scenarios requiring complex filtering, including regex matching on results post-query, which Datalog does not natively support for all data types. It can fetch broader results for client-side post-processing.
Highly Complex Boolean Logic: Ideal for intricate combinations of "AND", "OR", and "NOT" conditions across multiple terms or attributes.
Arbitrary Sorting Criteria: The go-to for highly customized sorting needs beyond default options.
Proximity Search: For advanced search capabilities involving proximity, which are difficult to implement efficiently with simpler tools.
List 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). Predicates (clojure.string/includes?, clojure.string/starts-with?, clojure.string/ends-with?, <, >, <=, >=, =, not=, !=). Aggregates (distinct, count, sum, max, min, avg, limit). Tips: 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.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| query | Yes | The Datomic query to execute (in Datalog syntax). Example: `[:find ?block-string :where [?block :block/string ?block-string] (or [(clojure.string/includes? ?block-string "hypnosis")] [(clojure.string/includes? ?block-string "trance")] [(clojure.string/includes? ?block-string "suggestion")]) :limit 25]` | |
| inputs | No | Optional array of input parameters for the query | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| regexFlags | No | Optional: Flags for the regex filter (e.g., "i" for case-insensitive, "g" for global). | |
| regexFilter | No | Optional: A regex pattern to filter the results client-side after the Datomic query. Applied to JSON.stringify(result) or specific fields if regexTargetField is provided. | |
| regexTargetField | No | Optional: An array of field paths (e.g., ["block_string", "page_title"]) within each Datomic result object to apply the regex filter to. If not provided, the regex is applied to the stringified full result. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond annotations: it notes case-sensitivity, explains that regex filtering is applied client-side after the query, and warns that graph conventions affect results. Annotations already declare readOnly, idempotent, and non-destructive, and the description does not contradict them; it enriches the agent's understanding of side effects and result interpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with sections (Optimal Use Cases, data model, predicates, tips) and all content is relevant to using the tool effectively. It front-loads the purpose and uses bold headers for scannability, though a slight trim could make it more concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex Datomic query tool, the description covers most essential context: syntax, use cases, data model, predicates, and a required guideline call. However, it does not describe the return format beyond mentioning client-side filtering, and could benefit from noting potential errors or performance implications, so it isn't fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds significant value by providing an example Datalog query, listing predicates and aggregates, and explaining the data model namespaces. This goes beyond the schema's parameter descriptions and helps the agent construct correct queries, especially for the 'query' parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool executes custom Datomic queries on the Roam graph for advanced data retrieval, explicitly distinguishing it from search tools. It further lists specific advanced use cases (regex filtering, complex boolean logic, arbitrary sorting, proximity search), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description has an 'Optimal Use Cases' section that clearly specifies when to use this tool (advanced filtering, complex boolean logic, etc.), and the opening sentence implies it should be used beyond the available search tools. It also mandates calling roam_get_guidelines before use, but doesn't explicitly name alternative tools for contrast or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_fetch_blockARead-onlyIdempotent
Fetch a block by its UID with optional children (down to a specified depth) and/or ancestors (up to page root). Returns the block's UID, text, order, children array, and optionally an ancestors array with the chain to the page root.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Optional: The number of levels deep to fetch children. Defaults to 4. Set to 0 to skip children. | |
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| block_uid | Yes | The UID of the block to fetch. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| include_ancestors | No | Optional: Include the ancestor chain from the block up to the page root. Each ancestor includes uid, string/title, and depth. Defaults to false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and idempotent, and the description aligns with that by stating it 'fetches' and 'returns' data. It adds valuable behavioral context beyond the annotations: the graph's conventions can change read semantics, and the response includes a specific ancestors array shape when requested.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short paragraphs with no filler. The first sentence states the core function and return values, and the second conveys an essential prerequisite in an 'IMPORTANT' callout. Every sentence earns its place and the structure is immediately scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the exact return fields. The mandatory prerequisite for roam_get_guidelines is highlighted, and all parameters are covered by the schema. For a read-only fetch tool with clear sibling context, this is fully adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameter descriptions already document depth, graph, block_uid, write_key, and include_ancestors. The description adds minimal extra semantic value beyond restating those concepts in prose (e.g., 'children down to a specified depth' maps to depth), but it does not introduce information absent from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Fetch a block by its UID' with optional children and ancestors, which clearly distinguishes it from page-level fetch siblings like roam_fetch_page_by_title and roam_fetch_page_full_view. It also enumerates the return fields, reinforcing what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs the agent to call roam_get_guidelines once per session before using the tool, including for reads, and explains that conventions affect how results are read. It does not explicitly name alternative tools or provide exclusion criteria, but the prerequisite and context are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_fetch_page_by_titleARead-onlyIdempotent
Fetch page by title. Returns content in the specified format.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| title | Yes | Title of the page. For date pages, use ordinal date formats such as January 2nd, 2025 | |
| format | No | Format output as markdown, JSON, or structure. 'markdown' returns readable string; 'raw' returns full JSON with nested blocks; 'structure' returns a flattened list (uid, order, text, depth, parent_uid) for locating blocks to update. In 'structure', `text` is a PREVIEW cut at 80 characters — an entry marked `truncated: true` is a fragment, and writing it back would replace the block with its own opening. Use it to find the uid, then fetch that block with roam_fetch_block before editing its text. | raw |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds behavioral context by warning that graph conventions affect how results are read, which is not captured by annotations or schema. This is useful and complements the structured metadata.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences achieve the core purpose and add a critical usage warning. There is no filler or redundant explanation. The important guideline is highlighted with 'IMPORTANT' and placed prominently, making it effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only fetch tool with rich schema descriptions and annotations, the description is sufficiently complete. It covers the core function, return format note, and the prerequisite guideline call. There is no output schema, but the format parameter description in the schema explains expected outputs. Minor gaps like behavior on missing pages are acceptable for this tool type.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage with detailed descriptions for all parameters, including the format enum and its behavior. The description adds no additional parameter-specific meaning beyond what the schema provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Fetch' and the resource 'page by title', making the tool's purpose unambiguous. It is specific enough to distinguish from sibling tools like roam_fetch_page_full_view or roam_fetch_block, which operate on different inputs or views.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs the agent to call roam_get_guidelines before every session, even for reads, adding important prerequisite guidance. It does not mention specific alternative tools or exclusion criteria, but the context of use is clear from the verb and resource.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_fetch_page_full_viewARead-onlyIdempotent
Fetch a complete page view that mirrors what Roam Research shows in its UI: the page's own content, plus all linked references (backlinks) grouped by source page, each with their ancestor breadcrumb context and children expanded to the specified depth. Use this when you need the full picture of a page — both what is written on it and everything else in the graph that references it.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| title | Yes | Title of the page to fetch. For date pages use ordinal format e.g. "January 2nd, 2025". | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| children_depth | No | How many levels deep to expand children of each referring block. Defaults to 4. | |
| max_references | No | Maximum number of linked references to return. Prevents timeouts on heavily-referenced pages (e.g. TODO, common tags). Defaults to 200. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds behavioral context: mirrors Roam UI, groups backlinks by source page, includes breadcrumbs, and mentions max_references to prevent timeouts. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences of purpose and usage, plus one important prerequisite note. Every sentence earns its place, front-loaded with the core purpose. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex read tool with no output schema, the description well explains the response composition: page content, grouped backlinks, breadcrumbs, and child expansion depth. It also includes a session-level prerequisite. Minor gap: no explicit mention of pagination beyond max_references, but that is partially covered in schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are already fully documented. The description's references to 'children expanded to the specified depth' and 'max_references' merely restate what the schema provides without adding new semantic meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Fetch a complete page view' which clearly identifies the verb, resource, and scope. It distinguishes itself from sibling tools by specifying it includes linked references grouped by source page with breadcrumb context, unlike a simple fetch_page_by_title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use case: 'Use this when you need the full picture of a page'. Also instructs to call roam_get_guidelines before use, which is a prerequisite. Does not explicitly name alternatives to exclude, but gives clear context for when to choose this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_find_pages_modified_todayARead-onlyIdempotent
Find pages that have been modified today (since midnight), with pagination and sorting options.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| limit | No | The maximum number of pages to retrieve (default: 50). Use -1 for no limit, but be aware that very large result sets can impact performance. | |
| offset | No | The number of pages to skip before returning matches. Useful for pagination. Defaults to 0. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| sort_order | No | Sort order for pages based on modification date. "desc" for most recent first, "asc" for oldest first. | desc |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (read-only, idempotent), the description adds a behavioral caveat: conventions change how results are read, and it requires calling roam_get_guidelines. This enriches the agent's understanding without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two impactful sentences: the main action and an important prerequisite. The description is front-loaded with the core purpose and wastes no words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the read-only nature, schema coverage, and annotations, the description covers the core function, the required guideline call, and a behavioral caveat. It lacks explicit return format or timezone clarification for 'midnight', but these are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters (limit, offset, sort_order, graph, write_key) are already fully described in the schema. The description only mentions pagination and sorting generically without adding new parameter-specific meaning, keeping the baseline at 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('Find') and the resource ('pages modified today'), with a precise time scope ('since midnight'). It is easily distinguished from sibling tools like roam_search_by_date or roam_fetch_page_by_title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit context for when to use the tool (for pages modified today) and a critical prerequisite (call roam_get_guidelines once per session). However, it does not mention alternatives or exclusions, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_get_guidelinesARead-onlyIdempotent
Retrieve this graph's user-defined agent conventions, read from the [[roam/agent guidelines]] page inside the graph (configurable per graph). These are the user's own rules — how they tag, how they name and namespace pages, what to never do, how they want your voice attributed.
Also returns roamSyntax: the rules whose violation destroys content — whole-page rewrites that delete, truncated previews written back as content, retyped block references, and the syntax that differs from standard markdown. These are returned on every call, including when the graph has no guidelines page, and they hold regardless of what the conventions say.
Call this ONCE per graph per session, before other tools, INCLUDING for reads: conventions change how results should be interpreted and presented, not just how content is written. Returns today's daily note title as orientation.
Distinct from roam_markdown_cheatsheet, which is the complete syntax reference — components, queries, embeds, tool selection. Call that when you need to look something up; this one you need before writing at all. Returns exists:false rather than failing when no page has been created.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=false, idempotentHint=true, destructiveHint=false. The description adds valuable context beyond these: it returns `roamSyntax` on every call, returns `exists:false` instead of failing when no page exists, returns today's daily note title, and explains that conventions affect interpretation/presentation, not just writing. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than the absolute minimum but well-structured: purpose, special return value, usage instruction, sibling differentiation, and existence behavior are each in their own sentence/paragraph. Every sentence earns its place, though it could be tightened slightly without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description explains what is returned (user conventions, roamSyntax, daily note title, exists:false), why it must be called before other tools, and the behavior when no guidelines page exists. It fully covers the operational context a read tool with no output schema needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage for both parameters (`graph` and `write_key`) with descriptions. The description adds no new parameter-specific meaning beyond noting the guidelines page is 'configurable per graph', which is already implied by the schema. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Retrieve this graph's user-defined agent conventions', and names the source page `[[roam/agent guidelines]]`. It also distinguishes itself from the sibling `roam_markdown_cheatsheet` by stating what each is for, eliminating ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs 'Call this ONCE per graph per session, before other tools, INCLUDING for reads' and contrasts with the alternative: 'Call that when you need to look something up; this one you need before writing at all.' This gives clear when-to-use and when-not-to-use guidance with a direct sibling reference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_get_subpagesARead-onlyIdempotent
Fetch all sub-pages (namespace children) of a given page prefix. Matches by page title prefix — pages titled "Prefix/Something" are sub-pages of "Prefix" and appear in the Hierarchy section of that page. This is namespace/title-prefix matching, distinct from roam_search_hierarchy which traverses block parent/child relationships. Optionally filter to only sub-pages containing a specific tag (e.g. filter active projects with filter_tag="active"), and optionally include each sub-page's full block content.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| prefix | Yes | The namespace prefix to search under, e.g. "Project", "Zettel", "Framework". The trailing "/" is added automatically if omitted. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| filter_tag | No | Optional. Only return sub-pages that contain at least one block referencing this tag. Matches both #tag and [[tag]] usage. Example: "active" to find active projects. | |
| include_content | No | If true, include each sub-page's block content in the output. Defaults to false (list only). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already declaring read-only/idempotent, the description adds meaningful behavioral details: it explains that the trailing slash is added automatically, that filter_tag matches both #tag and [[tag]] usage, and that include_content controls whether full block content is returned. The IMPORTANT note about conventions affecting how results are read adds extra context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences plus a focused IMPORTANT note. It front-loads the core purpose, uses no filler, and each sentence adds a distinct piece of information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's behavior, prerequisites, and optional parameters. Since there is no output schema, it would be helpful to state the exact return shape, but the description implies a list of sub-pages and mentions content inclusion for include_content. Overall it's sufficiently complete for a read-only list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all 5 parameters with detailed descriptions, so the baseline is 3. The description enhances the meaning of 'prefix' by explaining the namespace/title-prefix matching convention and the hierarchy section, which aids correct parameter use.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Fetch all sub-pages (namespace children) of a given page prefix,' which is a specific verb+resource. It further distinguishes itself from roam_search_hierarchy (block parent/child traversal) and clarifies the title-prefix matching rule.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names an alternative tool: 'distinct from roam_search_hierarchy which traverses block parent/child relationships.' It also mandates a prerequisite: 'call roam_get_guidelines for this graph once per session before using this tool,' including for reads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_import_markdownA
Import nested markdown content into Roam under a specific block. Can locate the parent block by UID (preferred) or by exact string match within a specific page. If a parent_string is provided and the block does not exist, it will be created. Returns a nested structure of the created blocks.
API Usage Note: This tool fetches the full nested structure after import for verification. For large imports or when rate limits are a concern, consider using roam_process_batch_actions with pre-structured actions instead.
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| order | No | Optional: Where to add the content under the parent ("first" or "last"). Defaults to "first". | first |
| content | Yes | Nested markdown content to import | |
| page_uid | No | Optional: UID of the page containing the parent block (preferred for accuracy). | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| page_title | No | Optional: Title of the page containing the parent block (used if page_uid is not provided). | |
| parent_uid | No | Optional: UID of the parent block to add content under (preferred for accuracy). | |
| parent_string | No | Optional: Exact string content of an existing parent block to add content under (used if parent_uid is not provided; requires page_uid or page_title). If the block does not exist, it will be created. |
Output Schema
| Name | Required | Description |
|---|---|---|
| success | Yes | |
| page_uid | Yes | |
| parent_uid | Yes | |
| created_blocks | Yes | The created block tree. Objects, not UID strings. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (write, non-destructive), the description discloses two important behaviors: it auto-creates a missing parent block when `parent_string` is used, and it fetches the full nested structure post-import for verification, adding rate-limit context. This is valuable extra transparency, though it does not detail all side effects (e.g., how existing content is affected).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loaded with the main purpose. It uses a clear structure with an API usage note and an important prerequisite. While slightly longer due to the usage warnings, every sentence serves a purpose and there is no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with a full output schema, the description covers the core behavior, parameter lookup logic, rate-limit implications, and required preconditions. It does not explicitly cover error cases or edge conditions, but the schema and output schema fill many gaps, making it reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaning by explaining the preference order (parent_uid/page_uid over parent_string) and clarifying that `parent_string` will create a new block if it doesn't exist. This goes beyond the schema definitions and helps agents choose the right parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Import nested markdown content into Roam under a specific block' with a specific verb, resource, and location. It distinguishes itself from siblings by detailing how the parent block is located (UID or exact string match) and refers to the alternative tool `roam_process_batch_actions` for large imports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit usage guidance: UID is preferred over string match, and it names an alternative for large imports or rate-limit concerns. It also instructs to call `roam_get_guidelines` and load the Markdown Cheatsheet before use, covering prerequisites and when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_markdown_cheatsheetARead-onlyIdempotent
Provides the comprehensive Roam syntax reference. Covers: formatting, links & references (page refs, block refs, embeds including embed-children and embed-path), tags, dates, tasks, callouts, attributes, queries (native {{query}} with its clause rules and page-ref inheritance, plus :q Datalog tables with built-in rules), tables, kanban, mermaid diagrams (with theme support), advanced components (dropdowns, tooltips, templates, document mode, word-count), CSS tags (#.rm-E, #.rm-hide, etc.), anti-patterns, tool selection guide, and API efficiency tips.
IMPORTANT: Always load this cheatsheet before creating or updating Roam content. It prevents common syntax errors and guides tool selection.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety. The description adds behavioral context by noting it 'prevents common syntax errors' and 'guides tool selection,' which goes beyond annotations. It doesn't describe the output format, but for a read-only reference the annotations carry the main safety burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded with the main purpose and then organized into a categorized list. Each sentence adds value, and the IMPORTANT warnings are clearly highlighted. It is appropriately detailed for a comprehensive reference tool, though slightly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only reference tool with no output schema, the description is complete: it lists the full scope of content covered, provides usage prerequisites, and includes warnings about guidelines. It explains why to load it and mentions the companion function. No significant information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, as both parameters (graph, write_key) have descriptions in the schema. The tool description itself does not mention parameters, but because the schema fully documents them, the baseline is 3. No additional parameter semantics are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource: 'Provides the comprehensive Roam syntax reference.' It enumerates a detailed list of covered topics (formatting, links, queries, diagrams, etc.), which distinguishes it from sibling tools like roam_create_table or roam_add_todo. The purpose is unmistakable and specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs 'Always load this cheatsheet before creating or updating Roam content' and explains it prevents syntax errors and guides tool selection. It also names a prerequisite: 'call roam_get_guidelines for this graph once per session before using this tool.' This is clear when-to-use guidance with an alternative tool mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_move_blockADestructiveIdempotent
Move a block to a new location (different parent or position). This is a convenience wrapper around roam_process_batch_actions for single block moves.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| order | No | Position under the new parent. Can be a number (0-based index) or "first"/"last". Defaults to "last". | last |
| block_uid | Yes | The UID of the block to move | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| parent_uid | Yes | The UID of the new parent block or page |
Output Schema
| Name | Required | Description |
|---|---|---|
| order | Yes | |
| success | Yes | |
| block_uid | Yes | |
| new_parent_uid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true, so the description does not need to restate these. It adds context about being a wrapper around batch actions and the importance of graph-specific guidelines. However, it does not disclose additional behavioral details such as whether the move is atomic, if child blocks are moved recursively, or the exact impact on references. With annotations covering the safety profile, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place. The first sentence states the action, the second frames it as a wrapper alternative, and the third provides a critical workflow prerequisite. It is front-loaded and free of fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (5 parameters, 2 required, output schema present), the description covers the essential context: what the tool does, how it relates to sibling tools, and the required pre-use step. The output schema handles return values, and annotations handle safety traits, so the description is complete for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for all five parameters, so the description does not need to explain each parameter. It does add a high-level semantic cue ('different parent or position') that maps to parent_uid and order, but this is already explicit in the schema. The description adds marginal value over the schema, matching the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Move a block to a new location' which is a specific verb+resource action, and immediately clarifies the scope: 'different parent or position'. It also distinguishes itself from the sibling tool by explicitly calling itself a 'convenience wrapper around roam_process_batch_actions for single block moves', making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates when to use this tool—for single block moves—by positioning it as a wrapper around the batch action tool, implying batch actions would be used for multiple moves. It also includes an explicit prerequisite: 'call roam_get_guidelines for this graph once per session', with a brief rationale. This is direct usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_process_batch_actionsADestructive
RATE LIMIT EFFICIENT: This is the most API-efficient tool for multiple block operations. Combine all create/update/delete operations into a single call whenever possible. For intensive page updates or revisions, prefer this tool over multiple sequential calls.
Executes a sequence of low-level block actions (create, update, move, delete) in a single, non-transactional batch. Actions are executed in the provided order.
UID Placeholders for Nested Blocks: Use {{uid:name}} syntax for parent-child references within the same batch. The server generates proper random UIDs and returns a uid_map showing placeholder→UID mappings. Example: { uid: "{{uid:parent1}}", string: "Parent" } then { location: { "parent-uid": "{{uid:parent1}}" }, string: "Child" }. Response includes { success: true, uid_map: { "parent1": "Xk7mN2pQ9" } }.
For actions on existing blocks, a valid block UID is required. Note: Roam-flavored markdown, including block embedding with ((UID)) syntax, is supported within the string property for create-block and update-block actions. For actions on existing blocks or within a specific page context, it is often necessary to first obtain valid page or block UIDs. Tools like roam_fetch_page_by_title or other search tools can be used to retrieve these UIDs before executing batch actions. For simpler, sequential outlines, roam_create_outline is often more suitable.
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| actions | Yes | An array of action objects to execute in order. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present only when success is false. |
| success | Yes | |
| uid_map | No | Placeholder name → generated UID. Present only on success. |
| actions_attempted | No | |
| validation_passed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by disclosing non-transactional execution, ordered actions, UID placeholder behavior with uid_map responses, and the requirement for valid block UIDs. It also notes that existing-block actions often need page/block UIDs first. The destructiveHint annotation is consistent with the write operations described; no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with bold section labels and examples. It contains some repetition (e.g., 'For actions on existing blocks' appears twice), but each sentence contributes either usage guidance, parameter enrichment, or prerequisite context. The front-loaded rate-limit note is practical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema (indicated but not shown), the description covers the essentials: what the tool does, when to use it, prerequisites for UIDs, nested-block placeholder mechanics, response shape, and the guideline prerequisite. It could mention failure semantics more explicitly, but the non-transactional note covers the key risk.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema by explaining the {{uid:name}} placeholder syntax with a concrete example, describing the structure of the uid_map response, and noting that Roam-flavored markdown including block embeds is supported in the 'string' property.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb-resource pairing: 'Executes a sequence of low-level block actions (create, update, move, delete) in a single, non-transactional batch.' It also brands itself as 'the most API-efficient tool for multiple block operations,' which distinguishes it from siblings like roam_create_outline and roam_move_block.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: 'Combine all create/update/delete operations into a single call whenever possible' and 'For simpler, sequential outlines, roam_create_outline is often more suitable.' It also directs users to call roam_get_guidelines once per session and to use search tools like roam_fetch_page_by_title to obtain UIDs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_recallARead-onlyIdempotent
Retrieve all stored memories on page titled ROAM_MEMORIES_TAG, or tagged block content with the same name. Returns a combined, deduplicated list of memories. Optionally filter blocks with a specific tag and sort by creation date.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| sort_by | No | Sort order for memories based on creation date | newest |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| filter_tag | No | 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) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description only needs to add context. It adds that results are deduplicated and that 'conventions change how results are read, not just written,' which is a valuable behavioral caveat. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two paragraphs; the first is a single dense sentence covering core behavior, the second is a necessary warning. It is efficient with no redundant content, though the first sentence is long and complex.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the dual retrieval source, deduplication, optional filtering/sorting, and a per-session prerequisite. It also states the return type ('combined, deduplicated list'). For a simple read-only tool with good annotations, this is adequate, though it could clarify the exact format of the returned list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with all four parameters described. The description mentions filter_tag and sort_by but does not add new semantic detail beyond the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the primary function: 'Retrieve all stored memories on page titled ROAM_MEMORIES_TAG, or tagged block content with the same name.' It specifies the resource (memories), the source (page or tags), and the output (deduplicated list). This distinguishes it from sibling search tools by focusing on memory recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly mandates calling roam_get_guidelines before using this tool, which is a clear prerequisite. However, it does not explicitly contrast with alternative tools like roam_search_for_tag, though the memory-specific scope implies the intended use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_rememberA
Add a memory or piece of information to remember, stored on the daily page with ROAM_MEMORIES_TAG tag and optional categories (unless include_memories_tag is false). NOTE on Roam-flavored markdown: For direct linking: use [[link]] syntax. For aliased linking, use alias syntax. Do not concatenate words in links/hashtags - correct: #[[multiple words]] #self-esteem (for typically hyphenated words).
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| memory | Yes | The memory detail or information to remember. Add tags in `categories`. | |
| heading | No | Optional heading text to nest the memory under (e.g., "Memories" or "## LLM Memories"). If the heading does not exist on the daily page, it will be created. Ignored if parent_uid is provided. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| categories | No | Optional categories to tag the memory with (will be converted to Roam tags). Do not duplicate tags added in `memory` parameter. | |
| parent_uid | No | Optional UID of a specific block to nest the memory under. Takes precedence over heading parameter. | |
| include_memories_tag | No | Whether to append the ROAM_MEMORIES_TAG tag to the memory block. |
Output Schema
| Name | Required | Description |
|---|---|---|
| success | Yes | |
| block_uid | No | UID of the stored memory block |
| parent_uid | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are all false, providing no behavioral safety hints (e.g., readOnlyHint=false implies a write, but no further detail). The description compensates by disclosing that the tool writes to the daily page, applies a tag and optional categories, and includes a markdown syntax warning to avoid formatting errors. It does not mention permission requirements or rate limits, but for a write tool with no other annotation coverage, it adds substantial behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description opens with a clear one-sentence purpose, followed by a detailed markdown note and a prerequisite warning. While the markdown note is verbose, it provides essential usage guidance. The structure is front-loaded and the additional paragraphs earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core purpose, storage location, tag behavior, and prerequisite calls, making it sufficient for an agent to invoke the tool correctly. It does not mention heading or parent_uid options, but these are fully described in the schema. Given the high schema coverage and output schema, the description is adequately complete, though it could briefly note that headings/parent_uid can organize memories.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds value by explaining the storage behavior (daily page + tag), the optionality of categories, and a detailed markdown note relevant to formatting memory content and categories. However, the phrase '(unless include_memories_tag is false)' is ambiguous, potentially implying categories are also omitted when the tag is disabled, which conflicts with the schema's separate handling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Add a memory or piece of information to remember') and specifies the storage location (daily page with ROAM_MEMORIES_TAG tag). This distinguishes it from siblings like roam_add_todo (adds tasks) and roam_recall (retrieves memories).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for use (storing memories) but does not explicitly state when to use this tool versus alternatives. It includes a prerequisite instruction to call roam_get_guidelines and load the markdown cheatsheet, but lacks exclusionary guidance such as 'use roam_add_todo for tasks' or 'use roam_recall to fetch memories.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_rename_pageADestructiveIdempotent
Rename a page by changing its title. Identifies the page by current title or UID.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | No | UID of the page to rename (use this OR old_title, not both) | |
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| new_title | Yes | New title for the page | |
| old_title | No | Current title of the page to rename (use this OR uid, not both) | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | Yes | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this tool destructive and idempotent. The description adds useful context beyond annotations by requiring a call to roam_get_guidelines and noting that conventions affect reads as well as writes. This provides behavioral nuance not captured in the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief (two sentences) and front-loaded with the core purpose. The second sentence conveys a critical prerequisite but is slightly convoluted with 'reads included.' Overall, it is compact and earns its place, though the phrasing could be clearer.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple rename tool with a complete input schema, output schema, and annotations covering safety, the description adds the essential prerequisite and identification method. It does not explain error conditions, but these are not critical for correct tool usage in most contexts.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for all parameters, including guidance on using old_title or uid. The description adds no additional parameter semantics beyond the phrase 'current title or UID,' which merely mirrors the schema. Baseline 3 is appropriate given high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb and resource: 'Rename a page by changing its title.' It also specifies the identification method ('by current title or UID'), distinguishing it from sibling tools like create_page or update_page_markdown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance by instructing the agent to call roam_get_guidelines before using this tool, including a rationale about conventions. However, it does not name alternative tools or state when not to use this tool, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_search_block_refsARead-onlyIdempotent
Search for block references within a page or across the entire graph. Can search for references to a specific block, a page title, or find all block references.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| title | No | Optional: Page title to find references to (uses :block/refs for [[page]] and #tag links) | |
| block_uid | No | Optional: UID of the block to find references to (searches for ((uid)) patterns in text) | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| page_title_uid | No | Optional: Title or UID of the page to search in (UID is preferred for accuracy). If not provided, searches across all pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and destructiveHint, but the description adds meaningful context: results must be interpreted based on graph conventions (calling roam_get_guidelines even for reads). This goes beyond the structured annotations by warning that behavior depends on per-graph conventions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short paragraphs: a focused purpose statement followed by a critical warning. Every sentence is useful, no filler, and the most important usage instruction is front-loaded with 'IMPORTANT.'
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the full schema coverage, read-only annotations, and lack of an output schema, the description sufficiently explains the tool's capability and a key prerequisite. It could mention default behavior when no parameters are provided, but 'find all block references' is already implied, so it is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters with descriptions, providing a solid baseline. The description adds relationship semantics: block_uid targets a specific block, title targets page references, and page_title_uid scopes the search to a page or graph-wide. This helps agents understand how to combine parameters effectively.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search for block references within a page or across the entire graph' and lists specific modes (specific block, page title, all references). This makes the tool's purpose unambiguous and distinguishes it from sibling text-search tools like roam_search_by_text, even though no alternatives are named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys when to use the tool (searching for references) and gives an explicit directive to call roam_get_guidelines first due to convention-dependent behavior. It does not explicitly compare with alternative search tools for when not to use it, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_search_by_dateARead-onlyIdempotent
Search for blocks or pages based on creation or modification dates. Not for daily pages with ordinal date titles.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Whether to search by creation date, modification date, or both | |
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| scope | Yes | Whether to search blocks, pages | |
| end_date | No | Optional: End date in ISO format (YYYY-MM-DD) | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| start_date | Yes | Start date in ISO format (YYYY-MM-DD) | |
| include_content | No | Whether to include the content of matching blocks/pages |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare read-only, idempotent, and non-destructive behavior. The description adds valuable context by requiring a call to roam_get_guidelines and warning that conventions change how results are read, going beyond what annotations and schema provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, front-loaded with the core action and followed by a critical exclusion and warning. Every sentence earns its place, and the formatting makes the important prerequisite prominent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 7 parameters, no output schema, and rich annotations, the description plus schema is almost sufficient. It provides a mandatory guidelines call and exclusion, but could benefit from a brief note on result format or edge cases like end_date inclusivity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage for all 7 parameters, so the baseline is 3. The description does not add any parameter-specific details, examples, or additional meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches blocks/pages by creation or modification dates, and includes an explicit exclusion for daily pages with ordinal date titles. It is specific and actionable, but does not explicitly name sibling alternatives to differentiate from.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Not for daily pages with ordinal date titles' (when-not) and instructs to call roam_get_guidelines once per session before using the tool (prerequisite). This provides clear usage context, even though it does not name an alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_search_by_statusARead-onlyIdempotent
Search for blocks with a specific status (TODO/DONE) across all pages or within a specific page.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| status | Yes | Status to search for (TODO or DONE) | |
| exclude | No | Optional: Comma-separated list of terms to filter results by exclusion (matches content or page title) | |
| include | No | Optional: Comma-separated list of terms to filter results by inclusion (matches content or page title) | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| page_title_uid | No | Optional: Title or UID of the page to search in (UID is preferred for accuracy). If not provided, searches across all pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds a meaningful behavioral nuance: graph conventions can change how results are read, not just written, and guidelines must be fetched once per session. This goes beyond the annotations and aids correct usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the purpose, the second delivers a critical usage prerequisite. It is front-loaded, concise, and every word adds value. No redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity and full schema coverage, the description is complete for selection and invocation. It discloses the prerequisite call, the scope options, and the status filter. It does not describe return format, but search tools without output schema are often self-explanatory. Minor gap: no mention of exclude/include filters beyond the schema, but those are documented there.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with detailed descriptions for all 6 parameters. The description does not add syntax or format details beyond the schema, so the baseline 3 is appropriate. The scope behavior (all pages vs specific page) is already captured in the page_title_uid parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches for blocks by status (TODO/DONE) across all pages or a specific page. The verb 'search' plus resource 'blocks' and filter 'status' makes the purpose specific and distinguishes it from sibling search tools like roam_search_by_text or roam_search_by_date.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit prerequisite: call roam_get_guidelines before using this tool, even for reads. It also mentions the optional scope (all pages vs a specific page). However, it does not explicitly contrast with alternative search tools or state when-not-to-use, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_search_by_textARead-onlyIdempotent
Search for blocks containing specific text across all pages or within a specific page. Use scope: "page_titles" to search for pages by namespace prefix (e.g., "Convention/" finds all pages starting with that prefix). This tool supports pagination via the limit and offset parameters.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to search for. When scope is "page_titles", this is the namespace prefix (trailing slash optional). | |
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| limit | No | Optional: The maximum number of results to return. Defaults to 50. Use -1 for no limit, but be aware that very large results sets can impact performance. | |
| scope | No | Search scope: "blocks" for block content (default), "page_titles" for page title namespace prefix matching. | blocks |
| offset | No | Optional: The number of results to skip before returning matches. Useful for pagination. Defaults to 0. | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| case_sensitive | No | Optional: Whether the search should be case-sensitive. If false, it will search for the provided text, capitalized versions, and first word capitalized versions. Only used when scope is "blocks". | |
| page_title_uid | No | Optional: Title or UID of the page to search in (UID is preferred for accuracy). If not provided, searches across all pages. Only used when scope is "blocks". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool read-only, idempotent, and non-destructive, lowering the bar. The description adds a meaningful behavioral note: graph conventions affect how results are read, not just written, implying results can vary between graphs. It also mentions pagination support, though the schema already documents limit/offset.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: two sentences covering core functionality and a one-sentence important note. It front-loads the primary purpose, explains the alternate scope, then delivers the essential prerequisite. Every sentence earns its place without fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 8 parameters but only 1 required, full schema coverage, and complete annotations, the description adds the crucial missing context: a session-level prerequisite to call roam_get_guidelines because conventions affect reads. The namespace prefix example clarifies a non-obvious mode. No output schema exists, but the return value for a block/page search tool is self-evident.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all 8 parameters, so the baseline is 3. The description's mentions of `scope: 'page_titles'`, the namespace prefix example, and pagination via `limit`/`offset` all reinforce but do not add substantive meaning beyond what the parameter descriptions already provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Search for blocks containing specific text across all pages or within a specific page,' a specific verb and resource. It clearly distinguishes the free-text blocks search from the namespace-prefix page_titles mode, and the availability of these two modes helps set it apart from sibling search tools like roam_search_for_tag or roam_search_by_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: it tells the agent to use scope 'page_titles' for namespace prefix searches and includes an 'IMPORTANT' instruction to call roam_get_guidelines once per session because conventions change how results are read. It lacks explicit exclusions or direct references to sibling alternatives, but the context is strong enough to guide appropriate selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_search_for_tagARead-onlyIdempotent
Search for blocks containing a specific tag. Use primary_tag for the tag to find, and optionally page_title_uid to limit search to a specific page. Supports pagination via limit and offset. Use this tool to search for memories tagged with the ROAM_MEMORIES_TAG.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| limit | No | Optional: The maximum number of results to return. Defaults to 50. Use -1 for no limit, but be aware that very large results sets can impact performance. | |
| offset | No | Optional: The number of results to skip before returning matches. Useful for pagination. Defaults to 0. | |
| near_tag | No | Optional: Another tag to filter results by - will only return blocks where both tags appear | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| primary_tag | Yes | The main tag to search for (without the [[ ]] brackets) | |
| case_sensitive | No | Optional: Whether the search should be case-sensitive. If false, it will search for the provided tag, capitalized versions, and first word capitalized versions. | |
| page_title_uid | No | Optional: Title or UID of the page to search in (UID is preferred for accuracy). Defaults to today's daily page if not provided. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds behavior beyond annotations by mentioning pagination via limit/offset and the important note that conventions change how results are read, requiring a one-time call to roam_get_guidelines. This enriches the agent's understanding of how to invoke and interpret results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short paragraphs, front-loaded with the primary purpose. The second paragraph is an important, non-obvious prerequisite that earns its place. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description doesn't detail the return structure, but the purpose implies a list of blocks. It covers the key parameters, pagination, page scoping, and a critical guideline call. This is sufficient for a read-only search tool with good annotation coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 8 parameters are documented. The description briefly references primary_tag, page_title_uid, limit, and offset, but doesn't add meaningful semantics beyond the schema—it mostly repeats the schema's parameter descriptions. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Search for blocks containing a specific tag', which clearly states the verb (search) and resource (blocks with a tag). It also differentiates from sibling search tools by emphasizing tag-based search and gives a concrete use case ('search for memories tagged with the ROAM_MEMORIES_TAG').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context with 'Use this tool to search for memories tagged with the ROAM_MEMORIES_TAG' and instructs to call roam_get_guidelines first. It doesn't explicitly name alternatives or when-not cases, but the tag-focused purpose and required preliminary call give sufficient guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_search_hierarchyARead-onlyIdempotent
Search for parent or child blocks in the block hierarchy. Can search up or down the hierarchy from a given block.
IMPORTANT: call roam_get_guidelines for this graph once per session before using this tool, reads included — conventions change how results are read, not just written.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| child_uid | No | Optional: UID of the block to find parents of | |
| max_depth | No | Optional: How many levels deep to search (default: 1) | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. | |
| parent_uid | No | Optional: UID of the block to find children of | |
| page_title_uid | No | Optional: Title or UID of the page to search in (UID is preferred for accuracy). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety. The description adds valuable behavioral context: the ability to search both up and down, and the critical caveat that per-graph conventions affect how results are read. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short paragraphs: the first front-loads the core purpose, the second delivers an essential prerequisite note. No filler words, every sentence earns its place, and the structure is easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (6 optional params, no output schema), the description covers the essential behavioral scope and a critical prerequisite. It does not explain edge cases like providing both parent_uid and child_uid, or default behavior when neither is given, but the annotations and schema fill many gaps, making the description reasonably complete for a read-only search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with descriptions for all six parameters, so the baseline is 3. The description adds minimal extra meaning beyond the schema, mainly correlating 'from a given block' with parent/child UID parameters. It does not elaborate on parameter interactions (e.g., mutual exclusivity), but the schema already handles the basics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Search for parent or child blocks') on a specific resource ('block hierarchy'), and clarifies the directional capability ('up or down') from a given block. This clearly distinguishes it from sibling search tools like roam_search_by_text or roam_search_by_status, which operate on content or status rather than hierarchy.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes it obvious when to use this tool: when you need to traverse parent/child relationships in the block hierarchy. It also provides a mandatory prerequisite instruction to call roam_get_guidelines once per session, which is concrete usage guidance. However, it does not explicitly mention alternatives or when not to use this tool, so it falls short of the strongest 'when-not' clarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roam_update_page_markdownADestructiveIdempotent
Update an existing page with new markdown content using smart diff. Preserves block UIDs where possible and generates minimal changes. This is ideal for:
Syncing external markdown files to Roam
AI-assisted content updates that preserve references
Batch content modifications without losing block references
⚠️ This REPLACES the page, it does not append. Any block your markdown does not account for is deleted. Pass the complete intended page, or use roam_process_batch_actions / roam_create_outline to change only part of one. Use dry_run: true to see the actions first.
How it works:
Fetches existing page blocks
Matches new content to existing blocks by text similarity
Generates minimal create/update/move/delete operations
Preserves UIDs for matched blocks (keeping references intact)
#.rm-hide / #.rm-private subtrees are excluded from the diff and left untouched — you cannot see them, so you cannot be asked to account for them. preserved_hidden reports how many, when any.
IMPORTANT: call roam_get_guidelines for this graph once per session, and load the Roam Markdown Cheatsheet, before using this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Target graph key from ROAM_GRAPHS config. Defaults to ROAM_DEFAULT_GRAPH. Only needed in multi-graph mode. | |
| title | Yes | Title of the page to update | |
| dry_run | No | If true, returns the planned actions without executing them. Useful for previewing changes. | |
| markdown | Yes | New GFM markdown content for the page | |
| write_key | No | Write confirmation key. Required for write operations on non-default graphs when write_key is configured. |
Output Schema
| Name | Required | Description |
|---|---|---|
| stats | Yes | |
| actions | Yes | Roam batch actions applied (or planned, when dry_run) |
| success | Yes | |
| summary | Yes | |
| preserved_uids | Yes | Blocks whose UIDs survived the diff, so refs to them still resolve |
| preserved_hidden | No | Present only when non-zero: how many #.rm-hide / #.rm-private blocks were excluded from the diff and left on the page untouched |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description explicitly discloses that 'This REPLACES the page' and any unaccounted block is deleted. It explains the smart diff algorithm step-by-step, mentions hidden subtrees are excluded and left untouched, and that `preserved_hidden` reports the count. It also notes the requirement to call guidelines once per session, offering deep behavioral insight beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite being long, the description is well-structured with clear sections: summary, use cases, warning, how-it-works steps, hidden subtree note, and important prerequisite. Every sentence adds critical information, and the formatting (bullets, bold warning, numbered list) makes it scannable. It is appropriately detailed for a complex, destructive tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is exceptionally complete given the tool's complexity. It covers purpose, alternatives, destructive behavior, algorithm steps, hidden content handling, output hints, and required prior steps. Combined with rich schema and annotations, the agent has all necessary context to select and invoke the tool safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds some context around `dry_run` usage and mentions `preserved_hidden` (an output field), but does not provide additional meaning for the parameters beyond what the schema already documents. It reinforces the purpose but does not elevate semantic understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'Updates an existing page with new markdown content using smart diff' and lists specific use cases. It distinguishes itself from siblings by explicitly naming alternatives like `roam_process_batch_actions` and `roam_create_outline` for partial edits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use the tool ('ideal for syncing...', 'AI-assisted content updates...') and when not to, warning that it replaces the whole page and directing to alternatives for partial changes. It also instructs to use `dry_run: true` and to call `roam_get_guidelines` first, covering prerequisites and exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v3.1.0- Changed
roam_fetch_page_by_title1 field changed- changed
Input schema / properties / format / descriptionPrevious value: -"Format output as markdown, JSON, or structure. 'markdown' returns readable string; 'raw' returns full JSON with nested blocks; 'structure' returns flattened list optimized for surgical updates (uid, order, text preview, depth, parent_uid)"New value: +"Format output as markdown, JSON, or structure. 'markdown' returns readable string; 'raw' returns full JSON with nested blocks; 'structure' returns a flattened list (uid, order, text, depth, parent_uid) for locating blocks to update. In 'structure', `text` is a PREVIEW cut at 80 characters — an entry marked `truncated: true` is a fragment, and writing it back would replace the block with its own opening. Use it to find the uid, then fetch that block with roam_fetch_block before editing its text."
- Changed
roam_update_page_markdown1 field changed- added
Output schema / properties / preserved_hiddenAdded value: +{ + "description": "Present only when non-zero: how many #.rm-hide / #.rm-private blocks were excluded from the diff and left on the page untouched", + "type": "number" +}
11 tool updates
v3.0.0- Changed
roam_add_todo1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
roam_create_outline1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "created_blocks": { + "description": "The created block tree. Objects, not UID strings.", + "items": { + "additionalProperties": true, + "properties": { + "children": { + "description": "Nested NestedBlock objects, same shape as this one", + "type": "array" + }, + "level": { + "type": "number" + }, + "order": { + "type": "number" + }, + "text": { + "type": "string" + }, + "uid": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "page_uid": { + "type": "string" + }, + "parent_uid": { + "description": "Block the outline was nested under", + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success", + "page_uid", + "parent_uid", + "created_blocks" + ], + "type": "object" +}
- Changed
roam_create_page1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "page_uid": { + "description": "UID of the created page", + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success", + "page_uid" + ], + "type": "object" +}
- Changed
roam_create_table1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actions_attempted": { + "type": "number" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": true, + "properties": { + "code": { + "type": "string" + }, + "details": { + "additionalProperties": true, + "properties": { + "action_index": { + "type": "number" + }, + "expected": { + "type": "string" + }, + "field": { + "type": "string" + }, + "received": { + "type": "string" + } + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "recovery": { + "additionalProperties": true, + "properties": { + "retry_after_ms": { + "type": "number" + }, + "suggestion": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + ], + "description": "Present only when success is false." + }, + "success": { + "type": "boolean" + }, + "table_uid": { + "type": "string" + }, + "uid_map": { + "additionalProperties": { + "type": "string" + }, + "description": "Placeholder name → generated UID. Present only on success.", + "type": "object" + }, + "validation_passed": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Added
roam_get_guidelines - Changed
roam_import_markdown1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "created_blocks": { + "description": "The created block tree. Objects, not UID strings.", + "items": { + "additionalProperties": true, + "properties": { + "children": { + "description": "Nested NestedBlock objects, same shape as this one", + "type": "array" + }, + "level": { + "type": "number" + }, + "order": { + "type": "number" + }, + "text": { + "type": "string" + }, + "uid": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "page_uid": { + "type": "string" + }, + "parent_uid": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success", + "page_uid", + "parent_uid", + "created_blocks" + ], + "type": "object" +}
- Changed
roam_move_block1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "block_uid": { + "type": "string" + }, + "new_parent_uid": { + "type": "string" + }, + "order": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success", + "block_uid", + "new_parent_uid", + "order" + ], + "type": "object" +}
- Changed
roam_process_batch_actions1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actions_attempted": { + "type": "number" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": true, + "properties": { + "code": { + "type": "string" + }, + "details": { + "additionalProperties": true, + "properties": { + "action_index": { + "type": "number" + }, + "expected": { + "type": "string" + }, + "field": { + "type": "string" + }, + "received": { + "type": "string" + } + }, + "type": "object" + }, + "message": { + "type": "string" + }, + "recovery": { + "additionalProperties": true, + "properties": { + "retry_after_ms": { + "type": "number" + }, + "suggestion": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + ], + "description": "Present only when success is false." + }, + "success": { + "type": "boolean" + }, + "uid_map": { + "additionalProperties": { + "type": "string" + }, + "description": "Placeholder name → generated UID. Present only on success.", + "type": "object" + }, + "validation_passed": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
roam_remember1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "block_uid": { + "description": "UID of the stored memory block", + "type": "string" + }, + "parent_uid": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" +}
- Changed
roam_rename_page1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "message": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success", + "message" + ], + "type": "object" +}
- Changed
roam_update_page_markdown1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "actions": { + "description": "Roam batch actions applied (or planned, when dry_run)", + "type": "array" + }, + "preserved_uids": { + "description": "Blocks whose UIDs survived the diff, so refs to them still resolve", + "items": { + "type": "string" + }, + "type": "array" + }, + "stats": { + "additionalProperties": true, + "properties": { + "creates": { + "type": "number" + }, + "deletes": { + "type": "number" + }, + "moves": { + "type": "number" + }, + "preserved": { + "type": "number" + }, + "updates": { + "type": "number" + } + }, + "type": "object" + }, + "success": { + "type": "boolean" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "success", + "actions", + "stats", + "preserved_uids", + "summary" + ], + "type": "object" +}
7 tool updates
v2.17.0- Changed
roam_create_outline1 field changed- added
Input schema / properties / orderAdded value: +{ + "description": "Insertion position for the first level-1 block relative to existing page/block children. Accepts \"first\", \"last\", or a non-negative integer (0-indexed). Default: \"last\".", + "type": [ + "string", + "integer" + ] +}
- Added
roam_fetch_block - Removed
roam_fetch_block_with_children - Added
roam_fetch_page_full_view - Added
roam_get_subpages - Changed
roam_import_markdown1 field changed- changed
Input schema / properties / order / descriptionPrevious value: -"Optional: Where to add the content undeIs this tr the parent (\"first\" or \"last\")"New value: +"Optional: Where to add the content under the parent (\"first\" or \"last\"). Defaults to \"first\"."
- Changed
roam_process_batch_actions1 field changed- changed
Input schema / properties / actions / items / properties / string / descriptionPrevious value: -"The content for the block, used in \"create-block\" and \"update-block\" actions."New value: +"The content for the block, used in \"create-block\" and \"update-block\" actions. Supports all Roam syntax: [[page refs]], ((block refs)), {{[[embed]]: ((uid))}}, {{[[embed-children]]: ((uid))}}, {{[[embed-path]]: ((uid))}}, {{[[TODO]]}}, {{[[table]]}}, {{[[mermaid]]}}, {{word-count}}, :hiccup, etc."
22 tool updates
v2.13.0- First observed
roam_add_todo - First observed
roam_create_outline - First observed
roam_create_page - First observed
roam_create_table - First observed
roam_datomic_query - First observed
roam_fetch_block_with_children - First observed
roam_fetch_page_by_title - First observed
roam_find_pages_modified_today - First observed
roam_import_markdown - First observed
roam_markdown_cheatsheet - First observed
roam_move_block - First observed
roam_process_batch_actions - First observed
roam_recall - First observed
roam_remember - First observed
roam_rename_page - First observed
roam_search_block_refs - First observed
roam_search_by_date - First observed
roam_search_by_status - First observed
roam_search_by_text - First observed
roam_search_for_tag - First observed
roam_search_hierarchy - First observed
roam_update_page_markdown
TDQS
Scored across 25 tools
Most tools have clearly distinct purposes (create page, fetch block, search by text, etc.), but there is some overlap between search tools (roam_search_by_text, roam_search_for_tag, roam_search_by_status, roam_search_by_date, roam_search_hierarchy, roam_search_block_refs) and between content-creation tools (roam_create_outline, roam_import_markdown, roam_process_batch_actions) that could cause misselection without careful reading.
The naming convention is mostly consistent with a roam_ prefix followed by verb_noun (e.g., roam_create_page, roam_fetch_block, roam_search_by_text). Minor deviations exist: roam_remember/roam_recall use non-descriptive verbs, and roam_get_subpages uses 'get' while most reads use 'fetch' or 'search'.
25 tools is on the high end but justifiable for a full-featured Roam Research MCP server covering pages, blocks, search, queries, and memory features. It is slightly heavy, but each tool addresses a distinct Roam capability.
The tool surface covers the full lifecycle: page create/read/update/rename, block-level operations via batch actions, multiple search dimensions, advanced Datomic queries, and memory/recall features. The only minor gap is no dedicated delete-page tool, but block deletion is covered via roam_process_batch_actions.
Maintenance
Related MCP Connectors
Zotero MCP server for Claude and ChatGPT: search, citations, safe writes, PDF passages and pages.
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Personal CRM for Claude. Contacts live as plain-text files in your own Google Drive.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides a standardized interface for AI assistants to interact with Obsidian vaults through a local REST API, enabling reading, writing, searching, and managing notes.67MIT
- AlicenseNot gradedqualityDmaintenanceA server that enables AI assistants like Claude to interact with Roam Research graphs through a standardized interface, providing comprehensive tools for content creation, search, retrieval, and optional memory management.8MIT
- FlicenseAqualityDmaintenanceA Model Context Protocol server that enables Claude Desktop to read from and write to Roam Research graphs, allowing for retrieving page content, finding references, and adding blocks to existing or daily pages.41-
- AlicenseAqualityNot gradedmaintenanceEnables AI assistants to interact with Roam Research graphs through comprehensive API access, supporting page/block operations, markdown import, search, memory storage, and complex batch actions for managing knowledge graphs.18432 npm-