AgentStack
SKILL verified MIT Self-run

Docs Collaborator

skill-mondaycom-skills-docs-collaborator · by mondaycom

|

No reviews yet
0 installs
7 views
0.0% view→install

Install

$ agentstack add skill-mondaycom-skills-docs-collaborator

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Docs Collaborator? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Docs Collaborator

Create, read, edit, and comment on monday.com docs. The skill is a capability surface, not a template engine. Every doc is a stream of typed blocks (headings, paragraphs, lists, tables, code, dividers, notice boxes, layouts, embedded boards / widgets / docs / images / videos / GIFs). The named shapes listed below are starting points - compose and extend freely. The differentiators (live column-value embeds, inline mentions, notice boxes, layouts) apply to any shape, named or invented.

The platform-native value over a raw markdown editor lives in three things most builders miss: inline mentions of users / docs / boards, live column-value embeds that reflect the current state of a board item, and a closed-loop edit pattern that prevents corrupting the doc's block graph.

Core constraint - read this first

Never edit a block you have not read. monday's update_doc API is block-ID-based, and block IDs are only knowable through read_docs with include_blocks: true. Skipping the read leads to operations referencing IDs that do not exist (silent failure) or - worse - reusing an ID from another doc. The closed-loop pattern is non-negotiable:

  1. read_docs with include_blocks: true to get block IDs, types, and positions.
  2. Identify the target block(s) by type and position or by content.
  3. update_doc with the operation that matches the target block's type (see the routing rule below).

Block operation routing - the non-obvious part

Each block type has a different set of allowed mutations. Picking the wrong operation is the #1 cause of "the call succeeded but the doc looks wrong" bugs.

| Target block type | Use this operation | Why | |---|---|---| | text (any subtype: NORMALTEXT, LARGETITLE, MEDIUMTITLE, SMALLTITLE, QUOTE) | update_block for content edits; replace_block to change the subtype (e.g. promote a paragraph to H2) | Subtype is set on creation; update_block cannot change it | | code | update_block | Content and language editable in place | | listitem (BULLETEDLIST, NUMBEREDLIST, CHECKLIST) | update_block for content edits; replace_block to switch between bulleted / numbered / check | List variant is set on creation | | divider | replace_block only | No mutable properties | | table | replace_block only | Row / column count and column widths immutable; table cell content not addressable via API after creation - see "Tables" below | | image | replace_block to swap source | URL / assetid immutable after creation | | video | replace_block to swap source | rawurl immutable after creation | | notice_box | replace_block to change theme | theme immutable; content lives in child blocks (see "Notice boxes" below) | | layout | replace_block only | Cell content cannot be populated via API at all - see "Layouts" below | | BOARD embed, WIDGET embed, DOC embed, GIPHY | delete_block only | No public API to create or modify these block types |

Rendering quirk - listitem + mention via update_block. When adding an inline mention to a listitem that previously contained only text, update_block may save the mention blot correctly (data confirms) but Cowork can fail to render the pill (text-prefix-before-mention case). Workaround: use replace_block with a fresh listitem containing the same delta. Same pattern in a normal_text block renders correctly; the quirk appears specific to listitem updates.

Full per-block-type detail with worked examples lives in references/block-operations-matrix.md. Read it before authoring any non-trivial structural edit.

Workflow: Create a doc

Step 1: Decide the location

monday docs live in one of two places:

  • Workspace (most common). Requires workspace_id. Optional doc_kind: public (default), private (only the creator), share (specific people). Optional folder_id to nest under a folder.
  • Item-attached. The doc lives in a doc-type column on a specific board item. Requires item_id. Optional column_id if the user picked a specific doc column; otherwise the tool auto-creates one.

Cell-limit preflight for item-attached docs. Doc-type cells hold one doc per cell - hard API limit. Before calling create_doc location=item, preflight the target column via get_board_items_page with columnIds: [] to check whether the cell is already populated. If populated, do NOT attempt the create - it will fail with CellLimitExceededException. Fall back to creating a workspace-level doc and adding a bi-directional DOC mention cross-link between the new doc and the existing attached doc. Never auto-detach the existing doc.

If the user does not name a workspace, fall back to the user's primary workspace via get_user_context. Ask once if it's still ambiguous; do not guess across multiple workspaces.

Step 2: Plan-tier guard before creating a 4th doc

Free and Basic plans cap at 3 docs per account. Before calling create_doc on a Free / Basic account, check whether this would be the 4th doc. There is no direct doc-count tool, so the practical guard is: if the user has hit this limit before or asks "can I create more than 3 docs?", warn them - upgrade to Standard+ removes the cap. Treat plan-tier as an open question rather than blocking the create call; the platform itself will reject if the cap is hit.

