Personal AI tooling stack: Podman Compose services for MCP servers, plus Claude Code plugins for productivity workflows.
| Service | Port | Description |
|---|---|---|
| ai-beacon | 17090 | Session manager for multiple Claude sessions |
| devlake-local-mysql-mcp | 17301 | Read-only MCP proxy for local DevLake MySQL |
| devlake-prod-mysql-mcp | 17300 | Read-only MCP proxy for remote Konflux RDS |
| gmail-mcp | 17633 | Gmail MCP server (search, draft, attachments) |
| mcp-atlassian | 17000 | Jira MCP server (streamable HTTP transport) |
| gdrive-mcp | 17100 | Google Drive MCP server (streamable HTTP transport) |
1. Copy and fill in secrets
cp env.example .env
# Edit .env2. Start services
just up
# or selectively:
podman compose up -d gmail-mcp mcp-atlassianContainer images are built by CI and published to ghcr.io/kpiwko/ — no local build needed.
1. Register the marketplace and install the ai-stack plugin:
claude plugin marketplace add https://github.com/kpiwko/ai-stack.git --scope user
claude plugin install ai-stack@ai-stack
2. Use it inside a Claude session to set up everything else:
/ai-stack:install-plugins ← install dev, track, quarterly plugins
/ai-stack:install-skills ← install bare skills (template-slide-deck, n8n-skills)
/ai-stack:install-mcps ← register MCP servers with Claude Code
All three commands are interactive: they show what's available, what's already installed, and let you pick scope (user / project / local) before making any changes.
Updating plugins:
claude plugin marketplace update ai-stack
claude plugin update ai-stack@ai-stack
Restart Claude Code after updating for changes to take effect.
just up # podman compose up -d
just down # podman compose down
just status # podman compose psThe container bind-mounts ~/.config/gmail-mcp-server/ so tokens from a previous run are
reused automatically. On first run, authorize via browser:
open http://localhost:17633/auth # complete Google Device AuthorizationThen register with Claude Code via /ai-stack:install-mcps.
Connects to a DevLake MySQL instance running on the host at port 3306. Start DevLake's
MySQL service first, then register this MCP via /ai-stack:install-mcps. The command
reads $DEVLAKE_MCP_SECRET_KEY from the environment — make sure .env is sourced first.
Optional: connect via shared Podman network instead of host port
If DevLake runs in Podman Compose with a named network, you can attach this service to that network and reach MySQL by container name — no host port exposure needed.
-
Find DevLake's network name:
podman network ls -
Declare it as external in
compose.yaml:networks: ai-stack: driver: bridge devprod: # replace with DevLake's actual network name external: true
-
Add the network to the service and update
MYSQL_HOSTto the MySQL container name:devlake-local-mysql-mcp: networks: [ai-stack, devprod] environment: MYSQL_HOST: mysql # replace with DevLake's MySQL container name
Credentials come from .env: JIRA_URL, JIRA_USERNAME, JIRA_API_TOKEN. Start the
service then register via /ai-stack:install-mcps.
Authenticate on the host before starting the container — the server cannot open a browser inside the container:
npx @piotr-agier/google-drive-mcp authThis writes credentials.json and tokens.json into ~/.config/google-drive-mcp/.
Then start the service and register via /ai-stack:install-mcps.
openshell/policy.yaml grants sandbox access to all services in this stack.
Services are reached via host.openshell.internal (OpenShell injects this as an alias
for the gateway host IP). Private IP ranges are explicitly allowlisted to override the
built-in SSRF guard.
OpenShell's gateway runs k3s inside a container. k3s requires kernel interfaces
(/dev/kmsg, OOM tuning, network namespaces) unavailable in rootless Podman.
Switch once:
podman machine stop
podman machine set --rootful
podman machine start
podman compose pull # re-pull images (rootful/rootless use separate stores)OpenShell's gateway defaults to port 8080, which conflicts with services here. Start it on a free port:
openshell gateway start --port 17711podman compose up -d gmail-mcp devlake-local-mysql-mcp
openshell sandbox create --policy ./openshell/policy.yaml -- claudeFrom inside the sandbox, services are reachable at host.openshell.internal:<port>.
- Named volumes are managed inside the Podman VM — data persists across restarts.
host.containers.internalresolves to the macOS host from inside containers.network_mode: hostis not supported; all services use bridge networking.
MIT — see LICENSE.