Skip to main content
Glama

Loupe

Pin feedback to the live UI. Hand it to Claude.

Loupe lets product managers inspect any element on a running product, pin a comment to it, and capture a screenshot — then hand that feedback straight to Claude Code as an actionable, fully-contextualized backlog. Comments persist and re-anchor across redeploys.

📖 Read the full documentation →

This is a monorepo (npm workspaces). Every piece runs locally with no external services — the database is embedded Postgres (PGlite), so npm install && npm run build && npm run seed && npm start is the whole setup.

Packages

packages/
  shared/      canonical types + normalizeUrl() (built to dist, consumed by all)
  sdk/         embeddable browser SDK — inspect, comment (element / region / free note), capture, re-anchor; dockable control panel
    demo/      a fake product ("Acme Analytics") to try it on
  server/      comment API — node:http, Postgres, object storage, HMAC auth, static hosting
  dashboard/   Kanban triage board (reads the API)
  mcp/         MCP server — exposes comments to Claude Code
  extension/   MV3 browser extension — inspect/comment on ANY site, pixel-perfect capture
  laravel/     Loupe for Laravel — composer package: widget + your DB + gating + dashboard + MCP
  hub/         Loupe Hub (optional, private) — orgs/members/projects; verifies issues, forwards to webhooks

Loupe for Laravel

Prefer to run the whole loop inside your own app? loupekit/laravel is a Composer package that embeds the widget, stores comments in your database, gates access with your authorization rules, serves the dashboard on your routes, and exposes the backlog to Claude over MCP — no separate Node backend. See the full guide.

composer require loupekit/laravel
php artisan loupe:install && php artisan migrate
# add @loupeWidget to your layout, then open /loupe/dashboard

Optional: set LOUPE_HUB_URL, LOUPE_PROJECT_ID and LOUPE_PROJECT_SECRET to also send every new comment to Loupe Hub, which checks the author belongs to your organization and forwards it to your project's webhook.

Related MCP server: Browser Feedback MCP

Run it

npm install
npm run build          # shared → sdk → dashboard → extension
npm run seed           # creates the demo project; prints its admin key + demo HMAC
npm start              # one process on http://localhost:8787 serves API + dashboard + demo + SDK

Then open:

Point Claude Code at the comments:

{
  "mcpServers": {
    "loupe": {
      "command": "node",
      "args": ["/absolute/path/to/loupe/packages/mcp/index.ts"],
      "env": {
        "LOUPE_API": "http://localhost:8787",
        "LOUPE_PROJECT_KEY": "pk_demo_acme",
        "LOUPE_ADMIN_KEY": "<admin key from npm run seed>"
      }
    }
  }
}

Then: "list the open Loupe comments and work through them." Claude calls list_comments → get_comment (request + element HTML + computed styles + the screenshot as an image + any screen-recording URL) → rewrites the UI → propose_change (its modified HTML/CSS, which the dashboard renders as code + a live before/after preview for the dev team) → update_status.

Architecture notes

Database — server/db.ts is a one-function query() seam. With DATABASE_URL set it uses node-postgres against real/hosted Postgres; otherwise embedded PGlite on disk. Same SQL, same $1 params.

Auth — every project has a secret. Writes require X-Loupe-User + X-Loupe-Hmac = HMAC-SHA256(userId, secret) (the host app's server computes this and injects it — the demo's value is precomputed by npm run seed). The dashboard and MCP server authenticate as admin with X-Loupe-Admin = secret. Screenshot blobs are served by unguessable id (prod: signed URLs).

Object storage — server/blobs.ts is the seam (local disk now, S3 later). The SDK uploads a screenshot to POST /v1/blobs and stores only the returned URL on the comment, so lists/reads stay small.

URL normalization — normalizeUrl() in @loupekit/shared strips utm_*, click ids, and Loupe's dev params, so a comment on /checkout?utm_source=x and one on /checkout don't fragment. Applied server-side on write and query.

Browser extension

The extension reuses the exact SDK core; its only difference is the screenshot source — chrome.tabs.captureVisibleTab (real pixels), cropped to the element with redaction, wired via the SDK's captureScreenshot override. Load it manually:

npm run build:extension      # builds packages/extension/content.js
  1. chrome://extensions → enable Developer mode → Load unpacked → select packages/extension.

  2. Click the Loupe icon → set project key (pk_demo_acme), user, API base (http://localhost:8787), and (optionally) the demo HMAC → Start Loupe on this tab.

Note: the extension is validated by build + manifest/bundle checks; full in-browser E2E wasn't automated in this repo's headless setup.

Roadmap

  1. Client SDK ✓ — inspect, comment, capture, re-anchor across redeploys.

  2. Backend API ✓ — Postgres, HMAC auth + per-project secrets, object storage, static hosting.

  3. MCP server ✓ — comments as a Claude Code backlog.

  4. Dashboard ✓ — Kanban triage.

  5. Hardening ✓ — monorepo, Postgres, enforced auth, blob storage, URL normalization.

  6. Browser extension ✓ — pixel-perfect capture on any site.

Next: real cloud object storage (S3/R2) + signed URLs, project/team management UI, Postgres migrations tooling, and packaging the SDK/MCP to npm + the extension to the Chrome Web Store.

Author

Loupe is created and maintained by Mohamed Ashraf Elsaed.

If Loupe is useful to you, a ⭐ on the repo and a connection on LinkedIn are always appreciated. For consulting or collaboration, reach out via any of the links above.

License

MIT © Mohamed Ashraf Elsaed

Available Tools

4 tools
get_commentA

Get the full context for one comment: the request, the page, the target element's HTML, and its computed styles — everything needed to make the change.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe comment id from list_comments.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; description indicates a read operation returning context. Lacks explicit mention of safety or side effects, but for a read tool this is acceptable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence (20 words) that is front-loaded with the primary action and includes explanatory details without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Simple tool with one param, no output schema. Description sufficiently explains what the return value contains, making it complete for an agent to understand usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% coverage with description for 'id'. Tool description adds that id comes from list_comments, providing useful context beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Get the full context for one comment' and lists specific components (request, page, target element HTML, computed styles). Distinct from sibling tools list_comments and update_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies use after list_comments to retrieve detailed context for a specific comment. No explicit when-not-to-use or alternative mention, but context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_commentsA

List Loupe product-feedback comments for the project as a task backlog. Use this to see what a PM has flagged, then work through the items.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNoFilter to a single page path, e.g. /checkout.
statusNoFilter by status. Omit for all.

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral traits. It does not mention read-only nature, side effects, authentication, or rate limits, which are important for safe invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no filler. The purpose is front-loaded in the first sentence, and the use case is in the second.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with two optional parameters and no output schema, the description gives adequate context about the task backlog usage. However, it could mention return format or ordering for completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The tool description adds no additional parameter detail beyond the schema's own descriptions, so it does not improve parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List' and resource 'Loupe product-feedback comments for the project as a task backlog'. It differentiates from siblings (get_comment, update_status) by emphasizing it returns a list for review.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context: 'Use this to see what a PM has flagged, then work through the items.' This implies when to use it, though explicit exclusions or comparisons to siblings are absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

propose_changeA

Submit the modified UI for a comment: the rewritten HTML (and optional CSS) that resolves the PM's request. This stores your proposal on the comment so the dev team can review the code and a live preview in the dashboard. Use get_comment first to see the original element, its computed styles, and the screenshot.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe comment id from list_comments.
cssNoAccompanying CSS. Omit if the styling is inlined in the HTML.
htmlYesThe modified element markup that implements the requested change.
notesNoA short explanation of what you changed and why.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden. It discloses persistence ('stores your proposal on the comment') and downstream consumption ('dev team can review the code and a live preview'), which is useful. However, it omits whether a proposal overwrites prior proposals, permission/auth requirements, and whether the action is reversible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action and payload, followed by the storage/consumer effect and the prerequisite lookup. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter mutation tool with no output schema or annotations, the description covers purpose, payload expectations, storage behavior, and the prerequisite read step. It stops short of describing the response or edge-case behavior (overwriting, validation failure), leaving a small gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds real context: it clarifies that html is the change-resolving markup and css is optional and should be omitted when styling is inlined, plus that id should come from a prior lookup. This meaningfully supplements the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Submit the modified UI for a comment') and immediately identifies the payload (rewritten HTML with optional CSS) that resolves the PM's request. It also explains where the result lands ('stores your proposal on the comment'), so an agent can distinguish this from read-only siblings like get_comment or list_comments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear operational sequence: call get_comment first to see the original element, computed styles, and screenshot, then submit the proposal. That establishes when to use this tool relative to a specific sibling, though it does not state exclusions (e.g. what to do if the proposal is rejected or how it differs from update_status).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_statusA

Update a comment's status. Set to in_progress when you start it and done when the change is shipped — this closes the loop back to the PM.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
statusYes

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; description only states it updates status and mentions closing the loop. Does not disclose mutation behavior, idempotency, auth requirements, or other side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: first states purpose, second provides usage guidance. No wasted words, front-loaded with key information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple update tool with 2 required params and no output schema, the description covers the main usage. Minor missing details (e.g., behavior when setting to 'open') but sufficient for typical use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% so description must compensate. Adds meaning to the status parameter with concrete use cases ('in_progress when you start it', 'done when shipped') but does not explain the id parameter beyond its type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Update a comment's status' with specific use cases for each status value, distinguishing from read-only siblings get_comment and list_comments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when to use 'in_progress' and 'done' statuses, providing context for closing the loop with the PM. No explicit exclusion of other scenarios, but sufficient for typical use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.8.0
    • Addedpropose_change
  2. 3 tool updatesv0.5.2
    • First observedget_comment
    • First observedlist_comments
    • First observedupdate_status

TDQS

A4.3/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct role in the comment-resolution workflow: listing comments, fetching one comment's context, proposing a UI change, and updating status. There is no meaningful overlap between them, so an agent can easily select the right tool.

Naming Consistency5/5

All four tools use a consistent snake_case verb_noun pattern: list_comments, get_comment, propose_change, update_status. This makes the names predictable and easy to scan.

Tool Count5/5

Four tools is well-scoped for a focused workflow of reviewing feedback, gathering context, submitting a proposal, and closing the loop. Each tool earns its place without redundancy.

Completeness5/5

The surface covers the full agent-facing lifecycle: discover comments, inspect context, propose a change, and update status. Creation and review of PM comments happen outside this MCP server, so no critical gap remains.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables visual annotation on web pages for Claude Code, allowing element selection, comment addition, screenshot capture, and structured UI feedback for code fixes via an MCP server.
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Enables visual browser feedback collection directly into Claude Code. Users can point at elements in their browser and send annotated feedback that Claude can act on immediately.
    12
    1
    -
  • A
    license
    A
    quality
    A
    maintenance
    Interactive feedback layer that lets users pin comments on live web apps with auto-captured context (failing requests, console, AI metadata), and coding agents fix issues via MCP, turning pins green upon verification.
    10
    64 npm
    MIT