Skip to main content
Glama
happytk
by happytk

roam-mcp

Roam Research MCP 서버 — Cloudflare Workers에 배포하여 Claude.ai 모바일을 포함한 모든 MCP 클라이언트에서 Roam Research 그래프에 접근할 수 있습니다.

구성

[Claude.ai / Claude Desktop / 모바일] → [Cloudflare Worker] → [Roam Research API]

Related MCP server: Remote MCP Server

사전 준비

Roam API 토큰 발급

  1. roamresearch.com 접속 후 그래프 열기

  2. 우측 상단 ...SettingsAPI tokens

  3. + New API Token 클릭하여 발급

  4. 토큰 형식: roam-graph-token-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

설치 및 배포

순서가 중요합니다. Secret은 Worker가 배포된 후에 등록해야 안정적으로 동작합니다.

1. 의존성 설치

npm install

2. Cloudflare 로그인

npx wrangler login

브라우저가 열리면 Cloudflare 계정으로 로그인합니다.

3. KV namespace 생성 (OAuth 토큰 저장용, 필수)

OAuth provider 가 grant/access token 을 저장할 KV namespace 를 1개 만듭니다:

npx wrangler kv namespace create OAUTH_KV

출력에 찍히는 id = "..." 값을 복사해서 wrangler.toml 의 placeholder 자리에 붙여넣습니다:

[[kv_namespaces]]
binding = "OAUTH_KV"
id = "여기에-출력된-ID-붙여넣기"

KV namespace ID 는 secret 이 아닙니다 — 외부에서 직접 접근할 수 없는 계정 내부 식별자라 평문 커밋해도 안전합니다. 비용은 무료 티어 안에서 충분 (100k reads/day, 1k writes/day).

3-b. R2 버킷 생성 (이미지 업로드 도구용, 선택)

roam_upload_image 를 사용하려면 R2 버킷이 필요합니다. 사용 안 할 거면 이 단계 건너뛰어도 다른 도구는 정상 동작합니다.

npx wrangler r2 bucket create roam-images

생성한 뒤 Cloudflare Dashboard → R2 → roam-imagesSettings 에서 다음 중 하나를 선택:

  • r2.dev 공개 접근 활성화 (빠른 시작): Public accessAllow Accesspub-<hash>.r2.dev URL 발급

  • 커스텀 도메인 연결 (장기 운영용): Custom DomainsConnect Domain → 본인 도메인의 서브도메인 (예: img.happytk.dev) 입력

발급된 base URL 을 wrangler.toml[vars] R2_PUBLIC_BASE_URL 에 붙여넣고 재배포합니다:

[vars]
R2_PUBLIC_BASE_URL = "https://pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.dev"

이 버킷은 단일 버킷 + <graph>/... prefix 로 그래프별 격리. 즉 같은 객체 listing 권한도 한 곳만 관리하면 됩니다. r2.dev URL 은 그대로 두고 나중에 custom domain 으로 갈아끼우려면 R2_PUBLIC_BASE_URL 한 줄만 바꾸면 됨.

저작권 / 사용 의도: 이 버킷은 개인 학습·주석 용도이며 third-party 콘텐츠를 public 배포할 의도가 없습니다. 객체 키에 random suffix 8자 이상을 포함해 enumeration 을 어렵게 두지만, 공유가 곤란한 자료는 업로드하지 마세요.

4. 그래프 이름 설정 (선택 — env 폴백 / /check 용)

그래프 이름은 secret으로 등록합니다. (5단계의 토큰과 같은 방식)

npx wrangler secret put ROAM_GRAPH_NAME

그래프 이름은 Roam URL roamresearch.com/#/app/<graph-name><graph-name> 과 정확히 일치해야 합니다. 대소문자와 하이픈까지 동일해야 합니다.

