====== 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