Skip to main content
Glama
Rootr MCP Server

Rootr MCP Server

rootr-cli

Official CLI and MCP server for Rootr — a team documentation workspace that AI agents can read and write.

Point Claude, Cursor, or any MCP client at your workspace and it can browse the document tree, read and edit markdown, add rows to a database, open and close issues, build a slide deck, run a spreadsheet, publish a public page, sign a document, or ask a question and get an answer with citations back to the exact paragraph.

(한국어 문서: README.ko.md)

  • rootr CLI — documents, databases, forms, signed documents, publishing, permissions, memory

  • rootr mcp — stdio MCP server, 167 tools (see MCP tools)

Plain Node.js ESM, no build step. Node 18+ (uses the built-in fetch).

Related MCP server: notes-mcp

Two ways to connect

1. Remote connector — nothing to install. Rootr hosts an MCP endpoint with OAuth:

https://rootr.io/mcp

Add it as a custom connector in Claude (Streamable HTTP), sign in, done. Same tools as the local server. This is the recommended path for most people.

2. Local CLI — use this package when you want the client running on your own machine or infrastructure, or when you want the shell commands.

npx rootr-cli mcp        # run the MCP server straight from npm
npm install -g rootr-cli # or install the `rootr` command globally

Or from a clone:

npm install
node bin/rootr.js --help

Docker:

docker build -t rootr-cli .
docker run -i --rm -e ROOTR_API_KEY=rootr_xxx -e ROOTR_WORKSPACE=ws_123 rootr-cli

Configuration

Precedence: environment variables > ~/.rootr/config.json

Env var

Config key

Description

ROOTR_API_KEY

apiKey

API key (rootr_...), sent as the x-api-key header

ROOTR_WORKSPACE

workspace

Workspace id

ROOTR_BASE_URL

baseUrl

Defaults to https://rootr.io/api/v1

ROOTR_LANG

—

en or ko. Without it the CLI follows your locale (LC_ALL/LC_MESSAGES/LANG): Korean if that starts with ko, English otherwise

Save them to the config file:

rootr config --api-key rootr_xxxxxxxxxxxxxxxx --workspace ws_123
# self-hosted or dev server
rootr config --api-key rootr_xxx --workspace ws_123 --base-url https://dev.rootr.io/api/v1

~/.rootr/config.json is written with mode 600.

Language

Help, messages and errors come out in English by default, and in Korean when your locale says Korean. Force it either way with ROOTR_LANG:

ROOTR_LANG=ko rootr --help    # Korean
ROOTR_LANG=en rootr --help    # English

The MCP server reads the same variable, so a client that spawns rootr mcp can set it in env. Tool descriptions are English either way — that is the schema an agent consumes.

Two kinds of key

  • Workspace key — scoped to one workspace. Scopes: docs:read, docs:write, graph:read, ask, webhooks:manage. Enough for almost every tool.

  • Account key (PAT) — acts for the whole account. With the workspaces:create scope it can create new workspaces (rootr_create_workspace). Trying that with a workspace key returns 403 with a hint saying an account key is required.

Show the current configuration (only the first 12 characters of the key are printed):

rootr config

Working with several workspaces

Register each workspace's key once:

rootr config --add-key rootr_xxx --label "Sales"
rootr config                       # list registered keys

After that, rootr use (and the rootr_use_workspace MCP tool) accepts a name, an id, or a rootr.io URL; the key that opens that workspace is selected and remembered automatically. An account key (PAT) switches to any workspace you belong to.

A workspace key does not open anything outside its own workspace. Because of that, rootr ws marks entries your registered keys cannot open — being listed and being reachable are not the same thing.