이 값은 OAuth 흐름과 무관한 폴백입니다 — /check 엔드포인트와 환경변수 기반 호출(curl/CI)에서 사용. Claude.ai 처럼 OAuth 로 연결되는 클라이언트는 이 값을 무시하고 사용자가 /authorize 에서 직접 입력한 graph + token 을 grant 단위로 사용합니다. 한 Worker 에 그래프 N 개를 붙이려면 OAuth 흐름이 정도이고, 이 secret 은 단일 그래프 환경에 편의용입니다.

5. 최초 배포 (Worker 생성)

npx wrangler deploy

이 시점에서는 ROAM_API_TOKEN 이 없어서 API 호출은 실패하지만, Worker 자체는 생성됩니다. 배포 완료 시 URL이 출력됩니다:

https://roam-mcp.{your-account}.workers.dev

6. API 토큰을 Secret으로 등록 (선택 — env 폴백 / /check 용)

npx wrangler secret put ROAM_API_TOKEN

프롬프트에 Roam API 토큰을 앞뒤 공백 없이 붙여넣습니다. (.dev.varswrangler.toml에 평문으로 저장하지 않음)

주의: 토큰은 roam-graph-token- 으로 시작해야 합니다. roam-graph-local-token- 으로 시작하는 로컬 전용 토큰은 API로 사용할 수 없습니다.

등록 확인:

npx wrangler secret list

Secret은 즉시 반영되므로 재배포가 필요하지 않습니다.

7. 토큰 검증 (선택)

셋업이 올바른지 한 번에 확인할 수 있는 진단 엔드포인트입니다:

curl https://roam-mcp.{your-account}.workers.dev/check

성공 응답:

{
  "ok": true,
  "graph": "your-graph-name",
  "message": "Token and graph name are valid. Roam API responded successfully.",
  "sampleCount": 1
}

실패 응답 예시와 대응:

stage

원인

해결

token + "not set"

Secret이 미등록

6단계 재실행

token + "does not start with"

토큰 접두사 오류

roam-graph-token-으로 시작하는 토큰으로 재등록

roam-api + "Token cannot be verified"

토큰이 해당 그래프 소유가 아님

그래프 이름/토큰 매칭 재확인

roam-api + "404"

그래프 이름 오타

wrangler.toml 수정 후 npx wrangler deploy

8. MCP 엔드포인트 동작 확인

curl https://roam-mcp.{your-account}.workers.dev/
# {"status":"ok","server":"roam-research-mcp","graph":"your-graph-name","tokenConfigured":true,"oauth":{...}}

# OAuth metadata (Claude.ai 가 자동으로 fetch)
curl https://roam-mcp.{your-account}.workers.dev/.well-known/oauth-authorization-server

# curl/CI: env 폴백 토큰 또는 직접 Bearer 토큰으로 호출 (resolveExternalToken 경로)
curl -X POST https://roam-mcp.{your-account}.workers.dev/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer roam-graph-token-..." \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

인증 모델

서버는 두 가지 인증 경로를 지원합니다 (한 Worker 가 둘 다 동시에 처리):

  1. OAuth 2.1 (Claude.ai 등 원격 MCP 커넥터용) — Claude.ai 가 /.well-known/oauth-authorization-server 로 메타데이터 발견 → DCR 로 클라이언트 등록 → 사용자가 /authorize 페이지에서 graph + roam-graph-token 입력 → 서버가 토큰을 Roam API 에 검증한 뒤 grant 발급. 이후 모든 요청은 OAuth access token (Bearer) 으로 인증되고, grant 에 묶인 graph + token 이 ctx.props 로 핸들러에 주입됨. 그래프 N 개 = grant N 개 = 별도 OAuth 토큰 N 개.

  2. External token passthrough (curl/CI 호환)Authorization: Bearer roam-graph-token-... 처럼 토큰 자체가 roam-graph-token- 으로 시작하면 OAuth 조회를 건너뛰고 그대로 사용. graph 는 path/header/query/env 중에서 결정. 환경변수만 세팅된 단일 그래프 셋업이나 스크립트 호출에 편리.

요청별 설정 (per-request override)

