# pp-docker ๐ณ
[](https://github.com/wryenmeek/pp-docker/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
[](https://bun.sh)
[](https://biomejs.dev)
[](https://docs.docker.com/ai/mcp-catalog-and-toolkit/)
Auto-containerize and register [Printing Press Library](https://github.com/mvanhorn/printing-press-library) MCP servers directly into **Docker Desktop MCP Toolkit** with **on-demand lifecycle management**.
---
## ๐ก The Problem & The Solution
Normally, running dozens of Model Context Protocol (MCP) servers across multiple AI clients (Claude Desktop, Cursor, VS Code, Zed) leads to:
* **Config Spaghetti:** Duplicating configurations across `claude_desktop_config.json`, `.cursor/mcp.json`, and `.vscode/mcp.json`.
* **Resource Drain:** 10+ background Node/Go processes constantly running in RAM and draining battery even when idle.
* **Credential Sprawl:** Storing sensitive API tokens in plain-text JSON files across your home directory.
**`pp-docker`** bridges the 500+ agent-native tools in the Printing Press Library to Docker's centralized **MCP Gateway**:
```text
[Claude Desktop] โโโ
[Cursor] โโโผโโ> [Docker Desktop MCP Gateway]
[VS Code] โโโค (Single Endpoint)
[Zed / Terminal] โโโ โ
โผ (On Tool Call)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Isolated Docker Container โ
โ e.g. jules-pp-mcp โ
โ - Spins UP on call โ
โ - Persistent SQLite vol โ
โ - Spins DOWN when idle โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
1. **Zero Client Clutter:** Your AI clients connect to Docker Desktop's gateway once (`MCP_DOCKER`).
2. **On-Demand Spin-Up / Spin-Down:** Servers are configured with `longLived: false`. Containers only spin up when a tool is called and terminate when idle.
3. **Encrypted Secrets:** API keys are stored in Docker Desktop's credential store instead of plain-text JSON files.
4. **Persistent SQLite Caching:** Volumes (`<slug>-data:/data`) are automatically provisioned so offline databases and mirror caches survive container teardown.
---
## โก Prerequisites
1. **Docker Desktop** (v4.38+) with **MCP Toolkit / Profiles** enabled:
* Open **Docker Desktop Settings** > **Features in development** > check **MCP Toolkit** (or run `docker mcp feature enable profiles`).
* Verify Docker is running: `docker info`
2. **Runtime Requirements**:
* **For CLI users**: **Node.js** >= 20 or **Bun** >= 1.2.
* **For development & tests**: **Bun** >= 1.2 is required (`bun test`, `bun run preflight`, `bun run ci`).
3. **Optional Companion Tools**:
* **1Password CLI (`op`)**: Optional, for piping secrets directly from 1Password vaults into Docker Desktop's keystore.
* **`antigravity-telemetry`**: Optional companion for deterministic session spend telemetry and branch pruning.
---
## ๐ Quick Start
### 1. Run via npx (Direct from GitHub)
You can run `pp-docker` directly without cloning or installing:
```bash
# Sync all printing-press tools already installed on your machine
npx github:wryenmeek/pp-docker sync
# Install a tool via printing-press and containerize it for Docker MCP
npx github:wryenmeek/pp-docker install jules
# Install multiple tools in one shot
npx github:wryenmeek/pp-docker install espn sentry cal-com
```
### 2. Local Global Installation
If you cloned this repository locally, link it to your `$PATH`:
```bash
cd printing-press-docker
npm link # or bun link
```
Now use `pp-docker` as a first-class command from any directory:
```bash
pp-docker sync
pp-docker install jules
```
---
## ๐ CLI Commands & Options
```text
Usage: pp-docker [options] [command]
Auto-containerize and register printing-press-library MCP servers into Docker Desktop
Options:
-V, --version output the version number
-p, --profile <name> Target Docker MCP profile name (default: "printing-press" or $MCP_PROFILE)
--dry-run Preview actions without building or modifying Docker (default: false)
--no-build Skip building the Docker image, only register the YAML spec (default: false)
--start-docker Automatically launch Docker Desktop if not running (default: false)
--verify Validate secrets in keystore and verify container handshake (default: false)
--json Emit structured, machine-parseable JSON on stdout (default: false)
-h, --help display help for command
Commands:
install [options] <tools...> Install tool(s) via printing-press-library and register into Docker MCP
register [options] <tools...> Register a tool or release URL directly to Docker MCP without installing native CLI
sync [options] Scan all installed printing-press CLIs and register missing ones into Docker MCP
verify [options] <tools...> Validate credential presence in Docker keystore and verify MCP container handshake
```
### Examples:
* **Preview what would be created (Dry Run):**
```bash
pp-docker sync --dry-run
```
* **Register into an existing profile with automatic verification:**
```bash
pp-docker register jules -p default --verify
```
* **Verify credentials and container health across tools:**
```bash
pp-docker verify figma flow jules
```
* **Emit machine-readable JSON in CI/agent scripts:**
```bash
pp-docker verify flow --json
```
* **Register directly from a specific GitHub Release URL:**
```bash
pp-docker register https://github.com/mvanhorn/printing-press-library/releases/tag/jules-current
```
---
## ๐ Connecting Your AI Clients
Once your servers are registered in Docker Desktop, connect your AI clients with one command:
```bash
docker mcp client connect claude-desktop
docker mcp client connect cursor
docker mcp client connect vscode
docker mcp client connect zed
```
To list all connected clients and verify their status:
```bash
docker mcp client ls
```
---
## ๐ Managing API Keys & Credentials
`pp-docker` automatically resolves the exact credentials required by each server from the `printing-press-library` registry:
* **Zero Auth Tools** (e.g. `flow`, `espn`): No secrets required. Docker Desktop immediately runs them on-demand.
* **Single Credential Tools** (e.g. `jules`): Requires `JULES_API_KEY` (`jules-pp-mcp.api_key`).
* **Format Alternative Tools** (e.g. `figma`): Dynamically resolves the primary token `FIGMA_ACCESS_TOKEN` (`figma-pp-mcp.access_token`).
* **Multi-Credential Tools** (e.g. `slack`): Requires distinct tokens `SLACK_BOT_TOKEN` (`slack-pp-mcp.bot_token`) and `SLACK_USER_TOKEN` (`slack-pp-mcp.user_token`).
### Setting Secrets in Docker Desktop
#### Option A: Direct Docker CLI
```bash
docker mcp secret set jules-pp-mcp.api_key="your-api-key-here"
docker mcp secret set figma-pp-mcp.access_token="your-figma-token-here"
```
#### Option B: 1Password CLI (`op`) Integration
If you store API keys in 1Password, securely inject them into Docker's keystore without exposing secrets in your shell history:
```bash
op read "op://vault/figma/access-token" | docker mcp secret set figma-pp-mcp.access_token
op read "op://vault/slack/bot-token" | docker mcp secret set slack-pp-mcp.bot_token
```
#### Option C: Docker Desktop GUI
1. Open **Docker Desktop**.
2. Click **MCP Toolkit** in the sidebar.
3. Select your profile (e.g. `printing-press`).
4. Click on the server entry and paste your credentials.
---
## ๐ Verification & Healthchecks
Validate that secrets are configured in Docker's keystore and that the container responds to standard MCP JSON-RPC protocol handshakes:
```bash
# Standalone verification
pp-docker verify jules flow figma
# Automatic post-registration verification
pp-docker register jules --verify
```
Output example:
```text
โ Keystore: All 1 required secret(s) configured
โ Container: Handshake succeeded (40 tools available)
```
---
## ๐ ๏ธ Troubleshooting
### 1. `Docker daemon is not running`
If you see this error during `sync` or `install`:
* Ensure Docker Desktop is open.
* On macOS, launch it from the terminal with:
```bash
open -a Docker
```
* Verify it is responsive with `docker info`.
### 2. `npm error code E404` when running `npx pp-docker`
If `pp-docker` is not yet published to the public npm registry under your namespace:
* Run directly via GitHub:
```bash
npx github:wryenmeek/pp-docker sync
```
* Or link it locally:
```bash
cd printing-press-docker && npm link
pp-docker sync
```
### 3. Verify Registered Servers in Docker Desktop
To inspect your profile and confirm all servers are attached:
```bash
docker mcp profile show printing-press
```
---
## ๐งช Development & Architecture
This repository uses modern, high-performance tooling:
* **Runtime & Testing:** [Bun](https://bun.sh) with native `bun:test` (100% function coverage).
* **Linter & Formatter:** [Biome](https://biomejs.dev) (Rust-powered, <10ms checks).
* **Dead Code & Dependency Hygiene:** [Knip](https://knip.dev).
### Quality & CI Commands:
```bash
# Run full CI pipeline locally (Biome + Typecheck + Knip + Bun Test with Coverage)
bun run ci
# Run tests and generate coverage report
bun run test:coverage
# Lint and format
bun run check
bun run check:fix
# Typecheck with TypeScript
bun run typecheck
# Audit for dead code and unused dependencies
bun run knip
# Build TypeScript distribution
bun run build
```
---
## ๐ License
[MIT](LICENSE) ยฉ 2026 wryenmeek and contributors