Every web project has the same weird gap.
A stakeholder sees something on a page and knows exactly what feels wrong:
- "This headline is too vague."
- "Move this CTA closer to the pricing table."
- "This form label reads like an internal field name."
- "This is the wrong button."
But by the time that feedback reaches the developer, it has usually been turned into a screenshot, a Slack thread, a Loom, a Jira ticket, or a sentence like "can we tweak this?"
That handoff loses the most important part: the exact element on the exact page in the exact state where the feedback happened.
I built Pincushion to test a different shape:
- A reviewer drops a visual pin on a live or staging page.
- The pin captures implementation context: URL, selector, XPath, viewport, browser, screenshot, and the comment thread.
- An AI coding agent reads that pin through MCP.
- The agent implements the fix in the repo.
- The commit and pin resolution close the loop.
The interesting part is not "visual feedback tool." Those already exist. The interesting part is treating a pin as an agent work packet.
Why screenshots are a bad substrate for agents
Screenshots are useful for humans. They are lossy for coding agents.
If I send an agent a screenshot and say "change this," the model has to infer:
- Which route or page this is.
- Which DOM element is being referenced.
- Which source file owns that element.
- Whether the issue is copy, layout, state, accessibility, or data.
- What the stakeholder meant by the words around the screenshot.
Sometimes it gets there. Sometimes it works on the wrong component.
The fix was not to make the model better at reading screenshots. The fix was to stop using screenshots as the handoff format.
When a pin is dropped, Pincushion captures structured context:
{
"pageUrl": "https://example.com/pricing",
"selector": "main section.pricing button.primary",
"xpath": "/html/body/main/section[3]/button",
"viewport": { "width": 1440, "height": 900 },
"browser": "Chrome",
"thread": [
{
"author": "Sarah",
"body": "This CTA should explain the trial. Try 'Start free project'."
}
]
}
That is a much better input for an agent than a rectangle of pixels.
Why MCP was the right layer
The first version of this idea could have been a dashboard, webhook, or browser automation flow. I avoided that.
AI coding agents already have the tools that matter:
- read files
- edit files
- run tests
- inspect git state
- make commits
The missing tool is not "drive a browser." The missing tool is "read the user's implementation intent."
MCP is a clean place to expose that intent. The Pincushion MCP server gives an agent tools like:
get_actionable_pins
implement_approved_pins
claim_pin
add_agent_reply
fix_and_resolve
The agent does not need to scrape a dashboard. It calls a tool, receives the work packet, and operates in the repo where it already has context.
The command I use most is effectively:
/implement
Behind that, the MCP server returns approved pins grouped by page, with selectors, thread context, and traceability data. The agent claims the pin, writes the change, and resolves it when the fix is done.
Design decision: thread context matters
At first I thought the pin body would be enough.
It was not.
The difference between:
Make this less vague.
and:
Make this less vague.
Sarah: The user already chose a plan by this point.
Josh: Good point. The CTA should confirm the next step, not resell the plan.
is huge.
Agents write better diffs when they have the "why," not just the "what." That is why implement_approved_pins returns the surrounding thread, not only the latest comment.
Design decision: fewer tools are better
Early MCP surfaces tend to expose every backend verb:
- get annotations
- list annotations
- update annotation
- approve annotation
- claim annotation
- resolve annotation
- search annotations
That makes sense to a human API designer. It is not always best for an agent.
For implementation work, the agent usually needs a smaller set of intent-shaped tools:
- "What should I work on?"
- "Give me the implementation packet."
- "Mark that I am working on this."
- "Resolve it with a trace."
The more generic the tool surface, the more likely the agent is to choose the wrong tool or do extra work.
The lesson: design MCP tools around agent decisions, not database tables.
Design decision: no stakeholder diff approval
I originally had a preview/approval flow.
The idea was:
- Agent proposes a diff.
- Stakeholder approves the diff.
- Agent lands the change.
It sounded responsible. It was wrong.
Most stakeholders do not read diffs. The preview step created a fake sense of safety and added another wait state.
The human reviewer who matters is the developer who merges the commit or PR. For Pincushion, the right loop is:
- Stakeholder expresses intent visually.
- Agent turns intent into a code change.
- Developer reviews the code.
- Pin resolution records what shipped.
No fake approval ceremony in the middle.
What I am testing now
Pincushion is soft launched. The Chrome extension is live, the MCP server is on npm, and I am looking for early testers.
The test I care about is not "does the landing page convert?"
The test is:
- Can a developer install it without help?
- Can a stakeholder drop a useful pin?
- Can Cursor, Claude Code, Codex, VS Code Copilot, or Windsurf read the pin?
- Can the agent implement a real change with less clarification than a screenshot or Slack thread?
- Does the resolved pin give the team enough traceability?
If you build web apps with non-technical feedback loops and want to try it, the ask is simple: use it on one real page, drop 1-3 pins, and tell me where the loop breaks.
Link: https://pincushion.io
The broader bet
Most feedback tools are built around dashboards.
That made sense when humans were the only implementation path. But if the person doing the first pass is an AI coding agent, the dashboard should not be the center of gravity.
The center of gravity should be the IDE and the repo.
That is the bet behind Pincushion: visual feedback is not a ticket. It is an agent-ready work packet.
Top comments (0)