The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Pincushion Plugin listing page.
The implementation-context layer for AI-native development. Stakeholders drop visual pins on any page of your live app; your AI coding agent reads each pin through MCP and ships the fix — in Claude Code, Cursor, VS Code, Windsurf, or any MCP client.
A pin isn't a feedback item — it's an agent work packet. Each one carries everything an agent needs to implement the change without a back-and-forth:
The loop closes itself: a stakeholder pins it → your agent reads it via MCP and fixes it in your IDE → the resolve records the commit, branch, and PR → an optional post-deploy critique verifies the fix actually landed.
This server is also how Pincushion AI runs design/copy/a11y critiques on a live page and writes the pins straight back onto it.
Or run directly without installing:
Download the Pincushion Chrome extension from pincushion.io/install/chrome.
Pick your AI agent below and follow the configuration for your setup.
Once configured, your agent can:
get_feedback_summarysearch_annotationsfix_and_resolveFile: .cursor/mcp.json
pnpm / yarn users: replace
"command": "npx"with"command": "pnpm"and add"dlx"as the first arg, or use"command": "yarn"with"dlx"likewise.
With Supabase sync:
File: ~/.config/Claude/claude_desktop_config.json (Linux/Windows)
or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
pnpm users:
yarn users:
With Supabase sync:
Run this command to add Pincushion to Claude Code:
Or with Supabase sync:
File: .vscode/settings.json
File: ~/.windsurf/mcp.json or ~/.config/windsurf/mcp.json
File: ~/.antigravity/mcp.json
For tools that don't support MCP directly, use the REST API wrapper:
This starts an HTTP server on localhost:3456. Endpoints:
GET /health — Check server statusPOST /call-tool — Invoke a tool
{ "toolName": "get_feedback_summary", "args": {} }Example using curl:
| Flag | Description | Default |
|---|---|---|
--project-dir PATH | Root directory containing .feedback/ | Current working directory |
--sync-url URL | Supabase API endpoint for remote sync | None (local only) |
--api-key KEY | API key for Supabase authentication | None |
--license-key KEY | Pro license key (optional) | None |
--rest | Enable REST API mode | Disabled (uses MCP/stdio) |
--port PORT | Port for REST API server | 3456 |
Local project:
With Supabase sync:
REST API server:
get_annotationsRetrieve annotations from .feedback/. Filter by page, component, or status.
Parameters:
pageUrl (string, optional) — Filter by page URL (partial match)componentName (string, optional) — Filter by LWC component namestatus (string, optional) — Filter by open, in-progress, or resolvedExample:
search_annotationsFull-text search across all annotations, comments, selectors, and tags.
Parameters:
query (string, required) — Search termExample:
get_feedback_summaryHigh-level rollup of all feedback: counts by status, priority, page, and component.
Example:
get_component_feedbackGet all feedback for a specific LWC component with a plain-language summary.
Parameters:
componentName (string, required) — LWC component nameExample:
resolve_annotationMark an annotation as resolved after fixing the issue.
Parameters:
annotationId (string, required) — Annotation IDcomment (string, optional) — Resolution messageresolvedBy (string, optional) — Name to attribute resolution (default: "AI Agent")Example:
add_agent_replyAdd a reply to an annotation thread (e.g., ask clarifying questions).
Parameters:
annotationId (string, required) — Annotation IDbody (string, required) — Reply messageauthor (string, optional) — Author name (default: "AI Agent")Example:
fix_and_resolveCombine fixing code and marking an annotation as resolved in one call. Optionally records commit / branch / PR metadata so the dashboard can backlink to what shipped.
Parameters:
annotationId (string, required) — Annotation IDfixDescription (string, required) — Description of the fixfilePath (string, optional) — File where fix was appliedlineNumber (number, optional) — Line number of the fixcommitSha (string, optional) — Commit SHA that landed the changebranchName (string, optional) — Branch the commit was made onprUrl (string, optional) — Pull request URL (GitHub/GitLab/Bitbucket; shape-validated)Example:
get_implementation_packetFetch a single implementation packet for one page URL — selector list, full pin payloads, suggested branch name, and traceability config. Use when an agent wants to batch-fix one page in a single branch.
assign_pin_to_agentDispatch a pin straight to your local coding agent. Promotes the pin to ready if not already, marks pending_implementation, and writes a .feedback/.agent-queue/<id>.json trigger file that agent-loop.mjs picks up and shells out to Cursor / Claude Code / Codex.
link_pin_deployAttach a deploy URL to a resolved pin. Typically called by the deploy-hook edge function once production includes the fix, but available manually too.
record_pin_verificationWrite Pincushion AI's post-deploy verdict back to the pin. Called by the critic agent after /critique-latest-deploy runs against a fresh deploy.
get_time_to_fix_metricsPro/Team feature — Free callers get sample size + upgrade hint. Median + p25/p75 of pin-to-resolve duration, with a 5-pin minimum so the metric is never noise.
get_setup_instructions (NEW)Get setup and configuration instructions for all supported agents.
Example:
Pincushion can notify Slack or Microsoft Teams through project-scoped incoming webhooks. The defaults are intentionally quiet and Figma-inspired: notify when a pin is ready for implementation, when someone is @mentioned, and when a collaborator adds follow-up on work already being handled. Every newly dropped pin and every resolution are opt-in events.
Recommended use cases:
pin_ready and follow_upmention and optionally resolvedpageUrlPatterns plus pin_ready, follow_up, and resolvedExample:
For Slack, use create_slack_install_link when the hosted Slack app secrets are configured. It returns an Add-to-Slack URL; after approval, Slack returns the incoming webhook and Pincushion stores it automatically.
Use list_collaboration_integrations to audit configured destinations, remove_collaboration_integration to disconnect one, and preview_collaboration_notification to see the payload shape before adding a real webhook. Webhook URLs are stored server-side and returned only as masked values.
For agents that don't watch the file system (Claude Code, Cursor, generic),
agent-loop.mjs polls .feedback/.agent-queue/ and dispatches new pins
to the configured agent automatically.
The bridge (server.js) writes one trigger file per approved pin into
.feedback/.agent-queue/. The loop reads them, builds a prompt with
the pin's thread + element selector, and shells out to the chosen agent.
The agent uses MCP tools (claim_pin → fix → fix_and_resolve) and
the queue file is removed when the pin closes.
detectAgent() auto-detects claude or cursor on the PATH; falls
back to generic (writes the prompt to .feedback/.agent-prompt and
stdout). Run with --interval 3000 to control poll cadence.
The server reads annotations from .feedback/ in your project:
Each annotation file contains:
To sync annotations with a remote Supabase database:
annotations table with columns matching the annotation schema--sync-url and --api-keyExample:
The server merges local .feedback/ files with remote data, with remote taking precedence on newer updates.
Pincushion Pro includes additional features. Activate with --license-key:
Make sure you have Node.js 18+ installed:
Install dependencies:
Check that .feedback/ exists in your project directory:
If it doesn't exist, create it and add some test annotations, or the extension will create it when you pin your first feedback.
Verify your credentials:
In your agent config, use the full path to pincushion-mcp:
Or use npx to let it find the package:
Clone the repository and install dependencies:
Run the server:
Or with test data:
MIT License. See LICENSE file for details.
.feedback/ file supportfix_and_resolve, get_setup_instructions