rootr-cli 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +56 -2
- package/README.md +52 -5
- package/bin/rootr.js +483 -13
- package/lib/client.js +220 -24
- package/lib/credentials.js +64 -7
- package/lib/mcp-tools/ask.js +6 -1
- package/lib/mcp-tools/attachments.js +153 -15
- package/lib/mcp-tools/booking.js +403 -0
- package/lib/mcp-tools/databases.js +230 -9
- package/lib/mcp-tools/documents.js +183 -16
- package/lib/mcp-tools/forms.js +3 -1
- package/lib/mcp-tools/logs.js +1 -1
- package/lib/mcp-tools/misc.js +9 -3
- package/lib/mcp-tools/pages.js +31 -7
- package/lib/mcp-tools/presentations.js +36 -12
- package/lib/mcp-tools/public.js +4 -1
- package/lib/mcp-tools/recordings.js +39 -15
- package/lib/mcp-tools/shared.js +28 -0
- package/lib/mcp-tools/workspaces.js +197 -79
- package/lib/mcp.js +3 -0
- package/lib/resolve.js +43 -1
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -138,6 +138,22 @@ rootr append /notes/log.md --file ./chunk.md
|
|
|
138
138
|
`--heading`을 지정하면 해당 헤딩 섹션 끝에 추가되고, 없으면 문서 끝에 추가됩니다.
|
|
139
139
|
append는 전체 내용을 다시 쓰지 않으므로 다른 프로세스와 동시에 써도 충돌하지 않습니다.
|
|
140
140
|
|
|
141
|
+
### 문서 안에 표 끼워 넣기 (embed) — 노션의 "링크된 데이터베이스"처럼
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
rootr embed /회의/주간회의.md /프로젝트/업무 표
|
|
145
|
+
rootr embed /회의/주간회의.md /프로젝트/업무 표 --heading "## 업무"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
문서 안에 표·스프레드시트·발표자료·화이트보드·폼·녹음·로그·이슈 트래커를 **살아 있는 채로**
|
|
149
|
+
보여 줍니다(복사본이 아니라 표를 고치면 문서에도 바로 보입니다). 편집기의 "끼워 넣기" 블록과 같습니다.
|
|
150
|
+
|
|
151
|
+
- MCP: `rootr_embed_node` (`target` = 문서, `node` = 끼울 것 — 둘 다 경로나 id)
|
|
152
|
+
- REST: `POST /v1/documents/:id/embeds` 에 `{ "node": "/프로젝트/업무 표" }`
|
|
153
|
+
- 직접 쓰기: `rootr_write`·`rootr_append` 내용에 `[[embed:/프로젝트/업무 표]]` 한 줄. 저장할 때 id 로
|
|
154
|
+
바뀌고, 없는 경로나 볼 권한이 없는 것이면 400 으로 거절하고 아무것도 쓰지 않습니다.
|
|
155
|
+
- 스캐폴딩: 같은 트리에서 만드는 표는 이름으로 — `[[embed:업무 표]]`
|
|
156
|
+
|
|
141
157
|
### 텍스트 치환 (edit)
|
|
142
158
|
|
|
143
159
|
```bash
|
|
@@ -195,6 +211,11 @@ rootr config # 등록된 키 목록 확인
|
|
|
195
211
|
워크스페이스가 바뀌고, 그 워크스페이스를 담당하는 키가 자동으로 선택·기억됩니다. 계정
|
|
196
212
|
키(PAT)를 쓰면 소속된 어느 워크스페이스로든 바로 전환됩니다.
|
|
197
213
|
|
|
214
|
+
MCP 서버를 `ROOTR_WORKSPACE` 환경변수로 띄웠다면(MCP 클라이언트 설정의 `env: {…}`), 재시작할 때마다
|
|
215
|
+
환경변수가 다시 이깁니다. `rootr_use_workspace` 전환은 그 서버 프로세스가 켜져 있는 동안만 적용되고,
|
|
216
|
+
전환 응답이 "재시작하면 어느 워크스페이스로 돌아가는지"를 알려 줍니다. 전환을 계속 유지하려면 그 설정의
|
|
217
|
+
`ROOTR_WORKSPACE` 를 바꾸거나 지우세요.
|
|
218
|
+
|
|
198
219
|
워크스페이스 키는 자기 워크스페이스 밖에서는 열리지 않습니다 — `rootr ws`(=`rootr_workspaces`)
|
|
199
220
|
목록에 보여도 접근은 안 되는 경우가 있어, 등록된 키가 워크스페이스 키뿐이면 목록에
|
|
200
221
|
`[등록된 키로는 접근 불가]`를 함께 표시합니다.
|
|
@@ -209,6 +230,8 @@ rootr config # 등록된 키 목록 확인
|
|
|
209
230
|
|
|
210
231
|
프로그램(API 키·MCP) 호출 중 **조회 계열**(`docs:read`/`graph:read`/`ask`)에만 한도가 있습니다.
|
|
211
232
|
쓰기·업로드는 제한하지 않습니다.
|
|
233
|
+
공개 주소(`rootr.io/p/{slug}`)를 `rootr_read` 로 읽는 것도 조회 1회로 셉니다(남의 워크스페이스 공개 문서 포함). 같은 주소를
|
|
234
|
+
브라우저로 여는 것은 세지 않습니다.
|
|
212
235
|
|
|
213
236
|
| 플랜 | 한도 |
|
|
214
237
|
| --- | --- |
|
|
@@ -328,7 +351,7 @@ rootr memory forget <id> # 폐기(--hard면 행 삭제)
|
|
|
328
351
|
|
|
329
352
|
## MCP 서버로 사용하기
|
|
330
353
|
|
|
331
|
-
`rootr mcp`는 stdio로 MCP(Model Context Protocol) 서버를 구동합니다. 제공 도구
|
|
354
|
+
`rootr mcp`는 stdio로 MCP(Model Context Protocol) 서버를 구동합니다. 제공 도구 186종:
|
|
332
355
|
|
|
333
356
|
노드를 가리키는 인자(`target`, `databaseId`, `spreadsheetId`, `formId`, `crmId`, `trackerId`,
|
|
334
357
|
`recordingId`, `presentationId`, `whiteboardId`, `logId`, `parentId` 등)는 **노드 id와 경로를 모두**
|
|
@@ -362,6 +385,8 @@ rootr memory forget <id> # 폐기(--hard면 행 삭제)
|
|
|
362
385
|
|---|---|
|
|
363
386
|
| `rootr_upload_attachment` | 로컬 파일(`filePath`) 또는 base64(`base64Data`)를 업로드하고 `{id, url, markdown}` 반환 |
|
|
364
387
|
| `rootr_attach_image_to_document` | 위 업로드 + 지정 문서에 `rootr_append`로 바로 삽입 (가장 흔한 용법) |
|
|
388
|
+
| `rootr_create_upload_url` | 잠깐(5분) 쓰는 올리기 주소를 받는다 — 파일 바이트를 그 주소에 직접 `PUT`. 큰 파일, 그리고 `filePath` 를 못 쓰는 원격 커넥터용 |
|
|
389
|
+
| `rootr_complete_upload` | `PUT` 이 끝난 뒤 호출 — 올라간 것을 확인하고 `{id, url, markdown}` 반환 |
|
|
365
390
|
|
|
366
391
|
`url`은 `/attachments/{id}/raw` — 로그인 없이 렌더되는 공개 경로라 published(`/p/`) 문서에도
|
|
367
392
|
그대로 쓸 수 있습니다. CLI에서는 `rootr attach <file> [--doc <path|id>] [--heading "## X"] [--alt <text>]`.
|
|
@@ -422,6 +447,9 @@ rootr memory forget <id> # 폐기(--hard면 행 삭제)
|
|
|
422
447
|
|---|---|
|
|
423
448
|
| `rootr_read_database` | 스키마(열 정의)+행 전체 읽기 — **다른 표 도구를 쓰기 전에 먼저** (`includeBody: true` 면 행마다 상세 내용까지) |
|
|
424
449
|
| `rootr_list_rows` | 행만 조회(스키마 제외, `includeBody` 지원, `backlinks: true`면 "나를 가리키는 다른 표의 행"도 함께) |
|
|
450
|
+
| `rootr_find_similar_rows` | 같은 표에서 **뜻이 가까운 행** 찾기(행 벡터). "검색 색인에서 제외"한 칸은 색인하지 않고, "본인 행만" 표는 내 행만 돌려준다. 표 안에서 **특히 닮은 행만**(`similarityLevel` high·mid) 돌려준다 — 한 표의 무관한 행도 코사인 0.8을 넘기 때문. `state`: `indexing`(색인 중)·`sync-off`(그래프 동기화 꺼짐)·`ready` |
|
|
451
|
+
| `rootr_set_row_vectors` | **벡터 칸**(`rootr_add_column` type `vector` + `dimensions`)에 내 임베딩을 행마다 넣는다(한 번에 500개, 다시 보내면 교체). 루터는 임베딩을 만들지 않는다(AI 크레딧 0) |
|
|
452
|
+
| `rootr_query_vectors` | 벡터 칸에서 내가 준 벡터와 코사인이 가까운 행 찾기(`topK`·`minScore`). 행 권한 그대로 |
|
|
425
453
|
| `rootr_add_row` | 행 추가 (`values`는 열 이름 또는 id로 지정, `body`로 상세 내용까지) |
|
|
426
454
|
| `rootr_update_row` | 행 수정 (칸반 카드 이동 = select 열 값 변경, `body`로 상세 내용 교체) |
|
|
427
455
|
| `rootr_bulk_create_rows` | 행 여러 개를 한 번에 추가 |
|
|
@@ -592,6 +620,29 @@ rootr db view <표> <뷰> --scale year # 달력 보기를 주·달·해
|
|
|
592
620
|
| `rootr_set_document_public` | 문서 전용 공개 설정 변경 |
|
|
593
621
|
| `rootr_document_public_status` | 문서 전용 공개 상태 |
|
|
594
622
|
|
|
623
|
+
#### 방문자 일정 등록(예약) · 구글 캘린더 (docs:read/docs:write)
|
|
624
|
+
|
|
625
|
+
공개한 **표**를 예약 페이지로 씁니다. 방문자가 빈 시간을 골라 잡으면 그 표에 행 하나로
|
|
626
|
+
들어옵니다. 남의 예약은 방문자에게 안 보이고(공개 페이로드에서 행을 뺍니다), 같은 시간을
|
|
627
|
+
동시에 눌러도 한 명만 들어갑니다. 예약은 **공개 주소 위에 서는 기능**이라 `rootr_publish_node`
|
|
628
|
+
를 먼저 해야 합니다.
|
|
629
|
+
|
|
630
|
+
| 도구 | 설명 |
|
|
631
|
+
|---|---|
|
|
632
|
+
| `rootr_get_booking` | 예약 설정·규칙·구글 연결 상태 보기 |
|
|
633
|
+
| `rootr_set_booking` | 예약 켜기/끄기와 규칙(요일·시간·길이·여유·며칠 전·하루 최대·쉬는 날·**막는 시간**·확정 방식·물어볼 칸·**결과 메일**·**구글 밋**·**방문자 직접 취소**·**방문자 직접 시간 변경**·**미리 알림**) |
|
|
634
|
+
| `rootr_booking_slots` | 방문자에게 실제로 보이는 빈 시간(규칙이 뜻대로 걸렸는지 확인) |
|
|
635
|
+
|
|
636
|
+
방문자 화면은 **방문자 자신의 시간대**로 빈 시간을 보여주고(고칠 수도 있습니다), 서버와
|
|
637
|
+
주고받는 값은 끝까지 주인 시간대입니다. 확정·이동 메일에는 **일정 초대장(.ics)** 이 붙어
|
|
638
|
+
방문자 캘린더에 바로 들어가고, 시간을 옮기면 그 일정이 고쳐지고 취소하면 사라집니다.
|
|
639
|
+
메일 속 링크 하나로 방문자가 **직접 취소하거나 시간을 옮길** 수 있고(`allowVisitorCancel`
|
|
640
|
+
/ `allowVisitorReschedule`), `reminders`(분 단위, 예 `[1440, 60]`)로 약속 전에 양쪽에 한 번
|
|
641
|
+
더 알립니다 — 기본은 하루 전 한 번입니다.
|
|
642
|
+
| `rootr_list_google_calendars` | 연결한 구글 계정과 그 캘린더 목록 |
|
|
643
|
+
| `rootr_connect_google_calendar` | 구글 동의 주소 만들기(허용은 브라우저에서 사람이 한 번) |
|
|
644
|
+
| `rootr_disconnect_google_calendar` | 구글 연결 끊기(구글 쪽 권한도 거둠) |
|
|
645
|
+
|
|
595
646
|
#### 스프레드시트 (docs:read/docs:write)
|
|
596
647
|
|
|
597
648
|
| 도구 | 설명 |
|
|
@@ -762,7 +813,10 @@ curl "$BASE/pages/$ID/live-data" -H "x-api-key: $KEY"
|
|
|
762
813
|
```
|
|
763
814
|
|
|
764
815
|
`liveStats`/`liveTable`/`liveChart`의 `source.nodeId`는 같은 워크스페이스의
|
|
765
|
-
DATABASE·LOG 노드이고, 칸은 **이름**으로 가리킵니다(칸 id가 아닙니다).
|
|
816
|
+
DATABASE·SPREADSHEET·LOG 노드이고, 칸은 **이름**으로 가리킵니다(칸 id가 아닙니다).
|
|
817
|
+
`liveChart`는 **차트 46종**(지난 기간 대비 증감이 붙는 KPI, 막대+선 이중축, 히트맵, 생키, 간트, 피벗…)을 그리고,
|
|
818
|
+
어느 블록이든 `width: half | third | twoThirds` 로 나란히 놓아 **실시간 대시보드**를 만들 수 있습니다 —
|
|
819
|
+
`/llms.txt`의 "Dashboards & charts" 참고.
|
|
766
820
|
`form` 블록의 `formNodeId`에 폼 노드를 걸면 방문자가 **그 자리에서 신청**합니다 —
|
|
767
821
|
폼을 따로 공개할 필요가 없습니다. 비공개(PRIVATE) 서브트리에 있는 표·폼은 공개
|
|
768
822
|
페이지에서 조용히 빠집니다(일부러 그렇습니다).
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ citations back to the exact paragraph.
|
|
|
11
11
|
*(한국어 문서: [README.ko.md](https://github.com/gwmage/rootr-cli/blob/main/README.ko.md))*
|
|
12
12
|
|
|
13
13
|
- `rootr` CLI — documents, databases, forms, signed documents, publishing, permissions, memory
|
|
14
|
-
- `rootr mcp` — stdio MCP server, **
|
|
14
|
+
- `rootr mcp` — stdio MCP server, **186 tools** (see [MCP tools](#mcp-tools))
|
|
15
15
|
|
|
16
16
|
Plain Node.js ESM, no build step. Node 18+ (uses the built-in `fetch`).
|
|
17
17
|
|
|
@@ -117,6 +117,11 @@ After that, `rootr use` (and the `rootr_use_workspace` MCP tool) accepts a **nam
|
|
|
117
117
|
rootr.io URL**; the key that opens that workspace is selected and remembered automatically. An
|
|
118
118
|
account key (PAT) switches to any workspace you belong to.
|
|
119
119
|
|
|
120
|
+
If the MCP server was started with `ROOTR_WORKSPACE` set (the usual `env: {…}` block in an MCP client
|
|
121
|
+
config), the env var wins again on every restart: a `rootr_use_workspace` switch applies for as long as
|
|
122
|
+
that server process runs, and the reply says which workspace it returns to after a restart/reconnect.
|
|
123
|
+
To make the switch permanent, change (or remove) `ROOTR_WORKSPACE` in that config.
|
|
124
|
+
|
|
120
125
|
A workspace key does not open anything outside its own workspace. Because of that, `rootr ws`
|
|
121
126
|
marks entries your registered keys cannot open — **being listed and being reachable are not the
|
|
122
127
|
same thing**.
|
|
@@ -149,6 +154,10 @@ rootr append /notes/log.md "deploy finished"
|
|
|
149
154
|
rootr append /notes/log.md "- one more item" --heading "## Todo"
|
|
150
155
|
cat diff.md | rootr append /notes/log.md
|
|
151
156
|
|
|
157
|
+
# Embed a LIVE table (or sheet / deck / board) inside a document — like Notion's linked database
|
|
158
|
+
rootr embed /meetings/weekly.md /projects/tasks
|
|
159
|
+
rootr embed /meetings/weekly.md /projects/tasks --heading "## Tasks"
|
|
160
|
+
|
|
152
161
|
rootr edit /notes/todo.md --find "- [ ] deploy" --replace "- [x] deploy"
|
|
153
162
|
rootr edit /notes/todo.md --find "TODO" --replace "DONE" --all
|
|
154
163
|
|
|
@@ -353,6 +362,8 @@ pollute the queue.
|
|
|
353
362
|
|
|
354
363
|
Only **read-type** calls (`docs:read` / `graph:read` / `ask`) made programmatically (API key or
|
|
355
364
|
MCP) are metered. Writes and uploads are not limited.
|
|
365
|
+
Reading a published public URL with `rootr_read` (`rootr.io/p/{slug}`, including another workspace's document) counts as one
|
|
366
|
+
read as well; opening the same URL in a browser does not.
|
|
356
367
|
|
|
357
368
|
| Plan | Limit |
|
|
358
369
|
| --- | --- |
|
|
@@ -383,7 +394,7 @@ is refused and says when the grace was used.
|
|
|
383
394
|
|
|
384
395
|
## MCP tools
|
|
385
396
|
|
|
386
|
-
`rootr mcp` speaks MCP over stdio.
|
|
397
|
+
`rootr mcp` speaks MCP over stdio. 186 tools:
|
|
387
398
|
|
|
388
399
|
| Group | Count | Tools |
|
|
389
400
|
|---|---|---|
|
|
@@ -402,12 +413,30 @@ is refused and says when the grace was used.
|
|
|
402
413
|
| LOG datastores | 5 | create store, update fields, add entries, query, stats |
|
|
403
414
|
| Templates | 4 | list, apply, save as template, update |
|
|
404
415
|
| Whiteboards | 3 | create, read and update the shapes & edges scene |
|
|
405
|
-
| Attachments |
|
|
416
|
+
| Attachments | 4 | upload a file, attach an image straight into a document, upload by presigned URL (`rootr_create_upload_url` → PUT the bytes → `rootr_complete_upload`; for large files and the remote connector, where `filePath` is not available) |
|
|
406
417
|
| Agent memory | 3 | remember, recall, forget |
|
|
407
418
|
| Webhooks | 3 | list, create (secret shown once), delete |
|
|
419
|
+
| Visitor booking & Google Calendar | 6 | turn a published table into a booking page, rules, open slots, connect / list / disconnect Google Calendar |
|
|
408
420
|
| Root-cause Q&A | 1 | ask the workspace knowledge graph, answer with citations |
|
|
409
421
|
| Feedback | 1 | send feedback to the Rootr team |
|
|
410
422
|
|
|
423
|
+
Open hours can be narrowed by blocked times — one afternoon, lunch every day, Monday mornings, or a whole
|
|
424
|
+
weekday — with `blockedTimes` on `rootr_set_booking` (CLI: `--block-time "daily 12:00-13:00, mon 09:00-11:00, fri"`).
|
|
425
|
+
|
|
426
|
+
Every booking is emailed to both sides (`notifyVisitor` / `notifyEmails`), and `google.meet` adds a Google Meet
|
|
427
|
+
room per booking — the link lands in a "회의 링크" column and in both emails (CLI: `--meet on --notify-email me@acme.com`).
|
|
428
|
+
Visitors cancel themselves from a link in their email (`allowVisitorCancel`, CLI `--self-cancel on|off`) — the link is a
|
|
429
|
+
secret only that booking's email carries, so no account is needed. The same link also **moves** the booking to
|
|
430
|
+
another time (`allowVisitorReschedule`, CLI `--self-move on|off`), picked under one lock so the new slot cannot be
|
|
431
|
+
taken in between. Slots are shown in the **visitor's own time zone** (they can switch it), every confirmation carries
|
|
432
|
+
a **calendar invite (.ics)** that updates itself when the time moves and cancels itself when the booking is cancelled,
|
|
433
|
+
and `reminders` emails both sides before the meeting (CLI `--remind 1d,1h`, default a day before, `--remind off` to stop).
|
|
434
|
+
|
|
435
|
+
Visitor booking turns a published DATABASE into a scheduling page: visitors pick an open slot and each
|
|
436
|
+
booking lands as one row. Other people's bookings are never exposed publicly, double-booking is blocked
|
|
437
|
+
server-side, and Google Calendar is optional — busy times block slots and confirmed bookings are written
|
|
438
|
+
back. Connecting a Google account needs a person to approve once in a browser; everything else is a tool.
|
|
439
|
+
|
|
411
440
|
Guidance baked into the tool descriptions: agents should reach for `rootr_append` and
|
|
412
441
|
`rootr_edit`, and use `rootr_write` only for a genuine full rewrite (ideally with `ifMatch`).
|
|
413
442
|
Tools that take a `workspace` argument fall back to `ROOTR_WORKSPACE` / the config file, and
|
|
@@ -445,14 +474,32 @@ curl -X PATCH "$BASE/pages/$ID" -d '{"config":{"theme":"warm"}}' ...
|
|
|
445
474
|
curl "$BASE/pages/$ID/live-data" -H "x-api-key: $KEY"
|
|
446
475
|
```
|
|
447
476
|
|
|
448
|
-
For `liveStats` / `liveTable` / `liveChart`, `source.nodeId` is a DATABASE or LOG node in the
|
|
449
|
-
same workspace and columns are referenced **by name** (not by column id).
|
|
477
|
+
For `liveStats` / `liveTable` / `liveChart`, `source.nodeId` is a DATABASE, SPREADSHEET or LOG node in the
|
|
478
|
+
same workspace and columns are referenced **by name** (not by column id). `liveChart` draws **46 chart
|
|
479
|
+
kinds** (KPI with period-over-period change, combo/dual axis, heatmap, sankey, gantt, pivot…) and any block
|
|
480
|
+
takes `width: half | third | twoThirds` so a page becomes a **live dashboard** — see "Dashboards & charts" in `/llms.txt`. Point a `form` block's
|
|
450
481
|
`formNodeId` at a form node and visitors submit **right there** — the form does not have to be
|
|
451
482
|
published separately. Tables and forms that live under a PRIVATE subtree are silently dropped
|
|
452
483
|
from a public page, on purpose.
|
|
453
484
|
|
|
454
485
|
Publishing works like any other node: `POST /v1/nodes/:id/publish` → `rootr.io/p/{slug}`.
|
|
455
486
|
|
|
487
|
+
### Embedding a table inside a document
|
|
488
|
+
|
|
489
|
+
A document can show another node — a table, spreadsheet, presentation, whiteboard, form,
|
|
490
|
+
recording, log store or issue tracker — **live**, the same as the editor's "Embed" block
|
|
491
|
+
(Notion's linked database). Edits to the table appear in the document; it is not a copy.
|
|
492
|
+
|
|
493
|
+
- MCP: `rootr_embed_node` (`target` = the document, `node` = what to embed; both take a path or
|
|
494
|
+
an id; optional `underHeading`).
|
|
495
|
+
- CLI: `rootr embed <doc> <node> [--heading "## X"]`.
|
|
496
|
+
- REST: `POST /v1/documents/:id/embeds` with `{ "node": "/projects/tasks" }`.
|
|
497
|
+
- Or write a line containing only `[[embed:/projects/tasks]]` (or `[[embed:<node id>]]`) in any
|
|
498
|
+
`rootr_write` / `rootr_append` content. Paths are turned into ids when saved; an unknown path —
|
|
499
|
+
or one you cannot read — is rejected with 400 and nothing is written.
|
|
500
|
+
- Scaffolding: inside a tree, a document's `content` can embed a node built in the same tree by
|
|
501
|
+
its name, e.g. `[[embed:Tasks]]`.
|
|
502
|
+
|
|
456
503
|
### Presentations
|
|
457
504
|
|
|
458
505
|
Decks are authored with `rootr_create_presentation`, `rootr_read_presentation`,
|