Keelen vs Pincushion Plugin

A side-by-side look at the Keelen and Pincushion Plugin MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.

Keelen logoKeelenCoding Agents · Remote HTTP/SSEAutonomous dev team steered from chat: plain-English requests in, tested merged PRs out.57GoodAuth: not declaredPincushion Plugin logoPincushion PluginCoding Agents · Local subprocess (stdio)Visual feedback as agent work packets. Stakeholders drop pins on your live app; your AI coding agent reads each pin (selector, screenshot, DOM snippet, thread, acceptance criteria) via MCP and ships the fix, recording the commit/branch/PR on resolve. Install: npx pincushion-mcp.64GoodAuth: no auth required

Verdict: choose Keelen for coding agents work over a hosted endpoint; choose Pincushion Plugin for coding agents as a local process. You can also run both side by side in one mcpServers block.

Which MCP server should you choose?

Keelen logoChoose Keelen when

  • You need dedicated capabilities in the Coding Agents domain.
  • You prefer a remote HTTP/SSE transport.
  • You want tools like list_projects, create_project, submit_request.
Explore Keelen

Pincushion Plugin logoChoose Pincushion Plugin when

  • You need dedicated capabilities in the Coding Agents domain.
  • You prefer a local stdio subprocess transport.
  • Its auth model fits you: No auth required.
  • You want tools like get_annotations, search_annotations, get_feedback_summary.
Explore Pincushion Plugin

Feature & specification comparison

Rows where the two servers differ are marked.

SpecKeelen logoKeelenPincushion Plugin logoPincushion Plugin
CategoryCoding AgentsCoding Agents
Quality signal57/100 · Good64/100 · Good
Install commandConfirmedConfirmed
TransportRemote HTTP/SSELocal subprocess (stdio)
AuthNot declaredNo auth required
PricingBYOK (pay the provider)Freemium
Required env varsNone listedNone listed
Verified ownerCommunity listingCommunity listing
GitHub stars01
Directory activity 0 views 0 installs 0 upvotes 1 views 0 installs 0 upvotes
Tools4965

Tools & capabilities