Step 3: Compose the body - shapes are examples, not boundaries

create_doc takes a markdown parameter that is parsed into blocks on import. This is the most efficient way to scaffold a doc in one call. Reach for one of these common shapes as a starting point when the user names a use case, then extend freely:

  • Meeting notes: title, date, attendees (with @mentions), agenda bullets, decisions, action items table, follow-ups.
  • Weekly update: highlights, key metrics, risks, next-week plan.
  • RFC: problem, proposed solution, alternatives considered, open questions, decision log.
  • Runbook: trigger, prerequisites, numbered procedure, rollback steps, escalation path.
  • Postmortem: incident summary, timeline, root cause, what went well, what did not, action items.

When the user invents a shape ("partner enablement page", "AI readiness snapshot", "Q3 onboarding context"), compose with judgment - sections, tables, notice boxes, embeds - rather than forcing a named template. The differentiators apply to any shape.

Default mode: passive scaffold. Reserve visible slots for embeds and mentions in the markdown body using machine-readable markers. Skill (and downstream agents) can later detect and fill these slots when the user names the underlying items / users.

| Slot type | Marker format | Example | |---|---|---| | Live column-value embed | _[embed: of ]_ | _[embed: status of ]_ | | User mention | _[mention: ]_ | _[mention: ]_ | | Doc / board mention | _[mention-doc: ]_ / _[mention-board: ]_ | _[mention-board: Project Tracker]_ |

Italic styling on slot markers gives visual signal that the content is dynamic. The bracket-keyword format is grep-able for downstream automation.

Active mode: escalate when intent signals are present. Switch from passive scaffold to wiring real embeds / mentions / cross-links when the user's prompt signals intent through name-based references. Never on item IDs - users speak in names.

Triggers that escalate to active mode:

  • Item names ("the Q3 plan", "the launch milestone", "the blocker we discussed")
  • Board names ("from the project tracker", "in the bug board")
  • Owner names ("Daniel's tasks", "my items", "the design team's")
  • Positional refs ("the top 3 priorities", "the most recent stuck items")
  • Imperative wiring ("embed live status from", "show current status of", "pull from ", "wire up the embeds", "tag me as owner")

Resolution chain (name -> ID, never ask the user for IDs):

  • Item name -> get_board_items_page with searchTerm scoped to the named board
  • Board name -> search with searchType: BOARD
  • Owner name -> list_users_and_teams with name: (scoped per cross-skill rule)
  • Ambiguous match -> ask once with the top 3 candidates; do not silently pick

Active mode communication contract. When the skill picks items / users in active mode, always state the choice and the reasoning: "Picked items X, Y, Z because . Override by naming different items."

