Google Flow Browser MCP
by Infraviored
README.md
<div align="center">
# π§ Google Flow Browser MCP
**Control [Google Flow](https://labs.google/fx/tools/flow) β image & video generation β directly from your AI agent via MCP.**
<p>
<img src="https://img.shields.io/badge/version-1.0.0-blue?style=flat-square" alt="Version 1.0.0">
<img src="https://img.shields.io/badge/node-%3E%3D18-green?style=flat-square" alt="Node >= 18">
<img src="https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square" alt="License MIT">
<img src="https://img.shields.io/badge/MCP-server-8A2BE2?style=flat-square" alt="MCP Server">
<img src="https://img.shields.io/badge/OpenCode-ready-4CAF50?style=flat-square" alt="OpenCode Ready">
</p>
<br>
[β¨ Features](#-features) β’
[π Quick Start](#-quick-start) β’
[π§ Tools](#-tools) β’
[βοΈ Configuration](#οΈ-configuration) β’
[π‘οΈ Safety](#οΈ-safety--ethics)
<br>
</div>
---
> **π«π· Ce serveur MCP permet Γ votre agent AI (OpenCode) d'utiliser Google Flow pour gΓ©nΓ©rer des images et des vidΓ©os, via votre propre compte Google et sans partager vos identifiants.**
---
## πΈ What It Does
This MCP server connects your AI agent to **[Google Flow](https://labs.google/fx/tools/flow)** β Google's creative suite for image and video generation. Your agent can:
- π¨ **Generate images** with Nano Banana Pro, Nano Banana 2, or Imagen 4
- π¬ **Create videos** and scenes with characters
- π§ **Manage characters** and scenes in your Flow workspace
- πΌοΈ **Use Grid Architect** for batch shot generation
- π **Discover and control** any Flow tool programmatically
All through your **own Google account** β no API keys, no third-party tokens.
---
## β¨ Features
<table>
<tr>
<td width="50%">
### π― For AI Agents
</td>
<td width="50%">
### π For Humans
</td>
</tr>
<tr>
<td>
- **15+ MCP tools** ready to use
- **Smart job queue** β no parallel conflicts
- **Auto-discover UI** β adapts to Flow changes
- **Structured logging** for debugging
- **Safe actions** β resilient click/fill logic
</td>
<td>
- **Your account, your data** β no token sharing
- **No password asked** β ever
- **Clean safety rules** β stops on captcha/verification
- **Config backup** before any modification
- **Single-job queue** β no runaway generation
</td>
</tr>
</table>
---
## π Quick Start
### Prerequisites
| What | Why |
|------|-----|
| **Node.js β₯ 18** | Runtime for the MCP server |
| **Google Chrome** | Required for browser automation |
| **OpenCode** | AI agent that connects to MCP servers |
| **A Google account** | To use Google Flow (yours, not shared) |
### 1οΈβ£ Install
```bash
git clone https://github.com/TMSSS05/google-flow-browser-mcp.git
cd google-flow-browser-mcp
npm install
```
### 2οΈβ£ Configure your Google profile
```bash
cp config/flow.config.example.json config/flow.config.json
```
Edit `config/flow.config.json`:
```json
{
"defaultProfile": "your-label",
"profiles": {
"your-label": {
"sourceProfile": "Profile 1",
"expectedAccount": "your.email@gmail.com"
}
},
"chromeUserDataDir": "/home/you/.config/google-chrome"
}
```
`profiles` is the single source of truth for every account this tool knows about β `defaultProfile` picks which entry `flow_connect` uses when you don't pass a `profile` arg. `your-label` is just a name you choose (no requirement to be an email or match anything). You never have to hand-edit this beyond the first entry β see "Adding another Google account" below; new profiles register themselves here automatically the first time they connect successfully.
> π‘ **Finding your Chrome profile:**
> Open Chrome and go to `chrome://version/`. Look for **"Profile Path"** β the last folder name is your profile (e.g., `Profile 1`), and the path before it is your `chromeUserDataDir`. `sourceProfile` is only used as a one-time seed β see below.
> β οΈ Nothing here needs to already be signed into Flow β the first `flow_connect` call handles that (next step).
### 3οΈβ£ Make scripts executable
```bash
chmod +x scripts/*.sh
```
### 4οΈβ£ Start the MCP server
```bash
./scripts/start-mcp.sh
```
There is no separate "launch Chrome first" step β `flow_connect` launches Chrome itself, from a **persistent** profile (`chrome-profile-{profile}/` in this repo, gitignored β one per entry in config's `profiles` map). The very first `flow_connect` call for a given profile needs a VISIBLE window (don't pass `headless`/`virtual_display`) so you can click your Google account in the account-chooser and complete 2FA if prompted β a one-time thing, unless seeded from `sourceProfile` (see below), which skips it entirely. Every `flow_connect` call after that reuses the same authenticated session automatically, in any display mode, with no further sign-in.
#### Adding another Google account
Each account gets its own independent, isolated Chrome profile β never your real everyday Chrome profile directly (see "why isolated copies, not your real profile" below). Two ways to set one up β **you never have to hand-edit `config/flow.config.json`'s `profiles` map**; a successful connect writes its own entry there automatically, backing up the previous config first:
**A) Fresh sign-in through this tool** (simplest, but needs one manual step):
```
flow_connect({ profile: "some-label", headless: false, virtual_display: false })
```
Pick any `profile` label you like β it's just a directory name, no requirement to be an email or match anything. This opens a real visible Chrome window on Google's account-chooser; sign into whichever account you want, complete 2FA if prompted, then re-run `flow_connect` with the same `profile` key. The moment the account is verified, its email is written into `config.profiles["some-label"]` automatically. Every call after that reuses it automatically.
**B) Seed from an already-signed-in system Chrome profile** (no manual step at connect time, but requires prep in your *real* Chrome first):
1. In your real Chrome, create a new profile (Chrome's own profile picker β "Add") and sign into the Google account you want to use.
2. **While still in that profile**, visit **https://labs.google/fx/tools/flow** and accept Flow's terms/contract once β otherwise the seeded copy will land on the same one-time contract-acceptance screen the very first time you use it.
3. Find that profile's directory name: go to `chrome://version/` in it and read **"Profile Path"** β the last folder name (e.g. `Profile 3`) is what you need.
4. Hand that name to `flow_connect` as `source_profile`, along with your own chosen `profile` label β only needed this once:
```
flow_connect({ profile: "some-label", source_profile: "Profile 3", virtual_display: true })
```
This copies that system profile's session into its own `chrome-profile-some-label/` β no interactive sign-in needed, works headed or on a virtual display right away. On success, `config.profiles["some-label"] = { sourceProfile: "Profile 3", expectedAccount: "<discovered email>" }` gets written automatically β future connects need only `{ profile: "some-label" }`, no `source_profile` required again (useful if the persistent copy ever needs re-seeding after being deleted).
**Why an isolated copy instead of automating your real profile directly?** Chrome won't run two instances against the same profile directory at once (`SingletonLock`) β pointing automation straight at your daily-driver profile would either fail to start or force-close your real browser. The copy is a one-time snapshot at connect time (not a live sync), so your real profile is never touched again afterward and automation flags never bleed into your everyday browsing fingerprint.
Switching `profile` on a later call automatically closes whatever's running and relaunches under the requested one. Once a profile has a recorded `expectedAccount`, future connects under that same key verify against it and fail loud on a mismatch; a brand-new profile with nothing recorded yet just reports whichever account is found.
### 5οΈβ£ Register with OpenCode
```bash
./scripts/register-opencode.sh
```
> π **Restart OpenCode** after registration for the changes to take effect.
### β
Verify it works
```bash
./scripts/test-flow-image.sh
```
---
## ποΈ Architecture
```
google-flow-browser-mcp/
β
βββ π config/
β βββ flow.config.example.json # Configuration template
β βββ selectors.map.json # UI selectors (auto-populated)
β
βββ π scripts/
β βββ start-browser.sh # DEPRECATED β flow_connect launches Chrome itself now
β βββ start-mcp.sh # Start the MCP server
β βββ test-flow-image.sh # Quick integration test
β βββ register-opencode.sh # Register in OpenCode config
β
βββ π src/
β βββ index.js # MCP server entry point
β β
β βββ π browser/ # Chrome & CDP management
β β βββ connect.js # CDP connection manager
β β βββ launch-profile.js # Chrome profile launcher
β β βββ account-check.js # Verify Google account
β β βββ safe-actions.js # Safe click, fill, detection
β β
β βββ π tools/ # All MCP tool implementations
β β βββ flow-open.js # Navigate to Flow
β β βββ flow-status.js # Connection status
β β βββ generate-image.js # Image generation
β β βββ generate-video.js # Video generation (setup only)
β β βββ download-latest.js # Download generated files
β β βββ create-character.js # Create a character
β β βββ import-character.js # Import character JSON
β β βββ open-characters.js # List characters
β β βββ create-scene.js # Create a scene
β β βββ open-tools-gallery.js # Open tools gallery
β β βββ grid-architect.js # Batch shot generation
β β βββ discover-ui.js # UI discovery & mapping
β β βββ use-flow-tool.js # Generic tool opener
β β
β βββ π queue/ # Job management
β β βββ job-queue.js # Single-job queue
β β
β βββ π utils/ # Helpers
β βββ config.js # Config loader
β βββ logger.js # Structured logging
β βββ errors.js # Error codes & types
β βββ file-manager.js # File download/save
β βββ screenshots.js # Screenshot capture
β
βββ π output/ # Generated files land here
```
---
## π§ Tools
All tools are organized by function for easy discovery.
### π Connection & Status
| Tool | Description |
|------|-------------|
| `flow_connect` | Launch Chrome, connect CDP, navigate to Google Flow |
| `flow_disconnect` | Close browser and clean up all connections |
| `flow_status` | Full status: connection, Flow loaded, account, queue state |
| `flow_account_check` | Verify logged-in account matches configured email |
| `flow_screenshot` | Capture a screenshot of the current Flow page |
### π¨ Image Generation
| Tool | Description |
|------|-------------|
| `flow_generate_image` | Generate image with **Nano Banana Pro**, **Nano Banana 2**, or **Imagen 4**. Supports aspect ratios, reference images, and brand-based model selection. |
| `flow_download_latest` | Download the most recently generated file |
### π¬ Video Generation
| Tool | Description |
|------|-------------|
| `flow_generate_video` | Set up video generation (Omni Flash, Veo models, custom duration/ratio). β οΈ **Stops at "ready to generate" β no credit consumed.** |
| `flow_create_scene` | Create a video scene with characters and a text prompt |
### π€ Characters
| Tool | Description |
|------|-------------|
| `flow_create_character` | Create a new character with name, description, and optional reference images |
| `flow_import_character` | Import a character from a saved JSON file |
| `flow_open_characters` | Open the characters page and list all existing characters |
### π οΈ Tools & Discovery
| Tool | Description |
|------|-------------|
| `flow_open_tools_gallery` | Open the tools gallery and browse available tools |
| `flow_use_tool` | Open any Flow tool by name with optional parameters |
| `flow_use_grid_architect` | Configure Grid Architect for batch shot generation with theme prompts, visual logic, and reference images |
| `flow_discover_ui` | Discover and map all interactive elements (buttons, inputs, headings) on any Flow page |
### π Queue & Monitoring
| Tool | Description |
|------|-------------|
| `flow_queue_status` | Check job queue: active job, pending queue, completed and failed history |
---
## βοΈ Configuration
Edit `config/flow.config.json` (copy from `config/flow.config.example.json`):
### π Essential
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `expectedAccount` | `string` | β | Your Google account email β
**REQUIRED** |
| `chromeProfile` | `string` | `"Profile 1"` | Chrome profile directory name β only used once, to seed the persistent profile (see setup step 4) |
| `chromeUserDataDir` | `string` | β | Full path to Chrome user data directory β
**REQUIRED** |
| `flowUrl` | `string` | *Flow labs URL* | Google Flow URL (supports `fr`, `en` locales) |
### π§ Advanced
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `cdpPort` | `number` | `9222` | Chrome DevTools Protocol port |
| `browserMode` | `string` | `"direct-cdp"` | `"direct-cdp"` (recommended) or `"playwright"` |
| `headless` | `boolean` | `false` | True Chrome headless. Fastest, but Flow's generate/upscale actions are reCAPTCHA-gated and headless scores worse on bot-detection β not recommended for anything that spends credits. |
| `virtualDisplay` | `boolean` | `false` | Run headed Chrome on an off-screen Xvfb display (`xvfb` package required) instead of your real screen β same rendering fingerprint/bot-detection profile as a normal visible window, but doesn't take over your mouse/keyboard/focus. Recommended over `headless` for unattended use once the profile is already authenticated (see setup step 4). |
| `locale` | `string` | `"fr"` | UI locale (`"fr"`, `"en"`, etc.) |
### β±οΈ Timing
| Key | Default | Description |
|-----|---------|-------------|
| `jobTimeoutMs` | `300000` (5 min) | Max job execution time |
| `actionDelayMs` | `800` | Delay between UI actions (anti-detection) |
| `generationPollIntervalMs` | `5000` (5s) | How often to poll for generation completion |
| `maxPollAttempts` | `120` | Max polling attempts before timeout |
| `downloadWaitMs` | `30000` (30s) | Wait time for file download |
### π¨ Models & Ratios
| Key | Description |
|-----|-------------|
| `imageModels` | Available models: `Nano Banana Pro`, `Nano Banana 2`, `Imagen 4` |
| `videoModels` | Available models: `Omni Flash`, `Veo 3.1 - Lite/Fast/Quality` |
| `ratios` | Supported aspect ratios: `16:9`, `4:3`, `1:1`, `3:4`, `9:16` |
---
## π‘οΈ Safety & Ethics
This project is built with **safety-first design**:
| β
Principle | How it's enforced |
|-------------|-------------------|
| **Your account only** | Uses your own Google profile β never asks for or stores passwords |
| **No credential theft** | Never exports cookies, tokens, or session data |
| **No bypass** | Stops cleanly on captcha, login walls, or verification challenges |
| **No parallel abuse** | Single-job queue prevents concurrent generation |
| **Credit-safe video** | Video generation sets up parameters but stops before the final "Generate" click (no credit consumed) |
| **Config backup** | Backs up OpenCode config before any modification |
> β οΈ **This is a browser automation tool.** Use it responsibly and in accordance with Google's Terms of Service.
---
## β FAQ
### Getting Started
<details>
<summary><strong>Which Chrome profile should I use?</strong></summary>
Open Chrome and go to `chrome://version/`. The **Profile Path** shows both your user data directory and profile name. For example:
- `/home/you/.config/google-chrome/Profile 1` β `chromeUserDataDir: "/home/you/.config/google-chrome"`, `chromeProfile: "Profile 1"`
This is only used once, to seed the MCP's own persistent copy β you don't need to already be signed into Flow in this profile. The first `flow_connect` call walks you through sign-in interactively (see setup step 4).
</details>
<details>
<summary><strong>Can I use this without OpenCode?</strong></summary>
Yes! Any MCP-compatible client (Claude Desktop, Continue.dev, etc.) can connect to this server. Just point your MCP config to `node /path/to/src/index.js`.
</details>
### Troubleshooting
<details>
<summary><strong>Chrome doesn't start</strong></summary>
Make sure Chrome is installed at the expected path. On Linux, the default is `/opt/google/chrome/chrome`. Edit `scripts/start-browser.sh` to set the correct `CHROME` path for your system.
</details>
<details>
<summary><strong>CDP port already in use</strong></summary>
The script checks for existing Chrome instances on port 9222. If something else is using that port, you can change `cdpPort` in `config/flow.config.json` (and update the script's `CDP_PORT` variable).
</details>
<details>
<summary><strong>"Expected account mismatch"</strong></summary>
Verify that `expectedAccount` in `config/flow.config.json` matches the email logged into your Chrome profile. Use `flow_account_check` to verify.
</details>
<details>
<summary><strong>Flow UI changed and tools don't work</strong></summary>
Run `flow_discover_ui` to re-map selectors. The `selectors.map.json` will auto-update with new UI element positions.
</details>
### Usage
<details>
<summary><strong>How do I generate images?</strong></summary>
Your AI agent calls `flow_generate_image` with a text prompt. Optionally specify model (`Nano Banana 2` is default), aspect ratio, and reference images. The server waits for completion and makes the file available for download.
</details>
<details>
<summary><strong>Can I generate videos for free?</strong></summary>
`flow_generate_video` sets up the video parameters (model, ratio, duration) but **stops before clicking Generate**. This lets you review the setup before consuming credits. The actual generation requires a paid Google Flow subscription.
</details>
---
## π€ Contributing
Contributions are welcome! Please follow these guidelines:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Commit your changes (`git commit -m 'Add my feature'`)
4. Push to the branch (`git push origin feature/my-feature`)
5. Open a Pull Request
---
## π License
[MIT](./LICENSE) Β© TMSSS05
---
<div align="center">
<sub>Built with β€οΈ for the OpenCode ecosystem</sub>
<br>
<sub>
<a href="https://github.com/TMSSS05/google-flow-browser-mcp/issues">Report Issue</a> Β·
<a href="https://github.com/TMSSS05/google-flow-browser-mcp/discussions">Discussion</a>
</sub>
</div>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues