/setup
Configure deliberation with Codex (GPT), Gemini, Grok, and OpenRouter MCP servers
$ npx -y skills add antonbabenko/deliberation --agent claude-codeShips with deliberation. Installing the plugin gets this command.
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/setup
Context preview
What this command does when you run it.
Configure deliberation with Codex (GPT), Gemini, Grok, and OpenRouter MCP servers
Command definition
setup.mdname: setup
description: Configure deliberation with Codex (GPT), Gemini, Grok, and OpenRouter MCP servers
allowed-tools: Bash, Read, AskUserQuestion
timeout: 60000
Setup
Configure GPT (via Codex), Gemini, Grok, and OpenRouter as expert subagents via MCP, install the orchestration rules, and (optionally) the short command aliases. Grok and OpenRouter are advisory-only.
This command runs in three phases: ONE main Bash call (checks + seed config + migrate + install rules + status), then isolated question turns for the optional aliases and the optional GitHub star. Do not batch a Bash call with an AskUserQuestion, and do not split the main block.
Step 1: Run setup
> Run the block below as ONE Bash call. Do NOT split it into smaller calls, and do NOT batch it > with any other tool call. It is idempotent - safe to re-run. > > **Run it with the Bash sandbox DISABLED.** The block writes `~/.claude/rules/deliberation/` > and `~/.claude.json`, both outside a typical sandbox write allowlist. Under a sandbox those > writes fail silently; the block verifies the result at the end and prints a `CRITICAL` block > telling you to re-run unsandboxed if it detects a problem.
The MCP servers are registered by the plugin manifest (inline `mcpServers` in `.claude-plugin/plugin.json`), so they load automatically when the plugin is enabled and update with `/plugin marketplace update antonbabenko` + `/reload-plugins`. This block is non-interactive: it seeds a default `config.json`, checks the provider CLIs, installs the rules, and prints a status report.
set -u
# --- resolve plugin root: env var -> marketplace cache (highest semver) -> current checkout ---
# A candidate is valid only if it contains server/mcp/index.js.
resolve_plugin_root() {
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "$CLAUDE_PLUGIN_ROOT/server/mcp/index.js" ]; then
printf '%s' "$CLAUDE_PLUGIN_ROOT"; return 0; fi
# marketplace cache, highest version (use find, not a glob - a failed zsh glob warns on stderr)
local c
c=$(find "$HOME/.claude/plugins/cache" -maxdepth 6 -path '*/deliberation/*/server/mcp/index.js' -type f 2>/dev/null | sort -V | tail -1)
if [ -n "$c" ]; then printf '%s' "${c%/server/mcp/index.js}"; return 0; fi
if [ -f "$PWD/server/mcp/index.js" ] && grep -q '"name": "deliberation"' "$PWD/.claude-plugin/plugin.json" 2>/dev/null; then
printf '%s' "$PWD"; return 0; fi
return 1
}
PLUGIN_ROOT="$(resolve_plugin_root)" || { echo "Error: cannot locate the deliberation plugin root. Install via /plugin, run from the plugin checkout, or set CLAUDE_PLUGIN_ROOT."; exit 1; }
# --- config path: env override > canonical XDG ---
# Mirrors core/paths.js: DELIBERATION_CONFIG wins; else the canonical
# ${XDG_CONFIG_HOME or ~/.config}/deliberation/config.json. Per the XDG spec a
# RELATIVE XDG_CONFIG_HOME is ignored and the default used.
if [ -n "${DELIBERATION_CONFIG:-}" ]; then
CFG="$DELIBERATION_CONFIG"
else
if [ -n "${XDG_CONFIG_HOME:-}" ] && [ "${XDG_CONFIG_HOME#/}" != "${XDG_CONFIG_HOME}" ]; then
XDG_BASE="$XDG_CONFIG_HOME"
else
XDG_BASE="$HOME/.config"
fi
CFG="$XDG_BASE/deliberation/config.json"
fi
# --- sessions store dir: env override > canonical XDG cache ---
# Mirrors core/paths.js resolveSessionsDir / canonicalCacheDir: DELIBERATION_SESSIONS
# wins; else ${XDG_CACHE_HOME or ~/.cache}/deliberation/sessions. A RELATIVE
# XDG_CACHE_HOME is ignored (XDG spec) and the default used.
if [ -n "${DELIBERATION_SESSIONS:-}" ]; then
SESSIONS_DIR="$DELIBERATION_SESSIONS"
else
if [ -n "${XDG_CACHE_HOME:-}" ] && [ "${XDG_CACHE_HOME#/}" != "${XDG_CACHE_HOME}" ]; then
CACHE_BASE="$XDG_CACHE_HOME"
else
CACHE_BASE="$HOME/.cache"
fi
SESSIONS_DIR="$CACHE_BASE/deliberation/sessions"
fi
# --- seed a default config on first run (never clobber an existing file) ---
# Codex/Gemini/Grok enabled; OpenRouter disabled with two example model records
# (also disabled). Edit $CFG to turn OpenRouter / the models on, then re-run setup.
CONFIG_CREATED=0
if [ ! -f "$CFG" ]; then
mkdir -p "$(dirname "$CFG")"
if cp "$PLUGIN_ROOT/config/config.default.json" "$CFG" 2>/dev/null; then
CONFIG_CREATED=1
else
echo "WARN: could not seed default config at $CFG"
fi
fi
# Helpers take their first arg WITHOUT the literal $1/$2 tokens: Claude Code
# interpolates $1..$9 / $ARGUMENTS in a command body before bash runs, and this is a
# no-arg command, so any $1 here would be blanked. `for x in "$@"; do break; done`
# binds x to the first arg; the guarded shift drops it so "$@" is the remainder.
# `$@` is NOT a slash-command placeholder, so it survives intact.
json_eval() {
local prog="" ; for prog in "$@"; do break; done ; [ "$#" -gt 0 ] && shift
node -e "$prog" "$CFG" "$@" 2>/dev/null
}
# openrouter on iff providers.openrouter.enabled!=false AND (>=1 models record OR defaultModel).
# Unified v1 shape: connection lives under providers.openrouter; models is the top-level map.
openrouter_enabled() {
json_eval 'try{const c=require(process.argv[1]);const p=(c.providers&&c.providers.openrouter)||{};const hasModel=(c.models&&typeof c.models==="object"&&Object.keys(c.models).length)||p.defaultModel;const on=p.enabled!==false&&hasModel;process.stdout.write(on?"1":"0")}catch(e){process.stdout.write("0")}'
}
or_key_env() {
json_eval 'try{const c=require(process.argv[1]);const p=(c.providers&&c.providers.openrouter)||{};process.stdout.write(p.apiKeyEnv||"OPENROUTER_API_KEY")}catch(e){process.stdout.write("OPENROUTER_API_KEY")}'
}
# sessions: "ON|OFF" + max records + max age, rendering -1 as "unlimited". Missing
# config or block => default OFF / 200 / 30d. Output shape: "<ON|OFF>|<recs>|<age>".
sessions_summary() {
json_eval 'try{const c=require(process.argv[1]);const s=c.sessions||{};const on=s.persist===true?"ON":"OFF";const mr=Number.isInteger(s.maxRecords)?s.maxRecords:200;const md=Number.isInteger(s.maxAgeDays)?s.maxAgeDays:30;const recs=mr===-1?"unlimited":String(mr);const age=md===-1Read more
name: setup description: Configure deliberation with Codex (GPT), Gemini, Grok, and OpenRouter MCP servers allowed-tools: Bash, Read, AskUserQuestion timeout: 60000
Setup
Configure GPT (via Codex), Gemini, Grok, and OpenRouter as expert subagents via MCP, install the orchestration rules, and (optionally) the short command aliases. Grok and OpenRouter are advisory-only.
This command runs in three phases: ONE main Bash call (checks + seed config + migrate + install rules + status), then isolated question turns for the optional aliases and the optional GitHub star. Do not batch a Bash call with an AskUserQuestion, and do not split the main block.
Step 1: Run setup
> Run the block below as ONE Bash call. Do NOT split it into smaller calls, and do NOT batch it > with any other tool call. It is idempotent - safe to re-run. > > **Run it with the Bash sandbox DISABLED.** The block writes `~/.claude/rules/deliberation/` > and `~/.claude.json`, both outside a typical sandbox write allowlist. Under a sandbox those > writes fail silently; the block verifies the result at the end and prints a `CRITICAL` block > telling you to re-run unsandboxed if it detects a problem.
The MCP servers are registered by the plugin manifest (inline `mcpServers` in `.claude-plugin/plugin.json`), so they load automatically when the plugin is enabled and update with `/plugin marketplace update antonbabenko` + `/reload-plugins`. This block is non-interactive: it seeds a default `config.json`, checks the provider CLIs, installs the rules, and prints a status report.
set -u
# --- resolve plugin root: env var -> marketplace cache (highest semver) -> current checkout ---
# A candidate is valid only if it contains server/mcp/index.js.
resolve_plugin_root() {
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "$CLAUDE_PLUGIN_ROOT/server/mcp/index.js" ]; then
printf '%s' "$CLAUDE_PLUGIN_ROOT"; return 0; fi
# marketplace cache, highest version (use find, not a glob - a failed zsh glob warns on stderr)
local c
c=$(find "$HOME/.claude/plugins/cache" -maxdepth 6 -path '*/deliberation/*/server/mcp/index.js' -type f 2>/dev/null | sort -V | tail -1)
if [ -n "$c" ]; then printf '%s' "${c%/server/mcp/index.js}"; return 0; fi
if [ -f "$PWD/server/mcp/index.js" ] && grep -q '"name": "deliberation"' "$PWD/.claude-plugin/plugin.json" 2>/dev/null; then
printf '%s' "$PWD"; return 0; fi
return 1
}
PLUGIN_ROOT="$(resolve_plugin_root)" || { echo "Error: cannot locate the deliberation plugin root. Install via /plugin, run from the plugin checkout, or set CLAUDE_PLUGIN_ROOT."; exit 1; }
# --- config path: env override > canonical XDG ---
# Mirrors core/paths.js: DELIBERATION_CONFIG wins; else the canonical
# ${XDG_CONFIG_HOME or ~/.config}/deliberation/config.json. Per the XDG spec a
# RELATIVE XDG_CONFIG_HOME is ignored and the default used.
if [ -n "${DELIBERATION_CONFIG:-}" ]; then
CFG="$DELIBERATION_CONFIG"
else
if [ -n "${XDG_CONFIG_HOME:-}" ] && [ "${XDG_CONFIG_HOME#/}" != "${XDG_CONFIG_HOME}" ]; then
XDG_BASE="$XDG_CONFIG_HOME"
else
XDG_BASE="$HOME/.config"
fi
CFG="$XDG_BASE/deliberation/config.json"
fi
# --- sessions store dir: env override > canonical XDG cache ---
# Mirrors core/paths.js resolveSessionsDir / canonicalCacheDir: DELIBERATION_SESSIONS
# wins; else ${XDG_CACHE_HOME or ~/.cache}/deliberation/sessions. A RELATIVE
# XDG_CACHE_HOME is ignored (XDG spec) and the default used.
if [ -n "${DELIBERATION_SESSIONS:-}" ]; then
SESSIONS_DIR="$DELIBERATION_SESSIONS"
else
if [ -n "${XDG_CACHE_HOME:-}" ] && [ "${XDG_CACHE_HOME#/}" != "${XDG_CACHE_HOME}" ]; then
CACHE_BASE="$XDG_CACHE_HOME"
else
CACHE_BASE="$HOME/.cache"
fi
SESSIONS_DIR="$CACHE_BASE/deliberation/sessions"
fi
# --- seed a default config on first run (never clobber an existing file) ---
# Codex/Gemini/Grok enabled; OpenRouter disabled with two example model records
# (also disabled). Edit $CFG to turn OpenRouter / the models on, then re-run setup.
CONFIG_CREATED=0
if [ ! -f "$CFG" ]; then
mkdir -p "$(dirname "$CFG")"
if cp "$PLUGIN_ROOT/config/config.default.json" "$CFG" 2>/dev/null; then
CONFIG_CREATED=1
else
echo "WARN: could not seed default config at $CFG"
fi
fi
# Helpers take their first arg WITHOUT the literal $1/$2 tokens: Claude Code
# interpolates $1..$9 / $ARGUMENTS in a command body before bash runs, and this is a
# no-arg command, so any $1 here would be blanked. `for x in "$@"; do break; done`
# binds x to the first arg; the guarded shift drops it so "$@" is the remainder.
# `$@` is NOT a slash-command placeholder, so it survives intact.
json_eval() {
local prog="" ; for prog in "$@"; do break; done ; [ "$#" -gt 0 ] && shift
node -e "$prog" "$CFG" "$@" 2>/dev/null
}
# openrouter on iff providers.openrouter.enabled!=false AND (>=1 models record OR defaultModel).
# Unified v1 shape: connection lives under providers.openrouter; models is the top-level map.
openrouter_enabled() {
json_eval 'try{const c=require(process.argv[1]);const p=(c.providers&&c.providers.openrouter)||{};const hasModel=(c.models&&typeof c.models==="object"&&Object.keys(c.models).length)||p.defaultModel;const on=p.enabled!==false&&hasModel;process.stdout.write(on?"1":"0")}catch(e){process.stdout.write("0")}'
}
or_key_env() {
json_eval 'try{const c=require(process.argv[1]);const p=(c.providers&&c.providers.openrouter)||{};process.stdout.write(p.apiKeyEnv||"OPENROUTER_API_KEY")}catch(e){process.stdout.write("OPENROUTER_API_KEY")}'
}
# sessions: "ON|OFF" + max records + max age, rendering -1 as "unlimited". Missing
# config or block => default OFF / 200 / 30d. Output shape: "<ON|OFF>|<recs>|<age>".
sessions_summary() {
json_eval 'try{const c=require(process.argv[1]);const s=c.sessions||{};const on=s.persist===true?"ON":"OFF";const mr=Number.isInteger(s.maxRecords)?s.maxRecords:200;const md=Number.isInteger(s.maxAgeDays)?s.maxAgeDays:30;const recs=mr===-1?"unlimited":String(mr);const age=md===-1Showing the first part of this file.
Get a second opinion in Claude Code from GPT, Gemini, and Grok - plus 400+ more models through OpenRouter, including Qwen, Kimi, and DeepSeek.
Repo: antonbabenko/deliberation
Other commands on deliberation.
- /analyze
Analyze recent runs - per-model latency, tokens, and verdict agreement - and suggest model/reasoning/fanout tuning. Advisory, read-only.
Open command - /ask-all
Ask GPT, Gemini, Grok, and any configured OpenRouter models in parallel for independent second opinions, then synthesize and compare. Zero cross-contamination.
Open command - /ask-gemini
Get Gemini second opinion on a question or current work. Single-shot, advisory, no contamination. Model pinned per call.
Open command - /ask-gpt
Get GPT (Codex) second opinion on a question or current work. Single-shot, advisory, no contamination.
Open command - /ask-grok
Get Grok (xAI) second opinion on a question or current work. Single-shot, advisory, no contamination.
Open command - /ask-openrouter
Ask a single configured OpenRouter model for a second opinion. Advisory only. Single-shot or multi-turn.
Open command

