Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.Developyn/laver-mcp

NPM · @LAVER/MCP · SCANNED OCT 4

Kanban boards, sprints, tickets and a team wiki, with versioned writes for concurrent agents.

Available components

0 this week 78 Trust /100
Trust breakdown (7 categories)

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 93 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency45
Schema Quality & AI Usability65
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 17838 tokens (~302/item across 59 items; 59 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 Management83
  • Stability observed for 25 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 10 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_comment" 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 59 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
Install

How do I install the io.github.Developyn/laver-mcp server?

io.github.Developyn/laver-mcp runs locally as an npm package, launched with npx -y @laver/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 · @laver/mcp

# add to Claude Code
claude mcp add developyn-laver-mcp -- npx -y @laver/mcp
// .cursor/mcp.json
{
  "mcpServers": {
    "developyn-laver-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@laver/mcp"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "developyn-laver-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@laver/mcp"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add developyn-laver-mcp -- npx -y @laver/mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "developyn-laver-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@laver/mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add developyn-laver-mcp --command npx --arg -y --arg @laver/mcp
# ~/.hermes/config.yaml
mcp_servers:
  developyn-laver-mcp:
    command: "npx"
    args: ["-y", "@laver/mcp"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "developyn-laver-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@laver/mcp"
      ]
    }
  }
}
# add to Vellum
assistant mcp add developyn-laver-mcp -t stdio -c npx -a -y @laver/mcp
// mcp.json
{
  "mcpServers": {
    "developyn-laver-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@laver/mcp"
      ]
    }
  }
}
Changelog

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.

  • 3 Oct 26 −3
    • Stability: pass → 0.80 functional
  • 2 Oct 26 +1
    • Stability: 0.97 → pass security
  • 30 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

  • 28 Sept 26 +1
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 27 Sept 26 −3
    • Stability: pass → 0.83 functional
  • 26 Sept 26 +1
    • Stability: 0.97 → pass security
  • 25 Sept 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 24 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

Diagnostics

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 4 Oct 2026 · Analysed npm/@laver/mcp@0.5.0

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 93 packages
Packages resolved 93
Stale 31
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 59 exposed · ~17,838 tokens

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 →

Tool Tokens
update_automation ~655

Edit a live automation rule: rename it, switch it off, change what triggers it, or replace its conditions or actions. `enabled: false` is the one to reach for first when a rule is misbehaving — it stops the rule immediately and reversibly, where deleting it also destroys its run history, so pause before you delete and read list_automation_runs while you still can. `conditions` and `actions` REPLACE the stored lists rather than merging into them, so send the complete array you want, built from what get_automation returned and not from memory. Requires a workspace OWNER or ADMIN and the current `version`; a stale version is a 409 carrying the current one, so re-read with get_automation and reapply rather than retrying blind. Send `version` plus at least one real change — a version on its own is a 400. `trigger_type` and `trigger_config` are two halves of one meaning: changing either alone is checked against the stored other half and refused if the pair would not make sense. Two things cannot be changed at all and are not parameters here: a rule's `task_uuid` and its `run_limit`, so a column.empty rule pointed at the wrong ticket has to be deleted and made again. Switching a rule back on clears the `disabled_reason` that a circuit breaker left, but does not give a retired run_limit rule any more runs.

NameTypeReqDescription
actionsarray–The complete action list after the write, replacing the stored one. Never build it from a rule you read as a non-admin: a `call_webhook` url comes back as "[hidden]" there and would be written back l…
board_uuidstringyesThe board's uuid, from list_boards
conditionsarray–The complete condition list after the write — an empty array removes every condition and makes the rule fire on every occurrence of its trigger, which is usually not what someone narrowing a rule mea…
enabledboolean–Whether the rule runs. False is the reversible way to stop a rule; it keeps the definition and the run history.
namestring–Renames the rule.
rule_uuidstringyesThe rule's uuid, from list_automations
run_as_user_uuidstring–Who the rule acts as from now on. It is a standing grant of that person's permissions to anybody who can cause the trigger, and every future run is attributed to them, so repointing a rule is a bigge…
trigger_configobject–Replaces the trigger's configuration, in the same shape create_automation documents. Changing a schedule's interval or time recomputes when it next fires; enabling or disabling a rule deliberately do…
trigger_typestring–Changes what starts the rule. If the new trigger needs a trigger_config, send that too — the pair is validated together against whatever is stored.
versionintegeryesThe rule's version as get_automation last returned it. Required. A mismatch is a 409 whose body carries the current version.

