PLMHub boards
Draw diagrams, build HTML pages and write Markdown in a live editor the user sees.
使うべきか
品質と安全性
検出事項(2)
- HIGH
- LOWopen_board 内
ツール定義とプロトコルへの準拠に関する自動分析に基づいています。
コンテキストコスト
これは、サーバーのツールがモデルのコンテキストに読み込まれるたびに消費されるおおよそのトークン数です。数が多いほど、ほかのタスクに使える注意が減ります。
インストール
ワンクリックインストール
これを `claude_desktop_config.json` ファイルに追加してください:
{
"mcpServers": {
"boards": {
"url": "https://plmhub.eu/mcp"
}
}
}リモートエンドポイント
https://plmhub.eu/mcpstreamable-httpできること
ツール一覧
ツール(5)
🟢open_board(kind)
Open a new, empty board and get its link. Give the link to the user: they watch your work there and download it.
入力スキーマ
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"doodle",
"html",
"markdown"
],
"description": "doodle, html or markdown"
}
},
"required": [
"kind"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢read_board(board)
Read a board: its kind and current content (the Markdown or HTML text, or the doodle's elements with their ids, roles, boxes and styles).
入力スキーマ
{
"type": "object",
"properties": {
"board": {
"type": "string",
"description": "The board's 22-character code, or its URL"
}
},
"required": [
"board"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}🟡write_board(board, content)
Replace everything on an HTML or Markdown board. HTML: one complete document with inline CSS and JS. Markdown: GitHub-flavored. For a doodle, use `draw` instead.
入力スキーマ
{
"type": "object",
"properties": {
"board": {
"type": "string",
"description": "The board's 22-character code, or its URL"
},
"content": {
"type": "string",
"description": "The new content"
}
},
"required": [
"board",
"content"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}🟡edit_text(board, ops)
Change part of an HTML or Markdown board without resending all of it. Ops (applied in order, all or nothing): - {"op": "write", "text": "..."} (replace everything) - {"op": "append", "text": "..."} - {"op": "replace", "find": "...", "replace": "..."} (find must occur exactly once)
入力スキーマ
{
"type": "object",
"properties": {
"board": {
"type": "string",
"description": "The board's 22-character code, or its URL"
},
"ops": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "write"
},
"text": {
"type": "string",
"maxLength": 256000
}
},
"required": [
"op",
"text"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "append"
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 256000
}
},
"required": [
"op",
"text"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "replace"
},
"find": {
"type": "string",
"minLength": 1,
"maxLength": 256000
},
"replace": {
"type": "string",
"maxLength": 256000
}
},
"required": [
"op",
"find",
"replace"
],
"additionalProperties": false
}
]
}
}
},
"required": [
"board",
"ops"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}🟡draw(board, ops)
Draw on a doodle board. The user sees each call appear live in the editor. ## Doodle ops A doodle is a board (default 1280 x 720 px, origin top-left, y grows down). Send ops as `{"ops": [...]}`; they apply in order, all or nothing. The answer lists the ids each op created, in order. Address elements by id; read the board for the ids it already has. **Positions:** x, y is the CENTER of a shape or text, the top-left of a comment, the midpoint of a line. Omit them to place at the board's center. Later elements draw on top. ### Create - `{"op": "add", "role": "text" | "box" | "button" | "input" | "card" | "ellipse" | "line" | "image" | "comment" | "draw" | "triangle" | "diamond" | "star" | "frame", "x", "y", "w"?, "h"?, "id"?, ...style}` Defaults (w x h): text 160 wide, box 180x110, card 240x150 (radius 12), button 150x46, input 220x44, ellipse 140x90, line 180 long, triangle 120x110, diamond/star 120x120, image 320x200 (needs "src": URL or data: URL), frame 360x240, draw needs "path". Pass your own "id" to address the element without reading back (it must be unused). Buttons and inputs are plain shapes: give them text with `label`. - `{"op": "draw", "path": "M 10 10 L 90 90", "stroke"?, "strokeWidth"?}` freehand; path coordinates are board coordinates. - `{"op": "comment", "text", "x"?, "y"?, "w"?}` a sticky note for the human. - `{"op": "label", "id": shapeId, "text", "fontSize"? = 16, "fill"?, "labelId"?}` text centered inside a shape that follows it when the shape moves. Empty text removes it. - `{"op": "duplicate", "id", "newId"?, "dx"? = 20, "dy"? = 20}` ### Change - `{"op": "update", "id", ...style}` (fields below; "x"/"y"/"w"/"h" set position and size) - `{"op": "move", "id", "dx", "dy"}` or `{"op": "move", "id", "x", "y"}`; moving a frame moves its children too. - `{"op": "reorder", "id", "to": "front" | "back" | "forward" | "backward"}` - `{"op": "delete", "id"}` · `{"op": "clear"}` removes everything. ### Style fields (add and update) fill, stroke, backgroundColor (CSS colors) · strokeWidth · opacity 0..1 · angle (degrees) · radius (corner radius; or rx, ry) · borderStyle "solid" | "dashed" | "dotted" | "dashdot" or strokeDashArray [numbers] · shadow "none" | "soft" | "medium" | "hard", {color, blur, offsetX, offsetY} or null · gradient {"type": "linear" | "radial", "stops": [{"offset": 0, "color": "#6366f1"}, {"offset": 1, "color": "#ec4899"}], "coords"?: 0..1 units} (replaces fill) · flipX, flipY, skewX, skewY · text, fontSize, fontFamily, fontWeight, fontStyle ("italic"), textAlign, underline, linethrough, lineHeight, charSpacing, padding · name (layer name), visible, locked (true/false). ### Structure - `{"op": "group", "ids": [2 or more], "name"?, "groupId"?}` returns the group id. `{"op": "ungroup", "group": groupId}` or `{"op": "ungroup", "ids": [...]}`. - `{"op": "wrap", "ids": [...], "direction"?, "justify"?, "align"?, "gap"?, "padding"?, "frameId"?}` puts the elements in a new auto-layout frame and returns its id. `{"op": "unwrap", "id": frameId}` removes the frame and keeps its children. - `{"op": "reparent", "ids": [...], "frame": frameId}` moves elements into a frame; `"frame": null` takes them out. - `{"op": "layout", "id": frameId, "mode"?: "block" | "flex", "direction"?: "row" | "col", "justify"?: "start" | "center" | "end" | "between", "align"?: "start" | "center" | "end" | "stretch", "gap"? = 16, "padding"? = 16, "wMode"?, "hMode"?: "hug" | "fixed", "w"?, "h"?}` A flex frame lines its children up (row = left to right, col = top to bottom) and hugs them, or keeps the fixed w/h. A block frame leaves children where they are. - `{"op": "size", "id", "w"?, "h"?: "fixed" | "hug" | "fill", "minW"?, "maxW"?, "minH"?, "maxH"?}` how a child of a flex frame sizes; fill shares the frame's spare room; null clears a min/max. ### Board - `{"op": "bg", "color": "#f8fafc"}` or `{"op": "bg", "src": imageUrl}` (an image behind everything). - `{"op": "board", "w"?, "h"?, "autoH"?: true, "padding"?, "minH"?, "maxH"?}` autoH grows the board to fit its content plus padding, within minH..maxH. Errors name the failing op (`ops[2] (move): ...`): 400 for a bad field, 404 for an unknown id, 409 for an id already in use. Fix that op and send the batch again.
入力スキーマ
{
"type": "object",
"properties": {
"board": {
"type": "string",
"description": "The board's 22-character code, or its URL"
},
"ops": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The ops, in order"
}
},
"required": [
"board",
"ops"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}コミュニティ
エビデンス