@lovinka/vitrinka-mcp
v1.0.1
Published
MCP server for vitrinka — browse artifact sets and drive the annotation-board work queue from any MCP-aware AI.
Maintainers
Readme
@lovinka/vitrinka-mcp
MCP server for vitrinka — the board-first screenshot artifacts library + annotation-board review surface. Lets any MCP-aware AI browse artifact sets and drive the annotation-board work queue (pick up an annotation → fix the app → attach the after-shot → reply) without touching the web UI.
It is a thin, stateless stdio process: every tool call becomes one HTTPS request against the deployed vitrinka Go server, so N concurrent agent sessions are just N independent processes — no shared connection to keep alive.
Install
claude mcp add --scope user vitrinka -- npx -y @lovinka/vitrinka-mcpThat registers the vitrinka MCP server for every project + window (Claude
Code). Restart Claude Code afterwards. For Claude Desktop or any other MCP
client, add the equivalent entry by hand:
{
"mcpServers": {
"vitrinka": {
"command": "npx",
"args": ["-y", "@lovinka/vitrinka-mcp"],
"env": {
"VITRINKA_BASE_URL": "https://vitrinka.lovinka.com",
"VITRINKA_TOKEN": "…"
}
}
}
}vitrinka is reachable over the WireGuard mesh — bring the VPN up (or point
VITRINKA_BASE_URL at any reachable host) before use.
Configuration (env)
| Var | Default | Purpose |
|---|---|---|
| VITRINKA_BASE_URL | https://vitrinka.lovinka.com | vitrinka server base URL. VITRINKA_URL is also accepted by the CLI; the MCP reads VITRINKA_BASE_URL. |
| VITRINKA_TOKEN | — | Bearer write token. Falls back to ~/.config/vitrinka/token (the CLI's convention). Required only by the mutating tools; read tools work unauthenticated. |
| VITRINKA_OPERATOR | — | Operator persona name. Falls back to ~/.config/vitrinka/operator (written by install.sh onboarding). When set, write calls carry X-Board-Actor: <name> so the board credits the operator's machine — agent-authored content (reply, attach_after) keeps its explicit claude attribution. |
Tools
Artifacts library
list_projects— all projects (name, branch/set counts, last update).list_sets— a project's (or one branch's) artifact sets, newest first.get_set— one set's metadata + full file list + share URL.rename_set— set/clear a set's custom URL-addressable name. (write)update_set— edit a set's custom name and/or human title. (write)
Annotation-board work queue
list_boards— the annotation boards (canvases over screenshot sets).scrape_board— read a whole board as one structured testing digest (media, notes, annotations, journey chains).wait_for_work— block (long-poll) until annotation work exists; returns ready-to-act markdown capsules. A listening session loops on this forever.list_work— the agent queue (FIFO); filter by status / board.get_annotation— one annotation's full brief (region, intent, thread, attempts, element context, crop URL).get_capsule— one annotation's compact markdown work brief.set_status— move an annotation through its lifecycle. (write)reply— post a reply into an annotation's thread asclaude. (write)attach_after— attach the "after" proof shot to an annotation. (write)highlight— draw an ink rectangle on an annotation's card (live via SSE). (write)
Agent loop: list_work → set_status working → fix the app → push a new set
(vitrinka snap/push) → attach_after → reply → set_status in_review.
Only the user resolves (accepts in the board UI) — never set status
resolved yourself.
Unattended worker
The package also ships the board-v3 fallback worker — when no listening Claude
session is open, it long-polls the queue and spawns one claude -p per
annotation:
npx -y @lovinka/vitrinka-mcp work --repo ~/Documents/Work/FixIt [--board <slug>] [--grace 8]Local development
cd mcp
npm install
npm run build # tsc → dist/
npm test # node --test *_test.mjs (spawns the server/worker over real stdio)
npm run typecheck
node dist/index.js # start the MCP server over stdio (Ctrl-C to stop)The source (server.ts / work.ts) is dependency-free, erasable TypeScript
(node builtins + global fetch only) and runs directly under Node 24 via type
stripping — that is exactly how a repo checkout registers it:
claude mcp add --scope user vitrinka -- node <repo>/mcp/server.tsThe published dist/ is plain ESM and runs on Node ≥ 20.
Release (Lovinka org)
npm login # as the lovinka npm org
cd mcp
npm publish --access public # prepublishOnly runs the buildfiles is a whitelist (dist + README.md), so npm pack --dry-run should
list only the compiled output — verify before publishing.
License
MIT
