Skip to main content

Gemini CLI

Connect Google's Gemini CLI to TermFlow so the agent can open terminals, split panes, run commands, and read output — all through TermFlow's built-in MCP server.

TermFlow ships no AI of its own: you bring your own Gemini CLI and your own key. Gemini connects as a plain MCP client over streamable HTTP, exactly like any other tool that speaks the protocol.

Prerequisites
  • TermFlow is installed and running.
  • Gemini CLI is installed and working.
  • In TermFlow, open Settings → Connections and confirm the health dot next to the MCP server is green (healthy).

The config Gemini CLI expects

Gemini CLI reads MCP server definitions from a settings.json file. Add an auto-terminal entry under mcpServers that points at TermFlow's MCP endpoint:

{
"mcpServers": {
"auto-terminal": {
"httpUrl": "http://127.0.0.1:42032/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}

That is exactly what TermFlow's in-app Connect an AI agent modal generates for Gemini (Settings → Connections → "Connect an AI agent"), so the easiest path is to open that modal, pick the Gemini tab, and copy the block straight out of it — the URL and token are filled in for you.

FieldValueNotes
Server keyauto-terminalThe name Gemini shows for this server and its tools. Keep it as-is to match TermFlow's docs.
httpUrlhttp://127.0.0.1:42032/mcpTermFlow's MCP endpoint. Gemini uses the httpUrl field (not url) for streamable-HTTP servers.
headers.AuthorizationBearer <token>The bearer token. Only enforced when TermFlow is exposed on the LAN — see below.

Notice there is no type field. Gemini CLI infers a streamable-HTTP transport from the presence of httpUrl; that is the difference from Claude Code's config, which uses "type": "http" with a url field.

Where the settings file lives

Gemini CLI merges a project-scoped .gemini/settings.json (in your working directory) over your home-directory settings. For a per-project connection, put the block in:

<your-project>/.gemini/settings.json

If you already scaffolded a project with tk init, a .gemini/settings.json is created for you — but replace any MCP entry there with the config from the in-app modal, which always carries the current port and token.

Do you need the token?

TermFlow's auth model is deliberately simple, and it changes what you paste here.

  • Default (localhost only). TermFlow binds to 127.0.0.1, and in that mode every endpoint is unauthenticated — safe precisely because nothing off your machine can reach it. The Authorization header is ignored, so you can leave it in with any value, or drop the headers block entirely:

    {
    "mcpServers": {
    "auto-terminal": {
    "httpUrl": "http://127.0.0.1:42032/mcp"
    }
    }
    }
  • Exposed on the LAN. If you turn on "Expose on local network" in Settings → Connections, TermFlow starts requiring the bearer token on every request. Now the Authorization header is mandatory. Replace <token> with the auth token shown in Settings → Connections (masked; use reveal/copy). If you rotate the token there, update settings.json to match.

Use the config token, not a minted JWT

The real credential is the authToken from Settings → Connections. Do not try to authenticate with a token from POST /api/auth/token — that JWT is not checked by the auth gate.

The identity header: an important difference

Agents that TermFlow launches inside one of its own terminals are handed a $TERMFLOW_TERMINAL_ID environment variable. Claude Code and Codex CLI forward that value through an X-Termflow-Terminal-Id header, which lets tools like get_my_terminal (and the "me" shorthand) resolve to "the terminal I'm running in."

Gemini CLI can't do this automatically.

An honest note: Gemini CLI treats MCP header values as literal strings — it does not expand environment variables such as ${TERMFLOW_TERMINAL_ID}. That is why the generated Gemini config omits the X-Termflow-Terminal-Id header entirely: a ${...} placeholder would be sent verbatim and wouldn't identify anything. So out of the box, get_my_terminal / "me" have nothing to resolve against.

If you need the running Gemini agent to self-identify, pass the terminal ID explicitly. Inside the TermFlow terminal where Gemini runs, read the injected value:

echo $TERMFLOW_TERMINAL_ID

Then hard-code that literal value into the header:

{
"mcpServers": {
"auto-terminal": {
"httpUrl": "http://127.0.0.1:42032/mcp",
"headers": {
"X-Termflow-Terminal-Id": "paste-the-value-here"
}
}
}
}

Because the value is fixed per terminal, this is only worth doing for a dedicated, long-lived setup. For most workflows it's simpler to skip self-identification: call list_terminals and pass explicit terminal IDs to the other tools.

How the connection flows

Gemini talks only to the MCP server on port 42032. That sidecar bridges to TermFlow's REST API on 42031, which actually drives the terminals. (During local development from source, these are 42052 and 42051 instead — the defaults above are the installed-app ports.)

Verify it works

  1. Save settings.json and start an interactive Gemini session.
  2. Run /mcp in the session to list connected MCP servers. You should see auto-terminal with its tools available.
  3. Ask Gemini to run a tool — for example, "list my terminals" — and confirm it calls list_terminals against TermFlow.

Once connected, Gemini has access to TermFlow's seven MCP tools: list_terminals, create_terminal, execute_command, get_terminal_output, get_terminal_detail, get_my_terminal, and close_terminal. Each tool that takes a terminal id also accepts the "me" shorthand — though, as noted above, "me" only resolves for Gemini if you supplied an explicit identity header.

Server not showing up?

Check that TermFlow is running and the MCP health dot in Settings → Connections is green, that the port in httpUrl matches the MCP port shown there, and — if you enabled "Expose on local network" — that the bearer token in your config is the current one.

Next steps