SharedTools
A Ruby gem providing LLM-callable tools for browser automation, file operations, code evaluation, document processing, network queries, data science, workflow management, and more
Overview
SharedTools is a comprehensive collection of production-ready tools designed for LLM (Large Language Model) applications. Built on the RubyLLM framework, it provides a unified interface for common automation tasks while maintaining safety through a human-in-the-loop authorization system.
Key Features
- 🔧 45+ Production Tools — Browser automation, file discovery and editing (glob/tree/diff/multi-edit/patch/replace), git, structured data (JSON/YAML/TOML/CSV), Ruby dev tooling (gem/bundle/lint/parse), background process management, guarded HTTP (fetch/request/download), database queries, code evaluation, document processing, DNS and WHOIS lookups, IP geolocation, data science, weather data, workflow management, system utilities, notifications, and more
- 🔒 Human-in-the-Loop Authorization — Built-in safety system for sensitive operations
- 🎯 Facade Pattern — Simplified interfaces with complex capabilities under the hood
- 🔌 Pluggable Drivers — Swap implementations for testing or different backends
- 📚 Comprehensive Documentation — Detailed guides, examples, and API reference
- ✅ Well Tested — 85%+ test coverage with Minitest
Installation
Add to your Gemfile:
gem 'shared_tools'
gem 'ruby_llm' # Required LLM frameworkOr install directly:
gem install shared_toolsOptional Dependencies
Depending on which tools you use, you may need additional gems:
# For BrowserTool
gem 'watir'
# For DatabaseTool and DatabaseQueryTool
gem 'sqlite3' # or pg, mysql2, etc.
# For DocTool
gem 'pdf-reader' # PDF support
gem 'docx' # Microsoft Word (.docx) support
gem 'roo' # Spreadsheet support: CSV, XLSX, ODS, XLSM
# Core dependencies (automatically installed)
gem 'dentaku' # For CalculatorTool
gem 'openweathermap' # For WeatherTool
gem 'sequel' # For DatabaseQueryTool
gem 'nokogiri' # For various toolsQuick Start
require 'shared_tools'
require 'ruby_llm'
# Initialize an LLM agent with SharedTools
chat = RubyLLM.chat.with_tools(
SharedTools::Tools::BrowserTool.new,
SharedTools::Tools::DiskTool.new,
SharedTools::Tools::DnsTool.new,
SharedTools::Tools::WeatherTool.new,
SharedTools::Tools::WorkflowManagerTool.new
)
# Use with human-in-the-loop authorization (default)
chat.ask("Visit example.com and save the page title to title.txt")
# User will be prompted: "Allow BrowserTool to visit https://example.com? (y/n)"
# Or enable auto-execution for automated workflows
SharedTools.auto_execute(true)
chat.ask("Calculate the square root of 144 and tell me the weather in London")Tool Collections
🌐 Browser Tools
Web automation and scraping capabilities.
Actions: visit, page_inspect, ui_inspect, selector_inspect, click, text_field_set, screenshot
browser = SharedTools::Tools::BrowserTool.new
browser.execute(action: "visit", url: "https://example.com")
browser.execute(action: "page_inspect", full_html: false)💾 Disk Tools
Secure file system operations with path traversal protection.
Actions: file_create, file_read, file_write, file_delete, file_move, file_replace, directory_create, directory_list, directory_move, directory_delete
disk = SharedTools::Tools::DiskTool.new
disk.execute(action: "file_create", path: "./report.txt")
disk.execute(action: "file_write", path: "./report.txt", text: "Hello, World!")
content = disk.execute(action: "file_read", path: "./report.txt")🔍 File Discovery Tools
Find files and content without shelling out to rg/grep/find. Pure Ruby, no external binary dependency.
-
GlobTool— finds files matching a glob pattern (**/*.rb,app/models/*.rb), returns sorted paths relative tobase. -
TreeTool— renders a depth-limited directory tree, skipping.git/node_modules/hidden entries by default. -
SearchCodebaseTool— searches file contents for a regular expression, returningpath:line: texthits (or context blocks withcontext/before/after). ReDoS-guarded with a per-match regex timeout, and caps results atmax_results(default 50, max 500).
glob = SharedTools::Tools::GlobTool.new
glob.execute(pattern: "**/*.rb", base: "./lib")
tree = SharedTools::Tools::TreeTool.new
tree.execute(path: "./lib", max_depth: 2)
search = SharedTools::Tools::SearchCodebaseTool.new
search.execute(pattern: "def execute", glob: "*.rb")
search.execute(pattern: "TODO", context: 2) # 2 lines of context around each matchNote:
SearchCodebaseTool's implementation changed from shelling out torg/grepto a pure-Ruby, ReDoS-guarded scanner. Theterm:andextension:params were renamed topattern:(a regex) andglob:(a filename glob, e.g."*.rb"instead of"rb");max_results:is unchanged. Thetool:result key now always reports"ruby".
✂️ File Editing Tools
Precise, deterministic text editing that complements DiskTool and GitTool — an alternative to Disk::FileReplaceTool's single global replace for coding-agent workflows.
-
DiffTool— compares two in-memory blocks of text and returns a readable unified diff. Read-only, no filesystem access. -
MultiEditTool— applies several find/replace edits to one file atomically. Each edit'sold_stringmust match exactly once (add context or setreplace_all) or the whole batch is rejected and nothing is written. Requires authorization. -
ApplyPatchTool— applies a unified diff (as produced bygit diff,DiffTool, ordiff -u) viagit apply, validating with--checkfirst. Every touched path is confined toroot. Setcheck: truefor a dry run. Requires authorization. -
ReplaceInFilesTool— batch find/replace across every file inrootmatching a glob (default**/*). Literal by default; setregex: truefor a pattern with\1-style backreferences. ReDoS-guarded, skips binary files and ignored directories. Setdry_run: trueto preview without writing. Requires authorization (dry runs don't).
diff = SharedTools::Tools::DiffTool.new
diff.execute(old: old_text, new: new_text)
multi_edit = SharedTools::Tools::MultiEditTool.new(root: "./my-project")
multi_edit.execute(path: "lib/foo.rb", edits: [
{ old_string: "def bar", new_string: "def baz" },
{ old_string: "BAR", new_string: "BAZ", replace_all: true }
])
apply_patch = SharedTools::Tools::ApplyPatchTool.new(root: "./my-project")
apply_patch.execute(patch: unified_diff_text, check: true) # dry run
apply_patch.execute(patch: unified_diff_text)
replace = SharedTools::Tools::ReplaceInFilesTool.new(root: "./my-project")
replace.execute(pattern: "OldClassName", replacement: "NewClassName", glob: "**/*.rb")🔀 Git Tools
Read a repository's history and working-tree state, and make basic mutating changes. Read-only actions (status, diff, log, show, blame, branch, grep) require no authorization; mutating actions (add, commit, checkout) require user authorization. External diff drivers, textconv filters, and core.fsmonitor are disabled so an untrusted checkout can't turn a read into command execution.
Actions: status, diff, log, show, blame, branch, grep, add, commit, checkout
git = SharedTools::Tools::GitTool.new(repo_root: "./my-project")
git.execute(action: "status")
git.execute(action: "diff", staged: true)
git.execute(action: "log", count: 10, path: "lib/foo.rb")
git.execute(action: "blame", path: "lib/foo.rb", start_line: 10, end_line: 20)
git.execute(action: "commit", message: "Fix the thing", all: true)Each action is also available as a standalone tool, e.g. SharedTools::Tools::Git::StatusTool, SharedTools::Tools::Git::DiffTool, SharedTools::Tools::Git::CommitTool.
💎 Ruby Dev Tools
Tooling for working on a Ruby project: gem metadata, Bundler, linting, and structural code navigation.
-
GemTool— read-only RubyGems.org metadata lookup (info,version,dependencies,search). No authorization needed. -
BundleTool— runs Bundler (install,update,outdated,check,lock,add) in a project. Requires a Gemfile and authorization. -
LintTool— runs RuboCop or Standard, auto-detected (Standard if.standard.ymlis present) or forced explicitly. Usesbundle execwhen a Gemfile exists. Offenses are a normal result, not an error;autocorrect: truerewrites files in place. Requires authorization. -
ParseRubyTool— outlines a Ruby file's structure (classes, modules, methods, constants with line numbers) via Prism (Ruby 3.3+) or the Ripper stdlib fallback — parses, never executes. Filter withquery/kindto locate a specific definition. Read-only.
gem = SharedTools::Tools::GemTool.new
gem.execute(name: "ruby_llm", action: "version")
bundle = SharedTools::Tools::BundleTool.new(root: "./my-project")
bundle.execute(action: "add", gem: "rack")
lint = SharedTools::Tools::LintTool.new(root: "./my-project")
lint.execute(path: "lib/foo.rb", autocorrect: true)
parse = SharedTools::Tools::ParseRubyTool.new
parse.execute(path: "./lib/foo.rb")
parse.execute(path: "./lib/foo.rb", kind: "method", query: "initialize")⚙️ Process Management Tools
Start, monitor, and stop long-running background processes (dev servers, watchers, log tails) without blocking the caller.
-
ProcessStartTool— starts a command as a background process and returns its id immediately. The executable must be onallowed_commands(empty by default — nothing is allowed until configured); argv only, no shell. Runs in its own process group. Requires authorization. -
ProcessListTool— lists background processes: id, status, pid, age, command. Read-only. -
ProcessOutputTool— reads new stdout/stderr since the last read (poll it to follow output), plus status and exit code. Read-only. -
ProcessKillTool— SIGTERM the process group, escalating to SIGKILL if it doesn't exit, then returns final output. Always available with no authorization prompt, so a runaway process can always be stopped.
start = SharedTools::Tools::ProcessStartTool.new(allowed_commands: ["rackup"])
started = start.execute(command: "rackup", args: ["-p", "9292"], name: "web server")
id = started[/proc_\d+/]
output = SharedTools::Tools::ProcessOutputTool.new
output.execute(id: id) # poll this in a loop to stream output
SharedTools::Tools::ProcessListTool.new.execute
SharedTools::Tools::ProcessKillTool.new.execute(id: id)🌐 Network Tools
Guarded HTTP — every request and redirect hop is checked against SSRF (server-side request forgery): only http/https, no embedded credentials, and the resolved IP is rejected (and the connection pinned to it) if it's private, loopback, link-local, cloud-metadata, or otherwise reserved.
-
WebFetchTool— fetches a URL and returns readable text (HTML is stripped to text). Read-only, no authorization needed. -
HttpRequestTool— a general HTTP client returning status, key headers, and body. GET/HEAD need no authorization; POST/PUT/PATCH/DELETE require it. -
DownloadFileTool— downloads a URL to a file withinroot, size-capped. Requires authorization.
fetch = SharedTools::Tools::WebFetchTool.new
fetch.execute(url: "https://example.com")
request = SharedTools::Tools::HttpRequestTool.new
request.execute(url: "https://api.example.com/items", method: "POST", body: '{"name":"x"}')
download = SharedTools::Tools::DownloadFileTool.new(root: "./downloads")
download.execute(url: "https://example.com/release.zip", path: "release.zip")🗄️ Database Tools
Execute SQL operations on databases.
Features: SELECT, INSERT, UPDATE, DELETE; read-only query mode; automatic LIMIT enforcement; pluggable drivers (SQLite, PostgreSQL, MySQL)
require 'sqlite3'
db = SQLite3::Database.new(':memory:')
driver = SharedTools::Tools::Database::SqliteDriver.new(db: db)
database = SharedTools::Tools::DatabaseTool.new(driver: driver)
results = database.execute(
statements: [
"CREATE TABLE users (id INTEGER, name TEXT)",
"INSERT INTO users VALUES (1, 'Alice')",
"SELECT * FROM users"
]
)💻 Eval Tools
Safe code evaluation for Ruby, Python, and shell commands.
Languages: ruby, python, shell
eval_tool = SharedTools::Tools::EvalTool.new
result = eval_tool.execute(language: "ruby", code: "puts 2 + 2")
output = eval_tool.execute(language: "shell", code: "ls -la")🖥️ Bash & Test Runner Tools
-
BashTool— runs ONE allowlisted executable with arguments. Deliberately not a shell: no pipes, redirects, globs, or variable expansion, so OS command injection has no surface to exploit.allowed_commandsis empty by default — nothing runs until configured. Requires authorization. -
RunTestsTool— runs a Ruby project's test suite (RSpec or Minitest, auto-detected). A failing suite is a normal result, not a tool error. Requires authorization. -
PythonTestsTool— runs a Python project's tests (pytest or unittest). Requires authorization.
bash = SharedTools::Tools::BashTool.new(allowed_commands: ["ls", "cat"])
bash.execute(command: "ls", args: ["-la"])
tests = SharedTools::Tools::RunTestsTool.new(root: "./my-project")
tests.execute(path: "spec/models/user_spec.rb")
py_tests = SharedTools::Tools::PythonTestsTool.new(root: "./my-project")
py_tests.execute(framework: "unittest")✅ Task Tracking
TodoWriteTool maintains a task list for multi-step work. Each call replaces the whole list and renders it back; state lives on the tool instance for the duration of a chat session. No authorization needed.
todo = SharedTools::Tools::TodoWriteTool.new
todo.execute(todos: [
{ content: "Write the tool", status: "completed" },
{ content: "Write the tests", status: "in_progress" }
])📄 Doc Tools
Read and reason over documents in any format.
Actions: text_read, pdf_read, docx_read, spreadsheet_read
doc = SharedTools::Tools::DocTool.new
# Plain text
doc.execute(action: "text_read", doc_path: "./notes.txt")
# PDF — specific pages or ranges
doc.execute(action: "pdf_read", doc_path: "./report.pdf", page_numbers: "1, 5-10")
# Microsoft Word
doc.execute(action: "docx_read", doc_path: "./meeting.docx")
# Spreadsheets (CSV, XLSX, ODS, XLSM)
doc.execute(action: "spreadsheet_read", doc_path: "./data.xlsx", sheet: "Q1 Sales")🌐 DNS Tool
DNS resolution, WHOIS queries, IP geolocation, and external IP detection. No API key required.
Actions: a, aaaa, mx, ns, txt, cname, reverse, all, external_ip, ip_location, whois
dns = SharedTools::Tools::DnsTool.new
dns.execute(action: "mx", host: "gmail.com")
dns.execute(action: "whois", host: "ruby-lang.org")
dns.execute(action: "external_ip")
dns.execute(action: "ip_location") # geolocate your own IP
dns.execute(action: "ip_location", host: "8.8.8.8") # geolocate any IP🧩 Structured Data Tools
Query and edit JSON, YAML, TOML, and CSV without writing a parser. Each query tool accepts either a file path or an inline string, and supports a dot/bracket path expression to extract a value (users[0].name, services[].image, dependencies.serde.version) — omit the query to pretty-print the whole document. YAML is loaded with safe_load (no arbitrary object deserialization) and TOML is parsed with a small dependency-free parser.
json = SharedTools::Tools::JsonQueryTool.new
json.execute(path: "./config.json", query: "servers[0].host")
yaml = SharedTools::Tools::YamlQueryTool.new
yaml.execute(path: "./docker-compose.yml", query: "services[].image")
toml = SharedTools::Tools::TomlQueryTool.new
toml.execute(path: "./Cargo.toml", query: "dependencies.serde.version")
csv_read = SharedTools::Tools::CsvReadTool.new
csv_read.execute(path: "./sales.csv", limit: 20)
csv_write = SharedTools::Tools::CsvWriteTool.new
csv_write.execute(path: "./out.csv", headers: ["name", "age"], rows: [["Alice", "30"]])CsvWriteTool is mutating and requires user authorization (see Authorization System); the query tools and CsvReadTool are read-only.
🌤️ Weather Tool
Real-time weather data from OpenWeatherMap API. Combine with DnsTool for automatic local forecasts.
Features: Current conditions, 3-day forecast, metric/imperial/kelvin units, global coverage
weather = SharedTools::Tools::WeatherTool.new
weather.execute(city: "London,UK", units: "metric", include_forecast: true)Local forecast with automatic location detection:
chat = RubyLLM.chat.with_tools(
SharedTools::Tools::DnsTool.new,
SharedTools::Tools::WeatherTool.new,
SharedTools::Tools::CurrentDateTimeTool.new
)
chat.ask("Get my external IP, find my city, then give me the current weather and 3-day forecast.")🧮 Calculator Tool
Safe mathematical calculations without code execution risks.
Features: Arithmetic, math functions (sqrt, round, abs), trigonometry (sin, cos, tan), configurable precision
calculator = SharedTools::Tools::CalculatorTool.new
calculator.execute(expression: "sqrt(16) * 2", precision: 4)
# => {success: true, result: 8.0}📊 Data Science Kit
Real statistical analysis on actual data — file-based or inline.
Analysis types: statistical_summary, correlation_analysis, time_series, clustering, prediction
Inline data formats: pipe-delimited tables, CSV strings, JSON arrays, comma-separated numbers
kit = SharedTools::Tools::DataScienceKit.new
# From a file
kit.execute(analysis_type: "statistical_summary", data_source: "./sales.csv")
# Inline pipe-delimited table
kit.execute(
analysis_type: "correlation_analysis",
data: "| month | revenue | cost |\n| Jan | 12400 | 8200 |\n| Feb | 11800 | 7900 |"
)📖 Full Data Science Documentation
🖱️ Computer Tools
System-level automation for mouse, keyboard, and screen control.
Actions: mouse_click, mouse_move, mouse_position, type, key, hold_key, scroll, wait
computer = SharedTools::Tools::ComputerTool.new
computer.execute(action: "mouse_click", coordinate: {x: 100, y: 200})
computer.execute(action: "type", text: "Hello, World!")🕐 Date/Time, System Info & Clipboard
Utility tools for context and system access:
# Current date and day of week (prevents LLM hallucination)
dt = SharedTools::Tools::CurrentDateTimeTool.new
dt.execute(format: "date")
# => { date: "2026-03-25", day_of_week: "Wednesday", ... }
# System hardware and OS info
info = SharedTools::Tools::SystemInfoTool.new
info.execute
# Clipboard
clipboard = SharedTools::Tools::ClipboardTool.new
clipboard.execute(action: "read")
clipboard.execute(action: "write", text: "Hello!")🔔 Notification Tool
Cross-platform desktop notifications, modal alert dialogs, and text-to-speech. Supports macOS and Linux with no gem dependencies.
Actions: notify, alert, speak
tool = SharedTools::Tools::NotificationTool.new
# Non-blocking desktop banner
tool.execute(action: "notify", message: "Build complete", title: "CI", sound: "Glass")
# Modal dialog — blocks until user clicks; returns clicked button label
result = tool.execute(action: "alert", message: "Deploy to production?", buttons: ["Yes", "No"])
result[:button] # => "Yes" or "No"
# Text-to-speech
tool.execute(action: "speak", message: "Task finished", voice: "Samantha", rate: 160)| Action | macOS | Linux |
|---|---|---|
notify |
osascript | notify-send |
alert |
osascript dialog | zenity or terminal fallback |
speak |
say | espeak-ng / espeak |
🔄 Workflow Manager Tool
Persistent multi-step workflow orchestration with JSON file storage.
Actions: start, step, status, complete, list
workflow = SharedTools::Tools::WorkflowManagerTool.new
# Start a workflow
result = workflow.execute(action: "start", step_data: {project: "release-v2.0"})
workflow_id = result[:workflow_id]
# Execute steps
workflow.execute(action: "step", workflow_id: workflow_id, step_data: {task: "run_tests"})
workflow.execute(action: "step", workflow_id: workflow_id, step_data: {task: "deploy"})
# Check status
workflow.execute(action: "status", workflow_id: workflow_id)
# List all workflows
workflow.execute(action: "list")
# Complete
workflow.execute(action: "complete", workflow_id: workflow_id)📊 Composite Analysis Tool
Multi-stage data analysis orchestration.
analyzer = SharedTools::Tools::CompositeAnalysisTool.new
analyzer.execute(
data_source: "./sales_data.csv",
analysis_type: "comprehensive",
options: {include_correlations: true, visualization_limit: 5}
)🐳 Docker Compose Tool
Execute Docker Compose commands safely.
docker = SharedTools::Tools::Docker::ComposeRunTool.new
docker.execute(service: "app", command: "rspec", args: ["spec/main_spec.rb"])🛠️ Error Handling Tool
Reference implementation for robust error handling patterns.
error_tool = SharedTools::Tools::ErrorHandlingTool.new
error_tool.execute(
operation: "process",
data: {name: "test", value: 42},
max_retries: 3
)MCP Clients
SharedTools bundles Model Context Protocol clients that connect AI agents to external services. Each client is opt-in — require only the ones you need.
Remote HTTP (API key only)
| Client | Env var | Provides |
|---|---|---|
require 'shared_tools/mcp/tavily_client' |
TAVILY_API_KEY |
Web search, news, research, URL extraction |
Brew-installed (auto-installs via Homebrew)
| Client | Env var | Provides |
|---|---|---|
require 'shared_tools/mcp/github_client' |
GITHUB_PERSONAL_ACCESS_TOKEN |
Repos, issues, PRs, code search |
require 'shared_tools/mcp/notion_client' |
NOTION_TOKEN |
Pages, databases, search, content CRUD |
require 'shared_tools/mcp/slack_client' |
SLACK_MCP_XOXP_TOKEN |
Channels, messages, threads, user info |
require 'shared_tools/mcp/hugging_face_client' |
HF_TOKEN |
Models, datasets, Spaces, model cards |
npx Auto-download (Node.js required)
| Client | Provides |
|---|---|
require 'shared_tools/mcp/memory_client' |
Persistent knowledge graph |
require 'shared_tools/mcp/sequential_thinking_client' |
Chain-of-thought reasoning |
require 'shared_tools/mcp/chart_client' |
Chart and visualisation generation |
require 'shared_tools/mcp/brave_search_client' |
Web and news search (BRAVE_API_KEY) |
require 'shared_tools/mcp/playwright_client' |
Browser automation: navigate, click, fill, screenshot, extract |
# Load all available clients at once (skips any whose env vars are missing)
require 'shared_tools/mcp'
# Or load a specific client
require 'shared_tools/mcp/notion_client'
client = RubyLLM::MCP.clients["notion"]
chat = RubyLLM.chat.with_tools(*client.tools)
chat.ask("Find my project planning pages and summarise what's in them")See MCP Clients README for full configuration details.
Authorization System
SharedTools includes a human-in-the-loop authorization system for safety:
# Require user confirmation (default)
SharedTools.auto_execute(false)
# The LLM proposes an action
disk.execute(action: "file_delete", path: "./important.txt")
# Prompt: "Allow DiskTool to delete ./important.txt? (y/n)"
# Enable auto-execution for trusted workflows
SharedTools.auto_execute(true)
disk.execute(action: "file_delete", path: "./temp.txt")
# Executes immediately without promptingDocumentation
Comprehensive documentation is available at madbomber.github.io/shared_tools
Documentation Sections
- Getting Started — Installation, quick start, basic usage
- Tool Collections — Detailed documentation for each tool
- Guides — Authorization, drivers, error handling, testing
- Examples — Working code examples and workflows
- API Reference — Tool base class, facade pattern, driver interface
- Development — Architecture, contributing, changelog
Examples
The /examples directory contains runnable demonstrations using a shared common.rb helper:
bundle exec ruby -I examples examples/weather_tool_demo.rb
bundle exec ruby -I examples examples/dns_tool_demo.rb
bundle exec ruby -I examples examples/doc_tool_demo.rb| Demo | What it shows |
|---|---|
browser_tool_demo.rb |
Web automation |
calculator_tool_demo.rb |
Math expressions |
clipboard_tool_demo.rb |
Clipboard read/write |
composite_analysis_tool_demo.rb |
Multi-stage analysis |
computer_tool_demo.rb |
Mouse and keyboard |
cron_tool_demo.rb |
Cron scheduling |
current_date_time_tool_demo.rb |
Real date and time |
data_science_kit_demo.rb |
Statistical analysis with inline data |
database_tool_demo.rb |
SQL operations |
database_query_tool_demo.rb |
Read-only SQL queries |
disk_tool_demo.rb |
File operations |
dns_tool_demo.rb |
DNS, WHOIS, geolocation |
doc_tool_demo.rb |
Text, PDF, Word, spreadsheets |
error_handling_tool_demo.rb |
Error handling patterns |
eval_tool_demo.rb |
Code evaluation |
mcp_client_demo.rb |
MCP client overview |
mcp/tavily_demo.rb |
Tavily web search (HTTP) |
mcp/github_demo.rb |
GitHub repos, issues, PRs |
mcp/notion_demo.rb |
Notion pages and databases |
mcp/slack_demo.rb |
Slack channels and messages |
mcp/hugging_face_demo.rb |
Hugging Face models and datasets |
mcp/memory_demo.rb |
Persistent knowledge graph |
mcp/sequential_thinking_demo.rb |
Chain-of-thought reasoning |
mcp/chart_demo.rb |
Chart generation |
mcp/brave_search_demo.rb |
Brave web search |
mcp/playwright_demo.rb |
Browser automation via Playwright |
notification_tool_demo.rb |
Desktop notifications, alerts, TTS |
system_info_tool_demo.rb |
System info |
weather_tool_demo.rb |
Weather + local forecast |
workflow_manager_tool_demo.rb |
Workflow orchestration |
comprehensive_workflow_demo.rb |
Multi-tool pipeline |
Development
Setup
git clone https://github.com/madbomber/shared_tools.git
cd shared_tools
bundle installRunning Tests
# Run all tests
bundle exec rake test
# Run specific test file
bundle exec ruby test/shared_tools/tools/browser_tool_test.rb
# Run with SimpleCov coverage report
COVERAGE=true bundle exec rake testBuilding Documentation
pip install mkdocs-material
mkdocs serve # Serve locally
mkdocs build # Build static siteCode Quality
- Testing: Minitest (85%+ coverage)
- Code Loading: Zeitwerk for autoloading
- Documentation: MkDocs with Material theme
-
Examples: Executable Ruby scripts in
/examples
Contributing
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Ensure tests pass (
bundle exec rake test) - Open a Pull Request
Requirements
- Ruby 3.0 or higher
- RubyLLM gem for LLM integration
License
This gem is available as open source under the terms of the MIT License.
Special Thanks
This gem was originally inspired by Kevin Sylvestre's omniai-tools gem. SharedTools has since evolved to focus exclusively on RubyLLM support with enhanced features and comprehensive documentation.
Also checkout the wonderful ruby gem ruby_llm-toolbox
Links
- Documentation: madbomber.github.io/shared_tools
- RubyGems: rubygems.org/gems/shared_tools
- Source Code: github.com/madbomber/shared_tools
- Issue Tracker: github.com/madbomber/shared_tools/issues
- RubyLLM: github.com/mariochavez/ruby_llm