No output schema declared.

No examples provided.

update_comment ~259

Rewrite one of YOUR OWN comments. Only the author may edit a comment: somebody else's is a 404, exactly the same 404 as a comment that does not exist, so this never tells you who wrote what. It REPLACES the whole body rather than appending — read the comment back with get_ticket_comments and send it plus your addition if you meant to add a line. The edit is visible: the comment is marked as edited with the time, so this is not a way to make a change quietly. Comments are not versioned, so there is no `version` here and no 409 — the last edit wins, and two edits racing is simply the later one. An empty body is a 400 rather than a deletion; delete_comment is how you retract one.

NameTypeReqDescription
bodystringyesThe comment's new text, Markdown, 1 to 10000 characters. It replaces everything the comment said.
comment_uuidstringyesThe comment's uuid, from get_ticket_comments — or from the reply comment_on_ticket gave you, which is the cheap way to hold on to one you just wrote.
task_uuidstringyesThe ticket's uuid, from list_tickets, get_board or search

No output schema declared.

No examples provided.

update_custom_field ~299

Rename a custom field, change a select's options, change a currency field's code, or move it up the list. The `type` is deliberately not editable and is not a parameter here. `options` REPLACES the whole list rather than adding to it, and removing an option does not clear it from tickets that already hold that value — those keep a value the dropdown no longer offers, so read the tickets before you shorten a list. Send at least one field; all omitted is a 400. Requires a workspace OWNER or ADMIN, like defining one.

NameTypeReqDescription
board_uuidstringyesThe board's uuid, from list_boards
currencystring–For a `currency` field, its ISO 4217 code. A field of any other type is a 404 saying so.
field_uuidstringyesThe field's uuid, from list_custom_fields or get_board
namestring–Replaces the field's name. Omit to leave it as it is.
optionsarray–For a `select`, the complete list of choices after the write — it replaces rather than adds. A field of another type takes it without complaining and then ignores it, so sending it there does nothing.
positionnumber–Sort key among the board's fields — smaller sorts first. Read the neighbours' `position` off list_custom_fields and send a number between them.

No output schema declared.

No examples provided.

update_label ~237

Rename or recolour a workspace label. It changes EVERYWHERE at once — every board, every ticket that carries it, for everybody in the workspace — because there is one label rather than a copy per board. That is the thing to be sure of before calling: a rename to something more specific may be wrong for whoever else is using it. The uuid does not change, so nothing holding one breaks. Renaming onto a name another label already has — ignoring case and surrounding space — is a 409. Send at least one of the two fields.

NameTypeReqDescription
colorstring–Replaces the colour. Six-digit hex, '#334455'.
label_uuidstringyesThe label's uuid, from list_labels or from a board's `labels` in get_board
namestring–Replaces the label's text. Omit to leave it as it is.
workspace_uuidstringyesThe workspace's uuid, from list_workspaces. A key only ever reaches the one workspace it was issued for, so this is that one; another workspace's uuid is a 404 rather than a permission error.

No output schema declared.

No examples provided.

update_status ~301

Rename a column, recolour it, or mark it as the one that means finished. `is_complete: true` is the interesting one: a board has at most ONE completed column, so setting it here silently clears the flag on whichever column held it, and the reply names what was unset. That flag is what `overdue` in list_workspace_tickets reads — a ticket sitting in a complete column is never overdue — so moving it changes what triage reports. Renaming is safe for tickets, which point at the uuid rather than the name, but it does break any saved text that named the old column. Send at least one of the three fields; all omitted is a 400 saying there is nothing to update.

NameTypeReqDescription
board_uuidstringyesThe board's uuid, from list_boards
color––The column's colour as a six-digit hex string, '#334455'. Explicit null clears it and the column falls back to the default for its position; omitting it leaves the colour alone. Those are different.
is_completeboolean–Whether tickets in this column count as finished. Only one column on a board may be the complete one, so true clears it elsewhere; false leaves the board with none.
namestring–Replaces the column's name. Omit to leave it as it is.
status_uuidstringyesThe column's uuid, from get_board's `statuses`

