mcp server
deepPairing
Review what Claude Code is about to change on a rich visual surface — inline comments, evidence, and a gate that remembers the approaches you rejected.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 27, 2026deepPairing
Hand Claude Code the implementation without handing it the decisions that matter. It shows you the evidence, you make the call in a local review UI, and what you turn down is checked against what the agent proposes next in that repo.
Who it's for: engineers who let Claude Code write most of the code but want to own the architecture — the calls that are expensive to reverse.
The expensive problem: an agent working alone quietly makes the load-bearing choices (a global singleton for config, a new queue, a schema change). You meet them in a 500-line diff, after the code is built on top of them. Or you reject an idea on Tuesday, and on Thursday a fresh session proposes it again.
What you get instead: before it builds, Claude Code shows you what it found (with file:line evidence), the options it weighed, and the plan. You comment, pick, or reject in the companion UI. When you reject an approach with a reason, this project's gate checks later proposals against it and refuses a match, quoting your reason back. The run ends with a debrief of what changed and what still needs your eyes.
What the gate does, and what it doesn't (the details are in Your taste compounds):
- In-protocol (
present_*tools) — refused. Reject "global mutable state for config", and "keep config in global mutable states" is refused before the artifact is recorded. - Matching is on words, not meaning. It uses stemmed words plus a small, hand-audited synonym list (delete↔remove, directory↔folder). "A module-level mutable settings object" shares too few words with that concept, so it gets through. False positives happen too: "remove global mutable state from config" is refused, because it contains every word of the concept. Choose Allow this proposal once to let that exact proposal through and keep the stance; Retire this stance deletes it.
- Direct
Edit/Write/MultiEdit— you're asked, not refused. APreToolUsehook pauses a matching edit with a permission prompt, and you decide. It doesn't checkBashor notebook edits against your stances, and if it breaks, it lets the edit through. An agent edit to deepPairing's own state (.deeppairing/preferences.json,team.json, anything in.deeppairing/hooks/, or the.claude/settings*.jsonfiles that register these hooks) always asks, notebook edits included, because rewriting the file would quietly drop a stance; a shell write to them (echo >,sed -i,cp) isn't checked. One narrowBashcheck asks you before the agent's shell runsstance allow; that's the only Bash command it looks at. (Like every hook prompt, it depends on how Claude Code is running:bypassPermissionsskips it anddontAskrefuses the command instead; see SECURITY.md.) - Other projects — a nudge only. It's off until you turn on cross-project publishing, and it never blocks.
MIT · no account · no telemetry · 3,000+ tests · everything stays on your disk.
Poor fit: one-line fixes and throwaway scripts (the review is heavier than the change). Fully unattended runs where nobody will look at the UI. Teams that need a hard policy engine: the gate is a local word matcher, not a security boundary. Editors other than Claude Code.
Get started
Install the plugin inside Claude Code. It needs no clone and no build: the plugin ships a prebuilt server. Node 22 or 24 (current LTS) is recommended and what CI tests; Node 20.11+ still works but is deprecated — Node 20 is EOL and support is planned for removal no earlier than v0.2.0 (not before January 2027; see INSTALL.md).
/plugin marketplace add https://github.com/mitchjablonski/deepPairing
/plugin install deeppairing@deeppairing
Then open Claude Code in your own project and ask for real work, for example "Analyze the auth module and propose options." The first steps are in Your first review ↓. To look around before installing, the sample demo ↓ runs with plain Node. It needs no build and no Claude Code.
What you get
- The rejection gate. Reject an approach with a reason, and in this
project a
present_*call that matches it is refused, with your reason quoted back. A directEdit/Writethat matches is paused for your approval by aPreToolUsehook rather than refused. Once you enable cross-project publishing, your other projects get an advisory nudge about the same stance, never a block. Matching is on words and a short synonym list, not meaning (limits). - Decision cards. Options arrive as cards you pick in the UI — pros, cons, effort, and risk laid out side by side. Hard-to-reverse calls are flagged "high stakes" so you see at a glance which choices are load-bearing.
- A closing debrief. Every feature or autonomous run ends with one debrief artifact: the narrative of what changed and why, the calls the agent made without you, what still needs your eyes, and an ask-anything thread — so you understand the change, not just approve it. For code archaeology ("how does auth work here?") the agent narrates a read-only explainer walk-through.
- Live plan checklists. Plans render as checklists that tick off as the work lands, so "what's left" never lies.
- Comment on the diagram itself. Drag a rectangle on a plan or spec's Mermaid diagram and your comment anchors to the nodes it covers — and survives the agent redrawing the diagram.
- Every decision, one place. A project-wide decisions view lists what was chosen and why across all your sessions, searchable, with a jump back into the session where you made the call.
- A Detail dial. Rich or Terse — how much text rides inside each artifact. Terse trims the prose; the artifacts and evidence stay.
- Session replay. Reopen any past session from the command palette → Browse past sessions (replay) and step back through its artifacts, comments, and decisions in order.
- Multi-project switcher. One companion UI aggregates every project you're pairing on, with a "waiting on you" badge when it's your move.
- Share the session. Export any session as a single self-contained web page
— the narrative, decisions, debrief, and the diffs by default — from the
companion UI's Share as page (.html) menu or
/deeppairing:share. It travels to teammates who never install deepPairing, and it warns before it ships anything that looks like a secret. Pass--redact-code(orincludeCode: false) to strip every code body and diff when the code shouldn't leave the building. - Review a PR in tandem.
/deeppairing:review-pr <N>pulls a colleague's GitHub PR onto the review surface — the diff per hunk, walk-me-through, and findings anchored to real lines. Your verdict stays local until you send it:/deeppairing:post-prposts it back as a PR review only when you say so. - Keyboard-first review. Navigate artifacts, comment, pick options, and ask "why" without leaving the keyboard.
Why this exists
Today's AI coding tools push you to two unhappy ends: full autonomy (review 500 lines after the fact and hope) or autocomplete (you do all the thinking). The collaborative middle — where you stay in the loop at the decision level, not the keystroke level — is where good engineers actually want to work, and almost nothing is built for it. Every tool starts autonomous and bolts human review on afterward.
deepPairing starts from collaboration. The agent gathers context, then pauses at the decisions that matter and asks you. You answer once; it remembers. Over weeks it stops re-litigating taste you've already settled and starts sounding like your pair, on every repo.
The aha: the loop isn't "AI writes → you approve." It's "AI thinks out loud → you steer → you both get better." Quality and taste compound instead of resetting every session.
How it works
Talk to Claude Code the way you already do. When the work involves investigating, deciding, planning, or changing code, deepPairing routes it through structured MCP tools instead of a plain-text dump:
GATHER → the agent investigates and presents findings with real evidence
PRESENT → options, specs, and plans land in the companion UI for you to read
DECIDE → you comment inline, pick options, ask "why", request revisions
BUILD → only after you've shaped the direction; changes show as diffs
DEBRIEF → the run ends with the story: what changed, why, what needs your eyes
The companion UI is where you review and steer; the terminal stays your primary
chat surface. The MCP server runs inside Claude Code (it IS the agent — no
separate orchestrator) and serves the UI on a deterministic per-project port in
3847-3974, derived from the project path (recorded in .deeppairing/daemon.json).
What makes it feel collaborative
- Structured artifacts you shape, not skim. Findings, specs, options, plans, and code diffs render with evidence (file:line, snippets, the reasoning) and inline commenting — so you engage with the thinking, not just a final patch.
- Concept-naming as a teaching lever. Every
log_reasoningsurfaces the pattern at play, so you pick up the vocabulary and the agent's reasoning is legible — learning flows both directions. - It writes to you. Second person, like a pair ("which of these fits how we handle auth?"), not a third-person audit log narrating what "the user" asked.
- Pair-tempo signals. An "I see you" toast on every comment, a questions-waiting badge, a turn indicator that's honest about whose move it is. The collaboration is felt, not just logged.
Your taste compounds
So you never have to make the same call twice:
- You're not silently re-proposed past. Four surfaces, four different
guarantees:
-
present_*tools, this project: refused. A matching proposal gets aREJECTED_APPROACH_BLOCKEDerror, the artifact is not recorded, and your reason is quoted back.revise_artifactruns the same check. The one exception is a proposal you allowed once (from the companion UI, or the interactive CLI): that exact proposal goes through, once, and the artifact carries an "Allowed once" badge. Forpresent_debriefand an external-PRpresent_changeset, a match is reported as advice instead, because those describe work that already exists. -
Direct
Edit/Write/MultiEdit, this project: asked. ThePreToolUsehook runs the same matcher on the new text and file path, and a match becomes a Claude Code permission prompt (ask). It never returnsdeny, so you can allow the edit. It doesn't checkBashorNotebookEditagainst your stances; one narrowBashcheck asks before the shell grants a stance allowance, and that is the only Bash command it looks at. An allowance never removes this prompt: a direct edit carrying an allowed proposal still asks. It only reads this project's stances, and it fails open: if it errors, or the stance file can't be parsed, the edit proceeds. -
Other projects: a nudge, never a block. Turn on cross-project publishing (off by default; see below) and a matching proposal elsewhere gets an advisory note ("you avoided this in
<project>— still want it here?"). Reject it there as well to make it block there. If the cross-project ledger can't be read, the note is skipped. -
What counts as a match. Every word of the concept (after light stemming, so state/states match) must appear in the proposal, or the rejected phrase itself must. A small, hand-audited synonym list widens that: delete↔remove, directory↔folder, cache↔memoize, env↔environment, authentication↔login↔signin, and authorization↔authz. Authentication and authorization are kept apart on purpose. That's the whole list. It is not semantic understanding. Reject "global mutable state for config", and "keep config in global mutable states" is caught, while "a module-level mutable settings object" is not. A partial overlap, such as "global state for config", goes through, with a near-miss note in the trace. So name the concept in the words the agent will reuse. Word matching needs a named concept: if you reject a finding, plan, or spec without typing one, the stance is just its title, and only that phrase (word-bounded) is matched. None of the rewordings above would be caught.
-
False positives: allow once, or retire. A proposal to remove global mutable state from config is refused too, because it contains every word of the concept. You have two ways out:
- Allow this proposal once (the block card's main button, or
deeppairing stance allow <blockId>in your own terminal). You see exactly what would be created, give a reason, and that exact proposal gets through the next time the agent retries the identical call. It is single-use, and it ends with the Claude session or after 72 hours, whichever comes first. The stance stays on for everything else. The allowance lives only in the daemon's memory, so a restart ends it; it is never mirrored to the cross-project ledger, and it records no approval. If what the proposal depends on changes first (say, a newer change to the same file), the allowance doesn't apply and you get a new block to look at instead. - Retire this stance (in the ⋯ gate log, behind a confirm) deletes the stance from this project. It stops blocking everywhere, not just here.
Allowances are granted by you, not by the agent: the agent has no tool for it, and when its shell runs
stance allow(or names the grant route, say withcurl) you get a prompt. Whether you actually see that prompt depends on how Claude Code is running:bypassPermissionsskips prompts, so the command can run without one;dontAskdenies it instead of asking; and a-prun with no one to answer denies it (details and sources in SECURITY.md). That is human-only by design, not by enforcement: a process running as your user can still script a terminal, build the command or the URL at runtime so the shell check doesn't see it, or call the daemon's route directly with the token it can read. The shell check also asks on harmless text that contains the words, such asgrep -rn "stance allow"or a commit message. Receipts (the block log, the badge, the debrief and export lists) cover these supported paths; they are not tamper-evident and don't identify who granted anything. (Blocks from a committed team rule can't be allowed once; they point you to.deeppairing/team.jsoninstead.) Tests: preflight-validator, paraphrase-alias, preflight-hook-core, tool-helpers-global-advisory. - Allow this proposal once (the block card's main button, or
-
- A backstop on the paths you can't undo. The same PreToolUse hook also
watches your guardrail paths — migrations, CI config, infrastructure,
.envand other secret files. If the agent starts writing to one of them without having presented any findings, options, spec, or plan first, you get a prompt naming the path and the class before the edit lands. Do the pairing and it never fires; by default it asks rather than hard-blocking, it fails open, andDEEPPAIRING_GUARDRAIL_BACKSTOP=offturns it off. If your Claude Code permission UI omits the reason, opt intoDEEPPAIRING_PREFLIGHT_MODE=strict-stopto deny matching edits and stop for review. See compatibility modes and recovery. A stopped worker does not stop its parent. Its automatic background completion notification may omit the warning. Delegated strict-stop work requires the bounded, supervised handoff check, not an assumption that a completion notification means approval. - The ledger underneath. Reject something with a reason and the stance is
remembered. It's remembered in this project always; it reaches your
other projects —
~/.deeppairing/philosophy/v1.json— only once you enable cross-project publishing. Reads are global (every repo sees whatever ledger you've accumulated); writes are opt-in per project, default off, so a dependency in one project can't poison the others. Turn it on from Autonomy → Cross-project memory in the companion UI (you're also offered it once, right after your first "Reject & remember"), atinit, or withdeeppairing philosophy publish on. Portable viadeeppairing philosophy export | import --merge; drop a stance you no longer hold (whole entry, ledger backed up first) withdeeppairing philosophy remove <concept>or the ✕ in the Ledger drawer. - Three-layer memory, never merged. Filesystem-sensed guardrails (migrations, CI), committable team conventions, and personal philosophy are surfaced to the agent separately.
What it isn't
- Not a code-review bot (CodeRabbit, Greptile). It pairs with you while the code is being written; a PR is just a surface to share what you paired on.
- Not an autonomous agent. The Autonomy dial goes Full / Light / Minimal — and even Minimal stops at the architectural decisions.
- Not just a memory file. Claude Code's CLAUDE.md and auto memory are
context the model is asked to follow, and its docs point you to a
PreToolUsehook when you need a hard stop (memory docs, checked 2026-09-27). deepPairing ties the rejection to the decision you made in the review UI and checks every later proposal in that repo against it. The check is a word matcher, so it's a strong default, not a guarantee. - Not a skin over MCP elicitation. The async review loop is standard protocol now — server-initiated requests went non-blocking in the 2026-07-28 spec (SEP-2322 MRTR), and deepPairing speaks it, native elicitation supported (opt-in) for the trivial approve-here case. But elicitation, as clients render it today, is a flat approve/decline form ("flat objects with primitive properties only … nested structures, arrays of objects … intentionally not supported" — Final spec) — the right shape for a yes/no, not for the review that is deepPairing's whole point. The difference isn't a protocol limit (rich in-client UI is now spec-possible — see the FAQ). It's the composed review system deepPairing focuses on: multi-file changeset review with per-line and cross-file comments and suggested edits the agent has to answer, the decision workbench with per-part comments and version carryover, region-anchored diagram comments, and the debrief/explainer comprehension pair with an answer-back question loop. The review surface is the product; the loop is plumbing.
Beyond Plan Mode
Plan modes have gotten good, and they aren't one product. As of 2026-10-07, their docs say:
- Claude Code plan mode researches without editing, then asks you to
approve. You can choose "No, keep planning" and say what to change, or press
Ctrl+Gto edit the plan in your own editor. Plans are written as files under~/.claude/plans/(or yourplansDirectory) (permission modes). - Cursor Plan Mode asks clarifying questions, and you edit the plan in chat or as a Markdown file. Plans are saved in your home directory, and Save to workspace moves one into the repo (plan mode).
- VS Code reviews the agent's edits. You accept or reject each change, use Add Feedback on a range for the agent to resolve, and Mark as Reviewed to track files (review code edits).
So editable plans, saved plans, and inline feedback on a diff are not what sets deepPairing apart. Its focus is decision continuity: the consequential calls in a piece of work stay structured, tied to their evidence and your reason, and they're still there the next time the agent reaches for the same thing.
- Decisions are their own artifact. Options arrive as cards with pros, cons, effort and risk, and the agent can flag a hard-to-reverse call as high stakes. You pick or reject on the card, not in a paragraph of plan text.
- Evidence sits next to the decision. Findings carry file:line evidence you comment on, in the same session as the decision card, and plan steps can name the findings that motivated them.
- Your reasons are kept. The project's decisions view lists what was
chosen and why, across sessions. A rejection, with its reason, becomes a
stance. A later
present_*proposal that matches it is refused, and a direct edit that matches is paused for your approval. Matching is on words plus a short synonym list, not meaning (limits). - The review keeps going after the plan. Findings, options, specs, plans, diffs, and the closing debrief all use the same comment-and-answer loop.
| Claude Code plan mode | Cursor Plan Mode | VS Code edit review | deepPairing | |
|---|---|---|---|---|
| What you review | A plan, before edits | A plan, before building | The agent's code edits | Findings, options, specs, plans, diffs, debrief |
| How you respond | Approve, keep planning, or Ctrl+G edit | Edit in chat or Markdown | Accept/reject per change, Add Feedback | Anchored comments, option picks, "why" questions, reject with reason |
| Where it's kept | ~/.claude/plans/ files | Home dir, or saved to workspace | The session's changes | .deeppairing/ in the repo, plus a decisions view |
| A rejected approach, next time | Not covered on the cited page | Not covered on the cited page | Not covered on the cited page | Matched by words: present_* refused, direct edit asks |
Each cell for another tool describes only what its cited page said on 2026-10-07. "Not covered" means that page doesn't describe it, not that the tool can't do it.
Where this might fit (candidate uses, not measured demand):
- A migration or large refactor, where an early call (a dual-write window, a schema shape) constrains weeks of later edits. Rejected alternatives stay on record, so a later session doesn't quietly bring them back.
- A technical lead overseeing agent work, who wants to review the consequential decisions and their evidence rather than every line.
- A maintainer handoff. Ask the agent to export the session as an ADR
(
export_sessionwithformat: "adr", ordeeppairing export adrfrom a source build). Or share it as a self-contained page from the companion UI's Share as page (.html) menu (/deeppairing:share), so the next person gets the decisions and reasons along with the diff.
We don't claim time savings for any of these.
Install in Claude Code
Supported path: the prebuilt plugin. Inside Claude Code:
/plugin marketplace add https://github.com/mitchjablonski/deepPairing
/plugin install deeppairing@deeppairing
- What you need: Claude Code and Node on your
PATH— 22 or 24 recommended (what CI tests), 20.11+ still works but is deprecated (Node 20 is EOL; support planned for removal no earlier than v0.2.0, not before January 2027 — see INSTALL.md). You don't need pnpm, a clone or a build. - What you get: the plugin runs the server bundle committed in
claude-plugin/server/. It also installs the MCP tools, the slash commands (/deeppairing:start,:review,:stance,:share,:review-pr,:post-pr) and the rejection-gate and checkpoint hooks. - What it is not: there is no npm package. deepPairing is distributed only as this plugin and this repository.
To load the same plugin from a clone for one session, use
claude --plugin-dir ./claude-plugin. That also needs no build: the committed
bundle is used when packages/mcp-server/dist is absent. Setup details, the SSH
note and the init-vs-plugin comparison are in INSTALL.md.
Your first review
Each step names where it happens and what to do next.
- Terminal: start Claude Code in your project. When the plugin's MCP
server starts, it starts a local daemon for the project. On the daemon's
first start it opens the companion in your browser. The companion runs on a per-project port in
3847-3974. If no tab opens, run/deeppairing:startand Claude gives you the URL. The daemon records its port in.deeppairing/daemon.json. - Companion: wait for the first artifact. Until Claude presents something, the companion shows Waiting for Claude. Next: go back to the terminal and ask for real work, such as an analysis, a set of options or a plan.
- Companion: review. Findings, options, plans and changes arrive as artifacts. Next: comment on a line, pick an option, ask "why", approve, or reject with a reason. A rejection becomes a gate in this project.
- Terminal: Claude picks up your feedback. Claude doesn't block while you
review. It reads your comments and decisions with
check_feedback, which it calls after presenting and whenever it next pauses. If you answered while it was busy, your feedback waits in the session. Next: if Claude hasn't responded, tell it in the terminal to "check feedback".
Where each part goes.
- Terminal chat: direction and quick questions.
- Companion: anything tied to an artifact, such as line comments, option picks and verdicts.
- Late feedback: you don't need to re-type it in the terminal. It stays queued in the session until Claude next checks.
If something is stuck, run the checks in
docs/troubleshooting.md. It covers the companion
staying on Waiting for Claude, a daemon that won't start, and MCP startup
timeouts on WSL /mnt/c.
Try the sample demo (no build)
The demo plays a scripted sample. No AI agent or model runs; a script plays the agent's part on synthetic content. In the companion you'll see:
- an agent's proposal, which you reject with a reason;
- the remembered consequence: the same approach, re-proposed in new words, is refused by the gate;
- an explainer and a closing debrief that summarise the run.
It runs straight from the shipped plugin bundle with plain Node. Node 22 or 24 is recommended; 20.11+ works but is deprecated. You don't need a clone build, pnpm or Claude Code:
# From a download of this repo (git clone or a ZIP) — no install, no build:
node claude-plugin/server/demo.mjs
# Or from an installed plugin — find the bundle once, then run it:
find ~/.claude/plugins -name demo.mjs -path '*deeppairing*'
node "<that path>"
It opens the companion in your browser, or prints the URL when
DEEPPAIRING_NO_OPEN=1 is set. Press Enter (or Ctrl+C) to end it.
The demo runs in a sandbox:
- Storage: a temporary HOME and a synthetic sample project, created under your system temp directory and deleted when the demo ends.
- Daemon: its own daemon on its own port range (
41000-41063). It never starts or contacts the daemon for your projects, and never uses their3847-3974range. - Your data: it never writes to your projects, their preferences or your
~/.deeppairingcross-project ledger. It sends no telemetry and calls no external model.
node packages/mcp-server/dist/cli/init.js demo from a source build runs the
same sandboxed demo.
From source (developer path)
Use this path to work on deepPairing itself or to run it without the plugin.
init writes .mcp.json and the hooks into the current project:
pnpm install && pnpm build
node packages/mcp-server/dist/cli/init.js init
How long it takes
Indicative only. Once the plugin is installed, its server, the daemon and the companion are ready in about half a second on Linux and in under 2 s on Windows. Times vary by machine: an independent re-run on the same kind of setup was 20–40% slower.
The ranges below are exactly what three runs measured on 2026-09-27, using
throwaway HOME and project directories. Your times depend on your network,
disk and machine.
| Step | Linux (WSL2 ext4, Node 20.20) | Windows (Node 24.18, project on a \\wsl.localhost share) |
|---|---|---|
Fetch the repo (what /plugin marketplace add downloads) | 1.1–1.4 s | not measured |
Plugin server and daemon up, MCP initialize answered | 406–428 ms | 1047–1113 ms |
| Companion page served | 467–489 ms | 1234–1307 ms |
| First artifact visible in the companion | 487–514 ms | 1349–1482 ms |
A companion comment reaches Claude's check_feedback | 509–538 ms | 1644–1741 ms |
Sample demo from the shipped bundle (node claude-plugin/server/demo.mjs) until the companion is ready | 0.76–1.14 s | 2.8–4.5 s, one 48 s outlier (sandbox temp dir on the \\wsl.localhost share) |
| Source build, cold pnpm store: clone, install, build, demo | 1.4 + 6.0 + 8.3 + 1.9 ≈ 18 s | not measured |
| Source build, warm pnpm store | 1.3 + 2.1 + 8.3 + 1.9 ≈ 14 s | not measured |
How these were measured:
- Plugin rows: the times are from launching the plugin's
server.mjswith plainnode. A scripted MCP client stood in for Claude Code and an HTTP client stood in for the browser. A separate headless-browser check confirmed that the companion renders the artifact. - What they leave out: installing the plugin inside Claude Code, Claude Code's own start-up, and the model's thinking time.
- Cold install: it downloaded 506 packages on a fast connection. A slow network adds to it.
- WSL
/mnt/c: a first start there is much slower; see troubleshooting.
VS Code extension (experimental preview). The supported workflow is Claude
Code plus the browser companion. The extension in
packages/vscode-extension/ is an experimental preview, with no parity
commitment and no date for one. Its known limitations are listed in
packages/vscode-extension/README.md.
How it fits together
Claude Code ←stdio→ deepPairing MCP Server ←WebSocket→ Companion UI
↓
.deeppairing/ (session artifacts, team prefs, metrics)
~/.deeppairing/ (cross-project Philosophy Ledger)
Sessions persist as JSON in .deeppairing/; the ledger lives at
~/.deeppairing/philosophy/v1.json. For the full picture see
docs/architecture.md. If something misbehaves,
docs/troubleshooting.md is keyed on the actual error
strings; common questions live in docs/faq.md; the origin-story
research brief is docs/research-brief.md (historical).
What's in the box
packages/mcp-server/— the MCP server, CLI subcommands, companion UI (React + Vite + Zustand).packages/shared/— Zod schemas + fixtures both server and UI import.claude-plugin/— the Claude Code plugin:.mcp.json, slash commands (/deeppairing:start,:review,:stance,:share,:review-pr,:post-pr), thepairing-protocolskill, and the rejection-gate + checkpoint hooks.
18 MCP tools: present_findings, present_options, present_spec,
present_plan, present_code_change, present_changeset, present_debrief,
present_explainer, update_plan_progress, log_reasoning, recall, revise_artifact,
withdraw_artifact, answer_question, post_pr_review, export_session, check_feedback,
get_companion_url — plus two MCP prompts (recall and seed) for
slash-style queries.
CLI
Pre-1.0, no npm publish yet — invoke the built CLI by path, or pnpm link --global once for the short deeppairing command:
deeppairing demo # fire the hero flow
deeppairing init # set up in this project (interactive)
deeppairing doctor [--fix] # diagnose / heal install issues
deeppairing port # bare daemon port to stdout (scriptable; !-friendly in Claude Code)
deeppairing status # friendly daemon picture: port, URL, pid, version, running/alive
deeppairing team init # scaffold .deeppairing/team.json
deeppairing philosophy export | import f --merge | publish on|off | remove <concept>
deeppairing post-pr-review <pr> --session-id ID # post the explicitly reviewed session
deeppairing review-posts <session-id> # inspect / recover an unresolved review post
deeppairing export <full|pr-comments|adr|replay|learnings>
review-posts also ships whole as a standalone operator entry in the plugin
bundle (node claude-plugin/server/review-posts.mjs --help), because a
marketplace install has no deeppairing binary. Five of its verbs are offline;
reconcile reads GitHub and only reads — the entry carries no way to submit a
review. See
docs/pr-posting-contract.md.
How it compares
Planning, memory, blocking, and inline diff feedback each exist elsewhere already (sources checked 2026-10-07). Claude Code plan mode and Cursor Plan Mode produce editable, saved plans. VS Code lets you comment on agent edits. Claude Code's memory carries your instructions across sessions, and its hooks can deterministically block a tool call. deepPairing doesn't claim any one of those. What it adds is decision continuity: the evidence, the decision you made on a card, the review of the change, and your rejection come back as a checked stance the next time the agent reaches for the same thing. (The limits of the word match are above and in docs/faq.md.)
Status
Pre-1.0. Installable from this repo — via the Claude Code plugin marketplace
(/plugin marketplace add https://github.com/mitchjablonski/deepPairing, which
ships the committed self-contained server bundle), --plugin-dir, or from
source. No npm publish or listing in a public/community marketplace yet.
3,000+ tests, an explicit threat model, a fully-live accessibility gate (axe,
zero disabled rules), and strict TypeScript throughout — the next step is
earning a handful of delighted real users before broader distribution.
Ships a committed, reproducible server bundle (verify via pnpm build:clean);
the two bundled hooks are local-only and fail-open — see
SECURITY.md.