Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ module("html2png", "./tutorials/html2png")
module("serve-from-directory", "./tutorials/serve-from-directory")
module("js-java", "./tutorials/js-java")
module("crx-extensions", "./tutorials/crx-extensions")
// Automation with MCP
module("mcp-devtools", "./tutorials/ai/mcp-devtools")
module("mcp-extension", "./tutorials/ai/mcp-extension")
98 changes: 98 additions & 0 deletions tutorials/ai/mcp-devtools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# DevTools Protocol ↔ Playwright MCP ↔ LLM

Automates JxBrowser using the [Playwright MCP server][playwright-mcp],
the Chrome DevTools Protocol, and an MCP host like [Cursor][cursor] or
[Claude Desktop][claude].

## Prerequisites

- Java 17+
- Node.js 20+
- A valid [JxBrowser license][licensing]
- An MCP host, such as [Cursor][cursor] or [Claude Desktop][claude].

## Set up MCP server

### Cursor

1. Open Cursor.
2. Go to **Settings...** → **Cursor Settings** → **Tools & MCP**.
3. In the **Installed MCP Servers** tab, click **New MCP Server**.
4. Add the following JSON to your config:

```json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--cdp-endpoint",
"http://localhost:9222"
]
}
}
}
```

http://localhost:9222 must match the debugging URL used by JxBrowser.

5. Save the config and ensure the **playwright** MCP server is enabled.

### Claude Desktop

1. Open Claude Desktop.
2. Go to **Settings...** → **Claude Desktop Settings** → **Developer**.
3. Click the **Edit Config** button to open the configuration file.
4. Add the following JSON to your config:

```json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--cdp-endpoint",
"http://localhost:9222"
]
}
}
}
```

http://localhost:9222 must match the debugging URL used by JxBrowser.

5. Save the configuration file and restart Claude Desktop.

## Run the application

Clone this repository:

```bash
git clone https://github.com/TeamDev-IP/JxBrowser-Examples
```

From the project root, run the app with your license key:

```bash
./gradlew :mcp-devtools:run -Djxbrowser.license.key="<your-license-key>" -Ddebugging.url=http://localhost:9222
```

`-Ddebugging.url` must match the value in the MCP config. If omitted, it
defaults to http://localhost:9222.

This launches a Java window with JxBrowser and enables remote debugging.

## Start automating

Open the AI chat in Cursor or Claude Desktop and try commands like:
> "Open Google and search for TeamDev. Return the company’s phone number."

The MCP host will send requests to the Playwright MCP server, which controls
JxBrowser via the DevTools Protocol.

[playwright-mcp]: https://github.com/microsoft/playwright-mcp
[cursor]: https://cursor.com/
[claude]: https://claude.ai/download
[licensing]: https://teamdev.com/jxbrowser/docs/guides/introduction/licensing/
27 changes: 27 additions & 0 deletions tutorials/ai/mcp-devtools/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2025, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
* disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

plugins {
application
}

application {
mainClass = "com.teamdev.jxbrowser.examples.DevToolsMCP"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2025, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
* disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package com.teamdev.jxbrowser.examples;

import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.view.swing.BrowserView;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URI;
import java.net.URISyntaxException;

import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;
import static javax.swing.SwingConstants.CENTER;
import static javax.swing.SwingUtilities.invokeLater;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;

/**
* An example app that demonstrates how to automate JxBrowser using
* the Chrome DevTools Protocol and a Playwright MCP server.
*
* <p>This example:
* <ol>
* <li>Starts a Chromium engine with remote debugging enabled.</li>
* <li>Opens a JFrame with a BrowserView inside.</li>
* <li>Loads a web page and connects to the Playwright MCP server via the DevTools Protocol.</li>
* </ol>
*/
public final class DevToolsMCP {

/**
* The remote debugging URL used by default.
*/
private static final String DEBUGGING_URL = "http://localhost:9222";

/**
* The initial URL to load in the browser.
*/
private static final String START_URL = "https://teamdev.com";

public static void main(String[] args) {
var debuggingUrl = System.getProperty("debugging.url", DEBUGGING_URL);
var debuggingPort = extractPort(debuggingUrl);
var engine = Engine.newInstance(
EngineOptions.newBuilder(HARDWARE_ACCELERATED)
.addSwitch("--remote-allow-origins=" + debuggingUrl)
.remoteDebuggingPort(debuggingPort)
.build());
var browser = engine.newBrowser();

showUI(browser);
browser.navigation().loadUrl(START_URL);
}

private static int extractPort(String url) {
try {
URI uri = new URI(url);
int port = uri.getPort();
return port > 0 ? port : 9222;
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid debugging URL: " + url, e);
}
}

private static void showUI(Browser browser) {
invokeLater(() -> {
var frame = new JFrame("JxBrowser DevTools MCP");
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setSize(1280, 900);
frame.setLocationRelativeTo(null);
frame.add(BrowserView.newInstance(browser), CENTER);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
browser.engine().close();
}
});
frame.setVisible(true);
});
}
}
62 changes: 62 additions & 0 deletions tutorials/ai/mcp-extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Chrome Extension ↔ Browser MCP ↔ LLM

Automates JxBrowser using the [Browser MCP][browsermcp] Chrome extension
and [Cursor][cursor].

## Prerequisites

- Java 17+
- Node.js 20+
- A valid [JxBrowser license][licensing]
- [Cursor][cursor] — a code editor that supports MCP

## Set up MCP server

1. Open Cursor.
2. Go to **Settings...** → **Cursor Settings** → **Tools & MCP**.
3. In the **Installed MCP Servers** tab, click **New MCP Server**.
4. Add the following JSON to your config:

```json
{
"mcpServers": {
"browsermcp": {
"command": "npx",
"args": [
"@browsermcp/mcp"
]
}
}
}
```

5. Save the config and ensure the **browsermcp** MCP server is enabled.

## Run the application

Clone this repository:

```bash
git clone https://github.com/TeamDev-IP/JxBrowser-Examples
```

From the project root, run the app with your license key:

```bash
./gradlew :mcp-extension:run -Djxbrowser.license.key="<your-license-key>"
```

This launches a Java window with JxBrowser and loads the Browser MCP Chrome
extension.

## Start automating

Open the AI chat in Cursor and try commands like:
> "Open Google and search for TeamDev. Return the company’s phone number."

Cursor will send requests to the Browser MCP server, which controls JxBrowser
via the installed Browser MCP Chrome extension.

[browsermcp]: https://browsermcp.io/
[cursor]: https://cursor.com/
[licensing]: https://teamdev.com/jxbrowser/docs/guides/introduction/licensing/
27 changes: 27 additions & 0 deletions tutorials/ai/mcp-extension/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2025, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
* disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

plugins {
application
}

application {
mainClass = "com.teamdev.jxbrowser.examples.ExtensionMCP"
}
Loading