ferrum-mcp 1.0.0

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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +90 -0
  3. data/CHANGELOG.md +229 -0
  4. data/CONTRIBUTING.md +469 -0
  5. data/LICENSE +21 -0
  6. data/README.md +334 -0
  7. data/SECURITY.md +286 -0
  8. data/bin/ferrum-mcp +66 -0
  9. data/bin/lint +10 -0
  10. data/bin/serve +3 -0
  11. data/bin/test +4 -0
  12. data/docs/API_REFERENCE.md +1410 -0
  13. data/docs/CONFIGURATION.md +254 -0
  14. data/docs/DEPLOYMENT.md +846 -0
  15. data/docs/DOCKER.md +836 -0
  16. data/docs/DOCKER_BOTBROWSER.md +455 -0
  17. data/docs/GETTING_STARTED.md +249 -0
  18. data/docs/TROUBLESHOOTING.md +677 -0
  19. data/lib/ferrum_mcp/browser_manager.rb +101 -0
  20. data/lib/ferrum_mcp/cli/command_handler.rb +99 -0
  21. data/lib/ferrum_mcp/cli/server_runner.rb +166 -0
  22. data/lib/ferrum_mcp/configuration.rb +229 -0
  23. data/lib/ferrum_mcp/resource_manager.rb +223 -0
  24. data/lib/ferrum_mcp/server.rb +254 -0
  25. data/lib/ferrum_mcp/session.rb +227 -0
  26. data/lib/ferrum_mcp/session_manager.rb +183 -0
  27. data/lib/ferrum_mcp/tools/accept_cookies_tool.rb +458 -0
  28. data/lib/ferrum_mcp/tools/base_tool.rb +114 -0
  29. data/lib/ferrum_mcp/tools/clear_cookies_tool.rb +66 -0
  30. data/lib/ferrum_mcp/tools/click_tool.rb +218 -0
  31. data/lib/ferrum_mcp/tools/close_session_tool.rb +49 -0
  32. data/lib/ferrum_mcp/tools/create_session_tool.rb +146 -0
  33. data/lib/ferrum_mcp/tools/drag_and_drop_tool.rb +171 -0
  34. data/lib/ferrum_mcp/tools/evaluate_js_tool.rb +46 -0
  35. data/lib/ferrum_mcp/tools/execute_script_tool.rb +48 -0
  36. data/lib/ferrum_mcp/tools/fill_form_tool.rb +78 -0
  37. data/lib/ferrum_mcp/tools/find_by_text_tool.rb +153 -0
  38. data/lib/ferrum_mcp/tools/get_attribute_tool.rb +56 -0
  39. data/lib/ferrum_mcp/tools/get_cookies_tool.rb +70 -0
  40. data/lib/ferrum_mcp/tools/get_html_tool.rb +52 -0
  41. data/lib/ferrum_mcp/tools/get_session_info_tool.rb +40 -0
  42. data/lib/ferrum_mcp/tools/get_text_tool.rb +67 -0
  43. data/lib/ferrum_mcp/tools/get_title_tool.rb +42 -0
  44. data/lib/ferrum_mcp/tools/get_url_tool.rb +39 -0
  45. data/lib/ferrum_mcp/tools/go_back_tool.rb +49 -0
  46. data/lib/ferrum_mcp/tools/go_forward_tool.rb +49 -0
  47. data/lib/ferrum_mcp/tools/hover_tool.rb +76 -0
  48. data/lib/ferrum_mcp/tools/list_sessions_tool.rb +33 -0
  49. data/lib/ferrum_mcp/tools/navigate_tool.rb +59 -0
  50. data/lib/ferrum_mcp/tools/press_key_tool.rb +91 -0
  51. data/lib/ferrum_mcp/tools/query_shadow_dom_tool.rb +225 -0
  52. data/lib/ferrum_mcp/tools/refresh_tool.rb +49 -0
  53. data/lib/ferrum_mcp/tools/screenshot_tool.rb +121 -0
  54. data/lib/ferrum_mcp/tools/session_tool.rb +37 -0
  55. data/lib/ferrum_mcp/tools/set_cookie_tool.rb +77 -0
  56. data/lib/ferrum_mcp/tools/solve_captcha_tool.rb +528 -0
  57. data/lib/ferrum_mcp/transport/http_server.rb +93 -0
  58. data/lib/ferrum_mcp/transport/rate_limiter.rb +79 -0
  59. data/lib/ferrum_mcp/transport/stdio_server.rb +63 -0
  60. data/lib/ferrum_mcp/version.rb +5 -0
  61. data/lib/ferrum_mcp/whisper_service.rb +222 -0
  62. data/lib/ferrum_mcp.rb +35 -0
  63. metadata +248 -0
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,469 @@
1
+ # Contributing to FerrumMCP
2
+
3
+ First off, thank you for considering contributing to FerrumMCP! It's people like you that make FerrumMCP such a great tool.
4
+
5
+ ## Code of Conduct
6
+
7
+ This project and everyone participating in it is governed by common sense and mutual respect. By participating, you are expected to uphold this standard. Please report unacceptable behavior to [eth3rnit3@gmail.com](mailto:eth3rnit3@gmail.com).
8
+
9
+ ## How Can I Contribute?
10
+
11
+ ### Reporting Bugs
12
+
13
+ Before creating bug reports, please check the existing issues to avoid duplicates. When you create a bug report, please include as many details as possible:
14
+
15
+ **Use the bug report template** (see `.github/ISSUE_TEMPLATE/bug_report.md`)
16
+
17
+ Include:
18
+ - **Clear title**: Describe the bug in one sentence
19
+ - **Description**: What happened vs. what you expected
20
+ - **Steps to reproduce**: Numbered list of steps
21
+ - **Environment**: Ruby version, OS, browser version
22
+ - **Logs**: Relevant excerpts from `logs/ferrum_mcp.log`
23
+ - **Screenshots**: If applicable
24
+
25
+ **Example**:
26
+ ```markdown
27
+ ### Bug: Screenshot tool fails with large images
28
+
29
+ **Description**
30
+ The screenshot tool crashes when capturing pages with images larger than 10MB.
31
+
32
+ **Steps to Reproduce**
33
+ 1. Create session: `create_session(headless: true)`
34
+ 2. Navigate to: `navigate(url: "https://example.com/large-image", session_id: ...)`
35
+ 3. Take screenshot: `screenshot(session_id: ...)`
36
+ 4. Error occurs: "Image too large for base64 encoding"
37
+
38
+ **Expected Behavior**
39
+ Screenshot should be resized or paginated.
40
+
41
+ **Environment**
42
+ - Ruby: 3.3.5
43
+ - OS: macOS 14.1
44
+ - Chrome: 119.0.6045.199
45
+ - FerrumMCP: 0.1.0
46
+
47
+ **Logs**
48
+ ```
49
+ ERROR -- : Screenshot failed: Image size exceeds limit
50
+ ```
51
+ ```
52
+
53
+ ### Suggesting Enhancements
54
+
55
+ Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, include:
56
+
57
+ **Use the feature request template** (see `.github/ISSUE_TEMPLATE/feature_request.md`)
58
+
59
+ Include:
60
+ - **Clear title**: Describe the feature in one sentence
61
+ - **Problem**: What problem does this solve?
62
+ - **Solution**: Describe your proposed solution
63
+ - **Alternatives**: Other solutions you've considered
64
+ - **Use cases**: Real-world examples
65
+
66
+ ### Pull Requests
67
+
68
+ We actively welcome your pull requests!
69
+
70
+ #### Before You Start
71
+
72
+ 1. **Check existing issues**: See if someone is already working on it
73
+ 2. **Open an issue first**: Discuss major changes before coding
74
+ 3. **One feature per PR**: Keep PRs focused and manageable
75
+ 4. **Follow the style guide**: Use RuboCop and existing patterns
76
+
77
+ #### Development Workflow
78
+
79
+ 1. **Fork the repository**
80
+ ```bash
81
+ git clone https://github.com/YOUR_USERNAME/FerrumMCP.git
82
+ cd FerrumMCP
83
+ ```
84
+
85
+ 2. **Create a branch**
86
+ ```bash
87
+ git checkout -b feature/my-awesome-feature
88
+ # or
89
+ git checkout -b fix/my-bug-fix
90
+ ```
91
+
92
+ **Branch naming**:
93
+ - `feature/` - New features
94
+ - `fix/` - Bug fixes
95
+ - `docs/` - Documentation changes
96
+ - `refactor/` - Code refactoring
97
+ - `test/` - Test improvements
98
+ - `chore/` - Maintenance tasks
99
+
100
+ 3. **Set up development environment**
101
+ ```bash
102
+ bundle install
103
+ cp .env.example .env
104
+ # Edit .env with your configuration
105
+ ```
106
+
107
+ 4. **Make your changes**
108
+ - Write clean, readable code
109
+ - Follow Ruby best practices
110
+ - Add tests for new functionality
111
+ - Update documentation
112
+
113
+ 5. **Run the linter**
114
+ ```bash
115
+ bundle exec rubocop
116
+ # Auto-fix issues
117
+ bundle exec rubocop -A
118
+ ```
119
+
120
+ 6. **Run the tests**
121
+ ```bash
122
+ bundle exec rspec
123
+ # With coverage
124
+ COVERAGE=true bundle exec rspec
125
+ ```
126
+
127
+ 7. **Commit your changes**
128
+ ```bash
129
+ git add .
130
+ git commit -m "feat: Add awesome new feature"
131
+ ```
132
+
133
+ **Commit message format**:
134
+ ```
135
+ <type>: <subject>
136
+
137
+ <body>
138
+
139
+ <footer>
140
+ ```
141
+
142
+ **Types**:
143
+ - `feat` - New feature
144
+ - `fix` - Bug fix
145
+ - `docs` - Documentation
146
+ - `style` - Formatting, missing semicolons, etc.
147
+ - `refactor` - Code restructuring
148
+ - `test` - Adding tests
149
+ - `chore` - Maintenance
150
+
151
+ **Examples**:
152
+ ```
153
+ feat: Add rate limiting to HTTP transport
154
+
155
+ - Implement token bucket algorithm
156
+ - Add MAX_REQUESTS_PER_MINUTE configuration
157
+ - Update docs with rate limit information
158
+
159
+ Closes #123
160
+ ```
161
+
162
+ ```
163
+ fix: Resolve screenshot encoding issue with large images
164
+
165
+ Images larger than 10MB now automatically resize to fit
166
+ within base64 encoding limits.
167
+
168
+ Fixes #456
169
+ ```
170
+
171
+ 8. **Push to your fork**
172
+ ```bash
173
+ git push origin feature/my-awesome-feature
174
+ ```
175
+
176
+ 9. **Open a Pull Request**
177
+ - Use the PR template (see `.github/PULL_REQUEST_TEMPLATE.md`)
178
+ - Link related issues
179
+ - Describe your changes
180
+ - Add screenshots/examples if applicable
181
+
182
+ #### Pull Request Requirements
183
+
184
+ Your PR must meet these requirements:
185
+
186
+ ✅ **Tests pass**: All RSpec tests must pass
187
+ ✅ **Linter passes**: No RuboCop offenses
188
+ ✅ **Coverage maintained**: Branch coverage ≥ 55%, line coverage ≥ 79%
189
+ ✅ **Documentation updated**: README, CHANGELOG, or docs/ if needed
190
+ ✅ **Zeitwerk check**: Autoloading must work (`bundle exec rake zeitwerk:check`)
191
+ ✅ **Commit messages**: Follow conventional commit format
192
+ ✅ **No merge commits**: Rebase on main before submitting
193
+
194
+ #### Code Review Process
195
+
196
+ 1. **Automated checks**: GitHub Actions runs CI checks
197
+ 2. **Maintainer review**: A maintainer will review your code
198
+ 3. **Feedback**: Address any requested changes
199
+ 4. **Approval**: Once approved, a maintainer will merge
200
+
201
+ **What we look for**:
202
+ - Code quality and readability
203
+ - Test coverage
204
+ - Documentation completeness
205
+ - Adherence to existing patterns
206
+ - Performance implications
207
+
208
+ ## Development Guidelines
209
+
210
+ ### Code Style
211
+
212
+ We use **RuboCop** for code style enforcement:
213
+
214
+ ```bash
215
+ # Check for offenses
216
+ bundle exec rubocop
217
+
218
+ # Auto-fix (with caution)
219
+ bundle exec rubocop -A
220
+ ```
221
+
222
+ **Key conventions**:
223
+ - 2 spaces for indentation (no tabs)
224
+ - `frozen_string_literal: true` at top of each file
225
+ - 120 character line length limit
226
+ - Snake_case for methods and variables
227
+ - CamelCase for classes and modules
228
+ - Double quotes for strings (unless single quotes avoid escaping)
229
+
230
+ ### Testing
231
+
232
+ #### Writing Tests
233
+
234
+ - **File location**: `spec/ferrum_mcp/tools/my_tool_spec.rb`
235
+ - **File naming**: `*_spec.rb`
236
+ - **Test structure**: Use `describe` and `context` blocks
237
+
238
+ **Example**:
239
+ ```ruby
240
+ # spec/ferrum_mcp/tools/my_tool_spec.rb
241
+ require 'spec_helper'
242
+
243
+ RSpec.describe FerrumMCP::Tools::MyTool do
244
+ let(:session_manager) { instance_double(FerrumMCP::SessionManager) }
245
+ let(:session) { instance_double(FerrumMCP::Session) }
246
+ let(:browser) { instance_double(Ferrum::Browser) }
247
+ let(:tool) { described_class.new(session_manager) }
248
+
249
+ before do
250
+ allow(session_manager).to receive(:with_session).and_yield(browser)
251
+ end
252
+
253
+ describe '#execute' do
254
+ context 'when successful' do
255
+ it 'returns success response' do
256
+ result = tool.execute({ session_id: 'test-session', param: 'value' })
257
+ expect(result[:success]).to be true
258
+ end
259
+ end
260
+
261
+ context 'when error occurs' do
262
+ it 'returns error response' do
263
+ allow(browser).to receive(:goto).and_raise(StandardError, 'Test error')
264
+ result = tool.execute({ session_id: 'test-session' })
265
+ expect(result[:success]).to be false
266
+ end
267
+ end
268
+ end
269
+ end
270
+ ```
271
+
272
+ #### Running Tests
273
+
274
+ ```bash
275
+ # All tests
276
+ bundle exec rspec
277
+
278
+ # Specific file
279
+ bundle exec rspec spec/ferrum_mcp/tools/my_tool_spec.rb
280
+
281
+ # Specific test
282
+ bundle exec rspec spec/ferrum_mcp/tools/my_tool_spec.rb:42
283
+
284
+ # With coverage
285
+ COVERAGE=true bundle exec rspec
286
+ ```
287
+
288
+ #### Coverage Requirements
289
+
290
+ - **Minimum line coverage**: 79%
291
+ - **Minimum branch coverage**: 55%
292
+ - **New code**: Should maintain or improve coverage
293
+
294
+ ### Adding New Tools
295
+
296
+ To add a new browser automation tool:
297
+
298
+ 1. **Create tool file**: `lib/ferrum_mcp/tools/my_tool.rb`
299
+
300
+ ```ruby
301
+ # frozen_string_literal: true
302
+
303
+ module FerrumMCP
304
+ module Tools
305
+ # MyTool does something awesome
306
+ class MyTool < BaseTool
307
+ def self.tool_name
308
+ 'my_tool'
309
+ end
310
+
311
+ def self.description
312
+ 'Does something awesome with the browser'
313
+ end
314
+
315
+ def self.input_schema
316
+ {
317
+ type: 'object',
318
+ properties: {
319
+ session_id: {
320
+ type: 'string',
321
+ description: 'Session ID to use for this operation'
322
+ },
323
+ my_param: {
324
+ type: 'string',
325
+ description: 'Description of my parameter'
326
+ }
327
+ },
328
+ required: ['session_id', 'my_param']
329
+ }
330
+ end
331
+
332
+ def execute(params)
333
+ session_id = params[:session_id]
334
+ my_param = params[:my_param]
335
+
336
+ session_manager.with_session(session_id) do |browser|
337
+ # Your logic here
338
+ result = browser.do_something(my_param)
339
+ success_response({ result: result })
340
+ end
341
+ rescue StandardError => e
342
+ error_response("Failed to do something: #{e.message}")
343
+ end
344
+ end
345
+ end
346
+ end
347
+ ```
348
+
349
+ 2. **Register in server**: Add to `TOOL_CLASSES` in `lib/ferrum_mcp/bin/ferrum-mcp`
350
+
351
+ ```ruby
352
+ TOOL_CLASSES = [
353
+ # ... existing tools ...
354
+ Tools::MyTool
355
+ ].freeze
356
+ ```
357
+
358
+ 3. **Write tests**: Create `spec/ferrum_mcp/tools/my_tool_spec.rb`
359
+
360
+ 4. **Update documentation**:
361
+ - Add to [docs/API_REFERENCE.md](docs/API_REFERENCE.md)
362
+ - Update CHANGELOG.md under `[Unreleased]`
363
+
364
+ ### Documentation
365
+
366
+ Documentation is as important as code!
367
+
368
+ **What to document**:
369
+ - Public APIs and methods
370
+ - Complex algorithms
371
+ - Non-obvious behavior
372
+ - Configuration options
373
+ - Breaking changes
374
+
375
+ **Where to document**:
376
+ - Inline comments for complex code
377
+ - [docs/API_REFERENCE.md](docs/API_REFERENCE.md) for tools
378
+ - [CHANGELOG.md](CHANGELOG.md) for changes
379
+ - README.md for user-facing features
380
+
381
+ **Example inline documentation**:
382
+ ```ruby
383
+ # Find element with retry logic for stale elements.
384
+ #
385
+ # Chrome can mark elements as stale if the page is modified
386
+ # during interaction. We retry up to 3 times to handle this.
387
+ #
388
+ # @param selector [String] CSS or XPath selector
389
+ # @param timeout [Integer] Timeout in seconds
390
+ # @return [Ferrum::Element] Found element
391
+ # @raise [ToolError] if element not found after retries
392
+ def find_element(browser, selector, timeout: 5)
393
+ # implementation...
394
+ end
395
+ ```
396
+
397
+ ### Architecture
398
+
399
+ Understand the architecture before contributing:
400
+
401
+ ```
402
+ FerrumMCP/
403
+ ├── Server (MCP Server)
404
+ │ ├── SessionManager (Thread-safe session pool)
405
+ │ │ └── Session (Browser wrapper)
406
+ │ │ └── BrowserManager (Ferrum lifecycle)
407
+ │ ├── ResourceManager (MCP Resources)
408
+ │ └── Tools (27+ automation tools)
409
+ └── Transport (HTTP or STDIO)
410
+ ```
411
+
412
+ **Key principles**:
413
+ 1. **Session-based**: All operations require a session
414
+ 2. **Thread-safe**: Use mutexes for shared state
415
+ 3. **Tool isolation**: Each tool is independent
416
+ 4. **Error handling**: Always catch and report errors
417
+ 5. **Resource cleanup**: Close sessions and browsers
418
+
419
+ See [CLAUDE.md](CLAUDE.md) for detailed architecture documentation.
420
+
421
+ ## Community
422
+
423
+ ### Communication Channels
424
+
425
+ - **GitHub Issues**: Bug reports and feature requests
426
+ - **GitHub Discussions**: Questions and general discussion
427
+ - **Pull Requests**: Code contributions
428
+ - **Email**: [eth3rnit3@gmail.com](mailto:eth3rnit3@gmail.com) for sensitive issues
429
+
430
+ ### Getting Help
431
+
432
+ - **Read the docs**: Start with [docs/](docs/)
433
+ - **Search issues**: Someone may have asked already
434
+ - **Ask a question**: Open a GitHub Discussion
435
+ - **Be specific**: Provide context and examples
436
+
437
+ ### Recognition
438
+
439
+ Contributors are recognized in:
440
+ - CHANGELOG.md for significant contributions
441
+ - README.md contributors section
442
+ - Release notes
443
+ - GitHub contributors page
444
+
445
+ ## Release Process
446
+
447
+ (For maintainers only)
448
+
449
+ 1. Update version in `lib/ferrum_mcp/version.rb`
450
+ 2. Update CHANGELOG.md with release date
451
+ 3. Commit: `chore: Release v1.0.0`
452
+ 4. Tag: `git tag -a v1.0.0 -m "Release v1.0.0"`
453
+ 5. Push: `git push && git push --tags`
454
+ 6. GitHub Actions builds and publishes Docker image
455
+ 7. Create GitHub Release from tag
456
+ 8. (Future) Publish gem to RubyGems.org
457
+
458
+ ## License
459
+
460
+ By contributing, you agree that your contributions will be licensed under the MIT License.
461
+
462
+ ## Questions?
463
+
464
+ Don't hesitate to ask! We're here to help:
465
+
466
+ - Open a [GitHub Discussion](https://github.com/Eth3rnit3/FerrumMCP/discussions)
467
+ - Email: [eth3rnit3@gmail.com](mailto:eth3rnit3@gmail.com)
468
+
469
+ Thank you for contributing to FerrumMCP! 🎉
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ferrum MCP Server Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.