매 요청마다 그래프/토큰/옵션을 OAuth grant, 헤더, path, query 중 어느 것으로든 전달할 수 있습니다. 우선순위: OAuth props > header > query > path > env. OAuth grant 가 있으면 이를 신뢰하고 외부 헤더/query 로 graph·token 을 덮어쓸 수 없습니다 (스푸핑 방어). 플래그(aiTag/mutate/dryRun)는 grant 와 무관하게 매 요청마다 토글 가능.

1) 헤더 — curl, CI, Claude Desktop 등 커스텀 헤더가 가능한 클라이언트

헤더

의미

기본값

X-Roam-Graph

그래프 이름

path → ROAM_GRAPH_NAME 환경변수 (없으면 에러)

X-Roam-Token

API 토큰 (Authorization: Bearer ... 도 허용)

ROAM_API_TOKEN 시크릿 (없으면 에러)

X-Roam-Ai-Tag

루트 블록·신규 페이지에 #ai 자동 태그 부착 여부. false/0/off/no 면 끔

true (켜짐)

X-Roam-Mutate

true/1/on/yes 면 update/delete/move 도구를 노출. 끄면 tools/list에서도 숨겨지고 호출도 거부됨

false (꺼짐)

X-Roam-Dry-Run

true이면 모든 쓰기 호출이 no-op이 되고 응답에 dry_run: true 포함. 권한 검증/사전 시뮬레이션 용도

false (꺼짐)

curl -X POST https://roam-mcp.{your-account}.workers.dev/mcp \
  -H "Content-Type: application/json" \
  -H "X-Roam-Graph: my-graph" \
  -H "X-Roam-Token: roam-graph-token-..." \
  -H "X-Roam-Ai-Tag: false" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

2) Path + Query — Claude.ai 커넥터처럼 커스텀 헤더를 못 보내는 클라이언트

Claude.ai 의 Custom Connector UI 는 Authorization: Bearer ... 외 임의 헤더를 추가할 수 없습니다. 이 경우 그래프는 path 로, 플래그는 query string 으로 인코딩하면 헤더 방식과 동일한 결과를 얻을 수 있습니다. 한 Worker 배포에 그래프별 커넥터를 N 개 등록하는 패턴입니다.

위치

의미

path

/g/<graph>/mcp

그래프 이름. /mcp, /check 모두 /g/<graph>/ 프리픽스 아래에서 동작

query

?graph=<graph>

path 대신 query 로도 그래프 지정 가능

query

?aiTag=0

#ai 자동 태그 끔 (ai_tag 도 허용)

query

?mutate=1

mutation 도구 노출

query

?dryRun=1

모든 쓰기 no-op (dry_run 도 허용)

토큰은 query 에 넣지 마세요. URL 은 액세스 로그·브라우저 히스토리·Referer 헤더에 그대로 남습니다. 토큰은 반드시 Authorization: Bearer ... 헤더(Claude.ai 커넥터의 표준 토큰 슬롯)로 전달하세요.

Claude.ai 에 등록할 URL 예시 — 그래프마다 별도 커넥터로 등록:

https://roam-mcp.{your-account}.workers.dev/g/personal/mcp
https://roam-mcp.{your-account}.workers.dev/g/work/mcp?mutate=1
https://roam-mcp.{your-account}.workers.dev/g/sandbox/mcp?mutate=1&dryRun=1

각 커넥터의 인증 토큰 칸에는 해당 그래프의 roam-graph-token-... 을 넣으면 됩니다.

MCP 클라이언트 연결

