Skip to content

@sightmap/mcp

@sightmap/mcp is an MCP server that wraps @playwright/mcp and adds sightmap-aware tools for browser-driving agents. It is the recommended way to let a host agent (Claude Code, Cursor, Subtext) curate a .sightmap/ directory: the agent gets a typed tool surface for browser introspection, runtime discovery, and YAML mutation — including the proposal workflow that drives bootstrap.

Terminal window
pnpm add -D @sightmap/mcp

If you ran sightmap init, the server is already wired into your agent harness (.mcp.json for Claude Code, ~/.codex/config.toml for Codex, .cursor/mcp.json for Cursor, opencode.json for OpenCode). Otherwise, wire it in by hand:

Terminal window
sightmap-mcp \
--sightmap-dir ./.sightmap \
--curate-root ./.sightmap \
-- npx -y @playwright/mcp@latest
FlagPurpose
--sightmap-dir <path>Directory of sightmap YAML files. Repeatable. Default: .sightmap.
--curate-root <path>Writable .sightmap/ for curation tools. Default: the first --sightmap-dir.
--curate-onlySkip spawning the upstream browser-MCP server. Only the curation, proposal, and runtime tools register (sightmap_list_views, sightmap_get_view, sightmap_check, sightmap_init_project, sightmap_add_view, sightmap_update_view, sightmap_delete_view, sightmap_propose_view, sightmap_propose_component, sightmap_review_proposals, sightmap_commit_proposals, sightmap_runtime_snapshot). Useful when paired with a Sightmap-aware browser tool like Subtext that already drives the browser.
--upstream-command <cmd>Command to spawn the upstream MCP server. Default: npx.
-- <args...>Args for the upstream command. Default: -y @playwright/mcp@latest.

These require an upstream Playwright MCP. The server proxies the upstream’s primitives and adds sightmap awareness:

ToolPurpose
sightmap_matchPure query: matches a URL against the loaded sightmap and returns view, components, requests, and aggregated memory.
sightmap_snapshotARIA snapshot enriched with sightmap awareness — matched view, applicable components with live matchCount.
sightmap_actClick / type / hover by sightmap component name; raw selector is an escape hatch.
sightmap_network_requestsRecent network requests, annotated with sightmap names where the request URL+method matches a sightmap requests: entry.

The upshot: an agent can drive a browser in terms of component names, not selectors. sightmap_act { component: "LoginButton", action: "click" } resolves the selector at call time, so renames in the YAML take effect immediately without prompt edits.

sightmap_runtime_snapshot captures the live fiber-tree from a running React app — the input that feeds the proposal workflow during bootstrap. As of v0.9, it accepts three source.kind discriminants, each suited to a different deployment:

source.kindShapeUse when
endpoint{ kind: "endpoint", url }You’re using @sightmap/react’s Vite plugin — the zero-config path. HTTP GET against /__sightmap__/snapshot.json.
browser{ kind: "browser", url, routes?, inject? }Non-Vite projects, apps without @sightmap/react, or static first-paint apps where post-navigate injection races React’s first commit. Drives the live browser via @playwright/mcp passthrough; the bippy IIFE + bootstrap pre-navigate-inject via PLAYWRIGHT_MCP_INIT_SCRIPT (requires @playwright/mcp >= 0.0.75), so the hook is in place before React mounts. Post-navigate browser_evaluate remains as a fallback.
literal{ kind: "literal", snapshot }You captured the snapshot yourself — Subtext’s live-eval-script, devtools console paste, custom Playwright scripts, CI capture. MCP validates the shape and returns it. The universal escape valve when MCP can’t reach the browser directly.

Vite users get the zero-config endpoint, non-Vite users get the browser-driven path, and anyone with their own capture mechanism gets the literal mode.

The read/write surface for .sightmap/ itself:

ToolPurpose
sightmap_list_viewsList all views (compact summary by default; pass detail: "full" for the entire view).
sightmap_get_viewFetch a single view + its source file path.
sightmap_checkValidate the corpus (level: "schema" or "quality"; default "quality"). Schema, key ordering, cross-file references, duplicates — corpus only, not against React source.
sightmap_init_projectScaffold an empty .sightmap/ in a target project.
sightmap_add_viewCreate a new view.
sightmap_update_viewPatch view fields (description, memory_append, memory_replace, etc.).
sightmap_delete_viewRemove a view.

Writes operate on the directory passed via --curate-root (defaults to the first --sightmap-dir).

The bootstrap-and-reconcile loop. The agent proposes views and components from the runtime snapshot, reviews the batch, then commits.

ToolPurpose
sightmap_propose_viewStage a proposed view (from a runtime route).
sightmap_propose_componentStage a proposed component (from the fiber-tree, with a ranked selector).
sightmap_review_proposalsList the staged batch with full detail — for agent or human triage.
sightmap_commit_proposalsAtomically write the accepted proposals to .sightmap/.

This is the mechanism behind the /sightmap:bootstrap skill. Existing fields (memory, requests, manual selector overrides) are preserved on re-run.

The server exposes prompt templates for multi-step authoring workflows.

Walks an author through writing a Sightmap Enhancement Proposal — the SEP markdown, the matching spec/ change, and the matching conformance/ fixture — in four phases:

PhaseProducesConfirmation gate?
draftseps/NNNN-{slug}.md from the templateYes
specA diff against spec/ referencing the SEPYes
fixtureconformance/<NNN>-{slug}/ with sightmap/ input + expected.jsonYes
verifyHand-off summaryNo (terminal)

Confirmation gates are encoded as text directives at the end of each non-final phase (“Stop here. Show the draft to the user, ask for explicit ‘go’ before calling this prompt again with phase: \"spec\".”). The agent honors them; MCP itself has no native pause-and-await primitive for prompts.

This exists because SEPs require coordinated edits across three trees (seps/, spec/, conformance/). The track encodes the order, the dependencies, and the user check-in points so neither author nor agent can short-circuit them.

@sightmap/mcp honors the SIGHTMAP_PLUGIN_VERSION environment variable on startup. When set, the server compares its own version against the plugin version using a built-in KNOWN_INCOMPATIBLE_RANGES table and emits one of three states:

  • Match — silent.
  • Untested combination — one warning line, server proceeds.
  • Known-incompatible pair — fail loud and exit 1, suggesting matching versions.

The @sightmap/plugin ships with compatibleMcpVersion in each per-harness plugin.json. sightmap init reads that field and pins it into the project’s .mcp.json via the npm spec @sightmap/mcp@<compatibleMcpVersion>, and sets SIGHTMAP_PLUGIN_VERSION on the spawned env. Together: the plugin declares its target MCP version, init propagates it, and MCP verifies on startup.

The MCP server is the underlying tool surface. The Claude Code plugin layers skills and advisory hooks on top — /sightmap:bootstrap drives the proposal workflow, /sightmap:reflect nudges when source files with data-sightmap markers have been edited, and the PostToolUse audit hook surfaces cross-file inconsistencies after any MCP write. Run both together for the smoothest experience; either one alone works, with predictable trade-offs.