Snagset

Connect your coding agent

Snagset speaks MCP, so a coding agent can read the comments left on your site. "Fix the pin on the PDP" becomes a task the agent can start — instead of a screenshot pasted into a chat window.

It works with Claude Code, Claude Desktop, Cursor, and anything else that speaks MCP.

1. Mint a token

On the machine running your instance:

snagset mcp-token create "Claude Code"
  snagmcp_PxQAYZv7_dPJxW8A7EcXsGg5xs6d5iZrplGyPAwM6yt-zhQblYL8

  Shown once — only its hash is stored.
  scopes: threads:read, source:map

Read the "shown once" literally. Only a hash is stored, so a lost token is revoked and replaced, never re-displayed:

snagset mcp-token list
snagset mcp-token revoke PxQAYZv7

This is not your API key, and the two are not interchangeable. An API key is a server-to-server credential for CI with no notion of scopes or a write budget, and handing one to a program that reads text typed by strangers and then writes is the wrong trade.

2. Point your client at it

{
  "mcpServers": {
    "snagset": {
      "command": "npx",
      "args": ["-y", "@snagset/mcp"],
      "env": {
        "SNAGSET_MCP_TOKEN": "snagmcp_…",
        "SNAGSET_MCP_HOST": "https://review.example.com",
        "SNAGSET_MCP_PROJECT": "prj_…"
      }
    }
  }
}

For Claude Code, that file is .mcp.json in your project. For Claude Desktop it is claude_desktop_config.json. Cursor uses .cursor/mcp.json.

Start your client from your checkout. map_thread_to_source searches the directory it was launched in; SNAGSET_MCP_REPO_ROOT overrides that if you need it to.

3. Ask it something

Which snags are open on /checkout?
Read SN-14, find the component, and tell me what is wrong.

The tools

ToolScopeWhat it does
list_threadsthreads:readWhat is broken, where, in which state
get_threadthreads:readOne snag's full conversation
get_thread_contextcontext:readBrowser, viewport, console breadcrumbs
map_thread_to_sourcesource:mapSearch your checkout for the element
comment_on_threadcomments:writeReply, as the agent
mark_readythreads:writeMove a snag to "ready for review"

There is no tool that resolves a thread. An agent can propose, never dispose — whoever reported a snag decides when it is fixed. Editing or deleting somebody's comment does not exist either.

Scopes

The token you just minted is read-only, plus local source mapping. That is deliberate. To let the agent write:

snagset mcp-token create "Claude Code" threads:read,source:map,comments:write,threads:write
ScopeGrants
threads:readlist and read threads, comments, anchor state
context:readcapture context, breadcrumbs, why a screenshot is missing
source:mapsearch the local checkout
comments:writepost a reply as the agent
threads:writemark a snag ready for review

context:read is separate from threads:read on purpose. Breadcrumbs and capture context are the part that can carry personal data, and an agent that only needs "what is broken and where" should not be handed a console log.

An agent's reply is attributed to the agent — a guest reviewer carrying the token's name, never a verified human. Your client sees "Claude Code said…", not a person who did not say it.

What to think about before granting a write scope

Anyone who can load your site can type a comment. In a project's first 24 hours that is anyone at all. Your agent then reads that text with access to your repository.

Everything Snagset returns is wrapped in <untrusted-content> tags and preceded by a statement telling the model it is reading data rather than instructions. That reduces how often a model follows injected text. It does not eliminate it, and nothing can.

So the controls that matter are the ones that hold when the model is fooled:

  • No execution. No shell tool, no file-write tool, no fetch tool. Source mapping searches inside your repo root and returns matched lines — never surrounding file contents, never a path outside the root, never through a symlink.
  • A write budget the agent cannot argue with. Twenty writes per ten minutes, enforced by the server. An agent talked into "resolve every thread" hits a wall on the twenty-first and has to tell you.
  • Read-only by default, which is why the first token above has no write scope.
  • A revocable token with an audit trail. Every agent write lands in events with the token id, so "what did the agent do on Tuesday" is one query, and turning it off is one revoke.

If that is not enough for what you are working on, the answer is not to issue a write scope.

It is not a second API

The MCP server holds no database connection. Every read goes through the same /api/v1 routes with the same authorisation as any other caller, so a bug in it cannot read a thread its token could not already read. It runs on your machine, talks to your instance, and stores nothing.