Web URLs (https://rootr.io/en/w/<ws>/d/<doc>) can be pasted directly into any node argument. If the URL belongs to another workspace, the error tells you to switch first.

The remote connector (https://rootr.io/mcp) is bound to the single workspace you picked when you authorized it. For another workspace, issue a new connector for that workspace.

CLI

Path arguments starting with / are resolved as paths through the by-path API (needs a workspace). Anything else is treated as a node id.

Documents

rootr ls                                  # whole tree, TYPE<TAB>path
rootr ls /notes                           # one subtree

rootr read /notes/todo.md                 # markdown to stdout
rootr read /notes/todo.md --json          # full JSON with metadata

echo "# Title" | rootr write /notes/new.md
rootr write /notes/new.md --file ./local.md
rootr write <nodeId> --file ./local.md --if-match '"abc123"'   # optimistic concurrency

rootr append /notes/log.md "deploy finished"
rootr append /notes/log.md "- one more item" --heading "## Todo"
cat diff.md | rootr append /notes/log.md

rootr edit /notes/todo.md --find "- [ ] deploy" --replace "- [x] deploy"
rootr edit /notes/todo.md --find "TODO" --replace "DONE" --all

rootr comments /notes/spec.md             # comments, including ones left on the public page
rootr search "deployment runbook"
rootr mv /notes/old.md /archive/old.md    # move and/or rename
rootr rm /notes/old.md --yes              # to the trash, recoverable
rootr restore <id>                        # undo a delete (id, not path)
rootr attach ./diagram.png --doc /notes/spec.md --heading "## Design"

append never rewrites the whole document, so concurrent writers cannot clobber each other — prefer it over write. --heading appends to the end of that heading's section.

edit returns 409 if the --find text is missing or not unique; the server's reason is printed as-is. write --if-match returns 412 if the document changed in the meantime.

Workspaces and questions

rootr ws                                  # id<TAB>name
rootr use "Sales"                         # switch — id, name, or rootr.io URL
rootr ask "why did latency go up after last week's deploy?"
rootr ask "why did payment failures rise?" --workspace ws_123

ask queries the workspace knowledge graph (GraphRAG) and prints the answer plus citations in document path: quote form. Requires the ask scope.

Databases

rootr db create --file spec.json --parent /projects   # columns in the given order, rows included
rootr db rows /projects/tasks --body --backlinks      # rows, with row bodies and inbound links
rootr db row-add /projects/tasks --values '{"Title":"Ship v2","Status":"Doing"}'
rootr db rows-new /projects/tasks --file rows.json    # many at once — all or nothing
rootr db rows-set /projects/tasks --ids r1,r2 --values '{"Status":"Done"}'
rootr db rows-each /projects/tasks --json '[{"rowId":"r1","values":{"Score":3}}]'
rootr db rows-rm  /projects/tasks --ids r1,r2 --yes
rootr db view /projects/tasks Calendar --scale month  # views: table, board, calendar, timeline
rootr db lock /projects/tasks --schema managers --rows own --locked "Approved,Score"
rootr db notify  /projects/tasks --file rules.json    # notification rules
rootr db buttons /projects/tasks --file buttons.json  # buttons that do work when pressed
rootr db button-run /projects/tasks fill-summary --rows r1,r2
rootr db row-page <rowId> --type RECORDING            # give one row a typed detail page

Forms

rootr form new /intake/request --collect db \
  --fields '[{"name":"Email","type":"email","required":true},{"name":"How urgent?","type":"scale"}]'
rootr form show /intake/request                       # read the questions before changing them
rootr form set  /intake/request --fields '[...]'      # replaces the question set
rootr form collect /intake/request --to sheet         # create and wire a destination
rootr form responses /intake/request --latest         # --latest = newest one per person
rootr form response-edit <responseId> --values '{"Email":"a@b.com"}'

--fields takes a JSON array as a string, not a file path.

18 question types, including text, email, phone, url, rating, scale, time, file, matrix, ranking, csat and nps. --collect db|sheet creates the destination and wires it up, mapping questions to columns.

Publishing and access

rootr publish /handbook --children              # works for every node type
rootr publish /handbook --status                # is it public, at what URL, children included?
rootr publish /projects/tasks --layout board --skin paper   # 9 layouts × 6 skins
rootr publish /handbook/policy.md --comments --expires 2026-12-31T00:00:00Z
rootr publish /handbook --off

rootr access /handbook --private                # or --public / --inherit
rootr access /handbook --grant <userId> --level WRITE
rootr access /handbook --revoke <userId>

rootr readreq /handbook/policy.md --users u1,u2 --due 2026-10-01T00:00:00Z --ack
rootr readreq /handbook/policy.md               # who has read it, completion rate

Signed documents and research notes

A signed document is a markdown document whose body freezes the moment it is submitted; the people on the approval line then sign in order. Every signature carries a trusted timestamp (TSA) and hash chaining, so tampering is provable, and signed documents are never deleted (30-year retention). Corporate approval flows and national R&D electronic research notes are the same feature.

# create — body and approval line in one step; a research note only needs a reviewer
rootr sign new "/notes/2026-08-25 experiment" --file note.md --reviewer <reviewer userId>

# build the approval line by hand (array order = signing order)
cat > line.json <<'EOF'
[ { "label": "Author",  "members": [{ "userId": "u1", "role": "AUTHOR" }] },
  { "label": "Manager", "rule": "ANY", "members": [{ "userId": "u2" }, { "userId": "u3" }] } ]
EOF
rootr sign line "/notes/2026-08-25 experiment" --file line.json

# submit: request a confirmation code by email, then pass those 6 digits
rootr sign code   "/notes/2026-08-25 experiment"
rootr sign submit "/notes/2026-08-25 experiment" --code 123456

# next signer: see only what is waiting on you, then sign (or reject with a reason)
rootr sign list --pending
rootr sign code <id> && rootr sign approve <id> --code 123456
rootr sign reject <id> --comment "supporting data is missing" --code 123456

# many at once (up to 100 with a single code)
rootr sign code --bulk
rootr sign bulk <id1> <id2> <id3> --code 123456

# proof
rootr sign verify <id>     # body, signatures, timestamps and ledger intact?
rootr sign ledger          # recompute the whole workspace ledger

The CLI cannot mint the confirmation code for you. It is emailed to the signer only. In a design where the server holds the private key, that code is the single piece of evidence that a human pressed the button. It is valid for 10 minutes, dies after 5 wrong attempts, and a repeat request within 30 seconds is refused.

Approval-line members are {"userId"} or {"email","displayName"} — with an email address a person can sign without a Rootr account.

A signed document is never edited in place. You issue a revision (rootr sign revise <id> --note "…") and the original stays as SUPERSEDED, because the regulations require both the original and the trace of the change to remain visible.

Team memory

rootr memory                                          # recall everything
rootr memory --query seminar --kind 지시               # filtered
rootr memory add "Report times in KST only" --kind 지시 --source /rules.md
rootr memory edit <id> --content "corrected sentence" # only the fields you pass change
rootr memory forget <id>                              # retire (--hard deletes the row)

--kind is one of four literal values: 지시 (how the team wants work done), 사람 (someone's role or preference), 프로젝트 (an ongoing effort), 참고 (a reference). The same four values are the enum on the rootr_remember / rootr_recall MCP tools.

One-line facts that outlive a session and are shared by the whole workspace. This is the same data as the rootr_remember / rootr_recall / rootr_forget MCP tools and the "Memory" menu in the app. Long things belong in a document; one-liners belong in memory.

Scaffolding a workspace

rootr scaffold plan "a workspace for running a hardware startup's QA process"
rootr scaffold review --file tree.json     # get graded before anything is created
rootr scaffold apply  --file tree.json --root /qa
rootr scaffold built --root /qa            # inspect the shape of what was created
rootr scaffold test  --root /qa            # actually exercise relations, rollups, formulas, forms

Reporting a problem

rootr feedback "rootr_add_row could not find my column by name; column ids worked." --kind friction
rootr feedback --file report.md --kind bug --email me@example.com
cat error.log | rootr feedback --kind bug

Sends bugs, friction and ideas to the Rootr team. No login, no workspace, no API key required — it works even when a wrong key means nothing else does, and that is exactly the report we most want. It does not count against usage limits and does not consume credits.

--kind is one of bug, friction, idea, praise, other (default other). Without --title the first line of the body becomes the title. Pass --email only if you want a reply. The same body sent twice within 10 minutes is merged into one report, so retry loops do not pollute the queue.

Usage limits

Only read-type calls (docs:read / graph:read / ask) made programmatically (API key or MCP) are metered. Writes and uploads are not limited.

Plan

Limit

Free

180 calls per day (resets at midnight KST)

Team

5,000 per hour

Business

50,000 per hour

Platform

Unlimited

At 80% of the limit, MCP tool responses append a note with the remaining count. At the limit you get a 429 with an upgrade link. The response headers carry the same information (X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Window).

MCP tools

rootr mcp speaks MCP over stdio. 167 tools:

Group

Count

Tools

Documents

22

list, read, write, append, edit, search, comment, version history, commits & merges, publish, trash & restore

Databases

26

create, columns, views, rows (single & bulk), row pages, permissions, notifications, buttons

CRM

18

companies, contacts, deals (incl. pipeline moves), activities, tasks, CSV import

Signed documents & research notes

14

create, sign, revise, reject, reopen, approval lines, signing codes, ledger verification, research-note preset

Forms

10

create, read, update, responses, share links, collectors

Presentations & images

10

decks, slides, diagram slides, image generation and background removal

Workspaces & scaffolding

9

list, create, delete, switch, plan / review / apply a document tree, health check

Pages

6

HTML page nodes: create, read, update, append and patch blocks, live data

Spreadsheets

7

create, read, update, per-sheet create/update/delete, patch cells & formulas

Recordings

7

create, upload & download audio, transcribe, summarize, rename speakers

Issue tracker

6

create tracker, list / create / get / update issue, comment

Permissions & visibility

10

grant / revoke node permissions, read access, visibility, public status, read requirements

LOG datastores

5

create store, update fields, add entries, query, stats

Templates

4

list, apply, save as template, update

Whiteboards

3

create, read and update the shapes & edges scene

Attachments

2

upload a file, attach an image straight into a document

Agent memory

3

remember, recall, forget

Webhooks

3

list, create (secret shown once), delete

Root-cause Q&A

1

ask the workspace knowledge graph, answer with citations

Feedback

1

send feedback to the Rootr team

Guidance baked into the tool descriptions: agents should reach for rootr_append and rootr_edit, and use rootr_write only for a genuine full rewrite (ideally with ifMatch). Tools that take a workspace argument fall back to ROOTR_WORKSPACE / the config file, and return a clear error if neither is set. Every tool description is written in English (it is the schema an agent consumes), and tools that return JSON reply with pretty-printed JSON text.

Scope notes: document, database, spreadsheet, whiteboard, form, page, presentation, recording, signed-document, issue, CRM and LOG tools need docs:read / docs:write; rootr_ask needs ask; webhook tools need webhooks:manage; rootr_create_workspace needs an account key with workspaces:create.

Pages

A PAGE is a screen for people outside the workspace — an event announcement, a product page, a sign-up. You do not write HTML: you stack 14 predefined block types — hero, text, features, gallery, pricing, testimonials, faq, timeline, cta, footer, the table-backed liveStats, liveTable, liveChart, the form block, and the free-form custom.

custom is an isolated room: write any HTML/CSS you like, but it renders inside a sandbox iframe (no scripts, not same-origin, no outbound calls), so even bold CSS cannot leak onto the rest of the page. <script> and on*= attributes are stripped on save. Inside the room you can use the page's palette through var(--pg-text), var(--pg-card), var(--pg-accent). Per-block props are tabulated in the "Pages" section of /llms.txt.

# create a page (omit blocks to start from a hero/text/footer skeleton)
curl -X POST "$BASE/workspaces/$WS/pages" -H "x-api-key: $KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Autumn meetup","config":{"theme":"midnight"},
       "blocks":[{"type":"hero","props":{"title":"Autumn Developer Meetup","subtitle":"Oct 12 · Seoul"}}]}'

# append blocks (existing ones untouched) / replace config / read live values
curl -X POST  "$BASE/pages/$ID/blocks" -d '{"blocks":[{"type":"faq","props":{"items":[]}}]}' ...
curl -X PATCH "$BASE/pages/$ID"        -d '{"config":{"theme":"warm"}}' ...
curl         "$BASE/pages/$ID/live-data" -H "x-api-key: $KEY"

For liveStats / liveTable / liveChart, source.nodeId is a DATABASE or LOG node in the same workspace and columns are referenced by name (not by column id). Point a form block's formNodeId at a form node and visitors submit right there — the form does not have to be published separately. Tables and forms that live under a PRIVATE subtree are silently dropped from a public page, on purpose.

Publishing works like any other node: POST /v1/nodes/:id/publish → rootr.io/p/{slug}.

Presentations

Decks are authored with rootr_create_presentation, rootr_read_presentation, rootr_append_presentation_slides, rootr_update_presentation_slide, rootr_reorder_presentation_slides and rootr_update_presentation. Artwork can be produced with rootr_generate_image (image from a sentence) and rootr_remove_image_background — both spend AI credits. The same thing works over plain REST with the same API key (x-api-key, docs:write):

# create a deck (slides optional)
curl -X POST "$BASE/workspaces/$WS/presentations" -H "x-api-key: $KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Proposal","slides":[{"id":"SLD-001","kind":"cover","title":"..."}]}'

# patch one slide (merge) / append / reorder
curl -X PATCH "$BASE/presentations/$ID/slides/SLD-001" -H "x-api-key: $KEY" \
  -H 'Content-Type: application/json' -d '{"slide":{"notes":"speaker notes"}}'
curl -X POST "$BASE/presentations/$ID/slides"  -d '{"slides":[]}' ...
curl -X POST "$BASE/presentations/$ID/reorder" -d '{"order":["SLD-002","SLD-001"]}' ...

Diagrams on a slide

For architecture, workflow, sequence, dataflow and lifecycle diagrams, do not hand-write SVG. Pass a typed JSON spec to rootr_create_diagram_slide; the server validates it, renders it, and drops it onto the slide — it survives PDF and PPTX export too. A slide's diagram (mermaid) field is not rendered by the viewer, so this tool is the only way.

Each type has its own spec shape, so fetch the schema and an example first with rootr_diagram_schema. A spec that does not fit is rejected with which field is wrong and how to fix it, so you can correct it and call again.

# see the spec shape (architecture | workflow | sequence | dataflow | lifecycle)
curl "$BASE/diagram-types/workflow/schema" -H "x-api-key: $KEY"

# render it onto a slide (pass slideId to redraw an existing slide)
curl -X POST "$BASE/presentations/$ID/diagram-slides" -H "x-api-key: $KEY" \
  -H 'Content-Type: application/json' \
  -d '{"type":"workflow","spec":{},"title":"An issue reaches main only through review",
       "blocks":[{"heading":"Review is the gate","body":"..."}]}'

