Skip to main content
Glama

Voter — a WithVibe plugin

Turn any WithVibe env into a team-voted workspace. When this plugin is enabled, the AI doesn't apply a prompt straight away — it opens a proposal the team votes on, and only an approved proposal gets built. Enable it on any env and that env becomes a vote-gated sandbox.

You (in chat):  "add a dark-mode toggle"
        │
        ▼
   voter_propose_change ──────►  Proposal #7 opens (10-min vote)
        │                           👍 👎  team votes in the panel
   voter_await_decision  ◄───────  APPROVED ✅  /  REJECTED ✗
        │
        ▼  (only if approved)
   agent makes the change  ──►  voter_record_change  ──►  shows up in History

It's content-agnostic — it knows nothing about what the env contains. Whatever the env is (an app, a doc, a 3D scene, a config), enabling Voter makes every change go through the team first. Multiple envs = multiple independent boards.

How the gate works (and why it's just a plugin)

WithVibe auto-injects an enabled plugin's MCP tools into the agent's turn. Voter uses that to gate prompts without any change to WithVibe core:

  1. voter_propose_change(prompt) — opens a proposal and tells the agent to not touch anything yet.

  2. voter_await_decision(proposal_id) — long-polls the vote. The platform's MCP bridge caps a single tool call at 60s, so this returns after ~45s with STILL_VOTING and the agent simply calls it again until it's terminal.

  3. On APPROVED, the agent makes the change and calls voter_record_change. On REJECTED / EXPIRED it makes no change.

Meanwhile every teammate votes in the plugin's own UI panel — independent of the agent. The gate is agent-cooperative (enforced via tool instructions), which is the right trade-off for a friendly workflow; hardening it to be unbypassable is a later option that would need a small core hook.

Related MCP server: jt-mcp-server

MCP tools

Tool

Purpose

voter_propose_change

Open a proposal for the requested change. Agent must call this instead of editing.

voter_await_decision

Long-poll the team's verdict (APPROVED / REJECTED / EXPIRED / STILL_VOTING).

voter_record_change

Record what shipped after applying an approved change.

voter_report_failure

Mark an approved change as failed (e.g. build broke).

voter_status

Show the current board: proposals in voting + recently resolved.

State

Four tables in the plugin's isolated Postgres schema (shared-postgres storage): settings (vote window + thresholds), proposal, vote, feed_event.

Resolution rule: a proposal passes when approvals reach the threshold, fails when rejections reach the threshold, and at the deadline the majority wins (ties expire). Defaults: 600s window, 1 approval / 1 rejection — tune them in the panel.

Architecture

manifest.yaml ──► WithVibe spawns one container per env (scope: env)
       │
   server.js (express)
   ├── /health      platform health probe
   ├── /mcp         agent's MCP endpoint            ─► mcp.js  (the gate)
   ├── /ui          htmx voting panel               ─► ui.js
   └── /ui/version  cheap freshness check (live updates)
                │
              db.js (pg) ─► shared-postgres, per-env schema

Build

docker build -t local/voter:0.1 .

For the marketplace this is published multi-arch as ghcr.io/withvibe/voter:<version>.

Install in WithVibe

  1. Workspace admin → PluginsInstall plugin (or Marketplace once listed).

  2. Paste manifest.yaml (or 1-click install from the catalog).

  3. Open any env → enable Voter → that env is now a vote-gated workspace.

Local development

docker build -t local/voter:0.1 .
docker run --rm -p 8080:8080 \
  -e DATABASE_URL="postgres://user:pass@host.docker.internal:5432/withvibe_plugins" \
  -e PGSCHEMA="voter_dev" \
  local/voter:0.1
# open http://localhost:8080/ui  — two browsers = two voters

Repository layout

manifest.yaml   WithVibe plugin manifest (install input)
Dockerfile      runtime image
package.json    deps (express, pg, @modelcontextprotocol/sdk, zod)
server.js       express entry — HTTP + MCP routes + vote handling
db.js           pg pool, schema, proposal/vote/resolution helpers
mcp.js          the gate: propose / await / record MCP tools
ui.js           htmx voting panel + dark theme

License

Apache License 2.0. See NOTICE for attribution.

A
license - permissive license
-
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

  • A MCP server built for developers enabling Git based project management with project and personal…

  • Official MCP server for Lovable, the AI-powered full-stack app builder.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/withvibe/withvibe-voter'

If you have feedback or need assistance with the MCP directory API, please join our Discord server