====== mcpc — univerzální CLI klient pro MCP ======
//Vytvořeno: **5.5.2026** | Aktualizováno: **~~LASTMOD~~**//
[[https://github.com/apify/mcpc|mcpc]] je open-source CLI klient pro [[https://modelcontextprotocol.io/specification/latest|Model Context Protocol]], který vytvořil [[https://apify.com|Apify]]. Tento článek pokrývá nejen co mcpc je, ale především **jak ho prakticky nasadit** jako centralizovaný hub pro MCP servery napříč AI nástroji (Claude Code, OpenCode), aby každý nový stroj šel nastavit za pár minut a aby byly tajnosti bezpečně izolované.
===== TL;DR =====
~/.config/mcpc/
├── mcp.json # všechny servery, secrets jako ${VAR}
├── secrets.env # API klíče (mode 0600)
└── README.md # lokální dokumentace
~/.bashrc # bash funkce mcpc() — subshell izolace tajností
~/.config/opencode/AGENTS.md # registr serverů + quick start (sdílen s ~/.claude/CLAUDE.md)
Volání ''mcpc @ tools-call ...'' funguje out-of-the-box, klíče jsou viditelné jen uvnitř mcpc subshellu, AI agent nikdy klíče nevidí v shellu ani jiných procesech.
===== Proč mcpc existuje =====
Klasické MCP klienty (Claude Code, OpenCode, Cursor) načtou při startu **všechny** definice nástrojů ze všech nakonfigurovaných MCP serverů do kontextu. To má dva praktické problémy:
- **Context bloat** — pokud máš 5 MCP serverů, AI startuje s desítkami až stovkami definic nástrojů, které nikdy nepoužije. Token spotřeba a context rot.
- **Duplicita instancí** — každý AI nástroj si pro každý projekt spawnuje vlastní instanci MCP serveru. Tři projekty = tři běžící Playwright Chromium instance navíc.
mcpc řeší oboje:
* **Lazy loading**: AI volá ''mcpc @server tools-call ...'' přes ''Bash()'' jen tehdy, když tool reálně potřebuje. Definice jsou na disku v configu, ne v kontextu.
* **Sdílený bridge**: jeden bridge proces na server, sdílený napříč všemi klienty. Tři projekty = jedna instance.
Apify projekt představil na Vibecoding Talks 20. 4. 2026 (Jan Curn) s tezí, že „CLI vs. MCP" je falešná dichotomie — správně je **MCP pro vzdálený standard + CLI jako lokální rozhraní agenta**.
===== Architektura =====
┌──────────────┐ Bash() ┌──────────┐ Unix socket ┌────────┐ MCP ┌────────────┐
│ AI agent │ ─────────────────▶ │ mcpc CLI │ ────────────────▶ │ bridge │ ────────▶ │ MCP server │
│ (CC/OpenCode)│ └──────────┘ └────────┘ └────────────┘
└──────────────┘ (perzistentní, (HTTP nebo lokální
1 na server) stdio child process)
* **mcpc CLI** — krátkodobý proces, který volá AI nebo uživatel
* **Bridge** — daemon, který drží MCP připojení živé. Jeden bridge na pojmenovanou session (např. ''@apify'')
* **MCP server** — pro HTTP servery vzdálená URL, pro stdio servery child proces bridge
Bridge přežívá mezi voláními — žádný timeout po nečinnosti. Žije, dokud ho explicitně nezavřeš (''mcpc @session close'') nebo se nereboot stroj.
===== Instalace =====
==== Předpoklad: Bun ====
mcpc je distribuovaný jako npm balíček, ale globálně ho lze instalovat přes Bun bez ''sudo''. Potřebuješ nainstalovaný Bun a jeho binární adresář v ''PATH''.
==== Instalace mcpc ====
bun install -g @apify/mcpc
# Ověření
mcpc --version
which mcpc
==== Headless prostředí (Docker, server, CI) ====
mcpc ukládá tajnosti (OAuth tokeny, bearer tokeny) do **OS keychainu** přes Secret Service API. Na desktopu (GNOME, KDE) to funguje automaticky. **Na headless systémech mcpc bezproblémově fallbackuje na file-based credential store** v ''~/.mcpc/credentials.json'' (mode 0600).
To znamená: **na Dockeru/Alpine/CI server nemusíš instalovat libsecret ani gnome-keyring**. Fallback je z bezpečnostního pohledu v izolovaném kontejneru ekvivalentní.
Pokud chceš plnohodnotný OS keychain i v headless (ne nutné):
# Ubuntu
sudo apt install -y libsecret-1-0 gnome-keyring dbus
# Alpine
sudo apk add libsecret gnome-keyring dbus
# Pak pouštět mcpc přes:
dbus-run-session -- bash -c "echo -n 'pwd' | gnome-keyring-daemon --unlock && mcpc ..."
V drtivé většině případů to není potřeba.
===== Centralizovaný hub config =====
Nyní k praktické části — jak nakonfigurovat mcpc tak, aby ho mohl AI agent využívat z více nástrojů, byly tajnosti izolované a přidávání nových serverů bylo triviální.
==== Filozofie ====
* **Jeden soubor pro všechny servery** (''~/.config/mcpc/mcp.json'') — nikoliv per-projekt
* **Jeden soubor pro všechny tajnosti** (''~/.config/mcpc/secrets.env'') — odděleně od configu, proto config může jít do gitu
* **Bash funkce v ''.bashrc''** — tajnosti se exportují jen do subshellu pro daný ''mcpc'' call, ne do interaktivního shellu
* **Registr serverů v ''AGENTS.md''** — krátká tabulka „kdo má co k dispozici", aby AI věděla, co volat
==== Struktura ====
~/.config/mcpc/
├── README.md # lokální dokumentace tohoto setupu
├── mcp.json # konfigurace všech serverů, secrets jako ${VAR}
└── secrets.env # API klíče v KEY=VALUE formátu (mode 0600)
~/.bashrc # obsahuje funkci mcpc()
~/.config/opencode/AGENTS.md # registr serverů (pro AI)
~/.claude/CLAUDE.md → ~/.config/opencode/AGENTS.md # symlink, sdíleno
~/.mcpc/ # runtime state (sessions, sockety, logy) — nesahat
==== Nastavení krok za krokem ====
=== 1. Vytvoř hub adresář a config ===
mkdir -p ~/.config/mcpc
cat > ~/.config/mcpc/mcp.json <<'EOF'
{
"mcpServers": {}
}
EOF
=== 2. Vytvoř ''secrets.env'' (zatím prázdný) ===
touch ~/.config/mcpc/secrets.env
chmod 600 ~/.config/mcpc/secrets.env
=== 3. Přidej bash funkci do ''~/.bashrc'' ===
cat >> ~/.bashrc <<'EOF'
# mcpc — load secrets only into mcpc subshell, not the interactive shell
mcpc() {
if [ -f "$HOME/.config/mcpc/secrets.env" ]; then
( set -a; . "$HOME/.config/mcpc/secrets.env"; set +a; command mcpc "$@" )
else
command mcpc "$@"
fi
}
EOF
source ~/.bashrc
type mcpc # mcpc is a function
**Jak to funguje:**
* Závorky ''(...)'' vytvoří **subshell** s vlastním env
* ''set -a'' zařídí, že každá proměnná z následujícího sourcu se exportuje
* ''. secrets.env'' načte tajnosti — jen v subshellu
* ''command mcpc "$@"'' spustí reálný binární ''mcpc'' z ''/usr/local/bin/'' (klíčové slovo ''command'' přeskočí naši funkci, aby nevznikla rekurze)
* Subshell skončí → tajnosti zaniknou, parent shell je nedotčený
**Ověření izolace:**
echo "$CONTEXT7_API_KEY" # prázdné — klíč není v interaktivním shellu
mcpc @ctx tools-list # funguje — klíč se substituuje uvnitř subshellu
echo "$CONTEXT7_API_KEY" # pořád prázdné
=== 4. Přidej sekci do ''AGENTS.md'' / ''CLAUDE.md'' ===
V Claude Code je globální konfigurace v ''~/.claude/CLAUDE.md'', v OpenCode v ''~/.config/opencode/AGENTS.md''. Pro sdílení:
mkdir -p ~/.claude
ln -s ~/.config/opencode/AGENTS.md ~/.claude/CLAUDE.md
(Pokud ''~/.claude/CLAUDE.md'' už existuje, prvně si ho zazálohuj a pak nahraď symlinkem.)
Do ''~/.config/opencode/AGENTS.md'' přidej tuto sekci (na konec):
# MCP servery přes mcpc
MCP servery se nepřipojují nativně v Claude Code/OpenCode (úspora kontextu) — místo toho se on-demand spouští přes CLI `mcpc`. Hub config: `~/.config/mcpc/mcp.json`. Pro detaily použití mcpc (sessions, OAuth, troubleshooting) je k dispozici skill `mcpc` — načti přes Skill tool.
## Dostupné servery
| Entry | Session | Popis | Pozn. |
|---|---|---|---|
| (přidávej řádky podle reálně nakonfigurovaných serverů) | | | |
## Quick start (platí pro libovolný entry z tabulky)
```bash
HUB=~/.config/mcpc/mcp.json
mcpc connect $HUB: @ # idempotentní; cold-start ~10–30 s, jinak instant
mcpc @ tools-list # přehled toolů
mcpc @ tools-get # plné schéma jednoho toolu
mcpc @ tools-call arg:=value # zavolat tool
mcpc --json @ tools-call ... # JSON výstup pro pipeline
```
**Sessions jsou warm pool — nezavírej je po dokončení úkolu.** Drží se v paměti záměrně kvůli rychlosti dalších volání. `mcpc @ close` volej jen na explicitní pokyn uživatele.
**Servery s API klíčem:** hodnota patří do `~/.config/mcpc/secrets.env` (formát `KEY=VALUE`), v `mcp.json` se referencuje jako `${KEY}`.
===== Recept: přidat nový MCP server =====
Tři varianty podle typu serveru.
==== A. HTTP server s API klíčem (např. context7, Apify, GitHub MCP) ====
**1. Přidej klíč do ''secrets.env'':**
echo 'CONTEXT7_API_KEY=ctx7sk-...' >> ~/.config/mcpc/secrets.env
(Žádné mezery kolem ''='', žádný ''export''.)
**2. Přidej entry do ''mcp.json'':**
"context7": {
"url": "https://mcp.context7.com/mcp",
"headers": {
"CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"
}
}
Některé servery chtějí standardní ''Authorization: Bearer ...'':
"apify": {
"url": "https://mcp.apify.com",
"headers": {
"Authorization": "Bearer ${APIFY_TOKEN}"
}
}
mcpc umí libovolný název headeru.
**3. Otestuj:**
mcpc connect ~/.config/mcpc/mcp.json:context7 @ctx
mcpc @ctx tools-list
**4. Aktualizuj tabulku v ''AGENTS.md'':**
| `context7` | `@ctx` | Aktuální dokumentace knihoven, frameworků, SDK. | — |
==== B. stdio server (lokální proces, většinou bez klíče) ====
**1. Entry v ''mcp.json'':**
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--isolated",
"--headless",
"--browser", "chrome"
],
"env": {
"PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD": "1"
}
}
**Pozor:** stdio podproces dědí z prostředí jen whitelist (''PATH'', ''HOME'', ''SHELL'', …). Cokoliv jiného (''HTTPS_PROXY'', ''NODE_EXTRA_CA_CERTS'', vlastní API klíč) musí být explicitně v ''env'' bloku, případně přes ''${VAR}'' reference na shell proměnnou (která může pocházet ze ''secrets.env'').
**2. Otestuj a aktualizuj AGENTS.md** (stejně jako varianta A).
==== C. HTTP server bez autentizace ====
**1. Entry s jen ''url'':**
"my-public": { "url": "https://public.example.com/mcp" }
**2. Otestuj a aktualizuj AGENTS.md.**
===== Použití =====
==== Základní příkazy ====
# Přehled aktivních sessions a OAuth profilů
mcpc
# Připojit (idempotentní — když session už existuje, jen potvrdí)
mcpc connect ~/.config/mcpc/mcp.json: @
# Detail serveru, capabilities, instructions, tooly
mcpc @
# Seznam toolů
mcpc @ tools-list # názvy + krátké popisy
mcpc @ tools-list --full # plné schéma všech toolů
# Plné schéma jednoho toolu
mcpc @ tools-get
# Zavolat tool
mcpc @ tools-call arg:=value
# Hledání napříč sessions
mcpc grep "search"
# Interaktivní shell
mcpc @ shell
# Restart bridge (ztratí state, ale obnoví spojení)
mcpc @ restart
# Zavřít session (uvolní paměť)
mcpc @ close
# Úklid (live sessions zachová, smaže staré logy a zombie sockety)
mcpc clean
# Nuclear option — všechno
mcpc clean all
==== Argumenty toolů ====
# String, number, bool — auto-parsing JSON
mcpc @s tools-call search query:="hello world" limit:=10 enabled:=true
# Force string z čísla
mcpc @s tools-call get-by-id id:='"123"'
# Inline JSON object (první arg začíná { nebo [)
mcpc @s tools-call create '{"name":"foo","tags":["a","b"]}'
# Z stdin
echo '{"query":"hello"}' | mcpc @s tools-call search
==== Code mode (JSON pipelines) ====
# Strojový JSON výstup
mcpc --json @apify tools-call search-actors keywords:="scraper" \
| jq -r '.content[0].text'
# Skládání přes pipe
mcpc --json @s1 tools-call get-data \
| jq '.id' \
| xargs -I {} mcpc @s2 tools-call process id:="{}"
===== Operační charakteristiky =====
==== Cold start ====
* **První ''connect''** na server, který ještě neběží: 10–30 s (HTTP servery rychlejší, stdio s těžkým podprocesem jako Puppeteer/Chromium pomalejší)
* **Další ''connect''** na live session: instantní (~50 ms, jen potvrzení)
* **Tool call přes existující session**: sub-sekundový režijní overhead, samotný call záleží na serveru
Pro AI workflow je proto idiomatické **vždy začít ''mcpc connect ...''** — díky idempotentnosti to nestojí nic, když session žije, a automaticky řeší cold start, když ne.
==== Warm pool memory ====
Bridge proces drží spojení a typicky i podproces serveru živý. Memory pattern:
^ Stav ^ Typický RSS ^
| Bridge bez spuštěného podprocesu | ~95 MB (node) |
| Bridge + lehký HTTP server (context7) | ~95 MB |
| Bridge + stdio server bez browseru (typický playwright neaktivní) | ~285 MB |
| Bridge + stdio server s otevřeným headless Chromium (playwright aktivní, perplexity) | 1.2–2.0 GB |
Memory **nestoupá nekontrolovatelně** — pool má fixní velikost. Po opakovaných voláních RSS osciluje kolem stabilní hodnoty (±50 MB).
==== Sessions persistence ====
* Sessions přežívají mezi Claude Code/OpenCode sessions
* Bridge zemře jen na: explicitní ''mcpc @s close'', restart stroje, OOM kill
* ''mcpc clean'' neruší live sessions, jen úklid
===== Troubleshooting =====
==== „Bridge failed to start: socket file not created within timeout" ====
Bridge se spustil, ale rychle umřel a parent CLI to interpretoval jako timeout. **Skutečnou příčinu hledej v bridge logu**:
cat ~/.mcpc/logs/bridge-@.log
Časté důvody:
* **Auth chyba** (HTTP 401) — server vyžaduje klíč, ale ''${VAR}'' se nepřeložil. Zkontroluj ''secrets.env'' a že bash funkce ''mcpc()'' je aktivní (''type mcpc'' musí říct „is a function").
* **Stdio command nenalezen** — chybí ''bun''/''npx''/zápis cesty.
* **Stdio podproces napsal na stderr** — bridge log ti tail stderr ukáže (řádky s ''[server stderr]'').
==== „Page not initialized" u perplexity-mcp-zerver ====
Cold-start race: první ''search'' přišla dřív, než server stihl otevřít browser pool. Řešení:
mcpc connect ~/.config/mcpc/mcp.json:perplexity @px
sleep 8 # dej serveru čas na inicializaci
mcpc @px tools-call search query:="..." # první call zabere ~30 s, další 13–18 s
==== „401 Unauthorized" / session ve stavu 🔴 unauthorized ====
Server odmítl klíč:
- Zkontroluj, že hodnota v ''secrets.env'' je aktuální
- Restartuj session, ať mcpc znovu načte resolved config:
mcpc @ close
mcpc connect ~/.config/mcpc/mcp.json: @
==== Memory roste neúměrně ====
mcpc samo nemá memory leak. Pokud RSS roste:
- Spusť ''mcpc'' a zkontroluj počet sessions — možná máš živé session, o kterých nevíš
- ''ps aux | grep -E 'bridge|mcp''' ukáže reálné procesy a jejich PIDs
- Pro restart konkrétního serveru: ''mcpc @ restart''
- Pro všeobecný úklid: ''mcpc clean sessions'' (zruší všechny)
==== Bash funkce se neuplatňuje ====
type mcpc
# Pokud výstup je "/usr/local/bin/mcpc", funkce není načtená:
source ~/.bashrc
type mcpc
# Teď musí být "is a function"
V neinteraktivních shellech (CI, některé hooks) se ''.bashrc'' automaticky nesourcuje — vyřeš nastavením ''BASH_ENV=$HOME/.bashrc'' nebo voláním ''bash -l'' (login shell).
===== Bezpečnost a izolace =====
==== Subshell isolation pattern ====
Bash funkce ''mcpc()'' načte tajnosti **jen do subshellu pro daný call**. To znamená:
^ Co ^ S auto-source v ''.bashrc'' ^ S bash funkcí (náš setup) ^
| ''echo $API_KEY'' v terminálu | vrátí klíč ⚠️ | prázdné ✅ |
| Jiný proces čte ''/proc//environ'' shellu | vidí klíč ⚠️ | bez klíče ✅ |
| Náhodný npm balíček spuštěný uživatelem | vidí klíč ⚠️ | bez klíče ✅ |
| ''mcpc connect/call ...'' | funguje | funguje ✅ |
==== Co AI agent vidí vs. nevidí ====
✅ AI vidí: výstup mcpc příkazů (stdout)
✅ AI vidí: seznam serverů v AGENTS.md (entry, popis, session alias)
❌ AI nevidí: obsah secrets.env (není v žádné šabloně/contextu)
❌ AI nevidí: hodnoty $API_KEY ve shellu (subshell isolation)
❌ AI nevidí: resolved hodnoty v mcp.json (substituce probíhá v paměti mcpc)
==== MCP proxy pro hard sandbox ====
Pro nedůvěryhodný kód můžeš spustit mcpc v proxy režimu:
# Ty jako uživatel: vytvoř autentizovanou session s proxy serverem
mcpc connect ~/.config/mcpc/mcp.json:apify @ai-relay --proxy 8080
# AI v sandboxu: připojí se na proxy bez znalosti původních credentials
mcpc connect localhost:8080 @sandboxed
mcpc @sandboxed tools-call search-actors keywords:="..."
AI vidí jen rozhraní proxy, ne původní OAuth tokeny ani API klíče.
===== Dokumentační workflow pro fresh stroj =====
Pro nasazení na nový stroj (např. Docker image, nový server):
- **Instalace mcpc** — viz sekce „Instalace" výše
- **Vytvoř hub config** — ''mkdir -p ~/.config/mcpc/'' + ''mcp.json'' skeleton
- **Vytvoř ''secrets.env''** s permissions 0600
- **Přidej bash funkci** do ''~/.bashrc''
- **Vytvoř ''~/.config/mcpc/README.md''** (lokální dokumentace pro budoucí AI agenty na tomto stroji)
- **Přidej sekci do ''AGENTS.md'' / ''CLAUDE.md''** s registrem serverů
- **Postupně přidávej servery** dle Receptu výše
Šablonu hub ''README.md'', který se na stroji vytvoří, najdeš v [[https://github.com/apify/mcpc/blob/main/docs/claude-skill/README.md|GitHub repo]] nebo si ji můžeš [[ai:mcp:nastroje:mcpc|stáhnout/přizpůsobit]] z této wiki.
===== Podpora MCP funkcí =====
^ Funkce ^ Stav ^
| Instructions / Tools / Prompts / Resources | ✅ plná podpora |
| Logování a notifikace | ✅ |
| Stránkování výsledků | ✅ automatické |
| Asynchronní úlohy | ✅ |
| OAuth 2.1 + PKCE + DCR + CIMD | ✅ |
| x402 platby | ✅ (experimentální) |
| Roots / Elicitation / Completion | 🚧 plánováno |
| Sampling | ❌ neaplikovatelné (mcpc nemá vlastní LLM) |
===== Zdroje =====
* [[https://github.com/apify/mcpc|mcpc na GitHubu (apify/mcpc)]]
* [[https://github.com/apify/mcpc/tree/main/docs/claude-skill|Oficiální Claude skill pro mcpc]]
* [[https://modelcontextprotocol.io/specification/latest|MCP specifikace]]
* [[https://x402.org|x402 payment protocol]]
* [[https://apify.com|Apify]] — autoři projektu
* Vibecoding Talks, 20. 4. 2026 — Jan Curn (@jancurn), Apify