Pixel Bridge MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Pixel Bridge MCPgenerate an image of a futuristic city skyline at night using gemini"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Pixel Bridge MCP
Free AI image generation for Claude Code — through the ChatGPT and Gemini web accounts you already have. A local MCP server that drives a real browser (Playwright) against provider web UIs, so you get generate_image / edit_image tools without any image-generation API keys. You log in manually once; Claude Code reviews the results with its own vision.
Bridges Claude Code → your browser → ChatGPT / Gemini image generation. Hence the name.
How it works
Claude Code ──MCP──> Pixel Bridge ──Playwright──> your logged-in browser profile
├─ chatgpt.com
└─ gemini.google.com
image saved to ./assets/… <── actual generated file downloaded
Claude Code reads the file with its own vision and judges quality itself.Key principles:
You authenticate manually, once. Each provider gets a persistent Chromium profile (
~/.pixel-bridge/profiles/<provider>). Log in yourself — including any CAPTCHA or MFA. The server never touches credentials and never attempts to bypass security challenges.The MCP is not the art critic. It returns file paths + metadata; the calling Claude Code model inspects the image visually and decides whether to keep it or regenerate with a better prompt.
Never silently "succeeds". If the real image bytes couldn't be retrieved, the job fails with a reason (refusal text, timeout, UI change, capture failure) and a debug screenshot is saved to
~/.pixel-bridge/logs/.
Related MCP server: BrowserPilot MCP
Setup (on your machine)
Option A — Managed browser (default)
git clone https://github.com/Mrshahidali420/pixel-bridge-mcp
cd pixel-bridge-mcp
npm install
npx playwright install chromium # once
npm run build
# One-time manual login per provider (opens a visible browser window):
npm run login -- chatgpt
npm run login -- geminiTip: set PIXEL_BRIDGE_BROWSER_CHANNEL=chrome to use your installed Google Chrome instead of the bundled Chromium.
Option B — Attach to your own browser (use your existing logins)
Instead of letting Pixel Bridge launch its own browser, you can attach it to a real Chrome/Edge/Brave you started, and it will use whatever logins that browser already has. Start your browser with a debugging port and a dedicated profile folder:
# Windows (PowerShell)
& "C:\Program Files\Google\Chrome\Application\chrome.exe" `
--remote-debugging-port=9222 --user-data-dir="$env:LOCALAPPDATA\pixel-bridge-chrome"
# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--remote-debugging-port=9222 --user-data-dir="$HOME/pixel-bridge-chrome"
# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir="$HOME/pixel-bridge-chrome"Log into chatgpt.com / gemini.google.com in that window (once — the profile persists), then run the MCP with:
PIXEL_BRIDGE_CDP_URL=http://127.0.0.1:9222Pixel Bridge opens its own tabs in that browser, never touches your tabs, and on shutdown closes only its tabs and disconnects — your browser keeps running. You can watch every generation live and handle any login challenge in the same window.
Why not my normal day-to-day Chrome profile? Chrome itself refuses remote debugging on the default profile (a security measure since Chrome 136 that protects your cookies from debugger-based theft), and a running Chrome locks its profile. That's why attach mode needs a dedicated
--user-data-dir— you still sign in only once there, and it stays signed in like your normal browser. Pixel Bridge does not attempt to bypass this protection.
Register with Claude Code — add to your project's .mcp.json (or claude mcp add):
{
"mcpServers": {
"pixel-bridge": {
"command": "node",
"args": ["/absolute/path/to/pixel-bridge-mcp/dist/index.js"]
}
}
}Tools
Tool | Purpose |
| Generate via |
| Upload a local image + edit instructions; saves the edited result. |
| Same prompt through both providers in parallel → two files to compare. |
| Poll a slow job by |
| Copy a completed job's image(s) to an additional location. |
| Is the persistent session logged in and usable? |
| Open the provider site (headed) and wait while you log in manually. |
Job model (a deliberate design change from the original spec)
Web generation can take minutes, which can exceed MCP client timeouts. So every generation runs as a background job that saves its own output:
generate_imagewaits inline (default 150 s). Usually the site finishes in time and you get the saved file paths directly.If not, you get a
job_idwith statusrunning— pollget_generation_status.The job writes the image to the originally requested
output_pathwhen it finishes, even if no one is polling — a client timeout never loses a finished image.download_generated_imageis therefore only for extra copies.
File handling
output_pathmay be a file (./assets/hero.png) or a directory (filename auto-derived, or passfilename).Directories are created automatically. PNG / JPEG / WebP supported — the extension follows the actual content type delivered by the provider.
Existing files are never overwritten unless
overwrite: true; a-1,-2… suffix is used instead.Results include both absolute and project-relative paths, byte size, content type, and
capture_method:"download"— the real generated file was fetched (full quality)."screenshot"— last-resort element screenshot fallback (reported honestly so Claude can decide to retry).
Aspect ratio
Web UIs expose no reliable aspect-ratio control, so aspect_ratio (e.g. "16:9") is folded into the prompt as natural language. Verify the result visually — the tool output reminds the calling model to check this.
Intended Claude Code workflow
Ask
generate_image(orgenerate_with_both) with a concrete prompt, e.g. a 16:9 hero image spec.Read the returned file with vision.
Judge: prompt match, composition, artifacts, hands/faces, unwanted text/watermarks, aspect ratio.
Keep it, or refine the prompt and regenerate. The MCP never scores quality itself.
Architecture
src/
├── index.ts MCP server + tool definitions (stdio transport)
├── cli-login.ts `npm run login -- <provider>` first-run helper
├── config.ts env-driven config (no credentials, no hardcoded paths)
├── logger.ts stderr + rolling file logs (stdout is MCP protocol)
├── files.ts path resolution, mkdir, collision-free naming
├── jobs.ts background job manager (client timeouts can't lose images)
├── browser.ts persistent Chromium profile per provider + per-provider queue
└── providers/
├── types.ts ImageProvider interface
├── base.ts shared choreography: selector fallbacks, new-image detection,
│ busy/refusal detection, download-with-screenshot-fallback
├── chatgpt.ts ChatGPT web adapter (~60 lines of provider-specific config)
├── gemini.ts Gemini web adapter (~70 lines)
└── registry.ts add future providers hereReliability decisions:
No brittle DOM assumptions: each provider supplies candidate selector lists tried in order; results are detected generically as "a new ≥300 px image appeared and stayed stable after the model stopped responding", not via provider DOM structure.
Refusal detection: if the model finishes replying with no image, the reply text is returned in the error so Claude can rephrase.
Per-provider serialization: concurrent calls to one provider queue up; different providers run in parallel (that's how
generate_with_bothworks).Debuggability: every failure saves a page screenshot to
~/.pixel-bridge/logs/, and job results include recent step-by-step logs.
Configuration (env vars, all optional)
Variable | Default | Meaning |
|
| Profiles + logs root |
|
| Browser profiles location |
|
| Headed is the default — friendlier to consumer sites and required for manual login |
| – | e.g. |
| – | Explicit browser binary path |
| – | Attach mode: connect to your own running browser (e.g. |
|
| Hard ceiling per generation |
|
| Default inline wait before returning a job id |
|
| Manual-login wait |
| – | Forwarded to the browser when set (corporate proxies) |
Security posture
No credentials in code, config, or logs; nothing to hardcode.
Sessions live only in the local browser profile —
.gitignoreexcludes profiles; never commit them (they contain live cookies).CAPTCHAs, MFA, and bot checks are never automated. When a provider challenges, the tools report it and
provider_loginhands control to you in a visible window.Respect each provider's terms of service; this drives your own account through its normal web UI at human-triggered, low volume.
Status / what's been verified
Built and smoke-tested in a headless cloud environment:
✅ Compiles clean; server starts and serves all 7 tools over MCP stdio.
✅ File naming/collision/extension logic verified with unit checks.
✅ Job lifecycle, error propagation, and failure screenshots verified.
⏳ The live browser flows (login → generate → download) need a run on a real desktop — the cloud sandbox has no display, blocks chatgpt.com entirely, and its TLS-intercepting proxy interferes with Playwright-driven navigation. First local test:
npm run login -- gemini, then ask Claude Code to generate a test image into./assets/.
Adding a provider later
Implement BaseChatProvider (URLs, selector candidates, logged-in/busy detection, prompt phrasing — see chatgpt.ts for how small that is) and register it in providers/registry.ts. Non-chat UIs can implement the ImageProvider interface directly.
Contributing
Contributions are very welcome — especially selector fixes when provider UIs change and new provider adapters (Bing Image Creator, Ideogram, Playground, …). See CONTRIBUTING.md for setup, the adapter guide, and the hard rules (no credential handling, no CAPTCHA/MFA/bot-detection bypassing, no silent success). If this project is useful to you, a ⭐ helps others find it.
License
MIT © Shahid Ali
Disclaimer
Pixel Bridge automates your own account through its normal web interface at human scale. Respect each provider's terms of service and rate limits; you are responsible for how you use it. This project is not affiliated with OpenAI, Google, or Anthropic.
Available Tools
2 toolsget_generation_statusA
Check a generation/edit job started by generate_image, edit_image or generate_with_both. Returns status, saved file paths when finished, error details on failure, and recent job logs.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The job_id returned by a generation tool | |
| wait_seconds | No | Optionally block up to this many seconds for the job to finish (default 0 = return current state) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It discloses blocking behavior (wait_seconds) and return content (status, paths, errors, logs), but does not explicitly state that the tool is read-only and non-destructive. This is adequate but could be more explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no fluff, directly conveys all necessary information. Perfectly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple input schema (2 params, 100% coverage) and no output schema, the description covers return values and usage context well. It could mention that wait_seconds defaults to 0 (return current state), but this is already in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds context by linking job_id to generation tools and explaining wait_seconds blocking, but this is already inferred from the schema. Minor added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool checks a generation/edit job's status, returns status, saved file paths, error details, and logs. It specifies the tools that start these jobs (generate_image, edit_image, generate_with_both), making the purpose distinct from the only sibling (provider_login).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (after calling generation tools) and provides clear context. It does not explicitly state when not to use it or mention alternatives, but the sibling list is minimal and unrelated, so exclusions are not critical.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
provider_loginA
Open the provider's website in the (headed) persistent browser and WAIT for the user to log in manually — including any CAPTCHA or MFA, which are never automated. Ask the user to complete the login in the opened window; returns once login is detected or the wait times out. Requires the server to run with PIXEL_BRIDGE_HEADLESS unset/false.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | Yes | Which web provider to use | |
| wait_seconds | No | How long to wait for manual login (default 300) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description fully covers behavior: opens headed browser, waits for manual login, does not automate CAPTCHA/MFA, returns on login or timeout. Also mentions server configuration requirement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the main action. Every sentence provides necessary information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the process and return behavior (detection or timeout) but does not specify the exact return value (e.g., success/failure). Still fairly complete for a login tool without output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so baseline is 3. The description adds no additional meaning beyond the schema's parameter descriptions for 'provider' and 'wait_seconds'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool opens a provider's website in a headed browser and waits for manual login, including handling CAPTCHA/MFA. It distinctly differs from its sibling get_generation_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use (manual login with CAPTCHA/MFA) and includes a configuration requirement for headless mode. It lacks explicit exclusion of alternatives, but the sibling tool is unrelated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
get_generation_status - First observed
provider_login
TDQS
Scored across 2 tools
The two tools have distinct purposes: one for authentication and one for checking job status. No overlap in functionality, making them easily distinguishable.
Tool names follow different patterns: 'get_generation_status' uses verb_noun, while 'provider_login' uses noun_verb. This inconsistency is confusing despite having only two tools.
With only two tools, the server feels under-scoped for image generation. The typical range for a well-scoped server is 3-15 tools, and this falls short.
The server lacks essential tools like generate_image or edit_image, which are critical for its domain. The presence of only login and status checking leaves major gaps.
Maintenance
Related MCP Connectors
Generate AI images, video, speech, music and presentations from Claude, ChatGPT and Cursor.
AI-powered browser automation — navigate, click, fill forms, and extract data from any website.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Stealth web automation for AI agents. Login, signup, navigate, screenshot.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to control a browser through Playwright automation tools, allowing them to perform web tasks like navigation, typing, clicking, and taking screenshots. Deployed on Cloudflare Workers and compatible with various AI platforms including Claude Desktop and VS Code.-
- AlicenseBqualityCmaintenanceA local browser automation bridge that connects AI agents like Claude to Chromium-based browsers, enabling web navigation, clicking, input, screenshots, and tab management.22GPL 3.0
- FlicenseAqualityCmaintenanceEnables Claude Code to delegate web research and image generation to ChatGPT via Playwright browser automation, allowing token-efficient search and visual design iteration without manual screenshots.4-
- AlicenseNot gradedqualityCmaintenanceBridges Claude Code to local OpenAI-compatible vision models, enabling image analysis, comparison, and OCR via three tools.2MIT