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.
- checksums.yaml +7 -0
- data/.env.example +90 -0
- data/CHANGELOG.md +229 -0
- data/CONTRIBUTING.md +469 -0
- data/LICENSE +21 -0
- data/README.md +334 -0
- data/SECURITY.md +286 -0
- data/bin/ferrum-mcp +66 -0
- data/bin/lint +10 -0
- data/bin/serve +3 -0
- data/bin/test +4 -0
- data/docs/API_REFERENCE.md +1410 -0
- data/docs/CONFIGURATION.md +254 -0
- data/docs/DEPLOYMENT.md +846 -0
- data/docs/DOCKER.md +836 -0
- data/docs/DOCKER_BOTBROWSER.md +455 -0
- data/docs/GETTING_STARTED.md +249 -0
- data/docs/TROUBLESHOOTING.md +677 -0
- data/lib/ferrum_mcp/browser_manager.rb +101 -0
- data/lib/ferrum_mcp/cli/command_handler.rb +99 -0
- data/lib/ferrum_mcp/cli/server_runner.rb +166 -0
- data/lib/ferrum_mcp/configuration.rb +229 -0
- data/lib/ferrum_mcp/resource_manager.rb +223 -0
- data/lib/ferrum_mcp/server.rb +254 -0
- data/lib/ferrum_mcp/session.rb +227 -0
- data/lib/ferrum_mcp/session_manager.rb +183 -0
- data/lib/ferrum_mcp/tools/accept_cookies_tool.rb +458 -0
- data/lib/ferrum_mcp/tools/base_tool.rb +114 -0
- data/lib/ferrum_mcp/tools/clear_cookies_tool.rb +66 -0
- data/lib/ferrum_mcp/tools/click_tool.rb +218 -0
- data/lib/ferrum_mcp/tools/close_session_tool.rb +49 -0
- data/lib/ferrum_mcp/tools/create_session_tool.rb +146 -0
- data/lib/ferrum_mcp/tools/drag_and_drop_tool.rb +171 -0
- data/lib/ferrum_mcp/tools/evaluate_js_tool.rb +46 -0
- data/lib/ferrum_mcp/tools/execute_script_tool.rb +48 -0
- data/lib/ferrum_mcp/tools/fill_form_tool.rb +78 -0
- data/lib/ferrum_mcp/tools/find_by_text_tool.rb +153 -0
- data/lib/ferrum_mcp/tools/get_attribute_tool.rb +56 -0
- data/lib/ferrum_mcp/tools/get_cookies_tool.rb +70 -0
- data/lib/ferrum_mcp/tools/get_html_tool.rb +52 -0
- data/lib/ferrum_mcp/tools/get_session_info_tool.rb +40 -0
- data/lib/ferrum_mcp/tools/get_text_tool.rb +67 -0
- data/lib/ferrum_mcp/tools/get_title_tool.rb +42 -0
- data/lib/ferrum_mcp/tools/get_url_tool.rb +39 -0
- data/lib/ferrum_mcp/tools/go_back_tool.rb +49 -0
- data/lib/ferrum_mcp/tools/go_forward_tool.rb +49 -0
- data/lib/ferrum_mcp/tools/hover_tool.rb +76 -0
- data/lib/ferrum_mcp/tools/list_sessions_tool.rb +33 -0
- data/lib/ferrum_mcp/tools/navigate_tool.rb +59 -0
- data/lib/ferrum_mcp/tools/press_key_tool.rb +91 -0
- data/lib/ferrum_mcp/tools/query_shadow_dom_tool.rb +225 -0
- data/lib/ferrum_mcp/tools/refresh_tool.rb +49 -0
- data/lib/ferrum_mcp/tools/screenshot_tool.rb +121 -0
- data/lib/ferrum_mcp/tools/session_tool.rb +37 -0
- data/lib/ferrum_mcp/tools/set_cookie_tool.rb +77 -0
- data/lib/ferrum_mcp/tools/solve_captcha_tool.rb +528 -0
- data/lib/ferrum_mcp/transport/http_server.rb +93 -0
- data/lib/ferrum_mcp/transport/rate_limiter.rb +79 -0
- data/lib/ferrum_mcp/transport/stdio_server.rb +63 -0
- data/lib/ferrum_mcp/version.rb +5 -0
- data/lib/ferrum_mcp/whisper_service.rb +222 -0
- data/lib/ferrum_mcp.rb +35 -0
- 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.
|