Visual review, written by people and fixed by agents.

A reviewer points at what is wrong on the preview. An agent gets what it needs to fix it.

The Maple overlay on a preview deployment: numbered leaf pins on the page, a picked region outlined and labelled, the comment thread in the corner, and a panel showing everything captured with the selected comment.

The comment is the easy part. The context is what goes missing.

Someone opens the preview link and sees the bug. What they saw lives in a screenshot, a Slack thread and a window size nobody wrote down. By the time it reaches whoever fixes it, most of it is gone, and the fix is a guess at which element they meant.

One solution that does it all. And it's free.

Pincushion, Vercel Toolbar, Chromatic, BugHerd and Marker.io each do some of this. None of them does all of it.

Open source

Apache-2.0, with no hosted service to sign up for and no account in the loop. Maple runs inside your own application and stores nothing itself.

A merge gate

CI blocks while a visual comment is open. The check is real, and it is named.

maple/visual-review

An agent loop

The agent reads the comments over MCP, makes the change, and resolves them. The gate clears because the work is done.

Deployed previews, not localhost

Maple runs on the preview URL your CI already builds, so anyone holding the link can leave a comment. A designer, a product manager, a client. A tool that runs against localhost can only ever hear from the person running the build.

A comment arrives with all the data you need.

Where they pointed
The element, an area of the page, or a passage of text. Maple keeps the CSS path that finds it again after a redeploy, and the file and line the JSX tagger resolves it to.
What they were looking at
The width, the breakpoint, the colour scheme, which sections of the page were open, and a screenshot taken at the moment of the pick.
Who wrote it
The reviewer, as your own application already knows them. Maple asks your app who is signed in rather than running an account system of its own.
Maple's detail panel for one comment: the area of the page it was left on, what the reviewer wrote, who they are and how surely the application knows it, whether anyone has addressed it, the width and colour scheme they were looking at, and the screenshot taken when they picked.
Maple's composer scoring a comment as it is typed: the comment reads 'nothing its perfect', tagged praise, and the five pillars rate it names nothing, reports only, padded, stands alone and unplaced.

And a score, if you want one.

Maple can judge the comment as it is being typed, against five pillars, with a classifier like Jev behind it. It says which rung the comment reached in plain words: names nothing, reports only, unplaced.

It is advice beside the field and nothing more. Never a gate, never a rewrite, and off entirely until you wire a classifier in.

Maple stores nothing itself.

You point it at what you already run. A connector is one file of plain Promise-returning methods: no Maple account, no Maple database, and nothing to migrate off later.

my-store.ts
import type { StoreConnector } from "@maple-kit/core/connectors";

export function myStore(options: MyOptions): StoreConnector {
  return {
    name: "my-store",
    async list(query) { /* your rows */ },
    async append(comment) { /* your write */ },
  };
}

There are four kinds, and a connector’s capabilities are exactly the methods it defines. There is no second list saying what it supports, because two lists disagree.

  • storewhere the comments live
  • mediawhere a screenshot goes
  • observabilitywhere a trace is read
  • identitywho the reviewer is
The capability matrix

The loop

Four steps, and the only one a person has to be awake for is the second.

  1. Mount

    One route in your application and one script in the preview build.

  2. Comment

    A reviewer opens the preview, points at the thing, and says what is wrong.

  3. Gate

    The action writes the comments onto the pull request and holds the merge.

  4. Resolve

    The agent reads them over MCP, makes the change, and closes them out.

In beta, and already usable.

Maple is published and still being built, in the open. Contributions are welcome, and the intro post says what already works.

Four packages

  • @maple-kit/core

    Server SDK, overlay and connector contracts

  • @maple-kit/cli

    The maple command

  • @maple-kit/mcp

    The MCP server an agent talks to

  • @maple-kit/classifier

    Model-backed scoring for the assist tier