Claude.ai (모바일 포함) — OAuth 흐름

  1. claude.aiSettingsIntegrations

  2. Add Integration 클릭

  3. URL 입력 (그래프별 1 개씩 등록):

    • https://roam-mcp.{your-account}.workers.dev/g/personal/mcp

    • https://roam-mcp.{your-account}.workers.dev/g/work/mcp?mutate=1

    • https://roam-mcp.{your-account}.workers.dev/g/sandbox/mcp?mutate=1&dryRun=1

  4. Claude.ai 가 자동으로 OAuth metadata 를 발견하고 인증 페이지로 이동시킵니다.

  5. 우리 /authorize 페이지가 뜨면:

    • Graph name: URL path 에서 자동으로 채워집니다 (/g/personal/...personal). 비어 있으면 직접 입력.

    • Roam API token: 해당 그래프의 roam-graph-token-... 붙여넣기.

    • Authorize 클릭 → 서버가 Roam API 로 토큰 검증 → Claude.ai 로 자동 redirect.

  6. 인증 완료. 이후 Claude.ai 가 보내는 모든 요청은 OAuth access token 으로 인증되고, 입력하신 graph + token 이 grant 에 묶여 사용됩니다.

토큰을 갱신하거나 권한을 회수하려면 Claude.ai 에서 해당 connector 를 disconnect → 다시 등록하면 됩니다 (새 OAuth grant 발급). 서버 KV 의 grant 는 access/refresh token TTL 에 따라 만료됩니다.

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json 수정:

{
  "mcpServers": {
    "roam-research": {
      "command": "npx",
      "args": ["-y", "roam-research-mcp"],
      "env": {
        "ROAM_API_TOKEN": "roam-graph-token-...",
        "ROAM_GRAPH_NAME": "your-graph-name"
      }
    }
  }
}

Claude Desktop은 roam-research-mcp npm 패키지를 로컬에서 직접 실행하는 방식도 사용할 수 있습니다.

로컬 개발

.dev.vars.example 파일을 복사해 .dev.vars 를 만듭니다 (.gitignore에 포함됨):

cp .dev.vars.example .dev.vars
# 이후 .dev.vars 파일을 열어 본인 토큰과 그래프 이름으로 수정

.dev.vars로컬 npm run dev 전용입니다. 배포 환경에는 영향을 주지 않으며, 배포 환경은 wrangler secret put 으로 등록한 값을 사용합니다.

로컬 서버 실행:

npm run dev
# http://localhost:8787 에서 실행

# 로컬에서도 /check 로 검증 가능
curl http://localhost:8787/check

CI/CD (GitHub Actions)

.github/workflows/ci.yml 이 포함되어 있습니다:

  • PR: tsc --noEmit 타입 체크만 수행

  • main 푸시: 타입 체크 → wrangler deploy/check 스모크 테스트

배포 결과가 성공으로 찍혀도 토큰이 깨진 상태면 /check 가 실패하므로 워크플로 전체가 실패 처리됩니다.

필요한 GitHub Secrets

리포지토리 Settings → Secrets and variables → Actions → Secrets 에 등록:

이름

CLOUDFLARE_API_TOKEN

Cloudflare Dashboard → My Profile → API Tokens → Create Token → "Edit Cloudflare Workers" 템플릿

CLOUDFLARE_ACCOUNT_ID

Cloudflare Dashboard 우측 사이드바의 Account ID

ROAM_API_TOKEN

(선택) /check 스모크 테스트용 폴백 토큰

ROAM_GRAPH_NAME

(선택) /check 스모크 테스트용 폴백 그래프 이름

OAuth 흐름은 KV 에 저장된 grant 만 쓰므로 ROAM_API_TOKEN/ROAM_GRAPH_NAME 은 더 이상 운영에 필수가 아닙니다. CI 의 /check 스모크 테스트가 빨리 끝나도록 둘 다 등록해두는 것을 권장합니다. OAUTH_KV namespace ID 는 secret 이 아니므로 wrangler.toml 에 직접 박아두세요.

필요한 GitHub Variables (선택)

Settings → Secrets and variables → Actions → Variables 에 등록:

이름

WORKER_URL

https://roam-mcp.<your-account>.workers.devwrangler-action 이 deployment URL을 반환하지 못할 때 스모크 테스트에서 사용

제공 도구

도구

설명

roam_find_pages_modified_today

오늘 수정된 페이지 목록 조회

roam_fetch_page_by_title

제목으로 페이지 전체 내용 조회

roam_search_by_text

텍스트 전체 검색

