Rootr MCP Server
This server is an MCP interface to the Rootr workspace, exposing 167 tools for reading, writing, and managing documents and structured data. It can:
Documents: list, read, write, append, edit, and search markdown documents; manage version history; add comments; publish documents to public read-only URLs; set public visibility.
Databases: read schemas and rows, add/update rows, query and aggregate data, manage database views and fields.
Spreadsheets: read and write cells, manage sheets, calculate formulas, handle budgets/models/estimates.
Forms: create forms, read questions/fields, submit responses, analyze collected answers, manage share links.
Presentations: create slide decks, read slides, update or reorder slides, generate slide images with AI.
Issue tracking: create issue trackers, add issues, manage labels/types.
Logs: create log databases, add entries, query logs, compute stats (count/avg/max/min/sum) grouped by time/source/level.
Memory: store and recall team knowledge via
rootr_remember/rootr_recall/rootr_forget.Scaffolding: plan and build entire workspace structures (folders, databases, spreadsheets, forms, issue trackers, documents) from user requirements.
Ask / GraphRAG: ask natural-language questions over the workspace and get cited answers from source documents/quotes.
Workspace & permissions: retrieve workspace info, manage node permissions, visibility, and public access.
CRM: work with CRM contacts and activities.
It also includes a CLI (rootr) for the same operations and supports configuration via environment variables or rootr config.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Rootr MCP Server read the weekly meeting notes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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)
rootrCLI — documents, databases, forms, signed documents, publishing, permissions, memoryrootr mcp— stdio MCP server, 167 tools (see MCP tools)
Plain Node.js ESM, no build step. Node 18+ (uses the built-in fetch).
Links
Remote connector (nothing to install):
https://rootr.io/mcpDocs: https://rootr.io/en/docs · authoring reference: https://rootr.io/llms.txt
License: MIT (see
LICENSE)
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/mcpAdd 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 globallyOr from a clone:
npm install
node bin/rootr.js --helpDocker:
docker build -t rootr-cli .
docker run -i --rm -e ROOTR_API_KEY=rootr_xxx -e ROOTR_WORKSPACE=ws_123 rootr-cliConfiguration
Precedence: environment variables > ~/.rootr/config.json
Env var | Config key | Description |
|
| API key ( |
|
| Workspace id |
|
| Defaults to |
| — |
|
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 # EnglishThe 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:createscope 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 configWorking with several workspaces
Register each workspace's key once:
rootr config --add-key rootr_xxx --label "Sales"
rootr config # list registered keysAfter 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_123ask 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 pageForms
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 rateSigned 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 ledgerThe 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, formsReporting 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 bugSends 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 scopes412— document changed since you read it; read again and retry (If-Match mismatch)409— the server's reason is shown verbatim (e.g.editfound no unique match)429— usage limit reached; the message carries the reset time and an upgrade link
Development
Dependencies:
@modelcontextprotocol/sdk(MCP server) andzod(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 mcpLicense
MIT — see LICENSE.
Available Tools
81 toolsrootr_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)ARead-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)ARead-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)ARead-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 idARead-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 idBRead-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 timelineBRead-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 CRMARead-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 CRMARead-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 CRMBRead-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 CRMARead-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)ADestructive
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 rowADestructive
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 spreadsheetADestructive
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 webhookADestructive
Delete a webhook from a Rootr (루터) workspace. This cannot be undone.
Inputs: webhookId (required), workspace.
rootr_document_public_statusPublic status of a Rootr documentARead-only
Whether a Rootr (루터) document is published, and at which public slug/URL.
Inputs: target (required).
rootr_document_versionsList a document's version historyARead-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 issueARead-only
Fetch full details of a single Rootr (루터) issue by id.
Inputs: issueId (required).
rootr_listList Rootr documentsARead-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 documentARead-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 responsesARead-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 trackerARead-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 rowsARead-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 workspaceARead-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 storeARead-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 storeARead-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 documentARead-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 rowsARead-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 formARead-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 presentationARead-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 spreadsheetARead-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 whiteboardARead-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 buildingARead-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_searchSearch the Rootr workspaceARead-only
Full-text search across the connected Rootr (루터) workspace. Use this to find relevant documents before reading or editing them.
Inputs: query (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)ADestructive
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 workspacesARead-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)ADestructive
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
Scored across 81 tools
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.
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.
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.
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
KnowMan MCP server: search, ask, save and read your Knowledge Base from any MCP client.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Unified 15-tool SEO, SERP, clean Markdown & GEO (LLM citation Share-of-Voice) MCP server.
Related MCP Servers
- AlicenseCqualityDmaintenanceMCP protocol server for managing multi-project Markdown documents, supporting project isolation and LLM tool integration.2925 npm4MIT
- AlicenseNot gradedqualityDmaintenanceA simple MCP server for chatbot/human collaborative management of text content stored as markdown files with YAML frontmatter.3MIT
- FlicenseNot gradedqualityCmaintenanceMCP 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-
- AlicenseNot gradedqualityBmaintenanceMCP server that enables AI agents to search, fetch, and analyze a self-maintaining markdown knowledge base with provenance, drift detection, and canonical definitions.1MIT