Architecture
How core, react, mcp, and the protocol package fit into one pipeline.
VibeCheck is a short, one-directional pipeline. Metrics are measured in the browser, turned into issues, POSTed to a local server, and read back by your coding agent. Four packages divide that work along a single seam: the browser side and the agent side never share a runtime, only a wire contract.
The pipeline
The packages
| Package | Role | Runtime deps |
|---|---|---|
@wcgw/vibe-check-core | Collectors, detectors, VibeCheckEngine, BeaconClient. | Zero. |
@wcgw/vibe-check | React overlay (<VibeCheck />, <PerfToggle />) + hooks. | React 18+ (peer). |
@wcgw/vibe-check-mcp | Shared HTTP hub + stdio bridge exposing nine project-scoped tools. | @modelcontextprotocol/sdk, zod. |
@wcgw/vibe-check-protocol | Snapshots, issues, project envelopes, dispatch results, and lease states. | Zero. Internal — bundled into the others. |
The decoupling seam
The MCP package does not import core. The browser produces a VibeSnapshot,
serializes it to JSON, and POSTs it; the server parses and validates it back
into the same shape. Both sides depend on @wcgw/vibe-check-protocol for that
type — core imports it type-only (preserving its zero-runtime-deps promise),
while mcp also imports the DETECTOR_NAMES and SEVERITIES const arrays to
build its zod validation schema. Deriving both from one source makes drift
between browser and agent a compile error rather than a silent bug.
Why the split matters
You can run any layer on its own: core headless with no UI, the React widget
with no MCP server, or the MCP server with any beacon pointed at it. Nothing
above requires the layer below to be present.
What runs where
- In the browser — collectors measure the page, detectors analyze each
snapshot into issues, the engine orchestrates them, and the beacon (when a
beaconUrlis configured) ships snapshots out. - On your machine — one hub holds isolated project stores, queues, and leases. Each agent client spawns a stdio bridge that talks to that hub. Only the hub binds the browser port.