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

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

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_commentsget_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

Databaseserver/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 storageserver/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 normalizationnormalizeUrl() 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 modeLoad 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

3 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.

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. 3 tool updatesv0.5.2
    • First observedget_comment
    • First observedlist_comments
    • First observedupdate_status

TDQS

A4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct operation: retrieving a single comment's full context, listing all comments, and updating a comment's status. There is no functional overlap.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with snake_case: get_comment, list_comments, update_status. Singular/plural usage is correct for each operation.

Tool Count4/5

Three tools is slightly low but appropriate for a focused server that handles comment viewing and status management. The set is concise without being insufficient.

Completeness3/5

The tools cover listing, detail retrieval, and status updates, which are core for working through feedback. However, creation and deletion of comments are absent, leaving notable lifecycle gaps.

Maintenance

ActivitySlowing
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
    A
    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
    22 npm
    MIT