seleniumboot-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: seleniumboot-mcp
3
+ Version: 0.1.0
4
+ Summary: A Python MCP server for Selenium WebDriver โ€” browser automation and Java TestNG/JUnit5 codegen
5
+ Author-email: Panjatan <panjatan.tech@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/seleniumboot/selenium-mcp
8
+ Project-URL: Repository, https://github.com/seleniumboot/selenium-mcp
9
+ Project-URL: Issues, https://github.com/seleniumboot/selenium-mcp/issues
10
+ Keywords: selenium,mcp,test-automation,webdriver,testng,junit,model-context-protocol
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Testing
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: mcp>=1.0.0
21
+ Requires-Dist: selenium>=4.6.0
22
+
23
+ # Selenium MCP Server ๐Ÿค–๐ŸŒ
24
+
25
+ A Python-based **Model Context Protocol (MCP)** server for Selenium WebDriver automation.
26
+ Built for AI assistants like Claude Desktop โ€” with first-class support for generating
27
+ **Java TestNG** and **JUnit 5** test scripts.
28
+
29
+ ---
30
+
31
+ ## Features
32
+
33
+ | Category | Tools |
34
+ |----------------|-------------------------------------------------------------------|
35
+ | **Browser** | start, navigate, screenshot, page source, title, URL, JS exec |
36
+ | **Elements** | click, type, find, hover, drag-drop, select, scroll, wait |
37
+ | **Assertions** | title, URL, text, visibility, attribute, page content, count |
38
+ | **Codegen** | Generate Python pytest ยท Java TestNG ยท Java JUnit 5 test scripts |
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ # Clone
46
+ git clone https://github.com/yourname/selenium-mcp
47
+ cd selenium-mcp
48
+
49
+ # Install dependencies
50
+ pip install -r requirements.txt
51
+
52
+ # Or install as a package
53
+ pip install -e .
54
+ ```
55
+
56
+ **requirements.txt**
57
+ ```
58
+ mcp>=1.0.0
59
+ selenium>=4.6.0
60
+ ```
61
+ > Selenium 4.6+ ships with **Selenium Manager** โ€” no separate driver manager needed.
62
+
63
+ ---
64
+
65
+ ## Configure Claude Desktop
66
+
67
+ Edit `claude_desktop_config.json`:
68
+
69
+ **macOS/Linux:** `~/.config/claude-desktop/config.json`
70
+ **Windows:** `%APPDATA%\claude-desktop\config.json`
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "selenium-mcp": {
76
+ "command": "python",
77
+ "args": ["/absolute/path/to/selenium-mcp/src/server.py"]
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ Restart Claude Desktop.
84
+
85
+ ---
86
+
87
+ ## Usage with Claude
88
+
89
+ ### Browser automation
90
+ ```
91
+ "Start Chrome browser, go to https://github.com, search for selenium, click the first result"
92
+ ```
93
+
94
+ ### Assertion example
95
+ ```
96
+ "Navigate to https://example.com and assert the page title contains 'Example Domain'"
97
+ ```
98
+
99
+ ### Java codegen โ€” the killer feature
100
+ ```
101
+ "Generate a Java TestNG test class for everything we just did"
102
+ ```
103
+ Claude will produce a ready-to-run Java class with WebDriverWait, @BeforeMethod,
104
+ @Test, @AfterMethod โ€” drop it straight into your Maven/Gradle project.
105
+
106
+ ---
107
+
108
+ ## Tool Reference
109
+
110
+ ### Browser Tools
111
+ | Tool | Description |
112
+ |--------------------|------------------------------------------|
113
+ | `start_browser` | Start Chrome or Firefox |
114
+ | `navigate` | Go to URL |
115
+ | `take_screenshot` | Capture page as base64 PNG |
116
+ | `get_page_title` | Return page title |
117
+ | `get_current_url` | Return current URL |
118
+ | `get_page_source` | Return full HTML source |
119
+ | `execute_script` | Run JavaScript |
120
+ | `go_back/forward` | Browser history navigation |
121
+ | `refresh` | Reload current page |
122
+ | `switch_to_window` | Switch between tabs/windows |
123
+ | `close_browser` | Quit the browser |
124
+
125
+ ### Element Tools
126
+ | Tool | Description |
127
+ |---------------------|-----------------------------------------|
128
+ | `find_element` | Find element, return tag/text/state |
129
+ | `find_elements` | Find all matching elements |
130
+ | `click` | Click with explicit wait |
131
+ | `type_text` | Clear + type into input |
132
+ | `get_text` | Get visible text |
133
+ | `get_attribute` | Get any attribute value |
134
+ | `select_option` | Select from `<select>` dropdown |
135
+ | `hover` | Mouse hover |
136
+ | `double_click` | Double click |
137
+ | `right_click` | Context menu click |
138
+ | `drag_and_drop` | Drag source โ†’ target |
139
+ | `is_displayed` | Check visibility |
140
+ | `is_enabled` | Check enabled state |
141
+ | `wait_for_element` | Wait: visible/clickable/present/hidden |
142
+ | `scroll_to_element` | Scroll element into view |
143
+ | `clear_field` | Clear input field |
144
+
145
+ ### Assertion Tools
146
+ | Tool | Description |
147
+ |----------------------------|-------------------------------------|
148
+ | `assert_title` | Page title equals/contains |
149
+ | `assert_url` | URL equals/contains |
150
+ | `assert_text` | Element text equals/contains |
151
+ | `assert_element_visible` | Element is visible |
152
+ | `assert_element_not_visible` | Element is hidden/absent |
153
+ | `assert_attribute` | Element attribute value |
154
+ | `assert_page_contains` | Body text contains string |
155
+ | `assert_element_count` | Count of matching elements |
156
+
157
+ ### Codegen Tools
158
+ | Tool | Description |
159
+ |-------------------------|----------------------------------------------|
160
+ | `generate_python_test` | Generate pytest class from session |
161
+ | `generate_java_testng` | Generate Java TestNG class from session |
162
+ | `generate_java_junit5` | Generate Java JUnit 5 class from session |
163
+ | `get_session_log` | View recorded actions |
164
+ | `clear_session_log` | Reset the session recording |
165
+
166
+ ---
167
+
168
+ ## Java Output Example
169
+
170
+ After a session: navigate โ†’ fill login form โ†’ click submit
171
+
172
+ ```java
173
+ // Generated by selenium-mcp
174
+ package com.tests.selenium;
175
+
176
+ import org.testng.annotations.*;
177
+ import org.openqa.selenium.*;
178
+ import org.openqa.selenium.chrome.ChromeDriver;
179
+ import org.openqa.selenium.support.ui.*;
180
+ import java.time.Duration;
181
+
182
+ public class LoginTest {
183
+
184
+ private WebDriver driver;
185
+ private WebDriverWait wait;
186
+
187
+ @BeforeMethod
188
+ public void setUp() {
189
+ driver = new ChromeDriver();
190
+ driver.manage().window().maximize();
191
+ wait = new WebDriverWait(driver, Duration.ofSeconds(10));
192
+ }
193
+
194
+ @AfterMethod
195
+ public void tearDown() {
196
+ if (driver != null) driver.quit();
197
+ }
198
+
199
+ @Test
200
+ public void recordedFlowTest() {
201
+ driver.get("https://app.example.com/login");
202
+ WebElement field = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#email")));
203
+ field.clear();
204
+ field.sendKeys("user@example.com");
205
+ wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button[type='submit']"))).click();
206
+ }
207
+ }
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Logs
213
+
214
+ Debug logs: `/tmp/selenium-mcp.log`
215
+
216
+ ---
217
+
218
+ ## Roadmap
219
+
220
+ - [ ] Self-healing locators (TestHeal integration)
221
+ - [ ] TestFlow export
222
+ - [ ] Page Object Model generation
223
+ - [ ] Cucumber/Gherkin step generation
224
+ - [ ] CI/CD config generator (GitHub Actions, Jenkins)
225
+
226
+ ---
227
+
228
+ ## License
229
+ MIT
@@ -0,0 +1,207 @@
1
+ # Selenium MCP Server ๐Ÿค–๐ŸŒ
2
+
3
+ A Python-based **Model Context Protocol (MCP)** server for Selenium WebDriver automation.
4
+ Built for AI assistants like Claude Desktop โ€” with first-class support for generating
5
+ **Java TestNG** and **JUnit 5** test scripts.
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ | Category | Tools |
12
+ |----------------|-------------------------------------------------------------------|
13
+ | **Browser** | start, navigate, screenshot, page source, title, URL, JS exec |
14
+ | **Elements** | click, type, find, hover, drag-drop, select, scroll, wait |
15
+ | **Assertions** | title, URL, text, visibility, attribute, page content, count |
16
+ | **Codegen** | Generate Python pytest ยท Java TestNG ยท Java JUnit 5 test scripts |
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ # Clone
24
+ git clone https://github.com/yourname/selenium-mcp
25
+ cd selenium-mcp
26
+
27
+ # Install dependencies
28
+ pip install -r requirements.txt
29
+
30
+ # Or install as a package
31
+ pip install -e .
32
+ ```
33
+
34
+ **requirements.txt**
35
+ ```
36
+ mcp>=1.0.0
37
+ selenium>=4.6.0
38
+ ```
39
+ > Selenium 4.6+ ships with **Selenium Manager** โ€” no separate driver manager needed.
40
+
41
+ ---
42
+
43
+ ## Configure Claude Desktop
44
+
45
+ Edit `claude_desktop_config.json`:
46
+
47
+ **macOS/Linux:** `~/.config/claude-desktop/config.json`
48
+ **Windows:** `%APPDATA%\claude-desktop\config.json`
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "selenium-mcp": {
54
+ "command": "python",
55
+ "args": ["/absolute/path/to/selenium-mcp/src/server.py"]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ Restart Claude Desktop.
62
+
63
+ ---
64
+
65
+ ## Usage with Claude
66
+
67
+ ### Browser automation
68
+ ```
69
+ "Start Chrome browser, go to https://github.com, search for selenium, click the first result"
70
+ ```
71
+
72
+ ### Assertion example
73
+ ```
74
+ "Navigate to https://example.com and assert the page title contains 'Example Domain'"
75
+ ```
76
+
77
+ ### Java codegen โ€” the killer feature
78
+ ```
79
+ "Generate a Java TestNG test class for everything we just did"
80
+ ```
81
+ Claude will produce a ready-to-run Java class with WebDriverWait, @BeforeMethod,
82
+ @Test, @AfterMethod โ€” drop it straight into your Maven/Gradle project.
83
+
84
+ ---
85
+
86
+ ## Tool Reference
87
+
88
+ ### Browser Tools
89
+ | Tool | Description |
90
+ |--------------------|------------------------------------------|
91
+ | `start_browser` | Start Chrome or Firefox |
92
+ | `navigate` | Go to URL |
93
+ | `take_screenshot` | Capture page as base64 PNG |
94
+ | `get_page_title` | Return page title |
95
+ | `get_current_url` | Return current URL |
96
+ | `get_page_source` | Return full HTML source |
97
+ | `execute_script` | Run JavaScript |
98
+ | `go_back/forward` | Browser history navigation |
99
+ | `refresh` | Reload current page |
100
+ | `switch_to_window` | Switch between tabs/windows |
101
+ | `close_browser` | Quit the browser |
102
+
103
+ ### Element Tools
104
+ | Tool | Description |
105
+ |---------------------|-----------------------------------------|
106
+ | `find_element` | Find element, return tag/text/state |
107
+ | `find_elements` | Find all matching elements |
108
+ | `click` | Click with explicit wait |
109
+ | `type_text` | Clear + type into input |
110
+ | `get_text` | Get visible text |
111
+ | `get_attribute` | Get any attribute value |
112
+ | `select_option` | Select from `<select>` dropdown |
113
+ | `hover` | Mouse hover |
114
+ | `double_click` | Double click |
115
+ | `right_click` | Context menu click |
116
+ | `drag_and_drop` | Drag source โ†’ target |
117
+ | `is_displayed` | Check visibility |
118
+ | `is_enabled` | Check enabled state |
119
+ | `wait_for_element` | Wait: visible/clickable/present/hidden |
120
+ | `scroll_to_element` | Scroll element into view |
121
+ | `clear_field` | Clear input field |
122
+
123
+ ### Assertion Tools
124
+ | Tool | Description |
125
+ |----------------------------|-------------------------------------|
126
+ | `assert_title` | Page title equals/contains |
127
+ | `assert_url` | URL equals/contains |
128
+ | `assert_text` | Element text equals/contains |
129
+ | `assert_element_visible` | Element is visible |
130
+ | `assert_element_not_visible` | Element is hidden/absent |
131
+ | `assert_attribute` | Element attribute value |
132
+ | `assert_page_contains` | Body text contains string |
133
+ | `assert_element_count` | Count of matching elements |
134
+
135
+ ### Codegen Tools
136
+ | Tool | Description |
137
+ |-------------------------|----------------------------------------------|
138
+ | `generate_python_test` | Generate pytest class from session |
139
+ | `generate_java_testng` | Generate Java TestNG class from session |
140
+ | `generate_java_junit5` | Generate Java JUnit 5 class from session |
141
+ | `get_session_log` | View recorded actions |
142
+ | `clear_session_log` | Reset the session recording |
143
+
144
+ ---
145
+
146
+ ## Java Output Example
147
+
148
+ After a session: navigate โ†’ fill login form โ†’ click submit
149
+
150
+ ```java
151
+ // Generated by selenium-mcp
152
+ package com.tests.selenium;
153
+
154
+ import org.testng.annotations.*;
155
+ import org.openqa.selenium.*;
156
+ import org.openqa.selenium.chrome.ChromeDriver;
157
+ import org.openqa.selenium.support.ui.*;
158
+ import java.time.Duration;
159
+
160
+ public class LoginTest {
161
+
162
+ private WebDriver driver;
163
+ private WebDriverWait wait;
164
+
165
+ @BeforeMethod
166
+ public void setUp() {
167
+ driver = new ChromeDriver();
168
+ driver.manage().window().maximize();
169
+ wait = new WebDriverWait(driver, Duration.ofSeconds(10));
170
+ }
171
+
172
+ @AfterMethod
173
+ public void tearDown() {
174
+ if (driver != null) driver.quit();
175
+ }
176
+
177
+ @Test
178
+ public void recordedFlowTest() {
179
+ driver.get("https://app.example.com/login");
180
+ WebElement field = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#email")));
181
+ field.clear();
182
+ field.sendKeys("user@example.com");
183
+ wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button[type='submit']"))).click();
184
+ }
185
+ }
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Logs
191
+
192
+ Debug logs: `/tmp/selenium-mcp.log`
193
+
194
+ ---
195
+
196
+ ## Roadmap
197
+
198
+ - [ ] Self-healing locators (TestHeal integration)
199
+ - [ ] TestFlow export
200
+ - [ ] Page Object Model generation
201
+ - [ ] Cucumber/Gherkin step generation
202
+ - [ ] CI/CD config generator (GitHub Actions, Jenkins)
203
+
204
+ ---
205
+
206
+ ## License
207
+ MIT
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "seleniumboot-mcp"
7
+ version = "0.1.0"
8
+ description = "A Python MCP server for Selenium WebDriver โ€” browser automation and Java TestNG/JUnit5 codegen"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Panjatan", email = "panjatan.tech@gmail.com" }]
13
+ keywords = ["selenium", "mcp", "test-automation", "webdriver", "testng", "junit", "model-context-protocol"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Topic :: Software Development :: Testing",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ ]
23
+ dependencies = [
24
+ "mcp>=1.0.0",
25
+ "selenium>=4.6.0",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/seleniumboot/selenium-mcp"
30
+ Repository = "https://github.com/seleniumboot/selenium-mcp"
31
+ Issues = "https://github.com/seleniumboot/selenium-mcp/issues"
32
+
33
+ [project.scripts]
34
+ seleniumboot-mcp = "selenium_mcp.server:main"
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,78 @@
1
+ """
2
+ Selenium MCP Server
3
+ A Python-based MCP server for Selenium WebDriver automation.
4
+ Serves both Python and Java test automation users.
5
+ """
6
+
7
+ import asyncio
8
+ import logging
9
+ import tempfile
10
+ from pathlib import Path
11
+ from mcp.server import Server
12
+ from mcp.server.stdio import stdio_server
13
+ from mcp.types import Tool, TextContent, ImageContent
14
+
15
+ from selenium_mcp.tools.browser_tools import BrowserTools
16
+ from selenium_mcp.tools.element_tools import ElementTools
17
+ from selenium_mcp.tools.assertion_tools import AssertionTools
18
+ from selenium_mcp.tools.codegen_tools import CodegenTools
19
+
20
+ _log_path = Path(tempfile.gettempdir()) / "selenium-mcp.log"
21
+ logging.basicConfig(
22
+ filename=str(_log_path),
23
+ level=logging.DEBUG,
24
+ format="%(asctime)s [%(levelname)s] %(message)s"
25
+ )
26
+ log = logging.getLogger(__name__)
27
+
28
+ app = Server("selenium-mcp")
29
+
30
+ browser = BrowserTools()
31
+ element = ElementTools(browser)
32
+ assertion = AssertionTools(browser)
33
+ codegen = CodegenTools(browser)
34
+
35
+ ALL_TOOLS = [
36
+ *browser.get_tools(),
37
+ *element.get_tools(),
38
+ *assertion.get_tools(),
39
+ *codegen.get_tools(),
40
+ ]
41
+
42
+ TOOL_HANDLERS = {
43
+ **browser.get_handlers(),
44
+ **element.get_handlers(),
45
+ **assertion.get_handlers(),
46
+ **codegen.get_handlers(),
47
+ }
48
+
49
+
50
+ @app.list_tools()
51
+ async def list_tools() -> list[Tool]:
52
+ return ALL_TOOLS
53
+
54
+
55
+ @app.call_tool()
56
+ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
57
+ log.info(f"Tool called: {name} | args: {arguments}")
58
+ handler = TOOL_HANDLERS.get(name)
59
+ if not handler:
60
+ return [TextContent(type="text", text=f"Unknown tool: {name}")]
61
+ try:
62
+ result = await handler(arguments)
63
+ if isinstance(result, str) and result.startswith("screenshot:base64:"):
64
+ b64 = result[len("screenshot:base64:"):]
65
+ return [ImageContent(type="image", data=b64, mimeType="image/png")]
66
+ return [TextContent(type="text", text=result)]
67
+ except Exception as e:
68
+ log.error(f"Tool error [{name}]: {e}")
69
+ return [TextContent(type="text", text=f"Error: {str(e)}")]
70
+
71
+
72
+ async def main():
73
+ async with stdio_server() as (r, w):
74
+ await app.run(r, w, app.create_initialization_options())
75
+
76
+
77
+ if __name__ == "__main__":
78
+ asyncio.run(main())