quality defaults to standard; showcase applies the stricter bar meant for hand-tuned hero diagrams and will reject specs that standard accepts. Text inside a rendered diagram does not reach the knowledge graph, so keep the facts in title, blocks and notes as well.

For high-quality decks, bake self-contained 1280×720 HTML into the slide's html field — the viewer renders it verbatim instead of the default template, giving you a completely free design. The rules (inline everything because outbound requests are blocked, images as data URIs, a font fallback stack, <span class="pn"> for page numbers, and keeping the text fields filled so the deck still feeds the knowledge graph) are documented in the "Presentations" section of /llms.txt — read it before authoring. AI image generation uses POST /v1/workspaces/:ws/images/generate and spends AI credits.

Register with Claude Code / Claude Desktop

{
  "mcpServers": {
    "rootr": {
      "command": "npx",
      "args": ["-y", "rootr-cli", "mcp"],
      "env": {
        "ROOTR_API_KEY": "rootr_xxxxxxxxxxxxxxxx",
        "ROOTR_WORKSPACE": "ws_123"
      }
    }
  }
}

With a global install, use "command": "rootr" and "args": ["mcp"]. From a clone, point command at node and args at ["/path/to/rootr-cli/bin/rootr.js", "mcp"].

Errors

On a non-2xx response the CLI prints the API's message to stderr and exits 1, with hints:

  • 401 / 403 — check the API key and workspace scopes

  • 412 — document changed since you read it; read again and retry (If-Match mismatch)

  • 409 — the server's reason is shown verbatim (e.g. edit found no unique match)

  • 429 — usage limit reached; the message carries the reset time and an upgrade link

Development

  • Dependencies: @modelcontextprotocol/sdk (MCP server) and zod (tool input schemas). The CLI itself (bin/rootr.js, lib/config.js, lib/client.js, lib/resolve.js) has none.

  • No build step — plain ESM JavaScript.

