Curated library of 41 public AI agent skills for Ruby on Rails development. Organized by category: planning, testing, code-quality, ddd, engines, infrastructure, api, patterns, context, and orchestration. Covers code review, architecture, security, testing (RSpec), engines, service objects, DDD patterns, and TDD automation. Repository workflows remain documented in GitHub but are intentionally excluded from the Tessl tile.
95
93%
Does it follow best practices?
Impact
96%
1.77xAverage score across 41 eval scenarios
Passed
No known issues
A Ruby MCP server that exposes the rails-agent-skills library to AI tools (Windsurf, Cursor, Claude Code, RubyMine, OpenCode, etc.) via the Model Context Protocol official spec (JSON-RPC 2.0, stdio transport).
This is the canonical setup guide for the official MCP distribution. It publishes repository docs and workflows as resources, lists available Rails skills through list_skills, then loads individual Rails skills on demand through the use_skill tool so agents do not need the full skill library in context at once.
Built on the official Ruby MCP SDK (gem 'mcp').
| Requirement | Version |
|---|---|
| Ruby | 4.0+ |
mcp gem | 0.15+ |
| Bundler | 2.x |
| Type | Prefix / Name | Source |
|---|---|---|
| Resources | doc/<name> | All *.md files under docs/, including nested docs such as docs/workflows/*.md |
| Resources | workflow/<name> | Every workflow directory under workflows/<workflow>/, exposed from its SKILL.md plus supported companion files |
| Tool | list_skills | Invocable read-only discovery tool: returns public skill names, categories, paths, and frontmatter descriptions |
| Tool | use_skill | Invocable read-only loader tool: given a skill_name, returns structured metadata plus the full SKILL.md content for a public skill |
Individual Skills are no longer exposed as resources to prevent context bloat. Discover them with list_skills, then load one on demand with use_skill.
Adding a new public skill directory to the repo automatically makes it available through list_skills and use_skill — no server changes needed.
The runtime code lives in mcp_server/, while the container build lives at ../Dockerfile because the image needs the full repository checkout, including skills, workflows, and docs.
mcp_server/
├── server.rb # Entry point: MCP::Server + StdioTransport
├── Gemfile # gem 'mcp' (official SDK), minitest, rake
├── Rakefile # bundle exec rake test
├── registry.json # Metadata for MCP registries (smithery.ai, glama.ai)
├── lib/
│ └── mcp_skills/
│ ├── skill_catalog.rb # Service: builds structured skill metadata
│ ├── resource_registry.rb # Service: discovers published docs and workflows
│ ├── resource_discovery.rb # Service: resolves published skill/workflow topology
│ ├── skill_resource_builder.rb # Service: builds MCP::Resource objects for workflow markdown
│ ├── doc_resource_builder.rb # Service: builds MCP::Resource objects for docs
│ ├── list_skills_tool.rb # MCP::Tool: 'list_skills' discovery
│ └── skill_tool.rb # MCP::Tool: 'use_skill' loader
└── test/
├── test_helper.rb
├── resource_registry_test.rb
├── skill_resource_builder_test.rb
├── doc_resource_builder_test.rb
└── skill_tool_test.rbService objects:
McpSkills::ResourceRegistry — scans the repo for published docs and workflows. Single source of truth for the resource set.McpSkills::ResourceDiscovery — resolves the published topology for nested skills/, root workflows/, and docs/.McpSkills::SkillResourceBuilder — maps a workflow directory path to MCP::Resource objects with file:// URIs and a configurable name prefix.McpSkills::DocResourceBuilder — builds doc/ resources for markdown files anywhere under docs/.McpSkills::SkillCatalog — builds structured skill metadata from discovered SKILL.md files.McpSkills::ListSkillsTool — MCP::Tool subclass. call returns names, paths, categories, and descriptions as structured content.McpSkills::SkillTool — MCP::Tool subclass. call(skill_name:) returns structured metadata plus the full SKILL.md content.git clone https://github.com/igmarin/rails-agent-skills.git ~/rails-agent-skills
cd ~/rails-agent-skills/mcp_server
bundle installRun the server manually (stdio — for debugging):
bundle exec ruby server.rbInspect with the MCP inspector:
npx @modelcontextprotocol/inspector bundle exec ruby server.rbThe repo includes a pre-populated .mcp.json at the root. When you open the cloned repo as a project in Claude Code, the server is registered automatically — no manual config needed.
For global setup (available in every project), add to ~/.claude/mcp.json:
Note: Always use absolute paths to avoid "Gems not found" or timeout errors.
{
"mcpServers": {
"rails-agent-skills": {
"type": "stdio",
"command": "bundle",
"args": ["exec", "ruby", "mcp_server/server.rb"],
"cwd": "/ABSOLUTE/PATH/TO/rails-agent-skills",
"env": {
"BUNDLE_GEMFILE": "/ABSOLUTE/PATH/TO/rails-agent-skills/mcp_server/Gemfile"
}
}
}
}The config goes in your global Windsurf MCP file (~/.codeium/windsurf/mcp_config.json):
{
"mcpServers": {
"rails-agent-skills": {
"type": "stdio",
"command": "bundle",
"args": ["exec", "ruby", "mcp_server/server.rb"],
"cwd": "/ABSOLUTE/PATH/TO/rails-agent-skills",
"env": {
"BUNDLE_GEMFILE": "/ABSOLUTE/PATH/TO/rails-agent-skills/mcp_server/Gemfile"
}
}
}
}Open Settings → MCP (or edit ~/.cursor/mcp.json) and add:
{
"mcpServers": {
"rails-agent-skills": {
"type": "stdio",
"command": "bundle",
"args": ["exec", "ruby", "mcp_server/server.rb"],
"cwd": "/ABSOLUTE/PATH/TO/rails-agent-skills",
"env": {
"BUNDLE_GEMFILE": "/ABSOLUTE/PATH/TO/rails-agent-skills/mcp_server/Gemfile"
}
}
}
}If you encounter errors like Could not find 'mcp' (>= 0) or the server times out:
cwd and BUNDLE_GEMFILE in your JSON config use absolute paths (e.g., /Users/name/... instead of ~/...).cd mcp_server && bundle install manually in your terminal to ensure the environment is ready.BUNDLE_GEMFILE=/ABSOLUTE/PATH/TO/rails-agent-skills/mcp_server/Gemfile bundle exec ruby /ABSOLUTE/PATH/TO/rails-agent-skills/mcp_server/server.rbcommand in your config points to the correct bundle executable if bundle alone doesn't work.Open Settings → Tools → AI Assistant → Model Context Protocol and add a new server:
bundle exec ruby mcp_server/server.rb/YOUR/PATH/TO/rails-agent-skillsBUNDLE_GEMFILE=/YOUR/PATH/TO/rails-agent-skills/mcp_server/GemfileRestart RubyMine.
For any other tool that supports the Model Context Protocol via stdio, use the following template. Crucial: Most external providers fail if you use relative paths or ~, so always use absolute paths.
{
"mcpServers": {
"rails-agent-skills": {
"type": "stdio",
"command": "bundle",
"args": ["exec", "ruby", "mcp_server/server.rb"],
"cwd": "/ABSOLUTE/PATH/TO/rails-agent-skills",
"env": {
"BUNDLE_GEMFILE": "/ABSOLUTE/PATH/TO/rails-agent-skills/mcp_server/Gemfile"
}
}
}
}For environments without Ruby, or for containerized deployment, Docker remains the fallback path. The primary setup for this repo is still local Ruby/Bundler.
# From the root of the repository:
docker build -t rails-agent-skills-mcp .
docker run --rm -i rails-agent-skills-mcpThe container uses stdio transport — wire it up the same way as the Ruby command, replacing bundle exec ruby server.rb with docker run --rm -i rails-agent-skills-mcp.
Docker Hub (published image):
{
"mcpServers": {
"rails-agent-skills": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "igmarin/rails-agent-skills-mcp"]
}
}
}Use a versioned image tag when you need repeatable installs:
{
"mcpServers": {
"rails-agent-skills": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "igmarin/rails-agent-skills-mcp:5.1.5"]
}
}
}latest tracks the most recent successful push to main. Versioned tags, such as 5.1.5, are created from Git release tags and should be preferred for shared team configuration.
The Docker image includes the following security measures:
mcp (UID 1000) instead of root. All application files are owned by this user.build-base) are installed as a virtual package and removed after bundle install, keeping the final image lean.ruby:4.0.4-alpine for a minimal footprint.The Docker publish workflow (.github/workflows/docker-publish.yml) includes:
| Step | Tool | Purpose |
|---|---|---|
| Vulnerability scan | Trivy | Fails the build on HIGH/CRITICAL vulnerabilities |
| SBOM generation | Syft (via anchore/sbom-action) | Produces an SPDX JSON software bill of materials |
| Image signing | cosign | Signs release images with keyless Sigstore signing |
| Scan artifacts | GitHub Actions artifacts | SARIF scan results uploaded for review |
Trivy scans run after every image push. The SBOM and scan results are uploaded as workflow artifacts. Image signing occurs only on tagged releases.
The Cloudflare MCP worker (cloudflare_mcp/) includes:
RATE_LIMIT_MAX_REQUESTS and RATE_LIMIT_WINDOW_SECONDS environment variables are defined in wrangler.jsonc (default: 60 requests per 60 seconds). These vars are not yet enforced in worker code — application-level rate limiting middleware must be implemented to read and apply them. They serve as the configuration foundation for a future implementation.npm audit runs in CI before deployment.The following settings should be configured manually in the Cloudflare dashboard for the worker domain:
security.txt file under Security → Settings that includes:
This server is published to the official MCP Registry as:
io.github.igmarin/rails-agent-skills-mcpThe official registry does not host this server's code or container image. It stores metadata in root server.json, including the server name, repository, stdio transport, and the Docker Hub image reference.
The package entry uses OCI:
{
"registryType": "oci",
"identifier": "docker.io/igmarin/rails-agent-skills-mcp:VERSION",
"transport": {
"type": "stdio"
}
}For OCI packages, do not add a package-level version field. The MCP Registry expects the package version to be encoded in the image tag inside identifier.
The Docker image must include this ownership label:
LABEL io.modelcontextprotocol.server.name="io.github.igmarin/rails-agent-skills-mcp"You can verify the local image metadata with:
docker build -t rails-agent-skills-mcp:test .
docker image inspect rails-agent-skills-mcp:test --format '{{ index .Config.Labels "io.modelcontextprotocol.server.name" }}'Expected output:
io.github.igmarin/rails-agent-skills-mcpThe repository also includes a hosted Streamable HTTP MCP server under ../cloudflare_mcp. It is separate from this Ruby stdio server and exists for hosted registries and clients that need a public HTTPS MCP URL.
Use this URL for Smithery or any MCP client that supports Streamable HTTP:
https://rails-agent-skills-mcp.ismael-marin.workers.dev/mcpUseful public checks:
Health: https://rails-agent-skills-mcp.ismael-marin.workers.dev/health
Server card: https://rails-agent-skills-mcp.ismael-marin.workers.dev/.well-known/mcp/server-card.jsonThe Cloudflare Worker is deployed by .github/workflows/cloudflare-mcp-deploy.yml after validation. It requires CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN repository secrets.
Normal pushes to main publish the Docker latest image and deploy the Cloudflare Worker when cloudflare_mcp/** changes. They do not publish a new MCP Registry version.
Release tags publish immutable versioned artifacts:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.ZThat tag triggers .github/workflows/docker-publish.yml:
docker.io/igmarin/rails-agent-skills-mcp:X.Y.Z.server.json so version is X.Y.Z and the OCI identifier points at the same Docker image tag.io.github.igmarin/rails-agent-skills-mcp version X.Y.Z.MCP Registry versions are immutable, so a failed registry publish should be fixed in code and released with a new tag. Do not move or reuse already-pushed release tags unless you intentionally want to rewrite release history.
After a successful release, verify registry discovery with:
curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.igmarin/rails-agent-skills-mcp"tools/call list_skills if it needs to discover available skill names and routing descriptions.tools/call use_skill with skill_name: "implement-graphql".implement-graphql/SKILL.md and returns structured metadata plus the full instructions.bundle exec rake testTests are written with Minitest: each file validates real behavior of a service object, not just structure.
ResourceRegistry uses explicit topology discovery for skills/*/*/SKILL.md, workflows/*/SKILL.md, supported Tessl tile mirrors, and docs/**/*.md. When you add a published workflow or doc file in those locations, it appears in resources/list on the next server start. Published skills become available through list_skills and use_skill without any server code changes.
This server is listed on:
lib/mcp_skills/ and must be independently testable (no MCP::Server dependency in unit tests).mcp gem — do not reimplement wire format in service objects.docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
scenario-36
scenario-37
scenario-38
scenario-39
scenario-40
scenario-41
mcp_server
skills
api
generate-api-collection
implement-graphql
code-quality
apply-code-conventions
apply-stack-conventions
assets
snippets
code-review
refactor-code
respond-to-review
review-architecture
security-check
context
load-context
setup-environment
ddd
define-domain-language
model-domain
review-domain-boundaries
engines
create-engine
create-engine-installer
document-engine
extract-engine
release-engine
review-engine
test-engine
upgrade-engine
infrastructure
implement-background-job
implement-hotwire
optimize-performance
review-migration
seed-database
version-api
orchestration
skill-router
patterns
create-service-object
implement-calculator-pattern
write-yard-docs
planning
create-prd
generate-tasks
plan-tickets
testing
plan-tests
test-service
triage-bug
write-tests
workflows