Keelen tools 49

  • list_projectsList the projects in this workspace, with what each one is building.
  • create_projectStart building something new: creates a GitHub repo and begins work on it. For a NEW repo. Given an existing repo, import_project(repo_full_name) is the right call — this one would create a second, empty repo beside it (list_github_repos() browses what the workspace can see). Scaffolds a new GitHub repo, a bootstrap-mode project, and submits `build_description` as the project's first Roadmap Request. `name` is a concise GitHub short repo slug (no owner); `project_kind` is REQUIRED and one of library | node_library | python_library | service | cli | web_app | godot_game | roblox_game; `preview_command` is required iff `project_kind == 'web_app'`. `engine` is OPTIONAL — one of claude_code | codex | glm | kimi | grok (defaults to claude_code); codex, glm, kimi, and grok require the workspace to have a matching connected credential. `org` is OPTIONAL — a GitHub organization login to create the repo inside (e.g. your company org); omit it to land the repo on a member's personal account. `private` defaults to True. `ci_runs_on` is OPTIONAL — the CI runner labels for the scaffolded workflow, e.g. ["self-hosted", "linux", "x64", "my-fleet"]. Omit it to inherit the workspace default (ubuntu-latest if unset). Labels no registered org runner carries are rejected, because GitHub would queue such a job forever rather than fail it. `framework` is OPTIONAL and `web_app`-only — one of vite | next (defaults to vite). It picks the scaffolded frontend rails: `vite` a vanilla-TypeScript SPA, `next` a Next.js app-router app. Passing it with any other `project_kind` is an error. The repo is created on the GitHub account of a workspace member with repo-create OAuth access (this path has no specific caller user), so the returned `repo` owner is whichever member's token resolved (or the chosen `org`). If no member has repo-create access — or the resolving member can't create in `org` — the call returns an actionable error. Returns {project_id, repo, thread_id, next_action, poll_after_seconds, next_step}; next_step names the follow-up poll of get_request_status with the returned thread_id. On the rare arm where the first Request failed to submit, next_action is "call_tool" with next_tool="submit_request". If scaffolding fails after the repository has been created, best-effort compensation deletes that just-created repository so a retry can reuse the name — this tool can therefore remove external state it created moments earlier.
  • submit_requestAsk for a change in plain English: a feature, a bug fix, or a new direction. Each call carries ONE feature or intent; a multi-feature ask belongs in separate requests. `text` must be under 16000 characters. Returns {thread_id, status, next_action, poll_after_seconds, next_step}; next_step names the re-check of get_request_status after poll_after_seconds.
  • get_request_statusCheck what happened to a request, and read any questions it asked back. Intake is async (~5min cadence), so the status changes between calls. `next_action` is one of: "wait" (still processing), "answer_questions" (answer_request takes one answer per question), "done" (see generated_roadmap_item_ids), "cancelled" (terminal, no items), "failed" (see intake_failure_reason), "approve_plan" (a planned request's plan awaits the user's approval in the dashboard). A planned request also carries `stage`, `plan_cycle` and `max_cycles`.
  • set_product_visionSay what this product is for, so every run knows what it is building toward. `vision_md` is free-form markdown and must be non-empty. Tenant-scoped: a project not in the caller's workspace 404s. Returns {project_id, product_vision_md, updated_at, next_step}.
  • set_product_goalSet the outcome to aim at right now, so work is prioritised toward one thing. `goal_md` is free-form markdown and must be non-empty. Tenant-scoped: a project not in the caller's workspace 404s. Returns {project_id, product_goal_md, updated_at, next_step}.
  • list_roadmapSee what is planned for a project and in what order. Queued rows also say whether the expand picker would elect them (`electable`) and, when not, why it skips them (`skip_reason`: awaiting_intake_thread | awaiting_clarification | crash_capped | noop_capped | crash_cooldown | noop_cooldown | held_on_open_pr | other). The first reason that applies, in that order, is the one returned. `awaiting_clarification` means the planner asked a planning question about the item and waits for the answer: `list_escalations` returns that card with the item's `roadmap_item_id`. A skipped item ahead of yours does not delay it.
  • reorder_roadmapChange what gets built first. `ordered_ids` is the desired front-to-back order of queued roadmap-item ids (list_roadmap returns them). The first id becomes the highest priority — the cadence expands the lowest-priority_int queued item next. Horizon pins still dominate: a pinned-later item stays at the back and a pinned-now item at the front, regardless of position in `ordered_ids`. Ids that are unknown or no longer queued are skipped; duplicates are rejected. Returns {updated, queue, next_step}.
  • cancel_roadmap_itemCancel / close a single roadmap item (list_roadmap returns its id). For a DELIVERED or duplicate item that keeps re-parking: once the work has shipped, every expand produces no dev-ready tasks and files a recurring `roadmap_item_parked` escalation that has to be acked. Cancelling drops the item out of the expand queue AND resolves any open expand-lane escalation for it. Business-level replay guard: an already expanded/cancelled item changes no state, and the dashboard can restore a cancelled item. Refuses (409) while the item is actively being expanded (a retry once that iteration ends succeeds). Returns {id, status, changed, next_step}.
  • clear_horizon_pinClear a queued roadmap item's horizon pin (now/next/later → none). A horizon pin dominates the queue sort, so `reorder_roadmap` cannot move a pinned item out of its band — a stale `now` pin on a delivered/duplicate item clogs the front of the queue. This unpins it and reprices the queue so the item follows plain priority order again (and reorder_roadmap can then move it). Only queued items carry a settable pin (in-flight / shipped items derive theirs), so this refuses (422) on a non-queued item — a delivered item is closed with cancel_roadmap_item. Returns {id, previous_pin, horizon_pin, next_step}.
  • rollback_roblox_placeRoll a Roblox project's place back to a previously-published version. For a `roblox_game` project, re-publishes the RETAINED build artifact for `version_number` (the web Roblox Publishing card lists published versions) — it never rebuilds from source, so rollback is fast + deterministic. This mints a NEW Roblox version pointing at the old build. Unknown version → 404; a version with no retained artifact → 422; a place open in Studio / rate-limited → 409 (a retry can succeed); an invalid or unscoped Open Cloud key → 409 / 403. Returns {version_number, env, published_at, status, next_step}.
  • project_statusCheck how a project is doing: what is in flight, what shipped, what is stuck. Returns lifecycle status, open task count, queued roadmap item count, runs today, verification pass rate, open blockers, pause state, and freshness. Zero `open_tasks` does not mean an empty roadmap: `queued_roadmap_items` counts planned work awaiting expansion, including work held while the scheduler is disabled. list_roadmap returns those items. `glm_peak_paused` is NOT a fault and sets no pause columns: it is the ephemeral GLM peak-hours skip. True means clean PRs hold and runs stop until `glm_peak_resumes_at`. It is an intentional cost gate, so the accurate description is "waiting for off-peak", not a failure. For `web_app` projects the optional `ui_review` block can mint a GitHub installation token and read the default branch's `ui-review.json`, so this status call is not guaranteed to be a purely local read. `model_roles` (only when the Researcher/Integrator feature is enabled for the project) reports each optional stage's on/off configuration and last outcome.
  • +37 more on the listing page

