Model Context Protocol (MCP) server that lets GitHub Copilot Chat spin up real AdsPower browser profiles, validate frontend builds, and iterate on Selenium-based RPA bots until they pass live testing.
This MCP works with our AdsPower Client gem.
1. Use adspower.start_session with {"profile_id":"koyynup","headless":false}
2. In the browser that you just opened, go to the page `https://google.com`
3. Write into the file `google.rb` a script that executes a google seearch, and return an array of organic results, ignoring ads.
4. Use the MCP `ruby-adspower-mcp` to test your own code and verify it is working fine.
My AdsPower API key is `<your AdsPower API key here>`.
Use the profile `<profile ID here>` for running your tests.
- Frontend loops: Render ERB/HTML/CSS/JS in a real AdsPower-controlled Chrome instance, inspect DOM/JS state, and re-run after each fix.
- Automation loops: Execute Ruby automation snippets that receive the actual
Selenium::WebDriverinstance, observe failures, and patch the script without leaving Copilot. - Safety & cleanup: Reuses adspower-client primitives for profile lifecycle, so every browser session is started/stopped exactly as AdsPower expects.
- Ruby 3.1.2
- AdsPower desktop app (or headless server) running on the same host
- Valid AdsPower API key with Local API enabled
- ChromeDriver matching the AdsPower Chromium build (handled by your AdsPower install)
git clone https://github.com/your-org/ruby-adspower-mcp.git
cd ruby-adspower-mcp
bundle install
chmod +x bin/ruby-adspower-mcpThe server reads the following environment variables (load them via .env or export in your shell). At minimum you must set ADSPOWER_API_KEY.
| Variable | Required | Purpose |
|---|---|---|
ADSPOWER_API_KEY |
✅ | AdsPower Local API key. |
ADSPOWER_HOST |
Local API host (default http://127.0.0.1). |
|
ADSPOWER_PORT |
Local API port (default 50325). |
|
ADSPOWER_HEADLESS |
Default headless mode (true / false, default false). |
|
ADSPOWER_SERVER_LOG |
Where AdsPower server logs should go (default ~/adspower-client.log). |
Example .env:
ADSPOWER_API_KEY=xxxxxxxxxxxxxxxx
ADSPOWER_HOST=http://127.0.0.1
ADSPOWER_PORT=50325
ADSPOWER_HEADLESS=falseAdd .vscode/mcp.json to your project that uses this browser automation:
{
"servers": {
"adspower": {
"command": "/absolute/path/to/ruby-adspower-mcp/bin/ruby-adspower-mcp",
"args": []
}
}
}Reload VS Code (Command Palette → “Developer: Reload Window”) after editing so Copilot picks up the new MCP server.
bundle exec ruby bin/ruby-adspower-mcpThe server speaks JSON-RPC over stdio (as required by MCP). Normally Copilot launches it automatically; running it manually is useful for debugging environment issues.
In the `ruby-adspower-mcp` project, use adspower.start_session with {"profile_id":"YOUR_PROFILE","headless":false} so we have a live browser to debug the current signup form.
In the `ruby-adspower-mcp` project, call adspower.navigate for profile "YOUR_PROFILE" and load http://localhost:3000 to verify that yesterday's CSS fixes render correctly.
In the `ruby-adspower-mcp` project, run adspower.dom_snapshot with {"profile_id":"YOUR_PROFILE","locator":{"using":"css","value":"form#signup input"},"max_nodes":10} and summarize which inputs fail validation.
In the `ruby-adspower-mcp` project, execute adspower.execute_script using {"profile_id":"YOUR_PROFILE","script":"return window.__LAST_ERROR__ || null;"} to see if the frontend logged runtime errors.
In the `ruby-adspower-mcp` project, call adspower.run_workflow with {"profile_id":"YOUR_PROFILE","code":"driver.navigate.to('https://app.example.com/login'); driver.find_element(:css,'#email').send_keys('bot@example.com'); driver.find_element(:css,'#password').send_keys('secret', :enter); sleep 2; driver.title"} and report the workflow output.
I already launched a browser from `profile.rb`. Use adspower.attach_session with {"profile_id":"YOUR_PROFILE"}, inspect the DOM around my failing selector, and keep the browser running when done.
| Tool | What it does |
|---|---|
adspower.start_session |
Starts or reuses an AdsPower profile and returns session metadata (headless mode, start time). |
adspower.attach_session |
Attaches MCP to an AdsPower profile that is already running (for example, started by profile.rb). |
adspower.stop_session |
Stops/detaches session. Stops browser for MCP-owned sessions; attached sessions are detached unless forced. |
adspower.detach_session |
Detaches MCP from the session and keeps the external browser running. |
adspower.navigate |
Calls driver.get(url) so Copilot can load local builds or remote staging URLs. |
adspower.dom_snapshot |
Returns full HTML or a limited set of nodes found via CSS/XPath/ID/class selectors. |
adspower.execute_script |
Runs arbitrary JavaScript in the tab to check DOM state, fire events, or mutate the UI. |
adspower.run_workflow |
Evaluates Ruby automation snippets with the Selenium driver object already bound. Ideal for RPA flows (click/type/submit, assert, retry). |
Each tool enforces AdsPower profile IDs per call so multiple browser projects can run in parallel.
adspower.start_sessionwith your profile ID (headless optional).adspower.navigateto load the HTML/JS you are iterating on (usefile://URLs, a local dev server, or a deployed preview).- Call
adspower.dom_snapshotoradspower.execute_scriptto gather the current DOM state, errors, or layout signals. - Apply code fixes in your repo, rerun build/integration steps, and trigger another navigation + snapshot until the UI behaves correctly.
- Start the profile.
- Use
adspower.run_workflowto send a Ruby snippet. Example:
driver.navigate.to("https://example.com/login")
driver.find_element(:css, "#email").send_keys("bot@example.com")
driver.find_element(:css, "#password").send_keys("secret", :enter)
sleep 2
driver.find_element(:css, "#status").text- Inspect the returned hash: when
status == "ok"you get the Ruby return value plus captured stdout; whenstatus == "error"you receive the exception class/message/backtrace for diagnosis. - Iterate until the automation completes the workflow, then stop the session.
You can debug a live browser launched outside MCP (for example by sdk/p/profile.rb) without changing that script.
- Run your
profile.rbcommand normally so AdsPower browser is already open. - Ask Copilot to call:
adspower.attach_session with {"profile_id":"YOUR_PROFILE"}
- Use
adspower.dom_snapshot,adspower.execute_script, oradspower.run_workflowto inspect/fix the failing path. - When done, call:
adspower.detach_session with {"profile_id":"YOUR_PROFILE"}
This keeps the browser/session alive for profile.rb.
If you really need to terminate that externally-started browser from MCP, call:
adspower.stop_session with {"profile_id":"YOUR_PROFILE","force_stop_browser":true}
- AdsPower plus Selenium are the source of truth. Keep the browser open while Copilot edits HTML/JS or Ruby automation, and re-run the relevant tool after every change.
- The MCP server never mocks DOM responses; snapshots and script results come directly from the running tab.
- When a workflow fails, Copilot should fix the code and call the tool again—repeat until the failure disappears.
ADSPOWER_API_KEY missing– export the key or create a.envfile before starting the MCP server.- Browser never opens – confirm the AdsPower desktop app (or headless server) is running and the Local API port matches
ADSPOWER_PORT. profile_id is required– every tool needs the target AdsPower profile ID; create one ahead of time via the AdsPower UI oradspower-clientgem.Profile <id> is not running. Start it first.–adspower.attach_sessiononly works if the profile/browser is already active.- Hanging sessions – run
adspower.stop_sessionor kill the profile from AdsPower’s UI; the MCP server also cleans up on exit.
These docs explain the driver lifecycle patterns that this MCP server follows.
Happy automating!