Search your team's Storybook components by text or image, so agents reuse what exists.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
One-click editor setup isnβt available for this listing yet β we donβt have a confirmed install command, and weβd rather show nothing than point your editor at the wrong package or host. Follow the projectβs own setup instructions, linked above.
A spec-compliant remote MCP server on Cloudflare Workers that exposes multi-modal vector search over the Scry component database. Authenticates users via Firebase and issues its own OAuth tokens to MCP clients.
Compatible with Claude Desktop, ChatGPT, Cursor, and any MCP client via mcp-remote.
The Worker acts as both an OAuth server to MCP clients (issuing its own tokens) and an OAuth client to Firebase (authenticating users upstream). The MCP client never sees the Firebase token.
| Tool | Description |
|---|---|
search_components | Text-based semantic + keyword hybrid search over UI components. scope: "project" (default) never widens; scope: "org" also returns opted-in, readable sibling projects' rows, marked crossProject |
search_by_image | Visual similarity search using base64 image input; same scope semantics |
get_component_screenshot | Fetch a component screenshot (returns image block + presigned URL) |
generate_image | Gemini image generation (fast / quality), billed in AI credits; routed through Cloudflare AI Gateway when LLM_GATEWAY_URL is set |
whoami | Returns the authenticated user's info |
ISSUE_TOOLS_ENABLED="1")Design-drift issues a human has promoted in the dashboard, resolvable in code or in Figma.
All six call the dashboard's /api/agent/issues/* with a signed X-Scry-Caller
(audience scry-dashboard-agent, claims sub = uid and agent_client = the MCP client's
name); the dashboard checks membership and role and records actor_kind: "agent". Needs
SCRY_DASHBOARD_API_URL, SCRY_AGENT_ASSERTION_SECRET (a secret shared only with the
dashboard, separate from the search secret; unset = SERVER_MISCONFIGURED) and, for the protected stage
dashboard, the SCRY_DASHBOARD_BYPASS_TOKEN secret. Writes are capped at 30/min/user on top
of the 60 req/min limit.
| Tool | Description |
|---|---|
list_design_issues | Promoted issues in a project, filterable by link, Figma node, story, fix side, status, side status, severity, assignee, changed_since |
get_design_issue | One issue with both crops, Figma file key + node id, story + source files, expected value, tracks, last re-check, how to fix |
claim_design_issue | Claim (15-min lease) or release the code or design side |
mark_design_issue_fixed | Record a fix with a PR URL / commit / Figma version |
request_verify | Re-check now (free, 20/project/hour, 200/day) or rediff: true (10 credits) |
comment_design_issue | Timeline comment, optionally proposing a fix side |
Each tool handler invocation records one Workers Analytics Engine data point for
use by the dashboard's staff-only KPI page. The only recorded values are the tool
name (blob1), environment (blob2), and Firebase uid (blob3 and index1), plus
double1 = 1 for counting. Missing environment/uid values become unknown and
anonymous. No query text, prompts, image data, tokens, or other tool data is sent
to Analytics Engine. Internal diagnostic logs do not add usage points. Missing or
failing analytics bindings never affect tool responses.
The MCP_USAGE binding writes to scry_mcp_usage in production and
scry_mcp_usage_staging in staging. Query production with the Analytics Engine SQL
API (substitute the staging dataset name for staging):
Every tool call has one x-scry-request-id (feature observability-request-id;
contract in scry-management/features/observability-request-id/briefs/_request-id-contract.md).
x-scry-request-id is always ignored: the MCP server faces end
users and API clients, so under the contract's trust rule it never accepts a
caller-chosen id. Code: src/lib/request-id.ts, src/lib/tool-request.ts.serverDraw in src/telemetry/producer.ts), never the id./api/search, /api/image/presign,
/api/image/upload), the dashboard issue API, and the diff-service credits
ledger. It is not sent to Google."request_id": "<id>"
(added by the tool wrapper, so no tool has to remember), e.g.
{"error":"SEARCH_API_500","message":"β¦","retryable":true,"request_id":"01M3β¦"}.
A handler that throws becomes INTERNAL_ERROR / UPSTREAM_TIMEOUT with the id.{"msg":"request","request_id":"01Mβ¦","route":"search_components","outcome":"ok","ms":412,"project_id":"4vR5β¦"}
(code is added when outcome is error). No uid, email, query text or body.
Find a call in Workers Logs by request_id. This replaces the old entry-only
{tool, userId} line; Analytics Engine counts are unchanged.run
metadata, the Langfuse trace (metadata.request_id; the trace id is the ULID's
128 bits in hex, traceIdFor in src/telemetry/ids.ts). The request id is
for tracing only and is never a billing or idempotency key: the credits hold
ref_id stays a server-minted UUID per call (mcp-image:<uuid>), so a reused
inbound id cannot replay a hold or merge two charges.src/lib/sentry-options.ts): environment = SCRY_ENV
(staging | production), sendDefaultPii: false, no bodies, and a scrubber
(src/lib/sentry-scrub.ts, copied from build-processing) on events and
breadcrumbs. The tool Durable Object is instrumented too, so a tool that throws
reaches Sentry tagged request_id and tool. Without SENTRY_DSN the SDK is a
no-op. Stage DSN: wrangler secret put SENTRY_DSN --env staging (the shared
Workers project, tagged service=scry-mcp)./api/search and /api/image/presign)Edit .dev.vars with your values:
SCRY_SEARCH_API_KEY is transport auth: it proves a request came from this
worker. SCRY_CALLER_ASSERTION_SECRET signs the short-lived X-Scry-Caller
JWT that tells the search API which user the worker is acting for; it is the
only channel that carries the uid, and the search API verifies it with the same
secret before it trusts the uid. Without the secret the search tools return
SERVER_MISCONFIGURED rather than searching anonymously.
The production and staging KV namespaces already exist and are configured in
wrangler.jsonc. Local development uses Wrangler's local KV emulator; no cloud
namespace creation is needed.
The server runs at http://localhost:8787.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/scry-2)<a href="https://allmcps.com/mcp/scry-2"><img src="https://allmcps.com/api/badge/scry-2?style=directory" alt="Scry on AllMCPs" /></a>