add_agent_reply
Add a reply to an annotation thread (e.g. to ask a clarifying question or note a finding).
Let a stakeholder drop a pin on the live page, and hand your coding agent the URL, selector, screenshot and acceptance criteria needed to fix it.
LABSCO SUMMARY
The point is what a pin carries: page URL and element selector, screenshot and DOM snippet, the thread, likely files and how to know it is done — enough for an agent to implement without a round trip to the person who filed it. The loop closes on the other side too, with the resolve recording the commit, branch and PR, and an optional post-deploy check verifying the fix actually shipped. Claiming a pin before work starts is what keeps two agents off the same one.
The agent-side half of Pincushion. Feedback pins placed through a Chrome extension land in a .feedback/ directory, and this server hands them to a coding agent as work packets with the page, element and context attached.
The Pincushion Chrome extension, installed from pincushion.io/install/chrome — that is how pins get created in the first place. Node.js 18 or newer; run it with npx pincushion-mcp --project-dir . over stdio, from the npm package pincushion-mcp, currently 1.3.5. The project directory is the one holding .feedback/. Remote sync is optional and adds --sync-url and --api-key; --license-key activates Pro features; --rest --port 3456 starts an HTTP wrapper for clients that do not speak MCP. On a project, collaborators added as developers consume a paid seat while commenters are free.
One command — npx pincushion-mcp --project-dir .
USE CASES
Read the rollup by status, page and component, then open the pins waiting on developer attention.
Pull the implementation packet for that page — selectors, pin payloads and a suggested branch name come with it.
Claim it first, then resolve it with the commit and PR recorded once the fix is in.
Post a reply into its thread asking what was meant, rather than guessing.
Mint a read-only report link and upload a page screenshot so the pins appear at their real positions.
Preview the notification shape first, then connect the Slack, Teams or Discord webhook.
Counted once with only startup setup. Other versions, modes or optional credentials may expose a different list.
add_agent_replyAdd a reply to an annotation thread (e.g. to ask a clarifying question or note a finding).
add_bot_replyPost a Pincushion AI reply to a pin's thread. Hardcodes author="Pincushion AI" and authorEmail="pincushion-bot@pincushion.io" so the Chrome extension applies bot styling. ONLY call from the /pincushion-replies flow — never as a generic reply. Refuses to post if the latest thread message is already bot-authored (defense-in-depth idempotency).
add_memberAdd a collaborator to a Pincushion project. Developers consume a paid seat and can implement pins. Commenters are free and unlimited. Returns an upgrade prompt if the seat limit is reached.
approve_pinMark a pin as approved for implementation. Only approved pins should be implemented by agents. This transitions the pin from "open" to "approved" status.
assign_pin_to_agentAssign a pin directly to your local coding agent. Promotes the pin to "ready" (if not already), marks it as pending_implementation, and drops a trigger file in .feedback/.agent-queue/ that agent-loop.mjs picks up and dispatches to Cursor / Claude Code / Codex. This is the first-class "assign to agent" action — turns a pin into agent work in one call. Workflow: assign_pin_to_agent → (agent-loop dispatches) → fix_and_resolve.
claim_pending_slack_installLEGACY FALLBACK. Since May 2026, Slack installs auto-link to a Pincushion license when the installer's Slack email matches, and channels are subscribed via /pincushion subscribe inside Slack — no claim token needed. This tool only applies when the installer's Slack email did NOT match an active Pincushion license at install time (the user sees a claim_token on the post-install page in that case). Pass claimToken (the on-page token, valid 7 days) + projectId to attach the webhook. Calling with no claimToken returns the new flow instructions instead of an error.
claim_pinClaim an actionable pin before starting work on it. Transitions the pin from "pending_implementation" to "implementing" so other agents know it is being worked on. Call this before making changes, then call fix_and_resolve when done.
complete_critique_requestMark a critique_queue request as completed after the critic subagent has run on its page URLs. Pass the request id (from get_pending_critiques) and the total pin_count produced. The server scopes the update to your license — you cannot complete another tenant's request even if you know the id.
configure_collaboration_integrationConnect a Pincushion project to Slack, Microsoft Teams, or Discord using an incoming webhook. Low-noise defaults mirror Figma-style subscriptions: pin activity plus the deploy/verify loop, where pin_deployed/pin_verified attach as a quiet threaded reply under the pin (never a new top-level message). The louder agent-pin, email-pin, and share-report events are opt-in. For Discord, create a channel Incoming Webhook (Channel Settings → Integrations → Webhooks) and pass its URL.
configure_projectRegister a Pincushion project and associate it with your app's URLs. Once registered, anyone visiting those URLs with the Pincushion extension installed will automatically see the pin UI — no meta tag or manual setup needed. Pass both your local dev URL and your live/staging URL so the extension activates in all environments. Optional traceability knobs (commitTrailers, attributionComments, recordCommitSha) control how implemented pins are recorded in git and source — see each property's description. NOTE for read-only use cases: if you only need to look up brand context, URLs, or other project metadata, call get_project_context instead — configure_project mutates state (upserts the project row, syncs to cloud, creates a deploy hook, idempotently inserts the bot member).
create_agent_pinFile a pin as a THIRD-PARTY agent — the write half of the browser-agent → coding-agent handoff. Use when a QA/browser agent (Claude in Chrome, computer-use, a Playwright a11y/visual check, a CI checker) finds a concrete issue on a page and wants to hand it to the implementing agent as a work packet. NOT the Pincushion AI voice: the pin renders as "<agentName> (agent)" with an agent chip (enforced server-side; is_bot/bot styling stays reserved for the critic). Pins start "open" and get triaged like any pin — never pre-approved. Each pin should be one specific element + problem + suggested fix; include acceptanceCriteria when the finding has a testable definition of done. Metered as an AI action (agent_pin). Repeating the same semantic finding on the same route and selector with only query values changed returns duplicate_variant; inspect a distinct state, scenario, or element instead.
create_critique_pinCreate a pin authored by Pincushion AI. ONLY call this from the pincushion-critic subagent or the /critique-latest-deploy flow — never from a regular user prompt, since the bot voice is reserved for AI-driven UI/copy/a11y and product-experience feedback (flows, empty/error states, terminology, trust). Each call should produce one tasteful, high-signal pin (max 3 per page in a critique run). The body must be concrete and actionable: name the specific element + the specific problem + the suggested fix in <40 words (up to 55 for a flow critique that must name the step before/after). Forbidden: layout philosophy, business-model commentary, roadmap ideation (a missing affordance at a specific element IS in scope), generic "consider improving hierarchy" advice. Always read the project's critique context (ai.critique.effectiveContext from get_project_context — falls back to brandContext when no compiled brief exists) before drafting the body so the critique is on-brand. If ai.critique.staleness is "stale" or "missing", suggest the user run /refresh-brand before continuing. Repeating the same semantic finding on the same route and selector with only query values changed returns duplicate_variant; inspect a distinct state, scenario, or element instead.
create_invite_linkGenerate a Figma-style shareable invite URL for a project. The recipient opens it, enters their name + email, and joins as the specified role. Returns the share URL plus expiry. Owners can mint Editor and Commenter links; Editors can mint Commenter links only. Editor links consume a paid seat on redemption.
create_share_reportMint a public read-only crit report link (pincushion.io/r/<token>) for a project: numbered pins with threads, screenshots, status, and the branch/PR/deploy/AI-verification trail. Anyone with the link can view it — no extension, no account, nothing to install. Free on every plan. Perfect for handing a design crit to a founder/client, or showing stakeholders what shipped. Optionally scope to a single page URL. Links never expire unless expiresInDays is set; viewers see live pin status.
create_slack_install_linkGenerate an Add-to-Slack OAuth URL pre-bound to a project. Most users should prefer the public storefront URL (also returned, https://pincushion.io/install/slack) — since May 2026, that auto-links to a Pincushion license when the installer's Slack email matches, and channels are subscribed afterward via /pincushion subscribe inside Slack. Use this agent-flow URL only when you want the install to attach to one specific project up front.
fix_and_resolveResolve a pin after applying a code fix. Transitions the pin directly to "resolved" status so it disappears from the stakeholder view. No thread comment is added — the commit is the record of the fix. Pass commitSha (from git rev-parse HEAD), branchName (git branch --show-current), and prUrl (from gh pr view --json url -q .url if a PR was opened) so the Pincushion dashboard can link the pin to the implementing commit, branch, and PR.
generate_critique_reportCanonical critique generation command. Uploads only the supplied real captures, then creates or refreshes one /r/<token> report and persists a truthful receipt. Use preset "full" only when you actually provide desktop/mobile captures; Journey becomes available only when journey.screenIds names at least two completed logical screens. Re-running generationKey "canonical" preserves the existing report URL.
get_actionable_pinsGet all pins waiting for developer attention. Returns three categories: (1) "auto-agent" — pins explicitly sent to the agent via "Send to Agent"; (2) "follow-up" — previously implemented pins with new user comments; (3) "review" — open reviewer comments that a developer has not yet picked up (the standard team collaboration queue). Use this as your starting point for both auto-agent workflows and manual review sessions.
get_annotationsRetrieve annotation pins from the .feedback/ directory. Filter by page URL, LWC component name, or status. Use this to understand what feedback exists before making changes.
get_component_feedbackGet all feedback pins targeting a specific LWC component, with a plain-language summary ready for implementation. Returns element selectors, comments, and thread history.
get_feedback_summaryGet a high-level rollup of all open feedback: counts by status, page, and component. Use this to plan what to address first.
get_implementation_packetGet a single implementation packet for one page URL. Useful when you want to batch-fix one page at a time. Returns the same shape as a single entry in implement_approved_pins.packets — pins, aggregated selectors, suggested branch, traceability config. Matches by exact URL or partial substring.
get_pending_critiquesUsed by /critique-latest-deploy. Lists pending critique requests queued by the deploy-hook for the current license. Returns request id + page URLs + deploy hash. Newest-first. Free on all plans (the gating happened at enqueue time on the deploy-hook side: Pro/Team — including trial-Pro — always enqueue; free licenses enqueue while their monthly AI-action pool has headroom).
get_project_contextRead-only lookup of a project's context (name, URLs, brand context, autoCritique flag, traceability settings). Use this whenever you only need to inspect — never mutates, never touches the network. The Pincushion AI critic subagent calls this before generating any pin, since configure_project would otherwise upsert the project, sync to cloud, and create a deploy hook on a typo'd project name. Pass projectId for an exact lookup, name to look up by display name, or no arguments to list all projects in this workspace.
get_reply_candidatesUsed by /pincushion-replies. Returns pins where Pincushion AI should respond, with each candidate tagged by trigger reason. Two triggers: (a) "mention" — the latest thread message contains @pincushion AND was authored by a human; (b) "reply-on-bot-pin" — the pin was originally authored by Pincushion AI and the latest message is from a human. Skips resolved/archived pins and any pin where the latest message is already bot-authored (idempotency). Newest-first ordering so the slash command can pace replies.
get_selected_pinsGet pins that the developer has selected for implementation from the dashboard or PINS.md checkboxes. Returns the selected pin IDs with full context (element, thread, deep link). Use this to know which pins the developer wants you to work on next.
get_setup_instructionsGet instructions for setting up and connecting the Pincushion browser extension to this MCP server. Includes configuration examples for Cursor, Claude Desktop, Claude Code, VS Code, Windsurf, and other agents.
get_time_to_fix_metricsCompute median + p25/p75 time-to-fix from resolved pins. Returns sample size + threshold flag so callers can honestly hide the metric when the dataset is too small (< 5 resolved pins). This is the marketing proof point that distinguishes Pincushion from "manage feedback" tools — agent-native means fast.
implement_approved_pinsCALL THIS FIRST when approved pins exist. Returns all stakeholder-approved pins grouped into implementation packets by page URL, each containing aggregated CSS selectors, full comment threads, and a suggested git branch name. One packet = one branch / one PR. Use the selectors to grep the source code, read the thread to understand what the stakeholder wants, then implement the fix. Workflow: implement_approved_pins → claim_pin → code change → fix_and_resolve. The result exposes both packets (canonical) and pages (alias).
link_pin_deployLink a deploy URL to a resolved pin. Typically called by the deploy-hook edge function once a deploy that includes the pin's fix goes live. Stakeholders see the deploy URL on the resolved pin in the dashboard. Re-runs overwrite the previous deploy URL (latest deploy wins).
list_collaboration_integrationsList Slack and Microsoft Teams webhook subscriptions for a Pincushion project. Webhook URLs are masked.
list_membersList all members of a Pincushion project with their roles, plus seat usage info.
preview_collaboration_notificationPreview the Slack, Teams, or Discord notification shape and recommended event routing before connecting a real webhook.
record_pin_verificationRecord the outcome of Pincushion AI's post-deploy verification on a resolved pin. Called by the critic subagent after running auto-critique on a fresh deploy. Lets stakeholders see "Pincushion AI verified this fix" (or regressed/inconclusive) directly on the pin in the dashboard, closing the "did my feedback actually ship correctly?" loop.
remove_collaboration_integrationRemove a Slack, Microsoft Teams, or Discord webhook subscription from a Pincushion project.
remove_memberRemove a collaborator from a Pincushion project. Frees up the seat if they were an editor.
resolve_annotationMark an annotation as resolved after addressing the feedback. Optionally add a resolution comment explaining what was changed.
resolve_quickstart_demoFinish the quickstart demo loop after editing the demo copy. Confirms the change, returns the bridge to real usage, and cleans up the throwaway .feedback/.quickstart/ files. Does NOT create or resolve any real pin.
search_annotationsFull-text search across all annotation comments, selectors, component names, and tags.
set_slack_preferencesRead or update the caller's Slack DM preferences. Resolves the user via license_key → email, then applies the change across every Slack workspace the email is linked to. Call with no args to see current state. Call with mute: "1h" (or "today", "forever", "off") to silence DMs for a window. Call with eventNewPin: false (or any event_* flag) to toggle individual event types off. Same surface as the App Home toggles and /pincushion mute, accessible from the agent — useful for "mute pin DMs during this refactor" workflows.
start_quickstart_demoStart the 60-second Pincushion quickstart: returns one sample stakeholder feedback pin (element selector + thread + acceptance criteria) on a bundled demo page that is copied to .feedback/.quickstart/landing.html. Edit ONLY that copy to satisfy the pin, then call resolve_quickstart_demo. Nothing is written to the real project or synced to the cloud. Use this to show a new user the full read-pin -> fix-code -> resolve loop.
update_critique_contextLightweight write-only path for the layered critique-context system. Use this from /setup and /refresh-brand after the dev agent has gathered repo signals (README, theme tokens, sample copy, competitor URLs, recent resolved pins) and compiled them into a critique brief. Unlike configure_project, this does NOT create a deploy hook, sync members, or validate URLs — it just persists the compiled brief (+ signals + policy) and pushes to cloud. Identify the project by projectId or name. The compiled critiqueContext is what the AI critic actually reads at pin time; critiqueSignals + critiquePolicy are inputs retained for traceability and the next recompile.
upload_page_snapshotUpload a full-page screenshot that turns the public share report into an annotated page: viewers see the real page with numbered pin markers at true positions and click-to-open thread bubbles. Capture the page yourself (kill animations, scroll to force lazy loads, full-page shot, JPEG/WebP ≤5MB), resolve each open pin's element.selector to document-pixel coordinates IN THAT CAPTURE, and pass them as pinPositions. Owner/editor only. One snapshot per (project, page) — re-upload replaces it. pageUrl must match the pins' page_url verbatim.
BEFORE YOU INSTALL
43 tools when we connected. get_time_to_fix_metrics is a Pro/Team feature: without --license-key it returns only a sample size and an upgrade hint.
Node.js 18+
CONTEXT COST
Rated by the size of the 43 tool definitions that ride along on every turn, not by how many there are
INSTALLATION
npx pincushion-mcp --project-dir .{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": [
"pincushion-mcp",
"--project-dir",
"."
]
}
}
}{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": [
"pincushion-mcp",
"--project-dir",
"<YOUR_PATH_TO_PROJECT>"
]
}
}
}claude mcp add pincushion -- npx pincushion-mcp --project-dir .{
"servers": {
"pincushion": {
"command": "npx",
"args": [
"pincushion-mcp",
"--project-dir",
"${workspaceFolder}"
]
}
}
}npx pincushion-mcp --rest --port 3456