Laver REST APIを介して、AIエージェントがカンバンボード、チケット、スプリント、およびワークスペースのWikiを管理できるようにします。
別名 Developyn/laver-mcp, @laver/mcp
- スター
- 0
- ツール
- 49
- ダウンロード数(30日間)
- —
- 最新バージョン
- 0.5.0
- 最終コミット
- 2026年8月27日
- ライセンス
- MIT
Laver MCPとは
LaverはMCPサーバーです。 Laver REST APIを介して、AIエージェントがカンバンボード、チケット、スプリント、およびワークスペースのWikiを管理できるようにします。. 49個のツールを提供しており、list_workspaces, list_boards, get_boardなどがあります。
プロジェクトのREADMEから生成された概要
Laver MCP server について
このサーバーを使用すると、開発者はAIエージェントを通じて、カンバンボード、チケット、およびワークスペースのWikiを管理できます。Laver REST APIに直接接続し、ローカルの状態や個別のキャッシュを保持することなく、プロジェクト管理のワークフローを読み取り、推進するためのツールを提供します。すべてのツールは公開APIへの軽量な呼び出しであるため、エージェントはAPIからのエラーレスポンスをそのまま受け取ることができ、バージョンの競合などの特定の問題に対して適切に対処できます。
サーバーをセットアップするには、環境変数LAVER_API_KEYまたはファイルパスを介して、ワークスペーススコープのAPIキーを指定する必要があります。また、LAVER_API_URL設定を使用して、カスタムホストを使用するように構成することも可能です。ユーザーは、検索ツールによるワークスペース全体の検索から、複雑なボード構造の管理まで、幅広い操作を行うことができます。チケットフローの読み取り、サブタスクの管理、Wikiツリーの整理に特化したツールが含まれており、AIクライアントから直接、トリアージ、スタンドアップ、ドキュメント更新を自動化したいチームに適しています。
できること
- 1チケット更新の同期開発者は、最近更新されたチケットのみをリクエストするようにエージェントに指示することで、ボードの変更を追跡させることができます。
プロジェクトの README から作成されています。すべてのユースケースは、その引用と照らし合わせて確認されています。
Laver MCPのインストール方法
フォーマット検証日 2026年11月10日Cursor に追加Gooseに追加Claude CodeにLaver MCPをインストール
$ claude mcp add --env 'LAVER_API_KEY=<YOUR_LAVER_API_KEY>' laver-mcp -- npx -y @laver/mcpCursorにLaver MCPをインストール
~/.cursor/mcp.json
{
"mcpServers": {
"laver-mcp": {
"command": "npx",
"args": [
"-y",
"@laver/mcp"
],
"env": {
"LAVER_API_KEY": "<YOUR_LAVER_API_KEY>"
}
}
}
}VS CodeにLaver MCPをインストール
.vscode/mcp.json
{
"servers": {
"laver-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@laver/mcp"
],
"env": {
"LAVER_API_KEY": "<YOUR_LAVER_API_KEY>"
}
}
}
}VS Code CLIにLaver MCPをインストール
$ code --add-mcp '{"name":"laver-mcp","type":"stdio","command":"npx","args":["-y","@laver/mcp"],"env":{"LAVER_API_KEY":"<YOUR_LAVER_API_KEY>"}}'Claude DesktopにLaver MCPをインストール
claude_desktop_config.json
{
"mcpServers": {
"laver-mcp": {
"command": "npx",
"args": [
"-y",
"@laver/mcp"
],
"env": {
"LAVER_API_KEY": "<YOUR_LAVER_API_KEY>"
}
}
}
}CodexにLaver MCPをインストール
$ codex mcp add laver-mcp --env 'LAVER_API_KEY=<YOUR_LAVER_API_KEY>' -- npx -y @laver/mcpCodex config.tomlにLaver MCPをインストール
~/.codex/config.toml
[mcp_servers.laver-mcp] command = "npx" args = ["-y", "@laver/mcp"] [mcp_servers.laver-mcp.env] LAVER_API_KEY = "<YOUR_LAVER_API_KEY>"
Gemini CLIにLaver MCPをインストール
$ gemini mcp add -s user -e 'LAVER_API_KEY=<YOUR_LAVER_API_KEY>' laver-mcp npx -- -y @laver/mcpGemini settings.jsonにLaver MCPをインストール
~/.gemini/settings.json
{
"mcpServers": {
"laver-mcp": {
"command": "npx",
"args": [
"-y",
"@laver/mcp"
],
"env": {
"LAVER_API_KEY": "<YOUR_LAVER_API_KEY>"
}
}
}
}Laver MCPツール 49
READMEから検出list_workspaceslist_boardsget_boardlist_ticketslist_workspace_ticketsget_ticketget_ticket_commentsget_ticket_flowlist_custom_fieldslist_labelssearchcreate_ticket
| list_workspaces | — | |
| list_boards | — | |
| get_board | — | |
| list_tickets | — | |
| list_workspace_tickets | — | |
| get_ticket | — | |
| get_ticket_comments | — | |
| get_ticket_flow | — | |
| list_custom_fields | — | |
| list_labels | — | |
| search | — | |
| create_ticket | — |
49個のツールをすべて表示ツールを折りたたむ
update_ticketmove_ticketcomment_on_ticketupdate_commentdelete_commentmark_comments_readadd_subtaskupdate_subtaskdelete_subtaskarchive_ticketdelete_ticketcreate_boardlink_ticketsunlink_ticketscreate_statusupdate_statusreorder_statusesdelete_statuscreate_groupreorder_groupsdelete_groupcreate_custom_fieldupdate_custom_fielddelete_custom_fieldcreate_labelupdate_labeldelete_labellist_ticket_attachmentsget_ticket_attachmentupload_ticket_attachmentdelete_ticket_attachmentlist_automationsget_automationlist_automation_runscreate_automationupdate_automationdelete_automation
| update_ticket | — | |
| move_ticket | — | |
| comment_on_ticket | — | |
| update_comment | — | |
| delete_comment | — | |
| mark_comments_read | — | |
| add_subtask | — | |
| update_subtask | — | |
| delete_subtask | — | |
| archive_ticket | — | |
| delete_ticket | — | |
| create_board | — | |
| link_tickets | — | |
| unlink_tickets | — | |
| create_status | — | |
| update_status | — | |
| reorder_statuses | — | |
| delete_status | — | |
| create_group | — | |
| reorder_groups | — | |
| delete_group | — | |
| create_custom_field | — | |
| update_custom_field | — | |
| delete_custom_field | — | |
| create_label | — | |
| update_label | — | |
| delete_label | — | |
| list_ticket_attachments | — | |
| get_ticket_attachment | — | |
| upload_ticket_attachment | — | |
| delete_ticket_attachment | — | |
| list_automations | — | |
| get_automation | — | |
| list_automation_runs | — | |
| create_automation | — | |
| update_automation | — | |
| delete_automation | — |
設定
LAVER_API_KEY必須シークレットA workspace-scoped API key, created in Laver under Admin → API keys. It acts as the person who created it, so it holds exactly their access and can be revoked without touching their account. Supply this or LAVER_API_KEY_FILE.
LAVER_API_KEY_FILEAlternative to LAVER_API_KEY: a path to a file holding nothing but the key, or a .env-style file carrying a LAVER_API_KEY= line. Use this to keep the key out of your client's config file.
LAVER_API_URLOverrides the API host. Defaults to https://api.laver.app, and must be https except for localhost.
| 名前 | 説明 | 種類 |
|---|---|---|
| LAVER_API_KEY | A workspace-scoped API key, created in Laver under Admin → API keys. It acts as the person who created it, so it holds exactly their access and can be revoked without touching their account. Supply this or LAVER_API_KEY_FILE. | 必須シークレット |
| LAVER_API_KEY_FILE | Alternative to LAVER_API_KEY: a path to a file holding nothing but the key, or a .env-style file carrying a LAVER_API_KEY= line. Use this to keep the key out of your client's config file. | |
| LAVER_API_URL | Overrides the API host. Defaults to https://api.laver.app, and must be https except for localhost. |
自動チェック
実行日 2026年11月14日完全なレポート →自動チェックに合格しました。これはセキュリティ監査ではありません。コードを読み、サーバーに必要最小限のアクセス権を与えてください。 チェックの仕組み
- ソースリポジトリがリンクされており、アクセス可能developyn/laver-mcp is public and reachablegithub.com/developyn/laver-mcp ↗合格
- パッケージがこのリポジトリをソースとして指定@laver/mcp names developyn/laver-mcp as sourcenpmjs.com/package/@laver/mcp ↗合格
- ビルドの来歴 (Sigstore 証明)No build attestation published for this release未チェック
- オープンソースライセンス (OSI)MITspdx.org/licenses/MIT.html ↗合格
- 過去1年以内にコミットまたはリリースありLast commit or release 2026-08-27github.com/developyn/laver-mcp ↗合格
- OpenSSF Scorecard未チェック
- パッケージ名が有名なパッケージに酷似していないNo popular package one edit away from @laver/mcp合格
- パッケージおよびその依存関係に重大な勧告なし99 resolved dependencies checked; no critical advisoryosv.dev ↗合格
- モデルへの隠れた指示がない49 tool descriptions and the README read; no override phrases, credential paths or hidden characters合格
- 破壊的なツールがラベル付けされている未チェック
- リモートエンドポイントが MCP ハンドシェイクに応答未チェック
README
GitHubで見る@laver/mcp
An MCP server for Laver. Gives an agent tools to read and drive kanban boards, tickets and the workspace wiki.
Every tool is a thin call to the same public REST API the web app uses. There is no local state, no cache, and no second implementation of anything — if Laver refuses a write, the refusal comes back verbatim, because an agent can act on "409, re-read and retry" and cannot act on "something went wrong".
Setup
Create a workspace-scoped API key in Laver under Admin → API keys. It acts as the person who created it, so it can do exactly what they can do and nothing more, and it can be revoked without touching their account.
{
"mcpServers": {
"laver": {
"command": "npx",
"args": ["-y", "@laver/mcp"],
"env": { "LAVER_API_KEY": "your key here" }
}
}
}
LAVER_API_URL overrides the API host; it defaults to https://api.laver.app.
LAVER_API_KEY_FILE is an alternative to LAVER_API_KEY: a path to either a
file containing nothing but the key, or a .env-style file with a
LAVER_API_KEY=… line among others (an assignment line wins; quotes and an
export prefix are both fine). That is how the .mcp.json in this repo
registers the server without a secret in a tracked file.
A file with neither — no assignment line, and more than one token in it — yields no key at all, and you get the "key is not set" error. It used to send the whole file as the token, which is fine for a file holding one secret and is a leak for anything else.
LAVER_API_URL must be https, except for localhost.
Working in this repo
.mcp.json at the repo root registers this server for anyone who opens the
project, reading the key from the gitignored .env. Nothing to export.
It runs the published package, npx -y @laver/mcp, rather than the
mcp/server.js beside it. That is deliberate: pointing it at the local file
meant everyone here ran the one code path no user takes, and that is precisely
how 0.1.0 shipped with an entry point that never connected its transport when
started through bin — which is the only way a real client starts it. Running
what we publish means we meet what users meet.
If you are editing this server, that same choice will fool you: your changes do nothing until they are published. Point the client at the working copy while you work on it —
{ "command": "node", "args": ["mcp/server.js"] }
— and put it back before you commit. npm run check and
frontend/tests/check-mcp-bin-entrypoint.mjs both run against the working copy
regardless, so the tests never depend on a publish.
A client only connects to MCP servers at startup. claude mcp add while a
session is already running does not retrofit the tools into that session — the
tool list was built before the server existed. Start a new session (or
reconnect from the client's MCP panel) and the tools appear.
Tools
Reading
| Tool | What it gives you |
|---|---|
list_workspaces |
Where to start when you have no uuids |
list_boards |
The boards in a workspace |
get_board |
A board with its status columns, labels, members and tickets |
list_tickets |
Tickets on a board, filterable, paged — updated_since is how you follow a board |
list_workspace_tickets |
Triage across every board at once — overdue, unassigned, or free text |
get_ticket |
One ticket in full, its subtasks, including its version |
get_ticket_comments |
Comments and activity history |
get_ticket_flow |
How long the ticket has spent in each column |
list_custom_fields |
A board's custom field definitions — the uuids update_ticket writes against |
list_labels |
Every label in the workspace, not only the ones already used on one board |
search |
Boards, tickets, wiki pages and comments across a whole workspace at once |
list_workspace_tickets is the stand-up read: it needs no board_uuid, and it
is the only thing here that answers "what is late" and "what does nobody own"
without walking every board. It is deliberately the small sibling of
list_tickets — one page, 50 by default and 200 at most, no cursor — so narrow
it rather than paging it.
get_ticket_flow derives its numbers from the moves already in a ticket's
history. Read visits rather than the by_status totals if you are adding
several tickets up: tickets worked in one batch overlap, and their totals do not.
gaps says when the history and the ticket's current column disagree, which
makes the totals a floor rather than a measurement.
To follow a board, call list_tickets again with updated_since set to the
server_time the previous call returned; you get back the tickets that changed
and nothing else. There is no tool for the server-sent event stream at
GET /boards/:uuid/events — a tool call is one request and one answer, and a
stream that never ends is neither.
Asking for less. A tool result is charged against the model's context, and
three of these calls are the ones you cannot route around: a status_uuid or a
label_uuid comes from get_board, and a page_uuid comes from
get_wiki_tree. On a busy board they were 154 kB, 119 kB and 180 kB. Each now
takes a parameter that narrows the reply, and every one of them is opt-in — a
call that passes none of them is unchanged.
| Call | Gives you | Measured |
|---|---|---|
get_board(include_tasks: false) |
the structure alone — statuses, labels, fields | 155 kB → 17 kB |
get_wiki_tree(depth: 1) |
the top level, nothing nested under it | 119 kB → 1.8 kB |
get_wiki_tree(parent_page_uuid: …) |
one page and everything beneath it | 119 kB → 9.8 kB |
list_tickets(include_descriptions: false) |
titles and uuids without the bodies | 167 kB → 45 kB |
Reach for get_board(include_tasks: false) whenever you called it for a uuid
rather than for the tickets, and list_tickets when you want the tickets —
that one takes status and limit as well.
Writing
| Tool | Notes |
|---|---|
create_ticket |
status takes the column name, or pass status_uuid; markdown in description is parsed |
update_ticket |
Needs version; markdown in description is parsed; custom_fields is keyed by field uuid and replaces the whole object |
move_ticket |
Needs version, and a column — neither column is a 400 |
comment_on_ticket |
Markdown in body is parsed; no version, so it cannot 409 |
update_comment |
Your own comments only; replaces the whole body and is marked as edited |
delete_comment |
Your own comments only; to the trash, and nothing here restores one |
mark_comments_read |
Clears this ticket's unread badge for the user the key acts as |
add_subtask |
One checklist item, appended — plain text, not markdown |
update_subtask |
Tick it off (is_done), rename it, or move it up the list |
delete_subtask |
Not recoverable — a checklist item has no trash |
archive_ticket |
To the trash — recoverable for 30 days |
delete_ticket |
Destroys one already in the trash — permanent |
create_board |
Optionally from a template — crm or sales-leads |
link_tickets |
"this before that" — direction is blocks or blocked_by |
unlink_tickets |
From either end, and removes every kind of link on the pair |
Comments are not versioned, so none of the three comment writes takes a
version and none of them can 409 — the last edit wins. Only the author may
edit or delete one, and somebody else's is a 404 indistinguishable from a
comment that does not exist, so these never report who wrote what.
get_ticket_comments deliberately marks nothing read; mark_comments_read is
the only call that does, and it marks up to the newest comment that exists at
that moment rather than subscribing.
Subtasks are the checklist on a ticket — a progress count on the card, and where
acceptance criteria belong when they are meant to be ticked off one at a time.
get_ticket returns the items themselves, so there is no separate list tool.
Board structure
| Tool | Notes |
|---|---|
create_status |
A new column, appended to the right-hand end |
update_status |
Rename, recolour, or set is_complete — a board has at most one |
reorder_statuses |
The complete list of uuids, in order; a stale list is a 409 |
delete_status |
The column must be empty, and a board keeps one |
create_group |
A swimlane; there is no rename route, so a wrong name is deleted and remade |
reorder_groups |
Same complete-list contract as reorder_statuses |
delete_group |
Tickets in it survive, ungrouped — and their versions all move |
create_custom_field |
Workspace owner or admin; type cannot be changed afterwards |
update_custom_field |
Rename, reorder, or replace a select's whole options list |
delete_custom_field |
Takes every ticket's value in that field with it — no trash, no restore |
This is what a board an agent creates needs to stop being its template's
defaults. The two reorder tools want the whole list because a partial one is how
two simultaneous reorders silently drop a column: read the uuids off get_board
immediately before calling, and re-read on a 409.
Labels
| Tool | Notes |
|---|---|
list_labels |
Workspace-wide, alphabetical — get_board shows only what a board uses |
create_label |
A hex colour is required; names are unique ignoring case and space |
update_label |
Renames it everywhere — one label, not a copy per board |
delete_label |
Removes it from every ticket that carries it |
A label is a workspace object shared by every board, which is the thing to be
sure of before renaming one: it changes for everybody. The uuids these return
are what update_ticket takes as label_uuids.
Attachments
| Tool | Notes |
|---|---|
list_ticket_attachments |
Name, type, size and uuid — never the bytes |
get_ticket_attachment |
Text inline, an image as an image block, anything else via save_to |
upload_ticket_attachment |
file_path for a file on disk, or text + filename for something written |
delete_ticket_attachment |
To the trash for 30 days; there is no restore tool |
get_ticket reports attachment_total, so you know whether listing is worth a
round trip.
Binary content crosses the tool boundary by not crossing it. A tool result
is text, Laver allows 25 MB per file, and 25 MB of base64 is roughly nine
million tokens — so only text, CSV and images under 4 MB come back inline, and
everything else needs save_to, which writes the file to a path on the machine
running this server (normally the agent's own, since the client starts it as a
subprocess). Uploads go the same way round: file_path reads from that machine
and costs no context.
An image comes back as an MCP image block rather than as text, which is the only form a model can actually look at — that is the whole point of the tool, since the screenshot somebody attached is usually the specification.
Wiki
list_wikis, search_wiki, get_wiki_tree, get_wiki_page,
get_wiki_page_version, append_wiki_page, update_wiki_page,
create_wiki_page — which takes the body as markdown and nests under
parent_page_uuid — and restore_wiki.
Archiving a wiki (done in the browser; there is no tool here for it) takes it
and every page under it out of list_wikis entirely. list_wikis takes
archived: true to see those instead — the only place an archived
wiki_uuid is visible at all — and restore_wiki is the only thing here
that does something with one: it un-archives the wiki, and every page under
it, in one call.
get_wiki_page_version is how you read something that was overwritten. It is a
read: the page does not move. There is deliberately no tool to put an old
version back — read it and write the wording you want with update_wiki_page,
which leaves a version of its own behind.
append_wiki_page adds to the end of a page and update_wiki_page replaces
what is on one; prefer the first when you are adding, because it takes no
version and two agents appending at once both get their text. Replacing takes
the version from get_wiki_page, and a page somebody wrote to meanwhile is a
409 carrying the current version rather than an overwrite — the guard that lets
this exist at all, since wiki pages sit behind a live collaborative editor. A
replace re-seeds that editor from what it just wrote, so a colleague with the
page open sees the new text instead of putting the old text back, and every
previous save stays readable through get_wiki_page_version. There is still no
tool to delete a page.
The markdown goes through the same parser ticket descriptions do. Headings,
lists, tables, code blocks, blockquotes, rules and links survive; so does an
 image, as a reference to that URL — there is no tool here to
upload an attachment, so the URL has to be public already. Raw HTML is kept as
literal text rather than interpreted.
Automations
| Tool | Notes |
|---|---|
list_automations |
The rules on a board, each with its version |
get_automation |
One rule in full — the conditions and actions an edit replaces |
list_automation_runs |
What a rule has actually done, newest first |
create_automation |
Owner or admin only — and see below before calling it |
update_automation |
Needs version; enabled: false is the reversible stop |
delete_automation |
Needs version, and takes the rule's whole run history with it |
An automation rule is a trigger, optional conditions and up to twenty actions, stored against a board. Three things about them are worth knowing before an agent touches these tools:
- A rule created here is live immediately. It fires on its trigger within a
couple of seconds, so read
list_automation_runsafterwards rather than creating one speculatively to see what it would do. - A rule is a standing grant. It runs as the user this key acts as, every time it is triggered, for as long as it exists — not once, like every other write in this server. Revoking the key does not stop it; disabling or deleting the rule does.
- Pause before you delete.
update_automationwithenabled: falsestops a misbehaving rule at once and keeps its history; deleting destroys the history along with the rule.conditionsandactionsreplace the stored lists rather than merging into them, so build them fromget_automationand not from memory.
Both writes take the rule's version and answer 409 with the current one, the
same contract ticket writes have.
Published links
list_published_links is the inventory read: what of this workspace's is on the
public internet right now, each row with its share token, who published it, when,
and how many strangers have looked. live is what a stranger actually gets and
dark_reason says why a row is not, which is the only way to find a published
page that is currently archived and would go straight back online if somebody
restored it. Workspace owner or admin only; an ordinary member is a 403. Taking
a link back down is deliberately not a tool — report what is published and let a
person decide what comes off.
Laver MCPのよくある質問
Laver MCPをClaude Codeに追加するには
ターミナルでclaude mcp add --env 'LAVER_API_KEY=<YOUR_LAVER_API_KEY>' laver-mcp -- npx -y @laver/mcpを実行します。すべてのプロジェクトで利用するには--scope userを追加します。
Laver MCPをCursorに追加するには
~/.cursor/mcp.jsonを開き、上記のインストールセクションに示すCursor設定を使ってmcpServersの下にサーバーを追加します。
Laver MCPが提供するツールは
49個のツールを提供しており、list_workspaces, list_boards, get_board, list_tickets, list_workspace_ticketsなどがあります。
サーバーはローカルキャッシュを保持しますか?
いいえ、すべてのツールは公開REST APIへの直接呼び出しであるため、ローカルの状態やキャッシュは保持されません。