Pincushion Plugin tools 65

  • 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.
  • search_annotationsFull-text search across all annotation comments, selectors, component names, and tags.
  • 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_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.
  • resolve_annotationMark an annotation as resolved after addressing the feedback. Optionally add a resolution comment explaining what was changed.
  • add_agent_replyAdd a reply to an annotation thread (e.g. to ask a clarifying question or note a finding).
  • 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.
  • 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).
  • get_pending_critiquesUsed by /critique-latest-deploy. Lists pending critique requests queued by the deploy-hook for the current license. Newer receipts also include a deployment event, prior page outcomes, project-page inventory, and latest per-device capture receipts for truthful local reconciliation before Crit runs. 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_pending_deployment_frame_refreshesLists production deployment frame-refresh work independently of the Critique queue. Use this even when autoCritique is false. The result is redacted: it contains no deployment URL/hash, browser state, storage path, or capture proof. Start a selected run before capturing.
  • start_deployment_capture_runStarts one short-lived local frame-refresh run for an exact deployment and returns its opaque proof once. Keep the proof only in process and pass it to authenticated upload_page_snapshot/record_deployment_page_result/complete_deployment_capture_run calls; never put it in capture-snapshot, shell argv, a report, pin, status message, or file.
  • complete_deployment_capture_runRequests server-side frame-refresh completion after all exact page/device receipts have been recorded. The server rejects missing, stale, replayed, cross-deployment, or expired capture-run evidence and never treats a queue state as a current frame.
  • +53 more on the listing page

Ready-to-paste client configs

Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.

Keelen

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "keelen": {
      "url": "https://keelen.ai/mcp"
    }
  }
}

Pincushion Plugin

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "jcooley8-pincushion-plugin": {
      "command": "npx",
      "args": [
        "-y",
        "pincushion-mcp"
      ]
    }
  }
}

Frequently asked questions

Keelen is categorized under Coding Agents and uses a remote HTTP/SSE transport. Pincushion Plugin belongs to Coding Agents and uses a local stdio subprocess. Pick Keelen for coding agents work and Pincushion Plugin for coding agents.

Copy the mcpServers block from the config section on this page into your client's config (for example claude_desktop_config.json or ~/.cursor/mcp.json), then fully restart the client.

Keelen is bring-your-own-key: usage is billed by the API provider you supply a key for. Pincushion Plugin is listed as freemium — a free tier with paid plans. Auth: no auth required. If a server needs environment variables such as API keys, define them under the env key in your client's MCP config.

Yes. MCP clients support multiple servers: add keelen and jcooley8-pincushion-plugin as separate keys in the same mcpServers object, and your assistant will call tools from either one.

On AllMCPs, Keelen has a quality signal of 57/100 (Good) with 0 views, 0 installs and 0 GitHub stars. Pincushion Plugin has 64/100 (Good) with 1 views, 0 installs and 1 GitHub stars.