Pincushion

Las partes interesadas fijan comentarios en tu aplicación en vivo; tu agente de codificación de IA lo lee a través de MCP y lo corrige.

Documentación

Servidor MCP de Pincushion

La capa de contexto de implementación para el desarrollo nativo con IA. Las partes interesadas colocan pines visuales en cualquier página de tu aplicación en vivo; tu agente de codificación con IA lee cada pin a través de MCP y envía la corrección — en Claude Code, Cursor, VS Code, Windsurf, o cualquier cliente MCP.

Qué hace diferente a un pin de Pincushion

Un pin no es un elemento de retroalimentación — es un paquete de trabajo para el agente. Cada uno lleva todo lo que un agente necesita para implementar el cambio sin idas y vueltas:

  • URL + selector de elemento — exactamente qué, exactamente dónde
  • Captura de pantalla + viewport + fragmento DOM — el contexto visual y estructural
  • Hilo + contexto del proyecto — la conversación y el código base en el que vive
  • Archivos probables + criterios de aceptación — dónde mirar y cómo saber que está hecho

El ciclo se cierra solo: una parte interesada lo fija → tu agente lo lee vía MCP y lo corrige en tu IDE → la resolución registra el commit, la rama y el PR → una crítica opcional post-despliegue verifica que la corrección realmente se aplicó.

Este servidor es también cómo Pincushion AI ejecuta críticas de diseño/texto/accesibilidad en una página en vivo y escribe los pines directamente sobre ella.

Instalación

# npm
npm install -g pincushion-mcp

# pnpm
pnpm add -g pincushion-mcp

# yarn
yarn global add pincushion-mcp

O ejecuta directamente sin instalar:

# npm
npx pincushion-mcp --project-dir .

# pnpm
pnpm dlx pincushion-mcp --project-dir .

# yarn
yarn dlx pincushion-mcp --project-dir .

Inicio rápido

1. Instala la extensión del navegador

Descarga la extensión de Chrome de Pincushion desde pincushion.io/install/chrome.

2. Configura tu agente

Elige tu agente de IA a continuación y sigue la configuración para tu entorno.

3. Comienza a usar

Una vez configurado, tu agente puede:

  • Ver todos los comentarios: get_feedback_summary
  • Encontrar pines específicos: search_annotations
  • Corregir y marcar como hecho: fix_and_resolve

Guías de configuración del agente

Cursor

Archivo: .cursor/mcp.json

{
  "mcpServers": {
    "pincushion": {
      "command": "npx",
      "args": ["pincushion-mcp", "--project-dir", "."]
    }
  }
}

Usuarios de pnpm / yarn: reemplaza "command": "npx" con "command": "pnpm" y agrega "dlx" como primer argumento, o usa "command": "yarn" con "dlx" de manera similar.

Con sincronización de Supabase:

{
  "mcpServers": {
    "pincushion": {
      "command": "npx",
      "args": [
        "pincushion-mcp",
        "--project-dir", ".",
        "--sync-url", "https://your-supabase.com/api",
        "--api-key", "YOUR_API_KEY"
      ]
    }
  }
}

Claude Desktop

Archivo: ~/.config/Claude/claude_desktop_config.json (Linux/Windows) o ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

{
  "mcpServers": {
    "pincushion": {
      "command": "npx",
      "args": ["pincushion-mcp", "--project-dir", "/path/to/your/project"]
    }
  }
}

Usuarios de pnpm:

{
  "mcpServers": {
    "pincushion": {
      "command": "pnpm",
      "args": ["dlx", "pincushion-mcp", "--project-dir", "/path/to/your/project"]
    }
  }
}

Usuarios de yarn:

{
  "mcpServers": {
    "pincushion": {
      "command": "yarn",
      "args": ["dlx", "pincushion-mcp", "--project-dir", "/path/to/your/project"]
    }
  }
}

Con sincronización de Supabase:

{
  "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)

Ejecuta este comando para agregar Pincushion a Claude Code:

claude mcp add pincushion -- npx pincushion-mcp --project-dir .

O con sincronización de Supabase:

claude mcp add pincushion -- npx pincushion-mcp --project-dir . --sync-url https://your-supabase.com/api --api-key YOUR_API_KEY

VS Code (Copilot / Continue)

Archivo: .vscode/settings.json

{
  "mcp.servers": {
    "pincushion": {
      "command": "npx",
      "args": ["pincushion-mcp", "--project-dir", "${workspaceFolder}"]
    }
  }
}

Windsurf / Codeium Windsurf

Archivo: ~/.windsurf/mcp.json o ~/.config/windsurf/mcp.json

{
  "mcpServers": {
    "pincushion": {
      "command": "npx",
      "args": ["pincushion-mcp", "--project-dir", "."]
    }
  }
}

Antigravity

Archivo: ~/.antigravity/mcp.json

{
  "mcpServers": {
    "pincushion": {
      "command": "npx",
      "args": ["pincushion-mcp", "--project-dir", "."]
    }
  }
}

OpenAI Codex / Clientes de API REST

Para herramientas que no soportan MCP directamente, usa el envoltorio de API REST:

npx pincushion-mcp --rest --port 3456

Esto inicia un servidor HTTP en localhost:3456. Endpoints:

  • GET /health — Verificar el estado del servidor
  • POST /call-tool — Invocar una herramienta
    • Cuerpo: { "toolName": "get_feedback_summary", "args": {} }

Ejemplo usando curl:

curl -X POST http://localhost:3456/call-tool \
  -H "Content-Type: application/json" \
  -d '{"toolName": "get_feedback_summary", "args": {}}'

Opciones de CLI

npx pincushion-mcp [flags]
FlagDescripciónPredeterminado
--project-dir PATHDirectorio raíz que contiene .feedback/Directorio de trabajo actual
--sync-url URLEndpoint de API de Supabase para sincronización remotaNinguno (solo local)
--api-key KEYClave de API para autenticación de SupabaseNinguno
--license-key KEYClave de licencia Pro (opcional)Ninguno
--restHabilitar modo de API RESTDeshabilitado (usa MCP/stdio)
--port PORTPuerto para el servidor de API REST3456

Ejemplos

Proyecto local:

npx pincushion-mcp --project-dir /path/to/project

Con sincronización de Supabase:

npx pincushion-mcp \
  --project-dir /path/to/project \
  --sync-url https://abcd1234.supabase.co/api \
  --api-key sb_project_key_abc123...

Servidor de API REST:

npx pincushion-mcp --rest --port 8080

Herramientas

get_annotations

Recupera anotaciones de .feedback/. Filtra por página, componente o estado.

Parámetros:

  • pageUrl (cadena, opcional) — Filtrar por URL de página (coincidencia parcial)
  • componentName (cadena, opcional) — Filtrar por nombre de componente LWC
  • status (cadena, opcional) — Filtrar por open, in-progress o resolved

Ejemplo:

await mcp.callTool('get_annotations', {
  componentName: 'wmlHomePage',
  status: 'open'
});

search_annotations

Búsqueda de texto completo en todas las anotaciones, comentarios, selectores y etiquetas.

Parámetros:

  • query (cadena, obligatorio) — Término de búsqueda

Ejemplo:

await mcp.callTool('search_annotations', {
  query: 'button label'
});

get_feedback_summary

Resumen de alto nivel de todos los comentarios: recuentos por estado, prioridad, página y componente.

Ejemplo:

await mcp.callTool('get_feedback_summary', {});

get_component_feedback

Obtén todos los comentarios para un componente LWC específico con un resumen en lenguaje sencillo.

Parámetros:

  • componentName (cadena, obligatorio) — Nombre del componente LWC

Ejemplo:

await mcp.callTool('get_component_feedback', {
  componentName: 'wmlHomePage'
});

resolve_annotation

Marca una anotación como resuelta después de corregir el problema.

Parámetros:

  • annotationId (cadena, obligatorio) — ID de anotación
  • comment (cadena, opcional) — Mensaje de resolución
  • resolvedBy (cadena, opcional) — Nombre para atribuir la resolución (predeterminado: "AI Agent")

Ejemplo:

await mcp.callTool('resolve_annotation', {
  annotationId: 'ann_abc123',
  comment: 'Updated button label in line 42 of wmlHomePage.js'
});

add_agent_reply

Agrega una respuesta a un hilo de anotación (por ejemplo, hacer preguntas aclaratorias).

Parámetros:

  • annotationId (cadena, obligatorio) — ID de anotación
  • body (cadena, obligatorio) — Mensaje de respuesta
  • author (cadena, opcional) — Nombre del autor (predeterminado: "AI Agent")

Ejemplo:

await mcp.callTool('add_agent_reply', {
  annotationId: 'ann_abc123',
  body: 'Is this button in the main navigation or sidebar?'
});

fix_and_resolve

Combina la corrección de código y el marcado de una anotación como resuelta en una sola llamada. Opcionalmente registra metadatos de commit / rama / PR para que el panel pueda enlazar de vuelta a lo que se envió.

Parámetros:

  • annotationId (cadena, obligatorio) — ID de anotación
  • fixDescription (cadena, obligatorio) — Descripción de la corrección
  • filePath (cadena, opcional) — Archivo donde se aplicó la corrección
  • lineNumber (número, opcional) — Número de línea de la corrección
  • commitSha (cadena, opcional) — SHA del commit que aplicó el cambio
  • branchName (cadena, opcional) — Rama en la que se hizo el commit
  • prUrl (cadena, opcional) — URL de la solicitud de extracción (GitHub/GitLab/Bitbucket; validada por forma)

Ejemplo:

await mcp.callTool('fix_and_resolve', {
  annotationId: 'ann_abc123',
  fixDescription: 'Updated button label to match design spec',
  filePath: 'src/components/wmlHomePage.js',
  lineNumber: 42,
  commitSha: 'abc123def456',
  branchName: 'pincushion/checkout-fix',
  prUrl: 'https://github.com/acme/app/pull/142'
});

get_implementation_packet

Obtén un paquete de implementación único para una URL de página: lista de selectores, cargas completas de pines, nombre de rama sugerido y configuración de trazabilidad. Úsalo cuando un agente quiera corregir por lotes una página en una sola rama.

await mcp.callTool('get_implementation_packet', { pageUrl: '/checkout' });

assign_pin_to_agent

Envía un pin directamente a tu agente de codificación local. Promueve el pin a ready si aún no lo está, marca pending_implementation y escribe un archivo de activación .feedback/.agent-queue/<id>.json que agent-loop.mjs recoge y ejecuta hacia Cursor / Claude Code / Codex.

await mcp.callTool('assign_pin_to_agent', { annotationId: 'ann_abc123' });

link_pin_deploy

Adjunta una URL de despliegue a un pin resuelto. Normalmente se llama desde la función de borde del gancho de despliegue una vez que producción incluye la corrección, pero también está disponible manualmente.

await mcp.callTool('link_pin_deploy', {
  annotationId: 'ann_abc123',
  deployUrl: 'https://acme-app.vercel.app'
});

record_pin_verification

Escribe el veredicto post-despliegue de Pincushion AI de vuelta al pin. Lo llama el agente crítico después de que /critique-latest-deploy se ejecute contra un despliegue reciente.

await mcp.callTool('record_pin_verification', {
  annotationId: 'ann_abc123',
  status: 'verified',  // or 'regressed' or 'inconclusive'
  notes: 'Button matches the primary token. No regression on adjacent CTAs.'
});

get_time_to_fix_metrics

Función Pro/Equipo — Los llamadores gratuitos obtienen tamaño de muestra + sugerencia de actualización. Mediana + p25/p75 de la duración de pin a resolución, con un mínimo de 5 pines para que la métrica nunca sea ruido.

await mcp.callTool('get_time_to_fix_metrics', { scope: 'project', projectId: 'pc_proj_abc' });
// → { sampleSize, thresholdMet, median, p25, p75, medianHuman, ... }

get_setup_instructions (NUEVO)

Obtén instrucciones de configuración e instalación para todos los agentes compatibles.

Ejemplo:

await mcp.callTool('get_setup_instructions', {});

Integraciones con Slack y Microsoft Teams

Pincushion puede notificar a Slack o Microsoft Teams a través de webhooks entrantes con alcance de proyecto. Los valores predeterminados son intencionalmente discretos e inspirados en Figma: notificar cuando un pin está listo para implementación, cuando alguien es @mencionado y cuando un colaborador agrega seguimiento a un trabajo que ya se está manejando. Cada pin recién colocado y cada resolución son eventos opcionales.

Casos de uso recomendados:

  • Canal de desarrolladores: pin_ready y follow_up
  • Canal de diseño o PM: mention y opcionalmente resolved
  • Canal de lanzamiento o QA: pageUrlPatterns más pin_ready, follow_up y resolved
  • Canal de incidente temporal: habilita una suscripción enfocada y luego pausa después de la ventana de lanzamiento

Ejemplo:

await mcp.callTool('configure_collaboration_integration', {
  projectId: 'my-project',
  provider: 'slack',
  webhookUrl: 'https://hooks.slack.com/services/...',
  targetLabel: '#product-feedback',
  events: ['pin_ready', 'mention', 'follow_up'],
  pageUrlPatterns: ['staging.example.com/checkout'],
  sendTest: true
});

Para Slack, usa create_slack_install_link cuando los secretos de la aplicación Slack alojada estén configurados. Devuelve una URL de Agregar a Slack; después de la aprobación, Slack devuelve el webhook entrante y Pincushion lo almacena automáticamente.

Usa list_collaboration_integrations para auditar los destinos configurados, remove_collaboration_integration para desconectar uno y preview_collaboration_notification para ver la forma del payload antes de agregar un webhook real. Las URL de webhook se almacenan en el servidor y se devuelven solo como valores enmascarados.


Bucle de agente automático (opcional)

Para agentes que no observan el sistema de archivos (Claude Code, Cursor, genéricos), agent-loop.mjs consulta .feedback/.agent-queue/ y envía nuevos pines al agente configurado automáticamente.

# from inside the pincushion-mcp directory
npm run agent-loop -- --project-dir /path/to/your/project

# or directly
node agent-loop.mjs --project-dir /path/to/your/project [--agent claude-code|cursor|generic] [--interval 3000]

El puente (server.js) escribe un archivo de activación por pin aprobado en .feedback/.agent-queue/. El bucle los lee, construye un prompt con el hilo del pin + selector de elemento, y ejecuta el agente elegido. El agente usa herramientas MCP (claim_pin → corregir → fix_and_resolve) y el archivo de cola se elimina cuando el pin se cierra.

detectAgent() detecta automáticamente claude o cursor en el PATH; recurre a generic (escribe el prompt en .feedback/.agent-prompt y stdout). Ejecuta con --interval 3000 para controlar la cadencia de consulta.


Estructura de archivos local

El servidor lee anotaciones de .feedback/ en tu proyecto:

.feedback/
├── annotations/
│   ├── example-com-login.json
│   ├── example-com-dashboard.json
│   └── ...
└── index.json

Cada archivo de anotación contiene:

{
  "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"
        }
      ]
    }
  ]
}

