PowerScroll
NPM · POWERSCROLL-MCP · SCANNED SEP 20
Read and edit a live local-first PowerScroll visual notebook.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security98
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- 31 of 96 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency48
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 28 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability70
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 7972 tokens (~215/item across 37 items; 37 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management97
- Stability observed for 29 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 0 of 5 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_page" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
- An AI judge read all 37 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the PowerScroll MCP server?
PowerScroll runs locally as an npm package, launched with npx -y powerscroll-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · powerscroll-mcp
claude mcp add cynacons-powerscroll -- npx -y powerscroll-mcp
{
"mcpServers": {
"cynacons-powerscroll": {
"command": "npx",
"args": [
"-y",
"powerscroll-mcp"
]
}
}
} {
"servers": {
"cynacons-powerscroll": {
"command": "npx",
"args": [
"-y",
"powerscroll-mcp"
]
}
}
} codex mcp add cynacons-powerscroll -- npx -y powerscroll-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"cynacons-powerscroll": {
"type": "local",
"command": [
"npx",
"-y",
"powerscroll-mcp"
],
"enabled": true
}
}
} openclaw mcp add cynacons-powerscroll --command npx --arg -y --arg powerscroll-mcp
mcp_servers:
cynacons-powerscroll:
command: "npx"
args: ["-y", "powerscroll-mcp"] {
"McpServers": {
"cynacons-powerscroll": {
"Transport": "stdio",
"Command": "npx",
"Arguments": [
"-y",
"powerscroll-mcp"
]
}
}
} assistant mcp add cynacons-powerscroll -t stdio -c npx -a -y powerscroll-mcp
{
"mcpServers": {
"cynacons-powerscroll": {
"command": "npx",
"args": [
"-y",
"powerscroll-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 20 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.
- 18 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 87 to 90. That category is still filling its 30-day observation window: 26 days of observed history at the previous scan, 27 at this one. The score rises as the window fills, whether or not the server changes.
- 16 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 80 to 83. That category is still filling its 30-day observation window: 24 days of observed history at the previous scan, 25 at this one. The score rises as the window fills, whether or not the server changes.
- 14 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 73 to 77. That category is still filling its 30-day observation window: 22 days of observed history at the previous scan, 23 at this one. The score rises as the window fills, whether or not the server changes.
- 12 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 67 to 70. That category is still filling its 30-day observation window: 20 days of observed history at the previous scan, 21 at this one. The score rises as the window fills, whether or not the server changes.
- 9 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.
- 7 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.
- 5 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 20 Sept 2026 · Analysed npm/powerscroll-mcp@0.67.1
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | npm |
Background: How many MCP packages publish verified provenance →
Dependencies 96 packages
| Packages resolved | 96 |
|---|---|
| Stale | 31 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
append_block ~265
Append a markdown block to the bottom of a page. This is the main way to write content. The markdown is rendered live in the app: use "- " for bullets, "1. " for numbered lists, "- [ ] " for checkboxes (which the user can then click to tick), "#"/"##" for headings, **bold**, `code`, tables, and $math$. Prefer one block per logical chunk (one list, one paragraph) rather than one block per line.
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | Raw A4 page-guide index: 0 is the leftmost, 1 the guide to its right. Legacy fallback — prefer scrollId, which keeps pointing at the same scroll after scrolls are reordered. Ignored when scrollId is… |
| markdown | string | yes | Markdown content for the block. |
| pageId | string | – | Page to append to. Defaults to the page currently open. |
| scrollId | string | – | Scroll (named column) to write into. THIS IS THE PREFERRED WAY to choose where a block lands — call list_scrolls first and pass an id from it. Each scroll stacks independently, so two workstreams can… |
No output schema declared.
No examples provided.
bridge_status ~126
Who else is working in this notebook. Several agents may be connected at once but only one may operate at a time, so call this when a tool comes back LOCKED, or before starting a long piece of work. Reports the connected notebook, every connected agent, which one holds the notebook, how long until it frees up, and whether that is you. This tool is never blocked. Note that a free result can go stale immediately -- another agent may take the lock before your next call -- so treat the LOCKED error as the real signal and this as a way to understand it.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
check_update ~58
Check whether a newer PowerScroll release exists on GitHub. Reports the running version and the latest one. Note "checked": when false the API was unreachable or rate limited and the status is unknown — that is not the same as up to date.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
create_diagram ~183
DEPRECATED - use create_diagram_plantuml, create_diagram_mermaid, create_diagram_svg or create_diagram_drawio instead, which name the language they take and each document their own subset. This name still works and sniffs the format from the source, but it will be removed. Behaviour is otherwise identical.
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | Legacy fallback - prefer scrollId. |
| pageId | string | – | Page to draw on. Defaults to the open page. |
| render | string | – | draw.io sources only: 'snapshot' (default) renders an exact image; 'nodes' transpiles to native shapes. |
| scrollId | string | – | Scroll to draw into. Defaults to the leftmost. |
| source | string | yes | Diagram source. The format is sniffed. |
| title | string | – | Title shown on the diagram frame. |
No output schema declared.
No examples provided.
create_diagram_drawio ~1,125
Draw a draw.io / mxGraph diagram onto the page. BY DEFAULT (v0.64+) the source is rendered by the embedded draw.io viewer into an exact vector snapshot — colours, gradients, curved edges, double-headed arrows, HTML labels, shadows and every built-in shape render exactly as diagrams.net shows them. The response then carries renderMode 'snapshot' and elementCount 0: a snapshot diagram has NO member nodes BY DESIGN — the stored XML remains the editable source, read_diagram returns it, and "Export as .drawio" emits it verbatim. Library stencil ICONS (mxgraph.aws4/mscae/cisco) are the one gap: they render as their styled box + label, since stencil packs are not bundled. If the viewer extension is unavailable (e.g. offline before it was installed), the tool FALLS BACK to transpiling the source into native PowerScroll shapes and says so in warnings. Pass render:'nodes' to force that transpile path deliberately, when you WANT individually-selectable member nodes instead of exact paint. Everything below documents the transpiled subset — it applies to render:'nodes' and to the fallback, NOT to snapshots. THIS TOOL IS A SIBLING OF create_diagram_svg: YOU have already done the layout and the coordinates are the payload. Use create_diagram_plantuml or create_diagram_mermaid when you want a diagram laid out well without doing the geometry yourself. Supported vertices: default and rounded rectangles, ellipses, rhombi (as a 45° rect fitted to the cell), triangles, labels, standalone text cells, and flattened groups / containers / swimlanes. Paint via fillColor, strokeColor, strokeWidth, dashed=1 and dashPattern. rotation on a rectangle is honoured. Supported vertices also include UML module/component (rectangle with two left tabs), ports (small rectangles, including relative geometry + mxPoint offset so they sit on the parent edge), and box-like mxgraph.uml / mxgraph.basic library shapes (drawn as rectangles; an ignored diagnostic names the original stencil). Supported edges: a st…
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | Raw A4 page-guide index. Legacy fallback - prefer scrollId. |
| pageId | string | – | Page to draw on. Defaults to the page currently open. |
| render | string | – | How to draw it. 'snapshot' (default): exact image via the draw.io viewer. 'nodes': transpile into native, individually-editable shapes (lossy — see the subset above). |
| scrollId | string | – | Scroll (named column) to draw into - call list_scrolls first. Lands below whatever is already in that column. Defaults to the leftmost. |
| source | string | yes | draw.io / mxGraph XML. An <mxfile> or a bare <mxGraphModel>. Compressed (base64+deflate) pages are accepted — they are inflated before use. |
| title | string | – | Title shown on the diagram frame. Defaults to "Diagram". |
No output schema declared.
No examples provided.
create_diagram_mermaid ~562
Draw a diagram on the page from MERMAID source. (For PlantUML source, use create_diagram_plantuml instead.) A DOCUMENTED SUBSET is read, and anything outside it comes back as a diagnostic instead of being drawn wrong. (1) FLOWCHART: "flowchart TD" / "flowchart LR" / "graph LR" as the first line, then nodes A[Label], A(Label) and A{Label}, and edges A --> B, A -->|guard| B and A --- B. Chains such as A --> B --> C work. (2) SEQUENCE: "sequenceDiagram" as the first line, then participant X (optionally "participant X as Label") and messages A->>B: text and A-->>B: reply. TWO THINGS TO EXPECT. Node SHAPE is carried as a stereotype above the name, not as geometry: a {decision} renders as a box labelled "decision" rather than as a diamond, because the shared layout has one box shape. LAYOUT is left to right whatever direction the header names, and a sequence renders as participants side by side with numbered messages between them, not as lifelines running down the page. NOT SUPPORTED, and refused with a diagnostic: subgraphs, dotted (-.->), thick (==>) and circle/cross (--o, --x) links, compound node shapes such as A[[Sub]] or A((Circle)), loop/alt/opt/par/note blocks, and the class, state, ER and Gantt families. What lands on the canvas is ordinary PowerScroll shapes and text inside a diagram frame, so the user can drag any part of it afterwards - this is NOT an image. Supply semantics only; every coordinate is computed here from real text metrics. The response carries the diagnostics, so one call is enough to know whether it came out right.
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | Raw A4 page-guide index. Legacy fallback - prefer scrollId. Ignored when scrollId is given. |
| pageId | string | – | Page to draw on. Defaults to the page currently open. |
| scrollId | string | – | Scroll (named column) to draw into - call list_scrolls first. The diagram lands below whatever is already in that column, like append_block. Defaults to the leftmost. |
| source | string | yes | Mermaid text. The FIRST line must be flowchart/graph with a direction, or sequenceDiagram. Example: "flowchart LR" then A[Read sensor] --> B{Uplink up?} then B -->|yes| C[Send batch]. |
| title | string | – | Title shown on the diagram frame. Defaults to "Diagram". |
No output schema declared.
No examples provided.
create_diagram_plantuml ~535
Draw a UML diagram on the page from PLANTUML source. (For Mermaid source, use create_diagram_mermaid instead - this tool refuses it rather than half-drawing it.) Two PlantUML dialects are supported, and the right one is detected automatically. (1) COMPONENT / COMPOSITE STRUCTURE: components, nested components, ports (port / portin / portout), provided and required interfaces, and assembly and delegation connectors. A composite-structure part puts its role in the label, as component "role : Type [multiplicity]" as alias. Nesting uses braces. (2) ACTIVITY / SWIMLANE FLOWCHARTS: |Lane| switches the swimlane, start and stop are the pseudostates, :action; is a step, and if (cond) then (label) / else (label) / endif adds a decision with guards on the arrows. Steps run top to bottom in source order and the lane fixes the column. What lands on the canvas is ordinary PowerScroll shapes and text inside a diagram frame, so the user can drag any part of it afterwards - this is NOT an image. Supply semantics only: name the steps or entities and what connects to what. Every coordinate is computed here from real text metrics, and there is no way to position anything yourself. Do NOT include skinparam, !include, !theme or any styling - PowerScroll supplies the style and those lines come back as skipped diagnostics. fork, split, while and repeat are refused rather than drawn wrong, and activity branches currently render in source order rather than as parallel paths that rejoin. The response carries the diagnostics, so one call is enough to know whether it came out right.
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | Raw A4 page-guide index. Legacy fallback - prefer scrollId. Ignored when scrollId is given. |
| pageId | string | – | Page to draw on. Defaults to the page currently open. |
| scrollId | string | – | Scroll (named column) to draw into - call list_scrolls first. The diagram lands below whatever is already in that column, like append_block. Defaults to the leftmost. |
| source | string | yes | PlantUML text; @startuml/@enduml optional, one statement per line. Component example: component "gateway" as gw { portin telemetry ... }. Swimlane example: |Sensor| then start then :sample burst; the… |
| title | string | – | Title shown on the diagram frame. Defaults to "Diagram". |
No output schema declared.
No examples provided.
create_diagram_svg ~466
Draw an SVG onto the page as native PowerScroll shapes. Every element becomes an ordinary rectangle, circle, line or text run that the user can select and drag afterwards -- it is transpiled, NOT embedded as an image. THIS TOOL IS THE OPPOSITE OF THE OTHER TWO: create_diagram_plantuml and create_diagram_mermaid want semantics and compute every coordinate for you, whereas here YOU have already done the layout and the coordinates are the payload. Use this when you want exact placement, and one of the others when you want a diagram laid out well without doing the geometry yourself. Supported: svg (viewBox and width/height set a uniform scale), g with translate and uniform scale, rect (incl. rx), circle, ellipse, line, polyline, polygon, and text with tspan and text-anchor. Paint via fill, stroke, stroke-width, stroke-dasharray and font-*, read from attributes or a style attribute and inherited down the tree. REFUSED, each with a diagnostic naming it: path (a bezier has no native node, and flattening it to line segments is a lie that survives every later edit), gradients, patterns, filters, masks, clipPath, use, symbol, image, foreignObject, textPath, style, script, animation and nested svg. rotate() transforms are refused too, because the native rotation turns about an element's own corner rather than the user-space origin, so honouring it would move your drawing. Keep to the supported subset and nothing is silently lost. The response carries the diagnostics, so one call tells you what was dropped.
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | Raw A4 page-guide index. Legacy fallback - prefer scrollId. |
| pageId | string | – | Page to draw on. Defaults to the page currently open. |
| scrollId | string | – | Scroll (named column) to draw into - call list_scrolls first. Lands below whatever is already in that column. Defaults to the leftmost. |
| source | string | yes | SVG markup. A root <svg> with a viewBox is best -- it fixes the scale and the corner lands where the diagram is placed. |
| title | string | – | Title shown on the diagram frame. Defaults to "Diagram". |
No output schema declared.
No examples provided.
create_page ~114
Create a new page and open it. By default also writes the title onto the canvas as an H1 block so the page reads as a titled note.
| Name | Type | Req | Description |
|---|---|---|---|
| column | integer | – | A4 page guide to place the heading in: 0 is the leftmost (default). |
| sectionId | string | – | Section to create the page in. Defaults to the active section. |
| title | string | yes | Page title. |
| withHeading | boolean | – | Write an "# Title" block onto the canvas too. Default true. |
No output schema declared.
No examples provided.
create_scroll ~115
Create a new named scroll on a page — a fresh vertical column to the right of the existing ones, with its title shown at the top on the canvas. Use this to keep a separate workstream (say "Open questions" beside "Research log") from interleaving with what is already there. Returns a scrollId to pass to append_block.
| Name | Type | Req | Description |
|---|---|---|---|
| pageId | string | – | Page to add the scroll to. Defaults to the page currently open. |
| title | string | yes | Title shown at the top of the scroll. |
No output schema declared.
No examples provided.
create_section ~43
Create a new section (a tab in the notebook sidebar). Sections contain pages. A first empty page is created along with it.
| Name | Type | Req | Description |
|---|---|---|---|
| title | string | yes | Section title. |
No output schema declared.
No examples provided.
delete_block ~142
Delete a single markdown block by id. Use read_page first to get block ids and check you are removing the right one. Passed a diagram FRAME id, this cascades to the frame's members and grouped strokes — same primitive as delete_diagram, which names the act and reports the counts. Passed a diagram MEMBER id (a node whose groupId is owned by a diagram frame), the call is refused (UNSUPPORTED) naming the owning diagram and pointing at delete_diagram or the redraw path.
| Name | Type | Req | Description |
|---|---|---|---|
| blockId | string | yes | Block to delete (from read_page). |
| confirm | boolean | yes | Must be true. Confirms the user agreed to the deletion. |
No output schema declared.
No examples provided.
delete_diagram ~183
Delete a diagram frame and everything that belongs to it: every node whose groupId is the frame id, and every stroke grouped with it. Use this when you placed a diagram you no longer want — delete_block on the frame id does the same cascade, but this tool names the act and reports how many members and strokes went. Occupants below the frame in the same scroll close the gap. An unknown id is NOT_FOUND. Passing a non-diagram node id is refused (the message names the type and points at delete_block). The bridge has no undo, so pass confirm:true once the user has agreed. Returns deletedMembers and deletedStrokes.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Confirms the user agreed to the deletion. |
| diagramId | string | yes | Id of the diagram frame (from read_page diagrams[].id or create_diagram). |
No output schema declared.
No examples provided.
delete_page ~92
Delete a page and everything on it. Cannot be undone from here — the app has no agent-facing undo — so ask the user before calling, then pass confirm:true. Refuses when the page is the last one in its section.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Confirms the user agreed to the deletion. |
| pageId | string | – | Page to delete. Defaults to the page currently open. |
No output schema declared.
No examples provided.
delete_scroll ~300
Delete a named scroll (a column band). When the band holds ANY content — nodes, group members, or ink — content is REQUIRED: "delete" removes them with the band, "keep" closes the gap and leaves them where they are. There is deliberately no default. The old default was keep (confirm:true used to be a safe trim); a default flip would silently destroy callers that never passed the flag. An empty band needs no content param. Membership is group-aware: a diagram belongs to the band of its frame origin, and its members and grouped ink follow that verdict. A page must keep at least one scroll: a plain page is one untitled scroll — untitle it instead of deleting the last one.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Confirms the user agreed to the deletion. |
| content | string | – | Required when the band is not empty. "delete" removes the band's nodes, group members and ink with the scroll. "keep" closes the gap and leaves them. There is no default — the old default was keep, a… |
| scrollId | string | yes | Scroll to delete (from list_scrolls). |
| withBlocks | boolean | – | Deprecated alias for content. true = delete, false = keep. Ignored when content is set. The response includes a deprecation notice. |
No output schema declared.
No examples provided.
delete_section ~82
Delete a section AND every page inside it. This is the widest-reaching delete available — confirm the page list with the user first (list_pages shows what would go). Refuses when it is the notebook's only section.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Confirms the user agreed to the deletion. |
| sectionId | string | yes | Section to delete. |
No output schema declared.
No examples provided.
fit_diagram ~135
Refit an existing diagram to the scroll band its frame sits in. Unlike placement-time fit (shrink-only), this scales BOTH directions: up to fill band-width minus padding when the diagram is under-width, down with the same 0.45 floor when over. Works on member diagrams (members rescale) and on renderMode 'snapshot' diagrams (the frame rescales; the image follows). Out-of-band frames are refused (PRECONDITION, naming the diagram). Discover ids from read_page diagrams[]. One undo in the app.
| Name | Type | Req | Description |
|---|---|---|---|
| diagramId | string | yes | Diagram frame id from read_page diagrams[].id. |
No output schema declared.
No examples provided.
get_background ~94
Read the canvas look a page is actually drawn with: which guide style is active and which background colour. A page may override the notebook default, so the reply also carries "source" (whether each value came from the page or the notebook) and "notebookDefault". Call before set_background when you intend to restore the previous look afterwards.
| Name | Type | Req | Description |
|---|---|---|---|
| pageId | string | – | Page to read. Defaults to the active page. |
No output schema declared.
No examples provided.
get_block ~137
Re-fetch a single markdown block by id (BlockSummary plus page location). Use this after read_page hits the size cap. A block larger than the 20000-character budget is returned in slices: the response carries markdownTruncated {fullLength, notice} and nextOffset — pass nextOffset back as offset to continue. Any block, any size, is fully readable in bounded calls. Unknown or non-block ids are NOT_FOUND.
| Name | Type | Req | Description |
|---|---|---|---|
| blockId | string | yes | Block id from read_page. |
| offset | number | – | Character offset into the block markdown (from a previous response's nextOffset). Omit to start at 0. |
No output schema declared.
No examples provided.
insert_block ~249
Insert a markdown block into a scroll at a chosen position, shifting every occupant below it (text, diagram frames, images, shapes, ungrouped ink) down by the new block's height + 12px. Frame members ride the frame. Prefer after (a block or diagram-frame id): ids survive reordering, indices do not. Exactly one of after or index. index 0 is the top of the column (ceiling-clamped when a titled scroll arms the page ceiling). index counts packed occupants of the scroll, not read_page blocks[] — prefer after. Returns the new block plus displacedCount.
| Name | Type | Req | Description |
|---|---|---|---|
| after | string | – | Insert after this occupant id (a markdown block or diagram frame in the same scroll). Preferred. Do not pass index at the same time. |
| index | integer | – | 0-based index in the scroll's packed-occupant reading order (text and diagrams). 0 = column top. Do not pass after at the same time. Prefer after: index is not read_page blocks[] order. |
| markdown | string | yes | Markdown content for the block. |
| scrollId | string | yes | Scroll to insert into (from list_scrolls). Required. |
No output schema declared.
No examples provided.
insert_image ~409
Insert an image into a scroll at a chosen position, shifting every occupant below it (text, diagram frames, images, shapes, ungrouped ink) down by the image's display height + 12px. Frame members ride the frame. Source is exactly one of data (a data:image/...;base64, URI) or path (a local png/jpg/jpeg/gif/webp file this server reads and encodes — the app never sees paths). Both or neither is an error. Placement matches insert_block: prefer after (an occupant id); exactly one of after or index. index 0 is the column top (ceiling-clamped when a titled scroll arms the page ceiling). Optional alt (defaults to "image") and mini (land as a 160px-wide thumbnail). Oversized images are downscaled to a 2048px long edge like UI imports. Returns id + display and natural dims + displacedCount — never the base64 payload. One undo.
| Name | Type | Req | Description |
|---|---|---|---|
| after | string | – | Insert after this occupant id (a markdown block or diagram frame in the same scroll). Preferred. Do not pass index at the same time. |
| alt | string | – | Alt text. Defaults to "image". |
| data | string | – | Base64 data URI (data:image/...;base64,...). Exactly one of data or path. |
| index | integer | – | 0-based index in the scroll's packed-occupant reading order. 0 = column top. Do not pass after at the same time. Prefer after. |
| mini | boolean | – | If true, land as a Mini thumbnail (default width 160). Displacement uses the mini height. |
| path | string | – | Local file path (png, jpg, jpeg, gif, or webp). This server reads and encodes it; the app never sees the path. Exactly one of data or path. |
| scrollId | string | yes | Scroll to insert into (from list_scrolls). Required. |
No output schema declared.
No examples provided.
list_pages ~41
List every section and page in the connected notebook, with the number of text blocks on each and which page is currently open. Call this first to discover page ids.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
list_scrolls ~111
List the scrolls (named vertical columns) on a page, with how many blocks each holds. Call this before writing when a page may have more than one workstream on it: passing the returned scrollId to append_block keeps your blocks in their own column instead of stacking under someone else's. A block belongs to whichever scroll it physically sits in, so a block the user drags to another scroll moves with it.
| Name | Type | Req | Description |
|---|---|---|---|
| pageId | string | – | Page to inspect. Defaults to the page currently open. |
No output schema declared.
No examples provided.
move_block ~226
Move a markdown block or diagram frame inside a scroll or across scrolls on the same page. Occupants below the source close up; occupants at the target open a gap. Diagram members ride the frame. ONE undo. Prefer after (a block or diagram-frame id) over index: ids survive reordering. scrollId is optional and defaults to the block's current scroll; when given it must be on the same page. Exactly one of after or index. Diagram members, shapes and images as the move target are refused by name. Returns the block plus displacedCount.
| Name | Type | Req | Description |
|---|---|---|---|
| after | string | – | Place after this block id in the destination scroll. Preferred. Do not pass index at the same time. |
| blockId | string | yes | Markdown block or diagram frame to move (from read_page / diagrams[].id). |
| index | integer | – | 0-based index in the destination scroll's remaining content blocks. Do not pass after at the same time. |
| scrollId | string | – | Destination scroll. Omit to stay in the current scroll. Must be on the same page. |
No output schema declared.
No examples provided.
move_page ~97
Move a page into a different section. Section ids come from list_pages. A section must keep at least one page, so moving the only page out of a section is refused — create another page there first.
| Name | Type | Req | Description |
|---|---|---|---|
| pageId | string | – | Page to move. Defaults to the page currently open. |
| toIndex | integer | – | Position within the destination section. Defaults to last. |
| toSectionId | string | yes | Destination section id. |
No output schema declared.
No examples provided.
move_scroll ~159
Move a scroll (named column band) left or right, or to an absolute column. Members, grouped ink and the band's own width travel with it; neighbouring scrolls shift to make room and cumulative offsets are recomputed. A diagram belongs to the band of its frame origin — the whole group moves, it is never split. Refuses with NOT_FOUND on an unknown id and PRECONDITION when the scroll is already at the named edge.
| Name | Type | Req | Description |
|---|---|---|---|
| direction | string | – | Step one band left or right. Refused at the corresponding edge. |
| scrollId | string | yes | Scroll to move (from list_scrolls). |
| toColumn | integer | – | Absolute 0-based column to move to. Refused when already there or past an edge. |
No output schema declared.
No examples provided.
read_diagram ~302
Read one diagram: id, title, format, source, bounds, memberCount, and a page of members [{id, type, x, y, w, h, label?}]. member_limit + member_cursor page members (cursor = last member id; same style as read_page). Default member_limit is derived from the 20000-character budget so a typical page sits well under it. If the serialized response still exceeds the budget, members trim at an entry boundary (truncated {at, notice}). Source counts toward the budget; if source alone blows it, source is cut (sourceTruncated {fullLength, notice}) and the notice names the full length and suggests exporting as .drawio. Discover ids from read_page diagrams[]. An unknown id is NOT_FOUND. A non-diagram id is UNSUPPORTED naming the type. A draw.io diagram rendered as an exact snapshot (renderMode 'snapshot', v0.64+) returns members: [] and memberCount 0 BY DESIGN — its structure lives entirely in the source XML, which is what you read and edit.
| Name | Type | Req | Description |
|---|---|---|---|
| diagramId | string | yes | Diagram frame id from read_page diagrams[].id or create_diagram. |
| member_cursor | string | – | Member id to start AFTER. Pass the last member id (or nextCursor) from the previous read_diagram. |
| member_limit | integer | – | Max members to return. Default is derived from the 20000-character budget. |
No output schema declared.
No examples provided.
read_image ~198
Export one image by node id so you can look at it. Discovers ids from read_page images[].id. The notebook returns the embedded bytes over the bridge; this server decodes them and writes a local file. Optional out_path (absolute) names the destination — parent dirs are created; an existing file is overwritten. When omitted, the file lands in os.tmpdir()/powerscroll-images/<id>.<ext>. The response is {path, format, bytes, naturalWidth, naturalHeight, alt} — NEVER the base64 payload. Unknown id is NOT_FOUND. A non-image id is UNSUPPORTED naming the type. Then open the file with your vision tools.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Image node id from read_page images[].id. |
| out_path | string | – | Absolute file path to write. Parent directory is created if missing. Omit to write os.tmpdir()/powerscroll-images/<id>.<ext>. |
No output schema declared.
No examples provided.
read_page ~491
Read a page. DEFAULT CHANGED in v0.54: blocks[] is free-standing markdown only — diagram labels (text nodes with a groupId) no longer leak in as fake content, and diagrams are collapsed to diagrams[] {id, title, format, memberCount, bounds} with NO members and NO source. Images are a compact images[] index {id, alt, x, y, w, h, naturalWidth, naturalHeight, bytes, mini, scrollId} — never the base64 payload. Discovery flow: read_page → diagrams[].id → read_diagram / delete_diagram / fit_diagram; read_page → images[].id → read_image (writes a local file you open with vision). include defaults to ["blocks","diagrams","images"]; pass ["images"] for an images-only fetch or ["diagrams"] for diagrams-only. Optional scrollId filters all three lists. limit + cursor page blocks in column-major reading order (cursor = last block id from the previous page; stable across appends). Serialized reads are hard-capped at 20000 characters and never fail for size: blocks drop first (truncated {at, notice}), then per-diagram source is replaced with sourceOmitted {length, notice: "use read_diagram"}, then diagrams[] trims at an entry boundary, then images[] trims (imagesTruncated {at, notice}). A single oversized block has its markdown cut (markdownTruncated {fullLength, notice}). include_diagram_source:true adds source on each diagrams[] entry. Use get_block(blockId) to re-fetch one block after a cap.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Block id to start AFTER. Pass the last blockId (or nextCursor) from the previous read_page. Stable across appends. |
| include | array | – | Which collections to return. Default ["blocks","diagrams","images"]. "images" alone is the images-only fetch; "diagrams" alone is diagrams-only. |
| include_diagram_source | boolean | – | If true, each diagrams[] entry includes its source text. Default false. |
| limit | integer | – | Max blocks to return (after filters). Combine with cursor to page. |
| pageId | string | – | Page to read. Defaults to the page currently open in the app. |
| scrollId | string | – | Restrict blocks, diagrams and images to this scroll band. |
No output schema declared.
No examples provided.
rename_notebook ~76
Rename the notebook itself (the title shown in the app and used for future Save As filenames). This does NOT rename the .html file already on disk — that keeps its current name until the user saves to a new location. The result reports the bound filename so you can tell them.
| Name | Type | Req | Description |
|---|---|---|---|
| filename | string | yes | New notebook name. |
No output schema declared.
No examples provided.
rename_page ~103
Retitle a page in the sidebar. If the page still opens with the "# Old title" heading block that create_page wrote, that block is retitled too so the two do not drift apart; a hand-edited heading is left alone.
| Name | Type | Req | Description |
|---|---|---|---|
| pageId | string | – | Page to rename. Defaults to the page currently open. |
| title | string | yes | New page title. |
| updateHeading | boolean | – | Also rewrite the matching canvas H1. Default true. |
No output schema declared.
No examples provided.
rename_scroll ~112
Rename a scroll. The new title appears immediately at the top of that column on the canvas. Naming a previously untitled scroll is how its header first appears. Pass an empty title to untitle it: the header disappears and the page ceiling disarms — a plain page is one untitled scroll, not zero scrolls.
| Name | Type | Req | Description |
|---|---|---|---|
| scrollId | string | yes | Scroll to rename (from list_scrolls). |
| title | string | yes | New title. Empty string untitleds the scroll (header gone, ceiling off). |
No output schema declared.
No examples provided.
resize_scroll ~107
Resize a scroll band by stable id. The width is clamped to PowerScroll's shared limits, persists on that page, and every node or stroke in bands to the right moves by the same delta. The resized band's own content stays fixed. One undo restores width and positions. list_scrolls reports the effective width.
| Name | Type | Req | Description |
|---|---|---|---|
| scrollId | string | yes | Scroll to resize (from list_scrolls). |
| width | number | yes | Requested band width in canvas pixels; clamped by the app. |
No output schema declared.
No examples provided.
run_update ~95
Install the latest PowerScroll release into the current notebook file. This rewrites the .html on disk and reloads the app, which drops this bridge connection until the notebook reconnects. Ask the user before calling it, then pass confirm:true. A safety backup is downloaded first where the browser allows it. Run check_update first.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true. Confirms the user agreed to the overwrite + reload. |
No output schema declared.
No examples provided.
save_notebook ~64
Write the notebook back to the file it was opened from. Only works when the notebook is already bound to a file: the Save As picker needs a click from the user, which an agent cannot supply. Call this after a batch of edits so the work is on disk.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
set_background ~234
Change the notebook's canvas look. "scroll" renders each column as one continuous vertical sheet with light page separators — best for long reading and for notes an agent is filling in. "pages" shows detached A4 cards, "grid" a dot grid, "none" a blank canvas. The setting is stored in the notebook itself, so it survives closing and reopening. Pass at least one of guideStyle or color. Scope defaults to "notebook" (every page that has not overridden it). Pass scope:"page" to change one page only — useful when a notebook wants a scrolling page of notes next to a grid page of diagrams.
| Name | Type | Req | Description |
|---|---|---|---|
| color | string | – | Canvas background colour. "paper" is a warm off-white. |
| guideStyle | string | – | Guide overlay to use. |
| pageId | string | – | Page to change when scope is "page". Defaults to the active page. |
| scope | string | – | Which layer to write. "notebook" (default) sets the default every page follows unless it overrides it, and leaves existing overrides alone. "page" overrides one page only. |
No output schema declared.
No examples provided.
update_block ~141
Replace the markdown of an existing block, found via read_page. Use this to revise content or tick a checkbox ("- [ ]" to "- [x]") rather than appending a duplicate block. If the block grows or shrinks, every occupant below it in the scroll (text, diagram frames, images, shapes, ungrouped ink) shifts by the height delta; frame members ride the frame. One undo. Returns displacedCount. A diagram-member id is refused (UNSUPPORTED) naming the owning diagram — redraw the source instead.
| Name | Type | Req | Description |
|---|---|---|---|
| blockId | string | yes | Block id from read_page. |
| markdown | string | yes | New markdown content. |
No output schema declared.
No examples provided.
What is the PowerScroll MCP server?
PowerScroll is an MCP server listed in the public MCP registry as io.github.CynaCons/powerscroll. Read and edit a live local-first PowerScroll visual notebook. This page covers its npm package (powerscroll-mcp).
Is the PowerScroll MCP server safe to use?
PowerScroll scores 82 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the PowerScroll MCP server expose?
PowerScroll exposes 37 tools: list_pages, read_page, read_diagram, read_image, get_block, and 32 more. Their descriptions and schemas cost roughly 7,972 tokens of context every time the server is loaded.
Is the PowerScroll MCP server still maintained?
PowerScroll is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the PowerScroll MCP server under?
PowerScroll declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.