pincushion-mcp
v1.0.2
Published
MCP server for PinCushion feedback annotations. Exposes feedback pins from .feedback/ directory to AI agents.
Maintainers
Readme
PinCushion MCP Server
A Model Context Protocol (MCP) server that exposes feedback annotations to AI agents. Connect your PinCushion browser extension to Claude, Cursor, VS Code, or any MCP-compatible tool.
What is PinCushion?
PinCushion is a lightweight browser extension that lets you pin feedback, bugs, and design notes directly on web pages. This MCP server allows AI agents to:
- Read all annotations from your project
- Search feedback by keyword, component, or priority
- Resolve annotations automatically after fixing issues
- Add notes and clarifications to feedback threads
- Get a high-level summary of open feedback
Installation
# npm
npm install -g pincushion-mcp
# pnpm
pnpm add -g pincushion-mcp
# yarn
yarn global add pincushion-mcpOr run directly without installing:
# npm
npx pincushion-mcp --project-dir .
# pnpm
pnpm dlx pincushion-mcp --project-dir .
# yarn
yarn dlx pincushion-mcp --project-dir .Quick Start
1. Install the Browser Extension
Download the PinCushion extension from pincushion.io/extension for Chrome, Firefox, or Safari.
2. Configure Your Agent
Pick your AI agent below and follow the configuration for your setup.
3. Start Using
Once configured, your agent can:
- See all feedback:
get_feedback_summary - Find specific pins:
search_annotations - Fix and mark as done:
fix_and_resolve
Agent Configuration Guides
Cursor
File: .cursor/mcp.json
{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": ["pincushion-mcp", "--project-dir", "."]
}
}
}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:
{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": [
"pincushion-mcp",
"--project-dir", ".",
"--sync-url", "https://your-supabase.com/api",
"--api-key", "YOUR_API_KEY"
]
}
}
}Claude Desktop
File: ~/.config/Claude/claude_desktop_config.json (Linux/Windows)
or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": ["pincushion-mcp", "--project-dir", "/path/to/your/project"]
}
}
}pnpm users:
{
"mcpServers": {
"pincushion": {
"command": "pnpm",
"args": ["dlx", "pincushion-mcp", "--project-dir", "/path/to/your/project"]
}
}
}yarn users:
{
"mcpServers": {
"pincushion": {
"command": "yarn",
"args": ["dlx", "pincushion-mcp", "--project-dir", "/path/to/your/project"]
}
}
}With Supabase sync:
{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": [
"pincushion-mcp",
"--project-dir", "/path/to/your/project",
"--sync-url", "https://your-supabase.com/api",
"--api-key", "YOUR_API_KEY"
]
}
}
}Claude Code (CLI)
Run this command to add PinCushion to Claude Code:
claude mcp add pincushion -- npx pincushion-mcp --project-dir .Or with Supabase sync:
claude mcp add pincushion -- npx pincushion-mcp --project-dir . --sync-url https://your-supabase.com/api --api-key YOUR_API_KEYVS Code (Copilot / Continue)
File: .vscode/settings.json
{
"mcp.servers": {
"pincushion": {
"command": "npx",
"args": ["pincushion-mcp", "--project-dir", "${workspaceFolder}"]
}
}
}Windsurf / Codeium Windsurf
File: ~/.windsurf/mcp.json or ~/.config/windsurf/mcp.json
{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": ["pincushion-mcp", "--project-dir", "."]
}
}
}Antigravity
File: ~/.antigravity/mcp.json
{
"mcpServers": {
"pincushion": {
"command": "npx",
"args": ["pincushion-mcp", "--project-dir", "."]
}
}
}OpenAI Codex / REST API Clients
For tools that don't support MCP directly, use the REST API wrapper:
npx pincushion-mcp --rest --port 3456This starts an HTTP server on localhost:3456. Endpoints:
GET /health— Check server statusPOST /call-tool— Invoke a tool- Body:
{ "toolName": "get_feedback_summary", "args": {} }
- Body:
Example using curl:
curl -X POST http://localhost:3456/call-tool \
-H "Content-Type: application/json" \
-d '{"toolName": "get_feedback_summary", "args": {}}'CLI Flags
npx pincushion-mcp [flags]| 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 |
Examples
Local project:
npx pincushion-mcp --project-dir /path/to/projectWith Supabase sync:
npx pincushion-mcp \
--project-dir /path/to/project \
--sync-url https://abcd1234.supabase.co/api \
--api-key sb_project_key_abc123...REST API server:
npx pincushion-mcp --rest --port 8080Tools
get_annotations
Retrieve 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 byopen,in-progress, orresolved
Example:
await mcp.callTool('get_annotations', {
componentName: 'wmlHomePage',
status: 'open'
});search_annotations
Full-text search across all annotations, comments, selectors, and tags.
Parameters:
query(string, required) — Search term
Example:
await mcp.callTool('search_annotations', {
query: 'button label'
});get_feedback_summary
High-level rollup of all feedback: counts by status, priority, page, and component.
Example:
await mcp.callTool('get_feedback_summary', {});get_component_feedback
Get all feedback for a specific LWC component with a plain-language summary.
Parameters:
componentName(string, required) — LWC component name
Example:
await mcp.callTool('get_component_feedback', {
componentName: 'wmlHomePage'
});resolve_annotation
Mark 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:
await mcp.callTool('resolve_annotation', {
annotationId: 'ann_abc123',
comment: 'Updated button label in line 42 of wmlHomePage.js'
});add_agent_reply
Add 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:
await mcp.callTool('add_agent_reply', {
annotationId: 'ann_abc123',
body: 'Is this button in the main navigation or sidebar?'
});fix_and_resolve (NEW)
Combine fixing code and marking an annotation as resolved in one call.
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 fix
Example:
await mcp.callTool('fix_and_resolve', {
annotationId: 'ann_abc123',
fixDescription: 'Updated button label to match design spec',
filePath: 'src/components/wmlHomePage.js',
lineNumber: 42
});get_setup_instructions (NEW)
Get setup and configuration instructions for all supported agents.
Example:
await mcp.callTool('get_setup_instructions', {});Local File Structure
The server reads annotations from .feedback/ in your project:
.feedback/
├── annotations/
│ ├── example-com-login.json
│ ├── example-com-dashboard.json
│ └── ...
└── index.jsonEach annotation file contains:
{
"pageUrl": "https://example.com/login",
"pageTitle": "Login",
"annotations": [
{
"id": "ann_abc123",
"status": "open",
"priority": "high",
"tags": ["design", "accessibility"],
"createdAt": "2026-03-19T10:30:00Z",
"element": {
"lwcComponent": "wmlLoginForm",
"selector": ".login-button",
"textContent": "Sign In"
},
"thread": [
{
"author": "Design Team",
"timestamp": "2026-03-19T10:30:00Z",
"body": "Button label should say 'Sign In' not 'Login'",
"type": "comment"
}
]
}
]
}Supabase Sync
To sync annotations with a remote Supabase database:
- Set up a Supabase project at supabase.com
- Create an
annotationstable with columns matching the annotation schema - Generate an API key from your project settings
- Configure the server with
--sync-urland--api-key
Example:
npx pincushion-mcp \
--project-dir . \
--sync-url https://your-project.supabase.co/rest/v1 \
--api-key sb_project_key_abc123...The server merges local .feedback/ files with remote data, with remote taking precedence on newer updates.
Pro License
PinCushion Pro includes additional features. Activate with --license-key:
npx pincushion-mcp --project-dir . --license-key YOUR_PRO_KEYTroubleshooting
"Module not found" error
Make sure you have Node.js 18+ installed:
node --versionInstall dependencies:
npm install @modelcontextprotocol/sdkAnnotations not appearing
Check that .feedback/ exists in your project directory:
ls -la .feedback/If it doesn't exist, create it and add some test annotations, or the extension will create it when you pin your first feedback.
Supabase sync not working
Verify your credentials:
curl -H "x-api-key: YOUR_API_KEY" \
https://your-project.supabase.co/rest/v1/annotationsAgent can't find the server
In your agent config, use the full path to pincushion-mcp:
which pincushion-mcp
# Use the output path in your configOr use npx to let it find the package:
{
"command": "npx",
"args": ["pincushion-mcp", "--project-dir", "."]
}Development
Clone the repository and install dependencies:
git clone https://github.com/yourusername/pincushion-mcp.git
cd pincushion-mcp
npm installRun the server:
npm startOr with test data:
npm start -- --project-dir ./test-feedbackLicense
MIT License. See LICENSE file for details.
Support
- Issues: GitHub Issues
- Docs: PinCushion Documentation
- Discord: PinCushion Community
Changelog
v1.0.0 (March 2026)
- Initial release
- Support for Cursor, Claude Desktop, Claude Code, VS Code, Windsurf, Antigravity
- Local
.feedback/file support - Supabase remote sync
- REST API wrapper for non-MCP clients
- New tools:
fix_and_resolve,get_setup_instructions