Markdown notes that matter:

  • Markdown headings (#, ##, ###) map to LARGETITLE / MEDIUMTITLE / SMALL_TITLE blocks.
  • Markdown tables work and the cells will be populated with the values you put in. This is the only way to get pre-filled table content. Cell-level API population after creation is not supported.
  • Markdown images and links work. For asset-based images (uploaded files in monday), use update_doc with create_block and block_type: "image" plus asset_id after creation - markdown cannot reference assets.
  • Markdown does not have notice_box, layout, embed, divider-with-spacing, mention, or live column-value syntax. Add those via update_doc after the doc is created.

Step 4: Call create_doc

create_doc({
  doc_name: "",
  location: "workspace",
  workspace_id: ,
  doc_kind: "public" | "private" | "share",  // optional
  folder_id: ,                            // optional
  markdown: ""
})

For item-attached (after preflight):

create_doc({
  doc_name: "",
  location: "item",
  item_id: ,
  column_id: "",  // optional
  markdown: ""
})

Capture the returned doc_id, object_id, and doc_url. The user wants the URL to share or open; the doc_id is the primary key for every subsequent edit.

Step 5: Layer in the rich-content extras

Mentions, live column-value embeds, notice boxes, layouts, and asset images all need a follow-up update_doc call. In active mode, wire them now using the resolved IDs from Step 3. In passive mode, leave the slot markers in place - the user fills slots later by naming items. See "Common edit patterns" below.

Step 6: Confirm and suggest next steps

Plain-language confirmation: name, workspace, doc URL. State the mode used (passive scaffold or active). Then 2-3 follow-ups appropriate to the shape:

  • "Want me to tag the attendees with @mentions?"
  • "Want me to embed live status from the project board?"
  • "Should I add a notice box at the top with the meeting outcome?"
  • "Want me to share the doc URL in a Slack channel?"

Workflow: Read a doc

Step 1: Resolve the doc identifier

Three ways the user might point at a doc:

  • doc_id (e.g., 41302579) - the API's primary key, returned by create_doc and read_docs.
  • object_id (e.g., 18411484379) - the numeric segment of the doc URL: https://monday.monday.com/docs/{object_id}.
  • doc name or fuzzy reference ("the Q3 retro doc") - resolve via read_docs with type: "workspace_ids" to list docs in a workspace, then match by name.

read_docs is forgiving: if you call it with type: "ids" and the value is actually an object_id, it auto-retries as object_ids. Lean on this rather than guessing.

Step 2: Decide what to read

Two modes:

  • content (default) - returns the doc's blocks and / or markdown projection.
  • include_blocks: true is mandatory if any edit will follow. Do not omit it.
  • include_comments: true to fetch all comments and replies. Use comments_limit to cap (default 50).
  • version_history - returns the doc's edit history (restoring points). Pass the object_id, not the id. Set version_history_limit for "last N changes" requests; set include_diff: true to see what changed (slower).

Step 3: Render with resolved mentions and embeds, not placeholders

The API's blocks_as_markdown projection renders mentions as @{USER-XXX} placeholders and live column-value embeds as empty space. This is not the right rendering for a "show me what's in this doc" prompt - the user sees pills and live chips when they open the doc; the textual rendering should mirror that.

For read responses to "show me / what's in / read this doc" prompts:

  • Always resolve mentions. Map every USER mention id to a display name (via cached list_users_and_teams or a scoped lookup). Map every DOC mention to its doc name. Map every BOARD mention to its board name. Render inline as **@Alex Polonsky** (or similar) rather than @{USER-38288909}.
  • Resolve embeds when data is cached or cheap to fetch. If the doc references items / columns already touched in the conversation, use the cached value. If not, fetch with get_board_items_page scoped to the specific items + columns. Render as the resolved column value ("Working on it", "No value", "2026-05-15") inline. Skip resolution only if it would require many extra MCP calls for a long doc.
  • Always keep the structured enumeration table as a secondary affordance. List every inline non-text element (mentions, embeds, notice_boxes, code blocks, tables) with block IDs and IDs. Useful for downstream edit operations and for users who want to target a specific element.

Do not use show-table for doc content - the doc itself is the UI. Render in chat with markdown.

Workflow: Edit a doc

Step 1: Read first

read_docs with include_blocks: true. This is the closed-loop precondition. Capture every block's id, type, and position.

Step 2: Pick the right operation

Reach for the simplest one that does the job:

  • Add new content at the end: add_markdown_content (no block IDs needed; supports text, lists, tables, code).
  • Add asset-based images: create_block with block_type: "image" and asset_id (markdown does not support asset images).
  • Edit existing text / code / list_item content in place: update_block with the matching block_content_type (text, code, or list_item).
  • Change a block's subtype (paragraph -> H2, bulleted -> numbered, INFO notice -> WARNING notice): replace_block. Subtypes are set on creation only.
  • Insert a block at a precise position: create_block with after_block_id set. There is no before_block_id operation - to insert at the very top of a doc, the only path is to insert after the doc's first block.
  • Delete: delete_block. The only path for BOARD / WIDGET / DOC embed / GIPHY blocks.
  • Comment: add_comment (see "Comments" below).
  • Rename the doc: set_name.

The full type-to-operation routing lives in references/block-operations-matrix.md.

Step 3: Compose the deltaformat (for text / code / listitem)

update_block and create_block for content blocks take a delta_format array of insert ops. Three rules govern every delta:

  1. The last op MUST be {insert: {text: "\n"}}. Always. No exceptions.
  2. Plain text uses {insert: {text: "..."}} with optional attributes (bold, italic, underline, strike, code, link, color, background).
  3. Two non-text inserts unlock the differentiators:
  • Mention: {insert: {mention: {id: , type: "USER" | "DOC" | "BOARD"}}}. Resolve user IDs via list_users_and_teams (always pass name to scope the call).
  • Live column-value embed: {insert: {column_value: {item_id: , column_id: ""}}}. Renders the current value of that column on that item, live, every time the doc is opened.

Worked examples and the full attribute table live in references/delta-format-cheatsheet.md.

Step 4: Batch operations carefully

update_doc accepts up to 25 operations in one call, executed in order, stopping at the first failure. Four gotchas:

  • Notice box nesting requires two calls. A noticebox created in the same call cannot be referenced by parent_block_id in a later operation in the same call. Create the noticebox, capture the returned ID, then make a second update_doc call to nest children.
  • Position dependencies. If operation B references the position of a block created by operation A, prefer two calls. Failures partway through the array leave the doc in a partial state.
  • Same-block conflict detection. When

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.