Gemini CLI
Google’s Gemini CLI works similarly to Claude Code in spirit – permissions are checked by the agent harness rather than the kernel – with an optional operating-system sandbox layer you can turn on if you want stricter isolation (macOS Seatbelt, or Docker/Podman elsewhere).
Connect to Portuni
Section titled “Connect to Portuni”Add Portuni to ~/.gemini/settings.json:
{ "mcpServers": { "portuni": { "httpUrl": "http://localhost:4011/mcp", "headers": { "Authorization": "Bearer $PORTUNI_MCP_TOKEN" }, "timeout": 5000 } }}Gemini CLI resolves environment variables in settings.json strings, so reference the token as $PORTUNI_MCP_TOKEN rather than pasting it in. Export the variable in your shell (Settings → MCP Server → Copy token in the desktop app), or launch Gemini from a terminal the desktop app spawned, which has it injected. The bearer header matters: the desktop sidecar always requires it, and a standalone server requires it whenever PORTUNI_AUTH_TOKEN is set.
The example above shows a standalone server on the default port 4011. The desktop app’s install buttons cover Claude Code, Codex, and Vibe but not Gemini, so to reach a desktop workspace you register it by hand the same way – each enabled workspace’s sidecar listens on its own loopback port allocated from 47011 up, with its token in the PORTUNI_MCP_TOKEN_<WORKSPACE_ID> env var. Grab the URL and token from Settings → MCP Server.
Other useful keys on the same object: trust (skip per-tool approval prompts), timeout (in milliseconds).
For the full picture, see the Gemini MCP server docs.
Letting Gemini into your mirror folders
Section titled “Letting Gemini into your mirror folders”Out of the box, Gemini CLI treats the directory you launched it from as its workspace and ignores everything else. Mirror folders living in a separate workspace root need to be included on purpose.
Three ways to do it:
At launch (recommended). Pass --include-directories – up to five, comma-separated:
gemini --include-directories /Users/me/Workspaces/portuniScope is the current session only. Bake it into a shell alias if you open Portuni mirrors often.
Mid-session. If you realise later that you need another folder:
/directory add ~/Workspaces/portuni/q2-rebrand/directory showHeads up: the slash command is disabled when running under a restrictive sandbox profile. In that case, use --include-directories at launch instead.
Persistent (use with care).
{ "context": { "includeDirectories": ["/Users/me/Workspaces/portuni"], "loadMemoryFromIncludeDirectories": true }}Every Gemini session on the machine now sees the folder. Useful on a dedicated workstation; otherwise the launch flag stays cleaner.
Approval modes
Section titled “Approval modes”Gemini CLI has a few different personalities when it comes to asking for confirmation:
| Mode | How to enable | What it does |
|---|---|---|
default |
no flag | Asks before every tool call |
auto_edit |
--approval-mode=auto_edit |
Auto-approves edits; still asks for the rest |
plan |
--approval-mode=plan |
Read-only planning – no writes execute |
yolo |
--yolo or Ctrl+Y |
Auto-approves everything |
--yolo automatically turns the sandbox on, which is a sensible safety net when you’re letting the agent act freely.
The optional sandbox
Section titled “The optional sandbox”If you’d like stronger isolation, Gemini can run the agent process inside a sandbox. Turn it on with --sandbox / -s, the GEMINI_SANDBOX=true env var, or tools.sandbox: true in settings.
- macOS – uses
sandbox-execwith thepermissive-openprofile: writes outside the project directory are restricted, most other operations are allowed. - Linux / cross-platform – uses a Docker or Podman image called
gemini-cli-sandbox, which you can customise via.gemini/sandbox.Dockerfile.
Pair the sandbox with --include-directories so the sandbox image picks up your mirror folders at start-up. Runtime additions through /directory add are blocked under restrictive profiles.
Running more than one Portuni instance
Section titled “Running more than one Portuni instance”With the desktop app, “more than one instance” is the normal state: every enabled workspace runs its own sidecar on its own port (from 47011 up) with its own token. Since there’s no Gemini install button, mirror the naming convention the app uses for the other clients – one entry per workspace, named portuni-<workspace-id>, token referenced via that workspace’s PORTUNI_MCP_TOKEN_<ID> variable. In app-spawned terminals all of those variables are already exported (plain PORTUNI_MCP_TOKEN aliases the active workspace).
For standalone CLI servers, register each instance as its own MCP server in ~/.gemini/settings.json the same way:
{ "mcpServers": { "portuni": { "httpUrl": "http://localhost:4011/mcp", "headers": { "Authorization": "Bearer $PORTUNI_MCP_TOKEN" } }, "portuni-alt": { "httpUrl": "http://localhost:3002/mcp", "headers": { "Authorization": "Bearer $PORTUNI_ALT_MCP_TOKEN" } } }}If you point Gemini’s MCP URL at the Portuni endpoint with the ?home_node_id=<id> query param (the same form portuni_mirror writes into other harness configs), the server auto-seeds the read scope on connect and you can call tools immediately. Without the query param, call portuni_session_init as your first move.