roam_search_for_tag

특정 태그/페이지를 참조하는 블록 검색

roam_search_by_status

TODO / DONE / LATER 상태별 블록 검색

roam_create_page

새 페이지 생성 (데일리 노트에는 사용 금지)

roam_add_todo

TODO 항목 추가 (page 생략 시 오늘 데일리 노트)

roam_create_block

블록 추가 (page 생략 시 오늘 데일리 노트)

roam_update_block

기존 블록 텍스트 교체 (uid 기반)

roam_delete_block

블록과 그 자식들 영구 삭제

roam_move_block

블록을 다른 부모/페이지로 이동

roam_rename_page

페이지 제목 변경

roam_delete_page

페이지와 모든 블록을 영구 삭제 (블록 삭제보다 파급 큼)

roam_datomic_query

직접 Datalog 쿼리 실행

roam_upload_image

base64 이미지를 R2 에 업로드하고 Roam 블록에 붙여넣을 마크다운 스니펫과 public URL 반환 (책 그림 + 출처 메타데이터 보존용)

⚑ 표시는 mutate 도구 — 기본 OFF. 요청에 X-Roam-Mutate: true 헤더를 보내야 노출되고 호출 가능. dry-run 시뮬레이션은 X-Roam-Dry-Run: true 헤더로.

LLM이 지켜야 할 Roam 컨벤션

서버가 MCP initialize 응답의 instructions 필드로 아래 규칙을 LLM에 전달합니다. 개별 도구 description에도 동일 규칙이 박혀 있어서 도구 호출 직전에도 다시 읽게 됩니다.

  1. 데일리 노트 제목은 ordinal suffix 필수: April 16th, 2026 ✅ / April 16, 2026 ❌ Roam은 접미사 유무에 따라 완전히 다른 페이지로 취급합니다.

  2. "오늘"에 쓸 때는 page 인자를 생략. roam_add_todoroam_create_block 둘 다 page 미지정 시 서버가 올바른 형식으로 오늘 데일리 노트 제목을 계산해서 사용합니다.

  3. roam_create_page 로 오늘 데일리 노트를 만들지 않음. 데일리 노트는 roam_add_todo / roam_create_block 이 쓰기 시 자동 생성합니다.

  4. 방어적 정규화: LLM이 실수로 April 16, 2026 형식을 넘겨도 서버가 April 16th, 2026 으로 자동 교정합니다. 하지만 이건 안전망이고, LLM이 처음부터 올바른 형식으로 넘기는 것이 선호됩니다.

트러블슈팅

토큰 오류 (Token cannot be verified)

  • 먼저 /check 엔드포인트로 원인을 진단: curl https://roam-mcp.xxx.workers.dev/check

  • Roam API 토큰이 roam-graph-token-으로 시작하는지 확인

  • roam-graph-local-token-으로 시작하는 것은 로컬 전용 토큰으로 API 사용 불가

  • 토큰이 등록한 그래프 이름과 일치하는지 확인 (각 그래프마다 별도 토큰 발급)

  • Secret 재등록: npx wrangler secret put ROAM_API_TOKEN

Secret이 사라진 경우

  • npx wrangler secret put ROAM_API_TOKEN으로 재등록

  • Secret은 배포와 무관하게 유지되지만 계정/Worker 이름이 다르면 별도 등록 필요

Claude.ai 연결 실패

  • URL이 /mcp로 끝나는지 확인: https://roam-mcp.xxx.workers.dev/mcp

  • Worker가 정상 배포됐는지 확인: npx wrangler deployments list

쓰기 성공했는데 Claude가 실패로 표시

  • Roam write API가 빈 응답을 반환할 때 발생하던 문제 (수정 완료)

오늘 수정 페이지가 0개로 표시

  • Cloudflare Worker는 UTC 기준으로 실행됨

  • 한국 시간(KST = UTC+9) 기준 자정은 UTC 15:00이므로 자정~09:00 사이 수정 항목이 누락될 수 있음

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/happytk/roam-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server