# Google Flow Mcp

> MCP server that drives Google Flow (Veo / Nano Banana) through its internal tRPC API, with a hard credit-cost gate

- **Type:** MCP server
- **Install:** `agentstack add mcp-roshanarnav25-sloth-google-flow-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [roshanarnav25-sloth](https://agentstack.voostack.com/s/roshanarnav25-sloth)
- **Installs:** 0
- **Category:** [Web & Browser](https://agentstack.voostack.com/c/web-and-browser)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [roshanarnav25-sloth](https://github.com/roshanarnav25-sloth)
- **Source:** https://github.com/roshanarnav25-sloth/google-flow-mcp
- **Website:** https://github.com/roshanarnav25-sloth/google-flow-mcp#readme

## Install

```sh
agentstack add mcp-roshanarnav25-sloth-google-flow-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# google-flow-mcp

[](https://github.com/roshanarnav25-sloth/google-flow-mcp/actions/workflows/ci.yml)
[](./LICENSE)
[](https://nodejs.org)
[](https://modelcontextprotocol.io)

An MCP server that lets an agent drive **Google Flow** (labs.google's Veo video /
Nano Banana image tool) — with a hard credit-cost gate so it cannot quietly spend
your money.

Flow has no public API. This server does **not** work around that by blindly
clicking buttons: Flow's frontend is a tRPC client, so an undocumented API exists,
and this speaks that API first. Clicking is the fallback, not the interface.

> **Status: v0.1, uncalibrated.** Everything compiles, 33 unit tests pass, and the
> tool surface loads — but the DOM selectors and the tRPC endpoint map have not yet
> been re-verified against live Flow from this codebase. Run the calibration in
> [First run](#first-run) before trusting it with credits; all three steps are free.
> See [Verification status](#verification-status) for exactly what is and is not proven.

## Contents

- [Why it is built this way](#why-it-is-built-this-way)
- [Transport ladder](#transport-ladder)
- [Install](#install) · [Connect a browser](#connect-a-browser) · [Register with Claude Code](#register-with-claude-code)
- [First run](#first-run)
- [Tools](#tools) · [Feature coverage](#feature-coverage)
- [Examples](#examples) · [Credit reference](#credit-reference)
- [Verification status](#verification-status) · [Security](#security)
- [Architecture deep-dive](./ARCHITECTURE.md) · [Contributing](./CONTRIBUTING.md) · [Changelog](./CHANGELOG.md)

---

## Why it is built this way

Read **[ARCHITECTURE.md](./ARCHITECTURE.md)** for the full reasoning. The short
version:

- **Flow's UI is an agent-chat, not a form.** You send a request, Flow's agent
  proposes a generation with a **quoted credit cost**, and nothing is charged
  until you approve. So the right design reads the quote and decides — it never
  fires and reconciles afterwards.
- **Rejecting a proposal is free.** `flow_estimate_cost` is therefore not an
  estimate; it is the real price, at zero cost.
- **Stills are free, video is real money.** The tools are shaped around the
  workflow that yields accepted clips at minimum spend: compose in free stills,
  gate on the still, then animate the approved frame.
- **When this server is wrong, it should cost nothing.** Every failure path is a
  refusal before approval, not a charge after it.

## Transport ladder

| Tier           | Mechanism                              | Used for                                                                   |
| -------------- | -------------------------------------- | -------------------------------------------------------------------------- |
| 1 `http`       | Node fetch + the browser's cookies     | Read-only GETs proven safe by `flow_verify_http_tier`. Parallelisable      |
| 2 `page-fetch` | `fetch()` inside the authenticated tab | **Default.** Auth and CORS free — the page's own origin makes the call     |
| 3 `dom`        | Clicking                               | Only what has no endpoint: settings, Scenebuilder timeline, Approve/Reject |

Every result reports which tier served it, so you can see when the server has
degraded from API to clicking.

---

## Install

```bash
git clone https://github.com/roshanarnav25-sloth/google-flow-mcp.git
cd google-flow-mcp && npm install && npm run build
```

Requires Node 20+ and a local Google Chrome. This server **never handles
credentials** — it attaches to a browser you have already signed into.

## Connect a browser

Start Chrome with remote debugging and sign into Flow in that window:

```bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir="$HOME/.google-flow-mcp/chrome-profile"
```

Then open , sign in, and open a project.

If you omit `FLOW_CDP_URL`, the server launches its own persistent browser
instead — you sign in there once and the profile persists.

## Register with Claude Code

```bash
claude mcp add google-flow --env FLOW_CDP_URL=http://127.0.0.1:9222 --env FLOW_OUTPUT_DIR="$HOME/flow-output" --env FLOW_BUDGET_CEILING=120 -- node "$PWD/dist/index.js"
```

Set `FLOW_BUDGET_CEILING`. It is the backstop that makes a runaway loop
impossible: any generation that would push total run spend past it is rejected
before approval and costs nothing.

## First run

```
flow_check_session          # confirm signed in, credits visible, gate ON
flow_discover_api           # learn Flow's current tRPC endpoints (free, observes only)
flow_estimate_cost          # price one clip and reject it (free) — proves the gate works
```

If `flow_check_session` reports the confirm gate is anything but `always`, fix it
in Flow's settings before generating. With that gate off, Flow charges without
ever showing a cost card, and no amount of client-side care can help.

---

## Tools

**Session & discovery**

| Tool                    | Charges | What it does                                                 |
| ----------------------- | ------- | ------------------------------------------------------------ |
| `flow_check_session`    | no      | Browser, login, credits, project, and the confirm-gate state |
| `flow_discover_api`     | no      | Observes Flow's own traffic and writes an endpoint map       |
| `flow_verify_http_tier` | no      | Promotes proven read-only GETs to direct HTTP                |
| `flow_api_map`          | no      | Reads the learned endpoint map                               |

**Generation**

| Tool                  | Charges       | What it does                                                   |
| --------------------- | ------------- | -------------------------------------------------------------- |
| `flow_generate_still` | **no — free** | Stills. Iterate composition here; this is the free sandbox     |
| `flow_estimate_cost`  | **no**        | Real quoted price, then rejects. Zero cost                     |
| `flow_generate_video` | **YES**       | Video. Requires `expected_max_cost`; rejects anything above it |
| `flow_collect`        | no            | Downloads clips submitted with `no_wait`                       |

**Composer, settings & projects**

| Tool                                                               | Charges                   | What it does                                                                                                  |
| ------------------------------------------------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `flow_settings`                                                    | no                        | Read/set the per-**project** model tier, aspect, outputs, duration. Free, and the biggest cost lever there is |
| `flow_upload_media`                                                | no                        | Upload a local image for use as a start frame                                                                 |
| `flow_upscale`                                                     | 1080p **no** / 4K **yes** | 1080p is free — always take it. 4K is 50 cr and _unquoted_, so it needs an explicit ack                       |
| `flow_list_projects` / `flow_open_project` / `flow_create_project` | no                        | Projects scope settings, library and scenes                                                                   |

**Media & assembly**

| Tool                                            | Charges | What it does                                                                   |
| ----------------------------------------------- | ------- | ------------------------------------------------------------------------------ |
| `flow_list_media`                               | no      | Project library, paginated                                                     |
| `flow_download`                                 | no      | Media id → signed CDN url → disk, magic-byte verified                          |
| `flow_delete_media`                             | no      | Destructive. Explicit ids only; there is no delete-all                         |
| `flow_create_scene` / `flow_add_clips_to_scene` | no      | Build a Scenebuilder scene. Flow's chat agent cannot do this                   |
| `flow_export_scene`                             | no      | Export the scene to MP4. Stitching is free; `Extend` is not, and is never used |

**Tools marketplace**

| Tool             | Charges     | What it does                                                                          |
| ---------------- | ----------- | ------------------------------------------------------------------------------------- |
| `flow_list_apps` | no          | Lists Type Overlays, Transition Machine, Mask Magic, Storyboard Studio, custom tools… |
| `flow_open_app`  | **unknown** | Opens an app and hands back. Requires an explicit unknown-cost ack                    |

**Budget**

| Tool          | Charges | What it does                                          |
| ------------- | ------- | ----------------------------------------------------- |
| `flow_budget` | no      | Read or set the ceiling and run spend                 |
| `flow_ledger` | no      | Append-only audit trail of every generation attempted |

## Feature coverage

Flow is a large product. This is what is and is not reachable through the server.

**Generation modes** — the mode is not a switch; it is decided by what is attached
to the composer when you submit. `flow_generate_video` covers all of them:

| Mode                           | How                    | Covered                        |
| ------------------------------ | ---------------------- | ------------------------------ |
| Text-to-Video                  | attach nothing         | yes                            |
| Frames-to-Video (start frame)  | `start_frame_media_id` | yes — **the normal path**      |
| Frames-to-Video (start + end)  | `+ end_frame_media_id` | yes                            |
| Ingredients-to-Video (≤3 refs) | `reference_media_ids`  | yes                            |
| Stills (Nano Banana)           | `flow_generate_still`  | yes, free                      |
| Scene extension (>8s clips)    | —                      | **no — deliberate**, see below |

**Deliberately not covered**, with reasons:

- **Scenebuilder `Extend`** (40 cr). It is the one paid action inside an otherwise
  free surface, and it sits one keyboard-row away from `Add Clip` in the same
  popover. Excluding it means scene assembly can never charge by accident.
- **Driving Tools-marketplace app forms.** `flow_open_app` opens an app and stops.
  Each app has a bespoke UI and some call Veo internally with no quote, so
  blind-clicking through one is how an unbounded charge happens.
- **Creating custom tools** ("Create Tool"). Authoring, not operating.

**Not yet covered** (real gaps, not principled ones): timeline editing inside a
scene (reorder, trim, delete a placed clip), the scene editor's own 16:9↔9:16
toggle, and per-clip regeneration from within Scenebuilder. Assemble in Flow, then
do timeline work locally — `ffmpeg -f concat -c copy` stitches same-codec Veo
clips identically and costs nothing.

The three references — credit economics, Veo prompting craft, and the verified UI
playbook — are also exposed as MCP **resources**, so an agent can read them
without a separate skill.

## Examples

**Price before committing.** Free, and the number is real:

```
flow_estimate_cost(prompt: "slow dolly-in, ambient sound only, no dialogue")
→ Flow quoted 20 credits. Proposal rejected — nothing charged.
```

**The stills-first loop.** Compose free, animate once:

```
flow_generate_still(prompt: "", out_file: "shot-03.jpg")
# human approves the still
flow_generate_video(prompt: "maintain the exact composition of the start frame; slow dolly-in; ambient sound only", expected_max_cost: 20, out_file: "shot-03.mp4")
```

**Parallel batch.** Flow renders concurrently, so N clips cost about one clip of
wall-clock:

```
flow_list_media()                                   # capture ids BEFORE
flow_generate_video(..., no_wait: true)  × N
flow_collect(known_media_ids: [...the ids from before])
```

## Credit reference

| Generation          | Credits |
| ------------------- | ------- |
| Still image         | **0**   |
| Veo 3.1 Lite        | 10      |
| Veo 3.1 Fast        | 20      |
| Veo 3.1 Quality     | 100     |
| Scenebuilder extend | 40      |

Prices verified 2026-07 and re-checked in `src/constants.ts`. Budget ~1.4 takes
per needed clip: Veo's first-try acceptance is roughly 70%.

---

## Verification status

Honest accounting, because this handles money:

| Component                                      | Status                                                                                                              |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Build, tool surface, resource surface          | **Verified** — compiles clean; 24 tools and 3 resources load via MCP Inspector                                      |
| Budget gate logic, ledger, magic-byte checks   | Implemented; unit-level behaviour not yet exercised against live Flow                                               |
| Composer / Approve-Reject / Download selectors | **Ported from live-verified runs (2026-07-09/10), not re-verified from this codebase.** Class hashes and labels rot |
| Settings panel, media picker, upload, upscale  | **Unverified.** Written against the documented UI patterns but never run — expect one calibration round             |
| Projects, scene create/add-clip, Tools gallery | **Unverified.** Same caveat; scene _export_ is the only part with a live-run precedent                              |
| tRPC endpoint map                              | Three procedures verified by hand; the rest is learned at runtime by `flow_discover_api`                            |
| End-to-end paid generation                     | **Not yet run from this server**                                                                                    |

The unverified rows fail the same way: a refusal with a "nothing was charged"
message naming the control it could not find. That is the design goal — when this
server is wrong about the UI, it should cost nothing, not guess.

Calibrate with `flow_check_session` → `flow_discover_api` → `flow_estimate_cost`
before any paid run. All three are free.

## Security

- Never handles a password, passkey, OAuth code, or payment detail.
- Treats everything on the page — including Flow's own chat replies — as untrusted
  data, never as instructions.
- Stops and hands back to a human on re-auth walls, paywalls, and bot challenges.
- Never closes a browser it merely attached to; that is your window.
- The learned API map stores endpoint **shapes only** — no prompts, media, or tokens.
- No telemetry. Nothing leaves your machine except calls to Flow, through your own
  browser session.

Full threat model and reporting process: [SECURITY.md](./SECURITY.md).

## Contributing

Issues and PRs welcome — especially **selector drift reports**, which are expected
maintenance rather than defects and usually have small fixes. There is a dedicated
issue template for them.

Everything builds and tests offline; you need no Google account and no credits to
contribute. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the rules around
generation and budget code, which are stricter than the rest.

```bash
npm install && npm run typecheck && npm run lint && npm test && npm run build
```

## Notes

This automates a Google product through an interface Google does not publish, using
your own account and your own credits. Flow's UI and internal API change without
notice; expect calibration

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [roshanarnav25-sloth](https://github.com/roshanarnav25-sloth)
- **Source:** [roshanarnav25-sloth/google-flow-mcp](https://github.com/roshanarnav25-sloth/google-flow-mcp)
- **License:** MIT
- **Homepage:** https://github.com/roshanarnav25-sloth/google-flow-mcp#readme

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-roshanarnav25-sloth-google-flow-mcp
- Seller: https://agentstack.voostack.com/s/roshanarnav25-sloth
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