No output schema declared.

No examples provided.

update_subtask ~278

Tick a checklist item off, rename it, or move it up the list. `is_done: true` is the common one and is what makes the ticket's progress count move; `is_done: false` un-ticks an item that was ticked too early. Send at least one of the three — all three omitted is a 400. Renaming REPLACES the whole title rather than appending to it. An item on another ticket, or on a ticket you cannot open, is a 404 naming neither.

NameTypeReqDescription
is_doneboolean–true ticks it off, false un-ticks it. Omit to leave the tick alone rather than sending false, which is a change.
positionnumber–Sort key within the checklist, not an index — smaller sorts higher. Read the neighbours' `position` off the ticket's `subtasks` and send a number between them. Omit to leave the order alone.
subtask_uuidstringyesThe item's uuid, from the ticket's `subtasks` in get_ticket — or from the reply add_subtask gave you.
task_uuidstringyesThe ticket's uuid, from list_tickets, get_board or search
titlestring–Replaces the item's text. Omit to leave it as it is.

No output schema declared.

No examples provided.

update_ticket ~900

Change a ticket. `version` must be the one from get_ticket; a 409 means somebody wrote first and you should re-read. Markdown in `description` is parsed, and it replaces the whole description rather than appending to it. `label_uuids`, `assignee_uuids` and `custom_fields` each REPLACE the whole set rather than adding to it, so send what is already on the ticket alongside what you are adding or you will silently remove the rest. `custom_fields` is keyed by the field's uuid — read them off get_ticket, since a name will not do — and a uuid no field on that board has is DROPPED SILENTLY rather than refused: the call answers 200 and the value is simply not there. The task in the reply carries the stored `custom_fields`, so read them back to confirm a write landed rather than assuming a 200 means it did.

NameTypeReqDescription
assignee_uuidsarray–The ticket's assignees, as the complete set after the write — it REPLACES rather than adds, so include whoever is already assigned. The uuids come from the board's `members`. An empty array unassigns…
custom_fieldsobject–Custom field values, keyed by the FIELD's uuid — read them off get_ticket, a field's name will not work. REPLACES the whole set, so send the values already on the ticket alongside the ones you are ch…
descriptionstring–Replaces the whole body, Markdown, up to 20000 characters — it does not append. To add a line, read the current description with get_ticket and send it back with your addition included.
due_date––Due date as an ISO 8601 date, e.g. 2026-08-14. Explicit null clears it; omitting it leaves it unchanged. Those are different, so do not send null to mean 'no change'.
label_uuidsarray–The ticket's labels, as the complete set after the write — it REPLACES rather than adds, so include the ones already on the ticket or you remove them. Bare uuids, which is the shape get_board returns…
parent_task_uuid––File this ticket under another one as a sub-ticket, by uuid. The sub-ticket is a whole ticket with its own column, assignees and comments — for a checklist line use add_subtask instead. Must be in th…
positionnumber–Sort key within the column, not an index — smaller sorts higher. Read the neighbours' `position` off get_board and send a number between them; omit it to append to the bottom. Positions come back as…
prioritystring–One of low, medium, high or urgent. Omit to leave it alone; there is no value here that clears a priority already set.
statusstring–Move it to this column, by name as shown on the board. Send this or `status_uuid`, not both. move_ticket is the tool for a move alone.
status_uuidstring–Move it to this column, by uuid, from get_board. The exact form of `status`, unaffected by a column being renamed.
task_uuidstringyesThe ticket's uuid, from list_tickets, get_board or search
titlestring–Replaces the title. Omit to leave it as it is.
versionintegeryesThe `version` from the ticket as you last read it. Not a number you choose or increment: send back exactly what get_ticket gave you. If somebody else has written since, the call answers 409 rather th…

No output schema declared.

No examples provided.

update_wiki_page ~620

