ccc-connect ยท diff
git:20261024.717fab8 to git:20261025.142f3cf
9 added, 9 removed. Audit A to A.
---
name: ccc-connect
description: "Opt-in connector wizard with affiliate disclosure: pick a service (Supabase, Linear, Vercel, Sentry, Notion, Slack, Stripe, research tools and more) and wire it as a plugin with userConfig, an OAuth MCP or a keyed MCP without secrets in chat. Use when connecting an MCP server or service."
allowed-tools:
- Read
- Bash
- AskUserQuestion
argument-hint: "[tasks | backend | hosting | cache | knowledge | comms | observability | billing | automation | agent-harness | email | research | productivity | dev | design]"
model: sonnet
effort: medium
disable-model-invocation: true
---
# /ccc-connect โ wire one connector safely
**CC Commander** ยท /ccc-connect ยท click through category and connector, then wire it through the current Claude Code primitive with no secret ever entering the transcript.
Show this disclosure at the top of every /ccc-connect response:
```
๐ฐ Some links below are affiliate โ CCC may earn a commission at no cost to you.
[Disclosure](https://docs.commanderplugin.com/affiliate-disclosure)
```
## When to use / when not to
- Use when the user wants a service connected: a database, host, tracker, chat, observability, billing, email, research or automation tool. Everything here is opt-in and absent by default; Commander bundles only credential-free servers.
- Do not use to change Commander's bundled `.mcp.json`, to debug an already-installed server (`/ccc-doctor`), or for Linear workflows once connected (`/ccc-linear`).
## What happens
1. **Context strip.** One Bash call (the last two lines report the project signals the pickers use):
```bash
claude mcp list 2>/dev/null
claude plugin list --json 2>/dev/null | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{console.log(JSON.parse(s).filter(p=>p.enabled).map(p=>p.id).join(", ")||"none")}catch{console.log("none")}})'
node -e 'try{const p=require("./package.json");const d={...p.dependencies,...p.devDependencies};console.log("signals:",["stripe","react","next"].filter(k=>d[k]).join(", ")||"none")}catch{console.log("signals: none")}'
test -f prisma/schema.prisma && echo "signals: prisma" || true
```
Render `Connected: <MCP names> ยท plugins: <ids>`, or "Nothing wired yet โ pick a category below." Never print server env values.
2. **Category picker** (cascade; see Decision points). An argument skips straight to its level. Every level has a stated ๐ข default; the project signals listed under Decision points can move it.
3. **Connector picker.** Show the connectors for the chosen category. A category with one connector skips this picker and confirms the choice in one line.
4. **Account check.** Ask once whether the user already has an account and key for the service; if not, give the signup or keys URL (the affiliate link for `[aff]` rows) and wait.
5. **Choose the wiring path.** Open [references/connectors.md](references/connectors.md) for the connector's row, then check for a plugin:
```bash
claude plugin list --available --json 2>/dev/null | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{for (const p of (JSON.parse(s).available||[])) if (p.name===process.argv[1]) console.log(p.pluginId)})' <connector-name>
```
Prefer, in order: **P** a Claude Code plugin (it carries its own MCP config and `userConfig`); **H** a remote HTTP MCP with OAuth; **S** a stdio MCP with a key captured by the user's own terminal. acpx is none of these; follow its section in the reference.
6. **Authorize the change.** Ask the install picker before the assistant runs any `claude plugin install` or `claude mcp add`; both change the user's Claude Code configuration. Path S wiring is run by the user, so it needs only the credential picker.
7. **Wire it.**
- **P โ plugin with userConfig.** Run `claude plugin install <pluginId> --config <key>=<value>` for non-secret options only (repeat `--config`; fixed-choice `options` are validated). Then `claude plugin configure <plugin> --json` and report only which option names are unset. Secret options are entered by the user in the `/plugin` configure flow or with the `--values-stdin` template in the reference. A plugin with no options usually authenticates by OAuth in `/mcp`.
- **H โ OAuth MCP.** Run `claude mcp add --transport http <name> <url>`, then the user runs `claude mcp login <name>` (or authenticates from `/mcp`). No credential file is written.
- **S โ keyed MCP.** The user captures the secret in their own terminal with the command below, clicks Done, then runs the wiring command from the reference (it reads the file inside `$(...)`, so the value never appears in a command line).
Credential capture (Path S), filled in with `<name>`, `<Connector>` and `<kind>` (`oauth` or `api-key`):
```bash
CCC_STATE="${CCC_CONFIG_DIR:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}/commander" && \
mkdir -p "$CCC_STATE/connections" && chmod 700 "$CCC_STATE/connections" && \
read -s -p "Paste your <Connector> credential (input hidden, nothing echoed): " CCC_SECRET && echo && \
printf '%s' "$CCC_SECRET" | node -e 'const fs=require("fs");let s="";process.stdin.on("data",d=>s+=d).on("end",()=>fs.writeFileSync(process.argv[1],JSON.stringify({name:"<name>",kind:"<kind>",credential:s,createdAt:new Date().toISOString(),tier:"free"},null,2)+"\n"))' "$CCC_STATE/connections/<name>.json" && \
chmod 600 "$CCC_STATE/connections/<name>.json" && \
unset CCC_SECRET && \
echo "Saved $CCC_STATE/connections/<name>.json (chmod 600)."
```
`read -s` hides the input and keeps the secret out of shell history; the value reaches `node` on stdin and is written with `JSON.stringify`, so quotes, backslashes or newlines cannot corrupt the file. The assistant shows the command and waits; it never runs it and never asks for the value back. If the user cannot finish now (an OAuth callback is pending), they run it later and click Done in a later session; never write a placeholder file.
8. **Verify.**
```bash
claude mcp get <name> 2>/dev/null || claude mcp list 2>/dev/null | grep -i '<name>'
claude plugin list --json 2>/dev/null | grep -i '"<plugin>@' # Path P only
```
On success: "โ
<Connector> connected. Run `/mcp reconnect all` (or restart the session) to load its tools." Add the connector's rate-limit note when the vendor documents one. If `claude mcp add` or `claude plugin install` fails, show the raw command for the user to run and the error; do not retry blindly.
9. **Next.** Ask the follow-up picker.
## Decision points
All pickers are `AskUserQuestion`, single select, two to four options, the ๐ข recommended option listed first, each option with a one-line consequence. In Codex or any surface without it, ask the same options as one plain-text question. A picker with a single possible option is skipped and its choice confirmed in one line.
**Category picker, level 1** (header "Connect"), default order:
- ๐ข **๐ฌ Research & observe** โ opens Research, Observability (broadest utility).
- **๐๏ธ Build & ship** โ opens Backend, Hosting, Cache / Queue, Billing.
- **๐ Team & comms** โ opens Tasks, Knowledge, Comms, Email.
- **๐ค Automate & design** โ opens Automation, Design, Agent harness.
Project signals from step 1 move the ๐ข to another group, which is then listed first: `prisma/schema.prisma`, a new SaaS, or `stripe` in `package.json` โ Build & ship; React or Next in `package.json` โ Automate & design. No signal keeps the default.
**Level 2, categories per group** (header "Category"; ๐ข option first):
| Group | Options |
|---|---|
| Research & observe | ๐ข Research โ search, scraping, docs ยท Observability โ errors and performance |
| Build & ship | ๐ข Backend โ database, auth, storage ยท Hosting โ deploys and previews ยท Cache / Queue โ Redis and Kafka ยท Billing โ payments |
| Team & comms | ๐ข Tasks โ issues and projects ยท Knowledge โ pages and databases ยท Comms โ channels and threads ยท Email โ sending and inboxes |
| Automate & design | ๐ข Automation โ browsers and app actions ยท Design โ files and components ยท Agent harness โ external agent CLI |
With `stripe` in `package.json`, Billing takes the ๐ข in Build & ship and is listed first.
- **Level 3, connectors per category** (header "Connector"; ๐ข option first; one-connector categories skip the picker):
+ **Level 3, connectors per category** (header "Connector"; connectors in alphabetical order, none pre-selected; one-connector categories skip the picker):
| Category | Connector options |
|---|---|
- | Backend | ๐ข Supabase [aff] โ first-class backend: auth, DB, storage, edge functions; also ships as a Codex plugin ยท Neon [aff] โ serverless Postgres ยท Postgres โ bring your own database |
- | Hosting | ๐ข Vercel [aff] โ web deploys, previews ยท Fly.io [aff] โ Docker services ยท Cloudflare [aff] โ Workers, Pages, R2, D1 |
+ | Backend | Neon [aff] โ serverless Postgres ยท Postgres โ bring your own database ยท Supabase [aff] โ auth, DB, storage, edge functions; also ships as a Codex plugin |
+ | Hosting | Cloudflare [aff] โ Workers, Pages, R2, D1 ยท Fly.io [aff] โ Docker services ยท Vercel [aff] โ web deploys, previews |
| Cache / Queue | Upstash [aff] โ serverless Redis and Kafka (only option) |
| Billing | Stripe โ payments, subscriptions, invoices (only option) |
- | Tasks | ๐ข Linear โ issues, projects, cycles (first-class Commander integration) ยท GitHub โ issues and PRs |
+ | Tasks | GitHub โ issues and PRs ยท Linear โ issues, projects, cycles (first-class Commander integration) |
| Knowledge | Notion โ pages, databases, comments (only option) |
- | Comms | ๐ข Slack โ channels, threads ยท Discord โ community server |
- | Email | ๐ข Resend [aff] โ transactional email ยท AgentMail โ agent-native inbox |
- | Research | ๐ข Tavily โ web search ยท Firecrawl โ scraping to markdown ยท Exa โ neural search ยท Context7 โ live library docs (already bundled; nothing to wire) |
+ | Comms | Discord โ community server ยท Slack โ channels, threads |
+ | Email | AgentMail โ agent-native inbox ยท Resend [aff] โ transactional email |
+ | Research | Context7 โ live library docs (already bundled; nothing to wire) ยท Exa โ neural search ยท Firecrawl โ scraping to markdown ยท Tavily โ web search |
| Observability | Sentry [aff] โ errors, performance, releases (only option) |
- | Automation | ๐ข Playwright โ local browser automation, no credential ยท Browserbase [aff] โ remote headless browsers ยท Zapier โ app actions ยท n8n โ self-hosted workflows |
+ | Automation | Browserbase [aff] โ remote headless browsers ยท n8n โ self-hosted workflows ยท Playwright โ local browser automation, no credential ยท Zapier โ app actions |
| Design | Figma โ files, components, comments (only option) |
| Agent harness | acpx โ bring-your-own agent harness; install-only, no MCP wiring (only option) |
- Supabase is the default backend for `/ccc-build` SaaS scaffolds: always list it first with ๐ข in Backend.
+ No connector is pre-selected. Mark one ๐ข only when step 1 shows it already in use (an installed plugin or MCP server, or its package in `package.json`). Affiliate status never changes the order or the ๐ข.
**Arguments:** a category name (`tasks`, `backend`, `hosting`, `cache`, `knowledge`, `comms`, `observability`, `billing`, `automation`, `agent-harness`, `email`, `research`, `design`) opens its level-3 picker; `productivity` opens a level-2 picker with ๐ข Tasks, Knowledge, Comms; `dev` opens a level-2 picker with ๐ข Backend, Hosting, Observability, Billing; no argument opens level 1.
**Install picker** (header "Install"): ๐ข **Install now** (runs the one install command shown) ยท **Show the command only** (the user runs it) ยท **Cancel**.
**Credential picker** (Path S, header "Credential"): ๐ข **Done โ saved** (continue to wiring) ยท **Cancel**.
**Follow-up picker** (header "Next"): ๐ข **Connect another** ยท **Show everything connected** ยท **Done**.
## Done when
- `claude mcp get <name>` (or `claude mcp list`) shows the server, or `claude plugin list --json` shows the plugin enabled, and the result was reported as observed.
- For Path S, `ls -l "${CCC_CONFIG_DIR:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}/commander/connections/<name>.json"` shows `-rw-------`.
- The user was told how to load the new tools (`/mcp reconnect all` or a restart).
## Guardrails
- Installing a plugin or MCP server changes the user's configuration: only on a click in this conversation, never automatically.
- Never ask for, accept, echo or log a secret in chat, and never run a command that contains one. If a user pastes a secret anyway, tell them to rotate it.
- Never pass a secret with `--config` or `-e KEY=value` in a command the assistant runs; secrets go through `/plugin` configure, `--values-stdin` from the user's terminal, OAuth, or the capture file.
- Never write a secret into a git-tracked file or a project `.mcp.json`; reference `${ENV_VAR}` there instead.
- Never use a command marked TBD; link the vendor's official docs.
- Never treat acpx as an MCP server: no `claude mcp add acpx`, no acpx credential file.
- Always show the affiliate disclosure before an `[aff]` connector is installed.
- Suggest at most five new servers in one session; each adds tools to load. `/ccc-xray context` measures plugin cost.
## See also
- `/ccc-linear` โ Linear workflows once connected.
- `/ccc-build` โ SaaS scaffolds that default to Supabase.
- `/ccc-doctor` โ diagnose a server that fails to start.
- `/ccc-xray` โ `context` scope inventories each plugin's token cost.
> โ๏ธ **Fable contract:** plan before build ยท verifier โ worker ยท prove before alarm ยท loops need gates ยท leave durable state โ `rules/fable-method.md`