Sincronización de Supabase

Para sincronizar anotaciones con una base de datos remota de Supabase:

  1. Configura un proyecto de Supabase en supabase.com
  2. Crea una tabla annotations con columnas que coincidan con el esquema de anotaciones
  3. Genera una clave de API desde la configuración de tu proyecto
  4. Configura el servidor con --sync-url y --api-key

Ejemplo:

npx pincushion-mcp \
  --project-dir . \
  --sync-url https://your-project.supabase.co/rest/v1 \
  --api-key sb_project_key_abc123...

El servidor fusiona los archivos locales .feedback/ con los datos remotos, y los remotos tienen prioridad en actualizaciones más recientes.


Licencia Pro

Pincushion Pro incluye funciones adicionales. Actívalo con --license-key:

npx pincushion-mcp --project-dir . --license-key YOUR_PRO_KEY

Solución de problemas

Error "Módulo no encontrado"

Asegúrate de tener Node.js 18+ instalado:

node --version

Instala las dependencias:

npm install @modelcontextprotocol/sdk

Las anotaciones no aparecen

Verifica que .feedback/ exista en el directorio de tu proyecto:

ls -la .feedback/

Si no existe, créalo y agrega algunas anotaciones de prueba, o la extensión lo creará cuando fijes tu primer comentario.

La sincronización de Supabase no funciona

Verifica tus credenciales:

curl -H "x-api-key: YOUR_API_KEY" \
  https://your-project.supabase.co/rest/v1/annotations

El agente no puede encontrar el servidor

En la configuración de tu agente, usa la ruta completa a pincushion-mcp:

which pincushion-mcp
# Use the output path in your config

O usa npx para que encuentre el paquete:

{
  "command": "npx",
  "args": ["pincushion-mcp", "--project-dir", "."]
}

Desarrollo

Clona el repositorio e instala las dependencias:

git clone https://github.com/jcooley8/pincushion-plugin.git
cd pincushion-plugin
npm install

Ejecuta el servidor:

npm start

O con datos de prueba:

npm start -- --project-dir ./test-feedback

Licencia

Licencia MIT. Consulta el archivo LICENSE para más detalles.


Soporte


Registro de cambios

v1.0.0 (marzo de 2026)

  • Lanzamiento inicial
  • Soporte para Cursor, Claude Desktop, Claude Code, VS Code, Windsurf, Antigravity
  • Soporte de archivo local .feedback/
  • Sincronización remota de Supabase
  • Envoltorio de API REST para clientes no MCP
  • Nuevas herramientas: fix_and_resolve, get_setup_instructions