REPLACE what is on a wiki page: its body, its title, or both. This is the tool for correcting a page that has gone stale — append_wiki_page can only add, so using it to fix something leaves the wrong version sitting above the right one, and a page maintained that way grows into drafts a reader cannot tell apart. Prefer append_wiki_page when you are ADDING a section; use this when something already written has to stop being there. `content_markdown` replaces the WHOLE body, not part of it: whatever you do not send is gone, so read the page with get_wiki_page first, edit the `content_markdown` it hands you and send that back — it is already in this format, so keeping the rest of the page is a matter of not deleting it. Check that read's `markdown_omits` before you replace: anything listed there is on the page and cannot survive being written back as markdown, so append or leave it to a person rather than dropping it. `version` is required and must be the one get_wiki_page just gave you; if somebody wrote in between, this is a 409 carrying the current version rather than an overwrite — re-read the page and decide against what it now says, because retrying with the fresh version alone would discard their change. Nothing is destroyed: every save keeps the previous text as a version, so get_wiki_page_version can read back what this replaced. Anyone with the page open in the live editor sees the replacement arrive. Send at least one of `title` and `content_markdown` — `version` alone is a 400, not a no-op. Markdown that parses to nothing is a 400 rather than a way to blank a page by accident. The reply is the page's identity and its new version, deliberately NOT the body you just sent. Needs write access to the workspace: a read-only role or a guest key is a 403 and retrying cannot fix it.

NameTypeReqDescription
content_markdownstring–The page's ENTIRE new body as markdown, converted server-side by the same parser create_wiki_page and append_wiki_page use. Omit to change only the title. Longer than 100k characters is refused rathe…
page_uuidstringyesThe wiki page's uuid, from get_wiki_tree or search_wiki. A page you cannot open is a 404, the same 404 as one that never existed.
titlestring–A new title, 1 to 500 characters. Omit to leave the page's title alone; this is a replace, not a rename of the body.
versionintegeryesThe `version` from the page as get_wiki_page last returned it. Not a number you choose or increment: send back exactly what you read. A stale one is a 409 that carries the current version with it, so…

No output schema declared.

No examples provided.

upload_ticket_attachment ~397

Attach a file to a ticket — the way an agent puts evidence on a ticket rather than describing it. Two ways to give it the bytes, and exactly one must be used. `file_path` reads a file from the machine THIS SERVER runs on (normally the agent's own machine, since the client starts this as a subprocess) and is the right one for anything that already exists on disk; it costs no context, so prefer it. `text` is for content the agent has just written — a log, a CSV, a diff — and needs `filename` alongside it. Laver refuses anything that is not one of application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.wordprocessingml.document, image/gif, image/jpeg, image/png, image/webp, text/csv, text/plain, video/webm, and refuses a file whose BYTES do not match the type its name claims, so renaming a zip to .png fails at the server rather than here. 25 MB is the ceiling. A workspace over its storage quota is a 402, which no retry fixes. Uploading is a write: a read-only role is a 403.

NameTypeReqDescription
content_typestring–Overrides the type guessed from the filename's extension
file_pathstring–Path to an existing file on the machine running this server. Mutually exclusive with `text`
filenamestring–The name to store it under. Required with `text`; defaults to the basename of `file_path`. Its extension decides the content type
task_uuidstringyesThe ticket's uuid, from list_tickets, get_board or search
textstring–Literal file content, for something the agent wrote rather than something on disk. Requires `filename`

No output schema declared.

No examples provided.

Common questions

What is the io.github.Developyn/laver-mcp server?

io.github.Developyn/laver-mcp is listed in the public MCP registry as io.github.Developyn/laver-mcp. Kanban boards, sprints, tickets and a team wiki, with versioned writes for concurrent agents. This page covers its npm package (@laver/mcp).

Is the io.github.Developyn/laver-mcp server safe to use?

io.github.Developyn/laver-mcp scores 78 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 4 October 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 io.github.Developyn/laver-mcp server expose?

io.github.Developyn/laver-mcp exposes 59 tools: list_workspaces, list_boards, get_board, list_tickets, search, and 54 more. Their descriptions and schemas cost roughly 17,838 tokens of context every time the server is loaded.

Is the io.github.Developyn/laver-mcp server still maintained?

io.github.Developyn/laver-mcp is still listed as active in the MCP registry. We last reached this channel on 4 October 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 io.github.Developyn/laver-mcp server under?

io.github.Developyn/laver-mcp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.