bin/rootr.js            entry point, command dispatch
lib/config.js           config load/save
lib/credentials.js      API key / workspace resolution
lib/context.js          per-call request context
lib/client.js           Rootr REST client
lib/resolve.js          path/id target resolution
lib/mcp.js              MCP stdio server, assembles the tool modules
lib/mcp-tools/*.js      one module per tool group (shared, documents, pages, workspaces,
                        databases, spreadsheets, whiteboards, forms, presentations,
                        recordings, signed, templates, attachments, public, memory,
                        logs, issues, crm, webhooks, ask, feedback, misc)

Smoke-test the MCP server without any credentials — it must start and list its tools:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | node bin/rootr.js mcp

License

MIT — see LICENSE.

Available Tools

81 tools
rootr_add_log_entriesAdd entries to a LOG storeA

Append one or more entries (rows) to a LOG store. Each entry may carry ts, source, level, message, data (shaped per the store's field schema). This is additive — existing entries are untouched.

Inputs: logId (required), entries (required).

rootr_add_rowAdd a database rowA

Append a row to a Rootr (루터) DATABASE. values maps property NAME (or id) → value. Value shapes by type: title/text/url/select/person → string; number → number; multi_select → string[]; checkbox → boolean; date → { start: "YYYY-MM-DD", end? }. A select value is the OPTION NAME. Call rootr_read_database first to learn the columns. Optionally set position to insert at an index.

Inputs: values (required), databaseId (required), position.

rootr_appendAppend to a Rootr document (preferred write)A

Append content to a Rootr document, optionally under a given heading. This is a conflict-free, additive operation — it never overwrites existing content, so PREFER this over rootr_write whenever you just need to add new information (log entries, notes, findings) to an existing document.

Inputs: target (required), content (required), underHeading.

rootr_append_presentation_slidesAppend slides to a Rootr presentation (preferred way to add slides)A

Append one or more slides to the END of a Rootr (루터) PRESENTATION, without touching existing slides. PREFER this over rootr_update_presentation when you are only adding new slides. Authoring guide: give each slide ONE assertion-style title (a claim, e.g. "Latency dropped 40% after the cache fix" — not a topic label like "Latency"), plus blocks[] (bullet-like {id, heading?, body?, icon?} items) and, where useful, a diagram ({type:"mermaid", code}) or images. Canvas is 16:9 (1280x720). Meaning must live in TEXT — title/blocks[].heading/blocks[].body/notes are what auto-connects into the knowledge graph; diagrams/code/html and the image pixels themselves are visual-only and are NOT indexed, so never put facts ONLY in a diagram or picture. Images: image is the single primary/background image (cover, section, full-bleed); images[] holds additional inserted images placed on the slide. Each image is {id?, src?, alt?, placement?, prompt?, x?, y?, w?, h?}. Set src to an uploaded file URL (upload via POST /v1/attachments/upload, then use /api/v1/attachments/{id}/raw), an https URL, or a data: URI — you cannot upload the file bytes through these MCP tools, only reference the resulting URL. To get a REAL image, call rootr_generate_image with an English prompt (say "no text"), then put the returned url into the slide image's src; rootr_remove_image_background cuts out an image's background. placement is a layout hint ("full"|"right"|"top"|...); x/y/w/h give freeform PPT-style placement in 1280x720 canvas coords. ALWAYS add an alt caption to every image — alt text is part of the graph text spine, so a captioned image connects into the knowledge graph while an uncaptioned one does not. Use kind to mark each slide's role: "cover" (deck title slide), "section" (chapter divider), "content" (body slide, the default), "closing" (last slide / call to action). Page numbers: "content" and "section" slides automatically show a page number that follows the slide order (it re-numbers itself when slides are reordered), so you do NOT set it yourself. "cover"/"closing" have none by design.

Inputs: slides (required), presentationId (required).

rootr_askAsk a question over the Rootr knowledge graph (RCA)A
Read-only

Ask a natural-language question against a Rootr (루터) workspace's knowledge graph (GraphRAG). Good for root-cause-analysis style questions ("why did X happen", "what changed before Y") that need to reason across linked documents and LOG anomalies rather than a single document. Requires the ask scope. Returns the answer text plus citations pointing at the source documents/quotes it drew from.

Inputs: question (required), workspace.

rootr_comment_documentComment on a Rootr documentA

Add a comment to a Rootr (루터) document (optionally anchored to a block, or as a reply via parentId). Comments carry a user identity, so this requires an ACCOUNT key (PAT) — a workspace-scoped key (including remote-connector tokens) gets a 403; fall back to rootr_append in that case.

Inputs: body (required), target (required), blockId, parentId.

rootr_comment_issueComment on an issueA

Add a comment to a Rootr (루터) issue within its tracker. Comments carry a user identity, so this requires an ACCOUNT key (PAT) as ROOTR_API_KEY — a workspace key gets a 403.

Inputs: body (required), issueId (required), trackerId (required).

rootr_create_formCreate a Rootr formA

Create a new FORM node (fillable intake) in a Rootr (루터) workspace, optionally seeded with field definitions. Use FORM for surveys/request queues collected from people outside the tree — set targetDatabaseId to also mirror each response into a DATABASE's rows. Fields are typed inputs shown to respondents: text | textarea | number | select | multi_select | checkbox | date; select/multi_select need options ({name,color}[]). Read the form first (rootr_read_form) before updating so you keep each field's id stable — response values are keyed by field id, so renaming/dropping an id orphans past responses' answers for that field.

Inputs: icon, name, config, fields, +3 more.

rootr_create_issueCreate an issueA

Create a new issue in a Rootr (루터) issue tracker. labels is an array of label ids, type is a type id (both from the tracker's custom type/label definitions — see rootr_read on the tracker or its metadata). parentIssueId nests this issue under another issue (sub-issue).

Inputs: title (required), trackerId (required), body, type, +2 more.

rootr_create_issue_trackerCreate an issue tracker in a Rootr workspaceA

Create a new GitHub-style issue tracker document in a Rootr (루터) workspace. Returns the tracker with its id, plus its default labels/types — use rootr_create_issue afterward to add issues to it.

Inputs: name (required), workspace.

rootr_create_log_storeCreate a typed LOG datastoreA

Create a new typed LOG store (a structured, queryable table-like node) in a Rootr (루터) workspace. Each field has a name/type; type is one of string|int|float|bool|datetime|json|enum|level|relation. Relation fields additionally need target (a node id to relate to) and optional many/relation flags. Use rootr_add_log_entries afterward to insert rows, and rootr_query_log_entries / rootr_log_stats to read them back.

Inputs: name (required), fields (required), parentId, workspace.

rootr_create_presentationCreate a Rootr presentation (slide deck)A

Create a new PRESENTATION node (a slide deck) in a Rootr (루터) workspace, optionally seeded with an initial theme and slides. Authoring guide: give each slide ONE assertion-style title (a claim, e.g. "Latency dropped 40% after the cache fix" — not a topic label like "Latency"), plus blocks[] (bullet-like {id, heading?, body?, icon?} items) and, where useful, a diagram ({type:"mermaid", code}) or images. Canvas is 16:9 (1280x720). Meaning must live in TEXT — title/blocks[].heading/blocks[].body/notes are what auto-connects into the knowledge graph; diagrams/code/html and the image pixels themselves are visual-only and are NOT indexed, so never put facts ONLY in a diagram or picture. Images: image is the single primary/background image (cover, section, full-bleed); images[] holds additional inserted images placed on the slide. Each image is {id?, src?, alt?, placement?, prompt?, x?, y?, w?, h?}. Set src to an uploaded file URL (upload via POST /v1/attachments/upload, then use /api/v1/attachments/{id}/raw), an https URL, or a data: URI — you cannot upload the file bytes through these MCP tools, only reference the resulting URL. To get a REAL image, call rootr_generate_image with an English prompt (say "no text"), then put the returned url into the slide image's src; rootr_remove_image_background cuts out an image's background. placement is a layout hint ("full"|"right"|"top"|...); x/y/w/h give freeform PPT-style placement in 1280x720 canvas coords. ALWAYS add an alt caption to every image — alt text is part of the graph text spine, so a captioned image connects into the knowledge graph while an uncaptioned one does not. Use kind to mark each slide's role: "cover" (deck title slide), "section" (chapter divider), "content" (body slide, the default), "closing" (last slide / call to action). Page numbers: "content" and "section" slides automatically show a page number that follows the slide order (it re-numbers itself when slides are reordered), so you do NOT set it yourself. "cover"/"closing" have none by design.

Inputs: icon, name, theme, config, +3 more.

rootr_create_sheetAdd a sheet (tab) to a Rootr spreadsheetA

Add a new empty sheet (tab) to an existing Rootr (루터) SPREADSHEET, without touching other sheets.

Inputs: spreadsheetId (required), name, colCount, rowCount.

rootr_create_spreadsheetCreate a Rootr spreadsheetA

Create a new SPREADSHEET node (a grid with formulas) in a Rootr (루터) workspace. Use SPREADSHEET when content needs calculation (budgets, models, estimates) — for plain tracked lists use DATABASE instead. Defaults to a single empty "Sheet1" if no data is given. Cells are addressed A1-style ("A1", "B12", ...) in a sparse map: { "A1": { v: 42 }, "B1": { f: "=A1*2" } }. Set a cell to null to clear it. Read the sheet first (rootr_read_spreadsheet) so you know current dimensions and existing content before patching — patchCells only touches the keys you send, everything else is untouched.

Inputs: data, icon, name, config, +2 more.

rootr_create_webhookCreate a webhookA

Create a webhook on a Rootr (루터) workspace. Valid events: document.created, document.updated, document.moved, document.deleted, comment.created, extraction.completed, extraction.failed, log.anomaly.rca, scaffold.applied. Optionally scope it to a subtree (scopeNodeId, inherited by descendants) and/or a tag filter (filterTags). debounceSeconds coalesces bursts of events (server enforces a fixed trailing debounce with a cap). IMPORTANT: the response secret is shown ONLY ONCE, in this call's result — copy it now, it will not be shown again. LOOP GUARD: deliveries carry the actor as data.actorId ("apikey:" for API writes) — a consumer MUST skip deliveries caused by its own key before reacting, or an agent that writes on notification will trigger itself forever.

Inputs: url (required), events (required), name, workspace, +3 more.

rootr_create_whiteboardCreate a Rootr whiteboardA

Create a new WHITEBOARD node (a freeform visual canvas) in a Rootr (루터) workspace, optionally seeded with an initial scene. Use WHITEBOARD for flow diagrams, brainstorming, journey maps — not for anything that needs typed/trackable rows (use DATABASE) or calculation (use SPREADSHEET). Authoring guide: a scene is { shapes: [{id,type,x,y,w,h,text?,style?}], edges: [{id,from,to,label?}] } — shapes are the nodes of a lightweight diagram (flow diagrams, brainstorming, journey maps), edges connect them by id. Meaning must live in shape/edge TEXT (text/label) — that is what gets indexed into the knowledge graph; x/y/w/h and style are visual-only layout. Read the board first (rootr_read_whiteboard) before updating so you know the existing shape ids edges refer to.

Inputs: icon, name, scene, config, +2 more.

rootr_create_workspaceCreate a brand-new Rootr workspace from a scaffold treeA

Create an entirely new Rootr (루터) workspace pre-populated with the given document tree. REQUIRES an account key (PAT) with the workspaces:create scope — a workspace-scoped key cannot do this. PRECONDITION: call rootr_scaffold_plan first and ask the user its 3-10 clarifying questions; design the tree from their answers. Build a real tool, not a pile of thin markdown files: mix DATABASE (board/timeline views, seed rows), SPREADSHEET (formulas), FORM, ISSUE_TRACKER and rich multi-section DOCUMENTs where they fit, and set an emoji icon on folders/databases/key documents. The tree shape follows the scaffold schema in llms.txt (max 200 nodes). AFTER creating: if your runtime can receive HTTP callbacks, offer the user to register a webhook on the new tree (rootr_create_webhook with scopeNodeId) so changes flow back to you — skip your own actorId to avoid self-triggering.

Inputs: name (required), tree (required), intent.

rootr_crm_createCreate a Rootr CRM nodeA

Create a new CRM node in a Rootr (루터) workspace — companies, contacts, multi-pipeline deals (kanban), activities and tasks all live inside it. Optionally seed custom pipelines (name + ordered stages, each with an optional win probability/color) and/or custom company/contact/deal fields; sane defaults are used if omitted. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: icon, name, path, config, +6 more.

rootr_crm_getGet a Rootr CRM node (pipelines, fields, counts)A
Read-only

Fetch a Rootr (루터) CRM node: its pipelines (with stages), custom field definitions, config, entity counts, and your access level. Call this before rootr_crm_update or before creating deals so you know the exact pipeline/stage ids. Set includeSummary to also merge in rootr_crm_get's stage-value/forecast/win-rate summary in one call. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), includeSummary.

rootr_crm_get_companyGet a company detail (contacts, deals, activities, tasks)A
Read-only

Fetch full detail of ONE Rootr (루터) CRM company: the company plus its contacts, deals, activities, and tasks. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: companyId (required).

rootr_crm_get_contactGet a contact by idA
Read-only

Fetch full detail of ONE Rootr (루터) CRM contact by id. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: contactId (required).

rootr_crm_get_dealGet a deal by idB
Read-only

Fetch full detail of ONE Rootr (루터) CRM deal by id. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: dealId (required).

rootr_crm_importBulk-import rows into a Rootr CRMA

Bulk-import rows into a Rootr (루터) CRM as companies, contacts, or deals in one call (entity picks which, rows is an array of plain field objects matching that entity's create shape, e.g. the same fields as rootr_crm_upsert_company/_contact/_deal). Use this for migrating a spreadsheet/CSV of leads or accounts instead of calling the upsert tools one row at a time. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: rows (required), crmId (required), entity (required).

rootr_crm_list_activitiesList activities on a Rootr CRM timelineB
Read-only

List logged activities in a Rootr (루터) CRM, filterable by contact, company, deal, or activity type. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), type, limit, dealId, +3 more.

rootr_crm_list_companiesList companies in a Rootr CRMA
Read-only

List/search companies in a Rootr (루터) CRM, optionally filtered by free-text query, owner, or tag, and sorted/paginated. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), q, tag, sort, +3 more.

rootr_crm_list_contactsList contacts in a Rootr CRMA
Read-only

List/search contacts in a Rootr (루터) CRM, filterable by free-text query, company, lifecycle stage (lead|mql|sql|opportunity|customer|evangelist), lead status (new|attempting|connected|open_deal|unqualified), owner, or tag. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), q, tag, sort, +6 more.

rootr_crm_list_dealsList deals in a Rootr CRMB
Read-only

List/search deals (kanban cards) in a Rootr (루터) CRM, filterable by query, pipeline, stage, status (open|won|lost|all), owner, company, contact, or tag. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), q, tag, sort, +8 more.

rootr_crm_list_tasksList follow-up tasks in a Rootr CRMA
Read-only

List follow-up tasks in a Rootr (루터) CRM, filterable by status (open|done|all), assignee, due bucket (overdue|today|upcoming), contact, company, or deal. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), due, limit, dealId, +5 more.

rootr_crm_log_activityLog an activity on a Rootr CRM timelineA

Log an activity (note|call|email|meeting) on a Rootr (루터) CRM's timeline, attached to a contact, company, and/or deal. Use this to record outreach/history that shows up on the contact/company/deal detail view. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: type (required), crmId (required), body, dealId, +4 more.

rootr_crm_move_dealMove a deal to another kanban stageA

Move a Rootr (루터) CRM deal to a different pipeline stage (kanban column), optionally into a different pipeline and/or a specific card position. Call rootr_crm_get first to learn the target stageId/pipelineId. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: dealId (required), stageId (required), position, pipelineId.

rootr_crm_updateUpdate a Rootr CRM node (pipelines/fields/config)A

Merge-patch a Rootr (루터) CRM node's pipelines, custom field definitions, config, or icon. Passing pipelines REPLACES the whole pipelines array — call rootr_crm_get first and resend any stages/pipelines you want to keep. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), icon, config, fields, +1 more.

rootr_crm_upsert_companyCreate, update, or delete a company in a Rootr CRMA

Create a new company (omit companyId), update an existing one (pass companyId + the fields to change), or delete one (pass companyId and delete: true). custom holds values for the CRM's custom field definitions (see rootr_crm_get). Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), name, size, tags, +9 more.

rootr_crm_upsert_contactCreate, update, or delete a contact in a Rootr CRMA

Create a new contact (omit contactId), update an existing one (pass contactId + fields to change), or delete one (pass contactId and delete: true). Setting email auto-links the contact to a matching company by domain, and leadScore is computed server-side automatically — do not try to set it yourself. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), name, tags, email, +11 more.

rootr_crm_upsert_dealCreate, update, or delete a deal in a Rootr CRMA

Create a new deal (omit dealId; defaults to the CRM's first pipeline if pipelineId is omitted), update an existing one (pass dealId + fields to change — set status to "won" or "lost" to close it, with wonLostReason, or "open" to reopen), or delete one (pass dealId and delete: true). To MOVE a deal between kanban stages, prefer rootr_crm_move_deal instead of patching stageId here. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), name, tags, value, +16 more.

rootr_crm_upsert_taskCreate or update a follow-up task in a Rootr CRMA

Create a new follow-up task (omit taskId) or update an existing one (pass taskId + fields to change, e.g. set status to "done" to complete it) in a Rootr (루터) CRM, optionally attached to a contact, company, and/or deal. Part of a Rootr (루터) CRM node: a full sales CRM (companies, contacts with lifecycle stages + auto lead-scoring, multi-pipeline deals/kanban, activity timeline, follow-up tasks), auto-linked into the knowledge graph.

Inputs: crmId (required), type, dueAt, title, +6 more.

rootr_delete_nodeDelete a node (move to trash)A
Destructive

Delete a Rootr (루터) document or folder by moving it to the trash — this is recoverable, not a permanent delete. Use rootr_read/rootr_list first to confirm you have the right target.

Inputs: target (required).

rootr_delete_rowDelete a database rowA
Destructive

Delete ONE row of a Rootr (루터) DATABASE by rowId (its linked page, if any, is moved to the trash). Verify the row via rootr_read_database first — do not guess rowIds.

Inputs: rowId (required), databaseId (required).

rootr_delete_sheetDelete a sheet (tab) from a Rootr spreadsheetA
Destructive

Delete one sheet (tab) from a Rootr (루터) SPREADSHEET by sheetId. Not recoverable — read first to confirm.

Inputs: sheetId (required), spreadsheetId (required).

rootr_delete_webhookDelete a webhookA
Destructive

Delete a webhook from a Rootr (루터) workspace. This cannot be undone.

Inputs: webhookId (required), workspace.

rootr_document_public_statusPublic status of a Rootr documentA
Read-only

Whether a Rootr (루터) document is published, and at which public slug/URL.

Inputs: target (required).

rootr_document_versionsList a document's version historyA
Read-only

List saved versions of a Rootr (루터) document, most recent first. Useful for seeing what changed and when, or to recover an older revision.

Inputs: target (required), limit.

rootr_duplicate_nodeDuplicate a Rootr node (deep copy)A

Deep-copy a Rootr (루터) node — a document or a whole folder tree — next to the original, or into another workspace the user can access (targetWorkspaceId). Returns the new root node.

Inputs: target (required), deep, targetWorkspaceId.

rootr_editEdit a Rootr document by anchor replaceA

Replace an exact snippet of text ("find") with new text ("replace") inside a Rootr document. Fails with a clear error if the snippet is missing or ambiguous (not unique), so read the document first to copy the exact text to find. Good for precise, targeted edits; use rootr_append instead when you are only adding new content.

Inputs: find (required), target (required), replace (required), replaceAll.

rootr_generate_imageGenerate an image from a text prompt (for a slide)A

Generate an image from a text prompt with AI (Gemini) and store it as a workspace attachment. Use this when building a Rootr (루터) presentation so slides get real, on-brand visuals instead of empty image placeholders — generate the image, then put the returned url into a slide image's src via rootr_update_presentation_slide (image or images[]). Returns { id, url, filename, mimeType, size }. Prompt tips: describe a clean, flat, presentation-ready illustration; specify colors to match the deck theme; and say "no text" — baked-in text is not indexed and often renders wrong (put the meaning in the slide title/blocks instead, and always give the image an alt caption). Consumes AI credits.

Inputs: prompt (required), nodeId, workspace.

rootr_get_issueGet an issueA
Read-only

Fetch full details of a single Rootr (루터) issue by id.

Inputs: issueId (required).

rootr_listList Rootr documentsA
Read-only

List documents and folders in the connected Rootr (루터) workspace, optionally filtered to a path prefix. Use this first to discover what exists before reading or writing.

Inputs: path.

rootr_list_document_commentsList comments on a Rootr documentA
Read-only

List the comment threads on a Rootr (루터) document, optionally filtered to one block. Works with any key.

Inputs: target (required), blockId.

rootr_list_form_responsesList a Rootr form's submitted responsesA
Read-only

List all responses submitted to a Rootr (루터) FORM, most recent first. Each response has values keyed by field id — call rootr_read_form first to map ids to field names. This is what lets an AI analyze responses collected from a form.

Inputs: formId (required).

rootr_list_issuesList issues in a trackerA
Read-only

List issues in a Rootr (루터) issue tracker, optionally filtered by state (OPEN/CLOSED/ALL), label id, type id, or a text query. Use rootr_get_issue for full details of one issue.

Inputs: trackerId (required), q, type, label, +1 more.

rootr_list_rowsList database rowsA
Read-only

List the rows of a Rootr (루터) DATABASE (id + values + position), without the schema. Use rootr_read_database instead when you also need the property/column definitions.

Inputs: databaseId (required).

rootr_list_webhooksList webhooks configured on a workspaceA
Read-only

List webhooks configured on a Rootr (루터) workspace. Secrets are not re-shown here (they only appear once, at creation time).

Inputs: workspace.

rootr_log_statsAggregate stats over a LOG storeA
Read-only

Compute aggregate statistics over a LOG store's entries, grouped by hour/day/source/level, with a metric of count/avg/max/min/sum (avg/max/min/sum require a numeric field). Useful for trend/volume questions without pulling raw entries.

Inputs: logId (required), to, from, field, +2 more.

rootr_patch_spreadsheet_cellsWrite cells into a Rootr spreadsheet sheet (preferred way to fill in data)A

Sparse-patch cells of ONE sheet in a Rootr (루터) SPREADSHEET, without touching the rest of the sheet. PREFER this over rootr_update_spreadsheet when you are only filling in / editing cell values or formulas. Cells are addressed A1-style ("A1", "B12", ...) in a sparse map: { "A1": { v: 42 }, "B1": { f: "=A1*2" } }. Set a cell to null to clear it. Read the sheet first (rootr_read_spreadsheet) so you know current dimensions and existing content before patching — patchCells only touches the keys you send, everything else is untouched.

Inputs: cells (required), sheetId (required), spreadsheetId (required).

rootr_publish_documentPublish a Rootr document to a public URLA

Publish a Rootr (루터) document at a public read-only URL (rootr.io/p/{slug}) — outsiders can read it and propose git-style edit suggestions the owner can merge. Publishing is an owner-level action: it needs MANAGE permission, which workspace-scoped keys (including remote-connector tokens) do not carry — use an ACCOUNT key (PAT) of the owner, or ask the user to publish from the share dialog. Returns the slug/URL. Check rootr_document_public_status first; unpublish via rootr_set_document_public.

Inputs: target (required).

rootr_query_log_entriesQuery entries from a LOG storeA
Read-only

Query/filter entries from a LOG store by time range, source, level, and/or anomaly flag. Use this to inspect recent activity or find anomalous entries before asking rootr_ask for root-cause analysis.

Inputs: logId (required), to, from, level, +4 more.

rootr_readRead a Rootr documentA
Read-only

Read the full markdown content of a Rootr (루터) document by path (starting with "/") or by node id. Read a document before editing or appending to it so you know its current structure.

Inputs: target (required).

rootr_read_databaseRead a database schema and rowsA
Read-only

Read a Rootr (루터) DATABASE node — its schema (properties with ids/types and select options) plus all rows (each with its rowId and values). ALWAYS call this before rootr_add_row / rootr_update_row so you know the exact property ids/names and, for board/kanban views, which select column holds the status. Only works on DATABASE nodes.

Inputs: databaseId (required).

rootr_read_formRead a Rootr formA
Read-only

Read a Rootr (루터) FORM node — its field definitions, targetDatabaseId, and config. Call this before rootr_update_form so you keep existing field ids stable, or before rootr_list_form_responses to know which field ids the response values are keyed by.

Inputs: formId (required).

rootr_read_presentationRead a Rootr presentationA
Read-only

Read a Rootr (루터) PRESENTATION node — its theme and full slides array. Read this before rootr_update_presentation / rootr_append_presentation_slides / rootr_reorder_presentation_slides so you know the current slide ids and content.

Inputs: presentationId (required).

rootr_read_spreadsheetRead a Rootr spreadsheetA
Read-only

Read a Rootr (루터) SPREADSHEET node — its sheets, each with a sparse cells map and dimensions. Call this before rootr_update_spreadsheet / rootr_patch_spreadsheet_cells so you know the current sheetIds and cell contents.

Inputs: spreadsheetId (required).

rootr_read_whiteboardRead a Rootr whiteboardA
Read-only

Read a Rootr (루터) WHITEBOARD node — its full scene (shapes[] and edges[]). Call this before rootr_update_whiteboard so you know the current shape/edge ids and content.

Inputs: whiteboardId (required).

rootr_remove_image_backgroundRemove the background of an imageA

Remove the background of an existing Rootr (루터) workspace attachment (e.g. a generated or uploaded image) and store the result as a new transparent PNG. Pass the source attachment id; returns { id, url, ... } for the cut-out image, which you can then place on a slide. Useful for product shots / logos / subjects that should sit on the slide without a boxed background.

Inputs: attachmentId (required), nodeId, workspace.

rootr_reorder_presentation_slidesReorder the slides of a Rootr presentationA

Reorder a Rootr (루터) PRESENTATION's slides. order must be the FULL list of the deck's slide ids, in the new desired order — call rootr_read_presentation first to get the current ids.

Inputs: order (required), presentationId (required).

rootr_scaffold_applyApply a scaffold tree to an existing workspaceA

Create the given document tree inside an existing Rootr (루터) workspace, optionally rooted under an existing path. Works with a workspace key (docs:write scope). PRECONDITION: call rootr_scaffold_plan first and ask the user its 3-10 clarifying questions; design the tree from their answers (same quality bar as rootr_create_workspace — real building blocks with icons/views/seed content, not thin markdown). AFTER creating: if your runtime can receive HTTP callbacks, offer a webhook on the new subtree (rootr_create_webhook with scopeNodeId) so changes flow back to you — skip your own actorId.

Inputs: tree (required), rootPath, workspace.

rootr_scaffold_planPlan a workspace scaffold from an intent — then ASK THE USER before buildingA
Read-only

Step 1 of scaffolding, ALWAYS call this first. Given a natural-language intent (e.g. "SRE 온콜 위키" or "sales CRM for a 5-person team"), Rootr's consultant returns a questionPolicy (ask the user MIN 3, up to 10 clarifying questions — this is not optional), the dimensions to cover, domain frameworks, and the buildingBlocks menu (DATABASE/DOCUMENT/SPREADSHEET/WHITEBOARD/FORM/ISSUE_TRACKER/FOLDER). You must then GENERATE your own questions from those frameworks, ask the user, and only design the tree AFTER their answers — every answer must visibly shape the result. Never build straight from a one-line intent. No workspace needed; create with rootr_create_workspace or rootr_scaffold_apply afterwards.

Inputs: intent (required).

rootr_set_document_publicUpdate public settings of a Rootr documentA

Update a published Rootr (루터) document's public settings — e.g. {"isPublic": false} to unpublish. Owner-level action (MANAGE): works with an account key (PAT), not with workspace-scoped/connector tokens.

Inputs: target (required), isPublic.

rootr_submit_form_responseSubmit a response to a Rootr formA

Submit one response to a Rootr (루터) FORM on behalf of the caller (authenticated submission, not the public/anonymous share-link flow). values is keyed by field id — call rootr_read_form first to get the exact field ids and types.

Inputs: formId (required), values (required).

rootr_update_formUpdate a Rootr form (fields/targetDatabaseId/config)A

Merge-patch a Rootr (루터) FORM: if you pass fields, it REPLACES the whole fields array — call rootr_read_form first and resend fields you want to keep (with their existing ids) so past responses stay attributable. Pass targetDatabaseId: null to unlink the mirrored DATABASE. Fields are typed inputs shown to respondents: text | textarea | number | select | multi_select | checkbox | date; select/multi_select need options ({name,color}[]). Read the form first (rootr_read_form) before updating so you keep each field's id stable — response values are keyed by field id, so renaming/dropping an id orphans past responses' answers for that field.

Inputs: formId (required), icon, config, fields, +1 more.

rootr_update_issueUpdate an issueA

Update arbitrary fields of a Rootr (루터) issue. To close an issue, set state to "CLOSED" and stateReason to one of completed | not_planned | duplicate.

Inputs: issueId (required), body, type, state, +4 more.

rootr_update_log_fieldsReplace a LOG store's field definitions (full replace)A
Destructive

Update the field schema of an existing LOG store. WARNING: this REPLACES THE ENTIRE FIELD SET — you must resend every field you want to keep, not just the ones you are changing/adding. Read the LOG store first (e.g. via rootr_read or a get-log call) to see its current fields before calling this.

Inputs: logId (required), fields (required).

rootr_update_presentationUpdate a Rootr presentation (theme/slides/config)A

Merge-patch a Rootr (루터) PRESENTATION: update theme and/or config, or REPLACE THE WHOLE slides array (if you pass slides, it replaces every existing slide — call rootr_read_presentation first and resend slides you want to keep, or use rootr_append_presentation_slides / rootr_update_presentation_slide instead for incremental changes). Authoring guide: give each slide ONE assertion-style title (a claim, e.g. "Latency dropped 40% after the cache fix" — not a topic label like "Latency"), plus blocks[] (bullet-like {id, heading?, body?, icon?} items) and, where useful, a diagram ({type:"mermaid", code}) or images. Canvas is 16:9 (1280x720). Meaning must live in TEXT — title/blocks[].heading/blocks[].body/notes are what auto-connects into the knowledge graph; diagrams/code/html and the image pixels themselves are visual-only and are NOT indexed, so never put facts ONLY in a diagram or picture. Images: image is the single primary/background image (cover, section, full-bleed); images[] holds additional inserted images placed on the slide. Each image is {id?, src?, alt?, placement?, prompt?, x?, y?, w?, h?}. Set src to an uploaded file URL (upload via POST /v1/attachments/upload, then use /api/v1/attachments/{id}/raw), an https URL, or a data: URI — you cannot upload the file bytes through these MCP tools, only reference the resulting URL. To get a REAL image, call rootr_generate_image with an English prompt (say "no text"), then put the returned url into the slide image's src; rootr_remove_image_background cuts out an image's background. placement is a layout hint ("full"|"right"|"top"|...); x/y/w/h give freeform PPT-style placement in 1280x720 canvas coords. ALWAYS add an alt caption to every image — alt text is part of the graph text spine, so a captioned image connects into the knowledge graph while an uncaptioned one does not. Use kind to mark each slide's role: "cover" (deck title slide), "section" (chapter divider), "content" (body slide, the default), "closing" (last slide / call to action). Page numbers: "content" and "section" slides automatically show a page number that follows the slide order (it re-numbers itself when slides are reordered), so you do NOT set it yourself. "cover"/"closing" have none by design.

Inputs: presentationId (required), icon, theme, config, +1 more.

rootr_update_presentation_slideUpdate ONE slide of a Rootr presentationA

Merge-patch a single slide by slideId, without touching the rest of the deck. Good for a precise, targeted edit (e.g. rewrite one slide's title/blocks); use rootr_append_presentation_slides instead when you are only adding new slides. Call rootr_read_presentation first to get the exact slideId. Authoring guide: give each slide ONE assertion-style title (a claim, e.g. "Latency dropped 40% after the cache fix" — not a topic label like "Latency"), plus blocks[] (bullet-like {id, heading?, body?, icon?} items) and, where useful, a diagram ({type:"mermaid", code}) or images. Canvas is 16:9 (1280x720). Meaning must live in TEXT — title/blocks[].heading/blocks[].body/notes are what auto-connects into the knowledge graph; diagrams/code/html and the image pixels themselves are visual-only and are NOT indexed, so never put facts ONLY in a diagram or picture. Images: image is the single primary/background image (cover, section, full-bleed); images[] holds additional inserted images placed on the slide. Each image is {id?, src?, alt?, placement?, prompt?, x?, y?, w?, h?}. Set src to an uploaded file URL (upload via POST /v1/attachments/upload, then use /api/v1/attachments/{id}/raw), an https URL, or a data: URI — you cannot upload the file bytes through these MCP tools, only reference the resulting URL. To get a REAL image, call rootr_generate_image with an English prompt (say "no text"), then put the returned url into the slide image's src; rootr_remove_image_background cuts out an image's background. placement is a layout hint ("full"|"right"|"top"|...); x/y/w/h give freeform PPT-style placement in 1280x720 canvas coords. ALWAYS add an alt caption to every image — alt text is part of the graph text spine, so a captioned image connects into the knowledge graph while an uncaptioned one does not. Use kind to mark each slide's role: "cover" (deck title slide), "section" (chapter divider), "content" (body slide, the default), "closing" (last slide / call to action). Page numbers: "content" and "section" slides automatically show a page number that follows the slide order (it re-numbers itself when slides are reordered), so you do NOT set it yourself. "cover"/"closing" have none by design.

Inputs: slide (required), slideId (required), presentationId (required).

rootr_update_rowUpdate a database rowA

Merge-patch ONE row of a Rootr (루터) DATABASE by rowId (get rowIds from rootr_read_database). values maps property NAME (or id) → new value; only the passed keys change, null clears a key, omitted keys are left unchanged. To MOVE a kanban card to another column, set its select/status property to the new option name. Optionally set position to reorder the row.

Inputs: rowId (required), databaseId (required), values, position.

rootr_update_sheetRename/resize ONE sheet of a Rootr spreadsheetA

Merge-patch a single sheet's name/dimensions/row-col sizing by sheetId, without touching its cells. Call rootr_read_spreadsheet first to get the exact sheetId.

Inputs: sheetId (required), spreadsheetId (required), name, merges, +4 more.

rootr_update_spreadsheetUpdate a Rootr spreadsheet (config/icon, or replace all sheets)A

Merge-patch a Rootr (루터) SPREADSHEET: update config/icon, or REPLACE THE WHOLE sheets array (if you pass sheets, it replaces every existing sheet — call rootr_read_spreadsheet first and resend sheets you want to keep, or prefer rootr_create_sheet / rootr_patch_spreadsheet_cells for incremental changes).

Inputs: spreadsheetId (required), icon, config, sheets.

rootr_update_whiteboardUpdate a Rootr whiteboard (replace the scene, or config/icon)A

Merge-patch a Rootr (루터) WHITEBOARD: update config/icon, or REPLACE THE WHOLE scene (if you pass scene, it replaces every existing shape/edge — call rootr_read_whiteboard first and resend the shapes/edges you want to keep so you don't lose existing content). Authoring guide: a scene is { shapes: [{id,type,x,y,w,h,text?,style?}], edges: [{id,from,to,label?}] } — shapes are the nodes of a lightweight diagram (flow diagrams, brainstorming, journey maps), edges connect them by id. Meaning must live in shape/edge TEXT (text/label) — that is what gets indexed into the knowledge graph; x/y/w/h and style are visual-only layout. Read the board first (rootr_read_whiteboard) before updating so you know the existing shape ids edges refer to.

Inputs: whiteboardId (required), icon, scene, config.

rootr_workspacesList my Rootr workspacesA
Read-only

List the Rootr (루터) workspaces the current API key can see. Works with either key type: with an account key (PAT) this lists all workspaces you belong to; a workspace key only sees the workspace it's scoped to. Use this to find a workspace id before calling other workspace-scoped tools.

Inputs: no named parameters.

rootr_writeOverwrite a Rootr document (destructive)A
Destructive

Replace the ENTIRE content of a Rootr document, or create a new document at a path if it does not exist. This is DESTRUCTIVE — it discards whatever is currently there. Read the document first and pass its etag as ifMatch to avoid clobbering concurrent changes. Prefer rootr_append or rootr_edit for incremental changes.

Inputs: target (required), content (required), ifMatch.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 81 tools

    Disambiguation4/5

    Most tools have distinct purposes, with clear domain separation (documents, databases, CRM, presentations, etc.). Overlaps exist within domains (e.g., rootr_read_database vs rootr_list_rows) but descriptions clarify when to use each. Overall, an agent can distinguish tools well.

    Naming Consistency4/5

    All tools start with 'rootr_' and use snake_case verb_noun pattern. However, verb choice varies (list/read/get, upsert/create/update) and some tools mix actions (e.g., rootr_crm_upsert_company covers create, update, delete). Mostly consistent but with minor deviations.

    Tool Count2/5

    81 tools is excessive for most use cases. While the server aims to be comprehensive, this many tools can overwhelm agents and increase selection errors. A more focused set (20-30) would be more appropriate for typical workspace management.

    Completeness4/5

    The tool set covers CRUD and advanced operations for many node types: documents, databases, spreadsheets, presentations, CRM (companies, contacts, deals, activities, tasks), issue trackers, logs, forms, whiteboards, and more. Minor gaps like user management exist, but overall it's quite complete for the workspace domain.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A simple MCP server for chatbot/human collaborative management of text content stored as markdown files with YAML frontmatter.
      3
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      MCP server for the Zenvoy Markdown notes app, providing 26 tools for vault operations like reading, creating, searching notes, and managing tasks, templates, and comments.
      2
      -