Add Ruby MCP Server Development collection (#330)
- Add Ruby MCP server best practices instruction - Add Ruby MCP server project generator prompt - Add Ruby MCP expert chat mode - Add Ruby MCP development collection manifest - Update category READMEs Features: - Server setup with official mcp gem - Tool/prompt/resource handlers with classes - Rails controller integration - Stdio and HTTP transport support - Input/output schemas with validation - Tool annotations for behavior hints - Structured content in responses - Exception reporting and instrumentation - Minitest test examples Co-authored-by: Aaron Powell <me@aaron-powell.com>
This commit is contained in:
parent
eec72209d0
commit
51b18a7577
@ -70,6 +70,7 @@ Custom chat modes define specific behaviors and tools for GitHub Copilot Chat, e
|
||||
| [Python MCP Server Expert](chatmodes/python-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fpython-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fpython-mcp-expert.chatmode.md) | Expert assistant for developing Model Context Protocol (MCP) servers in Python |
|
||||
| [Refine Requirement or Issue Chat Mode](chatmodes/refine-issue.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Frefine-issue.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Frefine-issue.chatmode.md) | Refine the requirement or issue with Acceptance Criteria, Technical Considerations, Edge Cases, and NFRs |
|
||||
| [Requirements to Jira Epic & User Story Creator](chatmodes/atlassian-requirements-to-jira.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fatlassian-requirements-to-jira.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fatlassian-requirements-to-jira.chatmode.md) | Transform requirements documents into structured Jira epics and user stories with intelligent duplicate detection, change management, and user-approved creation workflow. |
|
||||
| [Ruby MCP Expert](chatmodes/ruby-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fruby-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fruby-mcp-expert.chatmode.md) | Expert assistance for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration. |
|
||||
| [Rust Beast Mode](chatmodes/rust-gpt-4.1-beast-mode.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Frust-gpt-4.1-beast-mode.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Frust-gpt-4.1-beast-mode.chatmode.md) | Rust GPT-4.1 Coding Beast Mode for VS Code |
|
||||
| [Semantic Kernel .NET mode instructions](chatmodes/semantic-kernel-dotnet.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsemantic-kernel-dotnet.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsemantic-kernel-dotnet.chatmode.md) | Create, update, refactor, explain or work with code using the .NET version of Semantic Kernel. |
|
||||
| [Semantic Kernel Python mode instructions](chatmodes/semantic-kernel-python.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsemantic-kernel-python.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fsemantic-kernel-python.chatmode.md) | Create, update, refactor, explain or work with code using the Python version of Semantic Kernel. |
|
||||
|
||||
@ -31,6 +31,7 @@ Curated collections of related prompts, instructions, and chat modes organized a
|
||||
| [Power Platform MCP Connector Development](collections/power-platform-mcp-connector-development.md) | Complete toolkit for developing Power Platform custom connectors with Model Context Protocol integration for Microsoft Copilot Studio | 4 items | power-platform, mcp, copilot-studio, custom-connector, json-rpc |
|
||||
| [Project Planning & Management](collections/project-planning.md) | Tools and guidance for software project planning, feature breakdown, epic management, implementation planning, and task organization for development teams. | 17 items | planning, project-management, epic, feature, implementation, task, architecture, technical-spike |
|
||||
| [Python MCP Server Development](collections/python-mcp-development.md) | Complete toolkit for building Model Context Protocol (MCP) servers in Python using the official SDK with FastMCP. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 3 items | python, mcp, model-context-protocol, fastmcp, server-development |
|
||||
| [Ruby MCP Server Development](collections/ruby-mcp-development.md) | 'Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support.' | 3 items | ruby, mcp, model-context-protocol, server-development, sdk, rails, gem |
|
||||
| [Security & Code Quality](collections/security-best-practices.md) | Security frameworks, accessibility guidelines, performance optimization, and code quality best practices for building secure, maintainable, and high-performance applications. | 6 items | security, accessibility, performance, code-quality, owasp, a11y, optimization, best-practices |
|
||||
| [Swift MCP Server Development](collections/swift-mcp-development.md) | 'Comprehensive collection for building Model Context Protocol servers in Swift using the official MCP Swift SDK with modern concurrency features.' | 3 items | swift, mcp, model-context-protocol, server-development, sdk, ios, macos, concurrency, actor, async-await |
|
||||
| [Tasks by microsoft/edge-ai](collections/edge-ai-tasks.md) | Task Researcher and Task Planner for intermediate to expert users and large codebases - Brought to you by microsoft/edge-ai | 3 items | architecture, planning, research, tasks, implementation |
|
||||
|
||||
@ -97,6 +97,7 @@ Team and project-specific instructions to enhance GitHub Copilot's behavior for
|
||||
| [Quarkus](instructions/quarkus.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fquarkus.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fquarkus.instructions.md) | Quarkus development standards and instructions |
|
||||
| [Quarkus MCP Server](instructions/quarkus-mcp-server-sse.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fquarkus-mcp-server-sse.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fquarkus-mcp-server-sse.instructions.md) | Quarkus and MCP Server with HTTP SSE transport development standards and instructions |
|
||||
| [ReactJS Development Instructions](instructions/reactjs.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Freactjs.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Freactjs.instructions.md) | ReactJS development standards and best practices |
|
||||
| [Ruby MCP Server Development Guidelines](instructions/ruby-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fruby-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fruby-mcp-server.instructions.md) | Best practices and patterns for building Model Context Protocol (MCP) servers in Ruby using the official MCP Ruby SDK gem. |
|
||||
| [Ruby on Rails](instructions/ruby-on-rails.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fruby-on-rails.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fruby-on-rails.instructions.md) | Ruby on Rails coding conventions and guidelines |
|
||||
| [Rust Coding Conventions and Best Practices](instructions/rust.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Frust.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Frust.instructions.md) | Rust programming language coding conventions and best practices |
|
||||
| [Secure Coding and OWASP Guidelines](instructions/security-and-owasp.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fsecurity-and-owasp.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fsecurity-and-owasp.instructions.md) | Comprehensive secure coding instructions for all languages and frameworks, based on OWASP Top 10 and industry best practices. |
|
||||
|
||||
@ -98,6 +98,7 @@ Ready-to-use prompt templates for specific development scenarios and tasks, defi
|
||||
| [Refactoring Java Methods with Extract Method](prompts/java-refactoring-extract-method.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fjava-refactoring-extract-method.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fjava-refactoring-extract-method.prompt.md) | Refactoring using Extract Methods in Java Language |
|
||||
| [Repo Story Time](prompts/repo-story-time.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Frepo-story-time.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Frepo-story-time.prompt.md) | Generate a comprehensive repository summary and narrative story from commit history |
|
||||
| [Review And Refactor](prompts/review-and-refactor.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Freview-and-refactor.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Freview-and-refactor.prompt.md) | Review and refactor code in your project according to defined instructions |
|
||||
| [Ruby MCP Server Generator](prompts/ruby-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fruby-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fruby-mcp-server-generator.prompt.md) | Generate a complete Model Context Protocol server project in Ruby using the official MCP Ruby SDK gem. |
|
||||
| [Shuffle JSON Data](prompts/shuffle-json-data.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fshuffle-json-data.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fshuffle-json-data.prompt.md) | Shuffle repetitive JSON objects safely by validating schema consistency before randomising entries. |
|
||||
| [Spring Boot Best Practices](prompts/java-springboot.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fjava-springboot.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fjava-springboot.prompt.md) | Get best practices for developing applications with Spring Boot. |
|
||||
| [Spring Boot with Kotlin Best Practices](prompts/kotlin-springboot.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fkotlin-springboot.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fkotlin-springboot.prompt.md) | Get best practices for developing applications with Spring Boot and Kotlin. |
|
||||
|
||||
346
chatmodes/ruby-mcp-expert.chatmode.md
Normal file
346
chatmodes/ruby-mcp-expert.chatmode.md
Normal file
@ -0,0 +1,346 @@
|
||||
---
|
||||
description: 'Expert assistance for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration.'
|
||||
model: GPT-4.1
|
||||
---
|
||||
|
||||
# Ruby MCP Expert
|
||||
|
||||
I'm specialized in helping you build robust, production-ready MCP servers in Ruby using the official Ruby SDK. I can assist with:
|
||||
|
||||
## Core Capabilities
|
||||
|
||||
### Server Architecture
|
||||
- Setting up MCP::Server instances
|
||||
- Configuring tools, prompts, and resources
|
||||
- Implementing stdio and HTTP transports
|
||||
- Rails controller integration
|
||||
- Server context for authentication
|
||||
|
||||
### Tool Development
|
||||
- Creating tool classes with MCP::Tool
|
||||
- Defining input/output schemas
|
||||
- Implementing tool annotations
|
||||
- Structured content in responses
|
||||
- Error handling with is_error flag
|
||||
|
||||
### Resource Management
|
||||
- Defining resources and resource templates
|
||||
- Implementing resource read handlers
|
||||
- URI template patterns
|
||||
- Dynamic resource generation
|
||||
|
||||
### Prompt Engineering
|
||||
- Creating prompt classes with MCP::Prompt
|
||||
- Defining prompt arguments
|
||||
- Multi-turn conversation templates
|
||||
- Dynamic prompt generation with server_context
|
||||
|
||||
### Configuration
|
||||
- Exception reporting with Bugsnag/Sentry
|
||||
- Instrumentation callbacks for metrics
|
||||
- Protocol version configuration
|
||||
- Custom JSON-RPC methods
|
||||
|
||||
## Code Assistance
|
||||
|
||||
I can help you with:
|
||||
|
||||
### Gemfile Setup
|
||||
```ruby
|
||||
gem 'mcp', '~> 0.4.0'
|
||||
```
|
||||
|
||||
### Server Creation
|
||||
```ruby
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
version: '1.0.0',
|
||||
tools: [MyTool],
|
||||
prompts: [MyPrompt],
|
||||
server_context: { user_id: current_user.id }
|
||||
)
|
||||
```
|
||||
|
||||
### Tool Definition
|
||||
```ruby
|
||||
class MyTool < MCP::Tool
|
||||
tool_name 'my_tool'
|
||||
description 'Tool description'
|
||||
|
||||
input_schema(
|
||||
properties: {
|
||||
query: { type: 'string' }
|
||||
},
|
||||
required: ['query']
|
||||
)
|
||||
|
||||
annotations(
|
||||
read_only_hint: true
|
||||
)
|
||||
|
||||
def self.call(query:, server_context:)
|
||||
MCP::Tool::Response.new([{
|
||||
type: 'text',
|
||||
text: 'Result'
|
||||
}])
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Stdio Transport
|
||||
```ruby
|
||||
transport = MCP::Server::Transports::StdioTransport.new(server)
|
||||
transport.open
|
||||
```
|
||||
|
||||
### Rails Integration
|
||||
```ruby
|
||||
class McpController < ApplicationController
|
||||
def index
|
||||
server = MCP::Server.new(
|
||||
name: 'rails_server',
|
||||
tools: [MyTool],
|
||||
server_context: { user_id: current_user.id }
|
||||
)
|
||||
render json: server.handle_json(request.body.read)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Use Classes for Tools
|
||||
Organize tools as classes for better structure:
|
||||
```ruby
|
||||
class GreetTool < MCP::Tool
|
||||
tool_name 'greet'
|
||||
description 'Generate greeting'
|
||||
|
||||
def self.call(name:, server_context:)
|
||||
MCP::Tool::Response.new([{
|
||||
type: 'text',
|
||||
text: "Hello, #{name}!"
|
||||
}])
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Define Schemas
|
||||
Ensure type safety with input/output schemas:
|
||||
```ruby
|
||||
input_schema(
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
age: { type: 'integer', minimum: 0 }
|
||||
},
|
||||
required: ['name']
|
||||
)
|
||||
|
||||
output_schema(
|
||||
properties: {
|
||||
message: { type: 'string' },
|
||||
timestamp: { type: 'string', format: 'date-time' }
|
||||
},
|
||||
required: ['message']
|
||||
)
|
||||
```
|
||||
|
||||
### Add Annotations
|
||||
Provide behavior hints:
|
||||
```ruby
|
||||
annotations(
|
||||
read_only_hint: true,
|
||||
destructive_hint: false,
|
||||
idempotent_hint: true
|
||||
)
|
||||
```
|
||||
|
||||
### Include Structured Content
|
||||
Return both text and structured data:
|
||||
```ruby
|
||||
data = { temperature: 72, condition: 'sunny' }
|
||||
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: data.to_json }],
|
||||
structured_content: data
|
||||
)
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Authenticated Tool
|
||||
```ruby
|
||||
class SecureTool < MCP::Tool
|
||||
def self.call(**args, server_context:)
|
||||
user_id = server_context[:user_id]
|
||||
raise 'Unauthorized' unless user_id
|
||||
|
||||
# Process request
|
||||
MCP::Tool::Response.new([{
|
||||
type: 'text',
|
||||
text: 'Success'
|
||||
}])
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
```ruby
|
||||
def self.call(data:, server_context:)
|
||||
begin
|
||||
result = process(data)
|
||||
MCP::Tool::Response.new([{
|
||||
type: 'text',
|
||||
text: result
|
||||
}])
|
||||
rescue ValidationError => e
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: e.message }],
|
||||
is_error: true
|
||||
)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Resource Handler
|
||||
```ruby
|
||||
server.resources_read_handler do |params|
|
||||
case params[:uri]
|
||||
when 'resource://data'
|
||||
[{
|
||||
uri: params[:uri],
|
||||
mimeType: 'application/json',
|
||||
text: fetch_data.to_json
|
||||
}]
|
||||
else
|
||||
raise "Unknown resource: #{params[:uri]}"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Dynamic Prompt
|
||||
```ruby
|
||||
class CustomPrompt < MCP::Prompt
|
||||
def self.template(args, server_context:)
|
||||
user_id = server_context[:user_id]
|
||||
user = User.find(user_id)
|
||||
|
||||
MCP::Prompt::Result.new(
|
||||
description: "Prompt for #{user.name}",
|
||||
messages: generate_for(user)
|
||||
)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Exception Reporting
|
||||
```ruby
|
||||
MCP.configure do |config|
|
||||
config.exception_reporter = ->(exception, context) {
|
||||
Bugsnag.notify(exception) do |report|
|
||||
report.add_metadata(:mcp, context)
|
||||
end
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
### Instrumentation
|
||||
```ruby
|
||||
MCP.configure do |config|
|
||||
config.instrumentation_callback = ->(data) {
|
||||
StatsD.timing("mcp.#{data[:method]}", data[:duration])
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
### Custom Methods
|
||||
```ruby
|
||||
server.define_custom_method(method_name: 'custom') do |params|
|
||||
# Return result or nil for notifications
|
||||
{ status: 'ok' }
|
||||
end
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Tool Tests
|
||||
```ruby
|
||||
class MyToolTest < Minitest::Test
|
||||
def test_tool_call
|
||||
response = MyTool.call(
|
||||
query: 'test',
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
refute response.is_error
|
||||
assert_equal 1, response.content.length
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
```ruby
|
||||
def test_server_handles_request
|
||||
server = MCP::Server.new(
|
||||
name: 'test',
|
||||
tools: [MyTool]
|
||||
)
|
||||
|
||||
request = {
|
||||
jsonrpc: '2.0',
|
||||
id: '1',
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'my_tool',
|
||||
arguments: { query: 'test' }
|
||||
}
|
||||
}.to_json
|
||||
|
||||
response = JSON.parse(server.handle_json(request))
|
||||
assert response['result']
|
||||
end
|
||||
```
|
||||
|
||||
## Ruby SDK Features
|
||||
|
||||
### Supported Methods
|
||||
- `initialize` - Protocol initialization
|
||||
- `ping` - Health check
|
||||
- `tools/list` - List tools
|
||||
- `tools/call` - Call tool
|
||||
- `prompts/list` - List prompts
|
||||
- `prompts/get` - Get prompt
|
||||
- `resources/list` - List resources
|
||||
- `resources/read` - Read resource
|
||||
- `resources/templates/list` - List resource templates
|
||||
|
||||
### Notifications
|
||||
- `notify_tools_list_changed`
|
||||
- `notify_prompts_list_changed`
|
||||
- `notify_resources_list_changed`
|
||||
|
||||
### Transport Support
|
||||
- Stdio transport for CLI
|
||||
- HTTP transport for web services
|
||||
- Streamable HTTP with SSE
|
||||
|
||||
## Ask Me About
|
||||
|
||||
- Server setup and configuration
|
||||
- Tool, prompt, and resource implementations
|
||||
- Rails integration patterns
|
||||
- Exception reporting and instrumentation
|
||||
- Input/output schema design
|
||||
- Tool annotations
|
||||
- Structured content responses
|
||||
- Server context usage
|
||||
- Testing strategies
|
||||
- HTTP transport with authorization
|
||||
- Custom JSON-RPC methods
|
||||
- Notifications and list changes
|
||||
- Protocol version management
|
||||
- Performance optimization
|
||||
|
||||
I'm here to help you build idiomatic, production-ready Ruby MCP servers. What would you like to work on?
|
||||
35
collections/ruby-mcp-development.collection.yml
Normal file
35
collections/ruby-mcp-development.collection.yml
Normal file
@ -0,0 +1,35 @@
|
||||
id: ruby-mcp-development
|
||||
name: Ruby MCP Server Development
|
||||
description: 'Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support.'
|
||||
tags: [ruby, mcp, model-context-protocol, server-development, sdk, rails, gem]
|
||||
items:
|
||||
- path: instructions/ruby-mcp-server.instructions.md
|
||||
kind: instruction
|
||||
- path: prompts/ruby-mcp-server-generator.prompt.md
|
||||
kind: prompt
|
||||
- path: chatmodes/ruby-mcp-expert.chatmode.md
|
||||
kind: chat-mode
|
||||
usage: |
|
||||
recommended
|
||||
|
||||
This chat mode provides expert guidance for building MCP servers in Ruby.
|
||||
|
||||
This chat mode is ideal for:
|
||||
- Creating new MCP server projects with Ruby
|
||||
- Implementing tools, prompts, and resources
|
||||
- Setting up stdio or HTTP transports
|
||||
- Debugging schema definitions and error handling
|
||||
- Learning Ruby MCP best practices with the official SDK
|
||||
- Integrating with Rails applications
|
||||
|
||||
To get the best results, consider:
|
||||
- Using the instruction file to set context for Ruby MCP development
|
||||
- Using the prompt to generate initial project structure
|
||||
- Switching to the expert chat mode for detailed implementation help
|
||||
- Specifying whether you need stdio or Rails integration
|
||||
- Providing details about what tools or functionality you need
|
||||
- Mentioning if you need authentication or server_context usage
|
||||
|
||||
display:
|
||||
ordering: manual
|
||||
show_badge: true
|
||||
41
collections/ruby-mcp-development.md
Normal file
41
collections/ruby-mcp-development.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Ruby MCP Server Development
|
||||
|
||||
'Complete toolkit for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration support.'
|
||||
|
||||
**Tags:** ruby, mcp, model-context-protocol, server-development, sdk, rails, gem
|
||||
|
||||
## Items in this Collection
|
||||
|
||||
| Title | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| [Ruby MCP Server Development Guidelines](../instructions/ruby-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fruby-mcp-server.instructions.md)<br />[](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fruby-mcp-server.instructions.md) | Instruction | Best practices and patterns for building Model Context Protocol (MCP) servers in Ruby using the official MCP Ruby SDK gem. |
|
||||
| [Ruby MCP Server Generator](../prompts/ruby-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fruby-mcp-server-generator.prompt.md)<br />[](https://aka.ms/awesome-copilot/install/prompt?url=vscode-insiders%3Achat-prompt%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fprompts%2Fruby-mcp-server-generator.prompt.md) | Prompt | Generate a complete Model Context Protocol server project in Ruby using the official MCP Ruby SDK gem. |
|
||||
| [Ruby MCP Expert](../chatmodes/ruby-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fruby-mcp-expert.chatmode.md)<br />[](https://aka.ms/awesome-copilot/install/chatmode?url=vscode-insiders%3Achat-mode%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fchatmodes%2Fruby-mcp-expert.chatmode.md) | Chat Mode | Expert assistance for building Model Context Protocol servers in Ruby using the official MCP Ruby SDK gem with Rails integration. [see usage](#ruby-mcp-expert) |
|
||||
|
||||
## Collection Usage
|
||||
|
||||
### Ruby MCP Expert
|
||||
|
||||
recommended
|
||||
|
||||
This chat mode provides expert guidance for building MCP servers in Ruby.
|
||||
|
||||
This chat mode is ideal for:
|
||||
- Creating new MCP server projects with Ruby
|
||||
- Implementing tools, prompts, and resources
|
||||
- Setting up stdio or HTTP transports
|
||||
- Debugging schema definitions and error handling
|
||||
- Learning Ruby MCP best practices with the official SDK
|
||||
- Integrating with Rails applications
|
||||
|
||||
To get the best results, consider:
|
||||
- Using the instruction file to set context for Ruby MCP development
|
||||
- Using the prompt to generate initial project structure
|
||||
- Switching to the expert chat mode for detailed implementation help
|
||||
- Specifying whether you need stdio or Rails integration
|
||||
- Providing details about what tools or functionality you need
|
||||
- Mentioning if you need authentication or server_context usage
|
||||
|
||||
---
|
||||
|
||||
*This collection includes 3 curated items for ruby mcp server development.*
|
||||
629
instructions/ruby-mcp-server.instructions.md
Normal file
629
instructions/ruby-mcp-server.instructions.md
Normal file
@ -0,0 +1,629 @@
|
||||
---
|
||||
description: 'Best practices and patterns for building Model Context Protocol (MCP) servers in Ruby using the official MCP Ruby SDK gem.'
|
||||
applyTo: "**/*.rb, **/Gemfile, **/*.gemspec, **/Rakefile"
|
||||
---
|
||||
|
||||
# Ruby MCP Server Development Guidelines
|
||||
|
||||
When building MCP servers in Ruby, follow these best practices and patterns using the official Ruby SDK.
|
||||
|
||||
## Installation
|
||||
|
||||
Add the MCP gem to your Gemfile:
|
||||
|
||||
```ruby
|
||||
gem 'mcp'
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
bundle install
|
||||
```
|
||||
|
||||
## Server Setup
|
||||
|
||||
Create an MCP server instance:
|
||||
|
||||
```ruby
|
||||
require 'mcp'
|
||||
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
version: '1.0.0'
|
||||
)
|
||||
```
|
||||
|
||||
## Adding Tools
|
||||
|
||||
Define tools using classes or blocks:
|
||||
|
||||
### Tool as Class
|
||||
|
||||
```ruby
|
||||
class GreetTool < MCP::Tool
|
||||
tool_name 'greet'
|
||||
description 'Generate a greeting message'
|
||||
|
||||
input_schema(
|
||||
properties: {
|
||||
name: { type: 'string', description: 'Name to greet' }
|
||||
},
|
||||
required: ['name']
|
||||
)
|
||||
|
||||
output_schema(
|
||||
properties: {
|
||||
message: { type: 'string' },
|
||||
timestamp: { type: 'string', format: 'date-time' }
|
||||
},
|
||||
required: ['message']
|
||||
)
|
||||
|
||||
annotations(
|
||||
read_only_hint: true,
|
||||
idempotent_hint: true
|
||||
)
|
||||
|
||||
def self.call(name:, server_context:)
|
||||
MCP::Tool::Response.new([{
|
||||
type: 'text',
|
||||
text: "Hello, #{name}! Welcome to MCP."
|
||||
}], structured_content: {
|
||||
message: "Hello, #{name}!",
|
||||
timestamp: Time.now.iso8601
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
tools: [GreetTool]
|
||||
)
|
||||
```
|
||||
|
||||
### Tool with Block
|
||||
|
||||
```ruby
|
||||
server.define_tool(
|
||||
name: 'calculate',
|
||||
description: 'Perform mathematical calculations',
|
||||
input_schema: {
|
||||
properties: {
|
||||
operation: { type: 'string', enum: ['add', 'subtract', 'multiply', 'divide'] },
|
||||
a: { type: 'number' },
|
||||
b: { type: 'number' }
|
||||
},
|
||||
required: ['operation', 'a', 'b']
|
||||
},
|
||||
annotations: {
|
||||
read_only_hint: true,
|
||||
idempotent_hint: true
|
||||
}
|
||||
) do |args, server_context|
|
||||
operation = args['operation']
|
||||
a = args['a']
|
||||
b = args['b']
|
||||
|
||||
result = case operation
|
||||
when 'add' then a + b
|
||||
when 'subtract' then a - b
|
||||
when 'multiply' then a * b
|
||||
when 'divide'
|
||||
return MCP::Tool::Response.new([{ type: 'text', text: 'Division by zero' }], is_error: true) if b == 0
|
||||
a / b
|
||||
else
|
||||
return MCP::Tool::Response.new([{ type: 'text', text: "Unknown operation: #{operation}" }], is_error: true)
|
||||
end
|
||||
|
||||
MCP::Tool::Response.new([{ type: 'text', text: "Result: #{result}" }])
|
||||
end
|
||||
```
|
||||
|
||||
## Adding Resources
|
||||
|
||||
Define resources for data access:
|
||||
|
||||
```ruby
|
||||
# Register resources
|
||||
resource = MCP::Resource.new(
|
||||
uri: 'resource://data/example',
|
||||
name: 'example-data',
|
||||
description: 'Example resource data',
|
||||
mime_type: 'application/json'
|
||||
)
|
||||
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
resources: [resource]
|
||||
)
|
||||
|
||||
# Define read handler
|
||||
server.resources_read_handler do |params|
|
||||
case params[:uri]
|
||||
when 'resource://data/example'
|
||||
[{
|
||||
uri: params[:uri],
|
||||
mimeType: 'application/json',
|
||||
text: { message: 'Example data', timestamp: Time.now }.to_json
|
||||
}]
|
||||
else
|
||||
raise "Unknown resource: #{params[:uri]}"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Adding Prompts
|
||||
|
||||
Define prompt templates:
|
||||
|
||||
### Prompt as Class
|
||||
|
||||
```ruby
|
||||
class CodeReviewPrompt < MCP::Prompt
|
||||
prompt_name 'code_review'
|
||||
description 'Generate a code review prompt'
|
||||
|
||||
arguments [
|
||||
MCP::Prompt::Argument.new(
|
||||
name: 'language',
|
||||
description: 'Programming language',
|
||||
required: true
|
||||
),
|
||||
MCP::Prompt::Argument.new(
|
||||
name: 'focus',
|
||||
description: 'Review focus area',
|
||||
required: false
|
||||
)
|
||||
]
|
||||
|
||||
def self.template(args, server_context:)
|
||||
language = args['language'] || 'Ruby'
|
||||
focus = args['focus'] || 'general quality'
|
||||
|
||||
MCP::Prompt::Result.new(
|
||||
description: "Code review for #{language} with focus on #{focus}",
|
||||
messages: [
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'user',
|
||||
content: MCP::Content::Text.new("Please review this #{language} code with focus on #{focus}.")
|
||||
),
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'assistant',
|
||||
content: MCP::Content::Text.new("I'll review the code focusing on #{focus}. Please share the code.")
|
||||
)
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
prompts: [CodeReviewPrompt]
|
||||
)
|
||||
```
|
||||
|
||||
### Prompt with Block
|
||||
|
||||
```ruby
|
||||
server.define_prompt(
|
||||
name: 'analyze',
|
||||
description: 'Analyze a topic',
|
||||
arguments: [
|
||||
MCP::Prompt::Argument.new(name: 'topic', description: 'Topic to analyze', required: true),
|
||||
MCP::Prompt::Argument.new(name: 'depth', description: 'Analysis depth', required: false)
|
||||
]
|
||||
) do |args, server_context:|
|
||||
topic = args['topic']
|
||||
depth = args['depth'] || 'basic'
|
||||
|
||||
MCP::Prompt::Result.new(
|
||||
description: "Analysis of #{topic} at #{depth} level",
|
||||
messages: [
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'user',
|
||||
content: MCP::Content::Text.new("Please analyze: #{topic}")
|
||||
),
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'assistant',
|
||||
content: MCP::Content::Text.new("I'll provide a #{depth} analysis of #{topic}")
|
||||
)
|
||||
]
|
||||
)
|
||||
end
|
||||
```
|
||||
|
||||
## Transport Configuration
|
||||
|
||||
### Stdio Transport
|
||||
|
||||
For local command-line applications:
|
||||
|
||||
```ruby
|
||||
require 'mcp'
|
||||
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
tools: [MyTool]
|
||||
)
|
||||
|
||||
transport = MCP::Server::Transports::StdioTransport.new(server)
|
||||
transport.open
|
||||
```
|
||||
|
||||
### HTTP Transport (Rails)
|
||||
|
||||
For Rails applications:
|
||||
|
||||
```ruby
|
||||
class McpController < ApplicationController
|
||||
def index
|
||||
server = MCP::Server.new(
|
||||
name: 'rails_server',
|
||||
version: '1.0.0',
|
||||
tools: [SomeTool],
|
||||
prompts: [MyPrompt],
|
||||
server_context: { user_id: current_user.id }
|
||||
)
|
||||
|
||||
render json: server.handle_json(request.body.read)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Streamable HTTP Transport
|
||||
|
||||
For Server-Sent Events:
|
||||
|
||||
```ruby
|
||||
server = MCP::Server.new(name: 'my_server')
|
||||
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)
|
||||
server.transport = transport
|
||||
|
||||
# When tools change, notify clients
|
||||
server.define_tool(name: 'new_tool') { |**args| { result: 'ok' } }
|
||||
server.notify_tools_list_changed
|
||||
```
|
||||
|
||||
## Server Context
|
||||
|
||||
Pass contextual information to tools and prompts:
|
||||
|
||||
```ruby
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
tools: [AuthenticatedTool],
|
||||
server_context: {
|
||||
user_id: current_user.id,
|
||||
request_id: request.uuid,
|
||||
auth_token: session[:token]
|
||||
}
|
||||
)
|
||||
|
||||
class AuthenticatedTool < MCP::Tool
|
||||
def self.call(query:, server_context:)
|
||||
user_id = server_context[:user_id]
|
||||
# Use user_id for authorization
|
||||
|
||||
MCP::Tool::Response.new([{ type: 'text', text: 'Authorized' }])
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Exception Reporting
|
||||
|
||||
Configure exception reporting:
|
||||
|
||||
```ruby
|
||||
MCP.configure do |config|
|
||||
config.exception_reporter = ->(exception, server_context) {
|
||||
# Report to your error tracking service
|
||||
Bugsnag.notify(exception) do |report|
|
||||
report.add_metadata(:mcp, server_context)
|
||||
end
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
### Instrumentation
|
||||
|
||||
Monitor MCP server performance:
|
||||
|
||||
```ruby
|
||||
MCP.configure do |config|
|
||||
config.instrumentation_callback = ->(data) {
|
||||
# Log instrumentation data
|
||||
Rails.logger.info("MCP: #{data.inspect}")
|
||||
|
||||
# Or send to metrics service
|
||||
StatsD.timing("mcp.#{data[:method]}.duration", data[:duration])
|
||||
StatsD.increment("mcp.#{data[:method]}.count")
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
The instrumentation data includes:
|
||||
- `method`: Protocol method called (e.g., "tools/call")
|
||||
- `tool_name`: Name of tool called
|
||||
- `prompt_name`: Name of prompt called
|
||||
- `resource_uri`: URI of resource called
|
||||
- `error`: Error code if lookup failed
|
||||
- `duration`: Duration in seconds
|
||||
|
||||
### Protocol Version
|
||||
|
||||
Override the protocol version:
|
||||
|
||||
```ruby
|
||||
configuration = MCP::Configuration.new(protocol_version: '2025-06-18')
|
||||
server = MCP::Server.new(name: 'my_server', configuration: configuration)
|
||||
```
|
||||
|
||||
## Tool Annotations
|
||||
|
||||
Provide metadata about tool behavior:
|
||||
|
||||
```ruby
|
||||
class DataTool < MCP::Tool
|
||||
annotations(
|
||||
read_only_hint: true, # Tool only reads data
|
||||
destructive_hint: false, # Tool doesn't destroy data
|
||||
idempotent_hint: true, # Same input = same output
|
||||
open_world_hint: false # Tool operates in closed context
|
||||
)
|
||||
|
||||
def self.call(**args, server_context:)
|
||||
# Implementation
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Tool Output Schemas
|
||||
|
||||
Define expected output structure:
|
||||
|
||||
```ruby
|
||||
class WeatherTool < MCP::Tool
|
||||
output_schema(
|
||||
properties: {
|
||||
temperature: { type: 'number' },
|
||||
condition: { type: 'string' },
|
||||
humidity: { type: 'integer' }
|
||||
},
|
||||
required: ['temperature', 'condition']
|
||||
)
|
||||
|
||||
def self.call(location:, server_context:)
|
||||
weather_data = {
|
||||
temperature: 72.5,
|
||||
condition: 'sunny',
|
||||
humidity: 45
|
||||
}
|
||||
|
||||
# Validate against schema
|
||||
output_schema.validate_result(weather_data)
|
||||
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: weather_data.to_json }],
|
||||
structured_content: weather_data
|
||||
)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Structured Content in Responses
|
||||
|
||||
Return structured data with text:
|
||||
|
||||
```ruby
|
||||
class APITool < MCP::Tool
|
||||
def self.call(endpoint:, server_context:)
|
||||
api_data = call_api(endpoint)
|
||||
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: api_data.to_json }],
|
||||
structured_content: api_data
|
||||
)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Custom Methods
|
||||
|
||||
Define custom JSON-RPC methods:
|
||||
|
||||
```ruby
|
||||
server = MCP::Server.new(name: 'my_server')
|
||||
|
||||
# Custom method with result
|
||||
server.define_custom_method(method_name: 'add') do |params|
|
||||
params[:a] + params[:b]
|
||||
end
|
||||
|
||||
# Custom notification (returns nil)
|
||||
server.define_custom_method(method_name: 'notify') do |params|
|
||||
puts "Notification: #{params[:message]}"
|
||||
nil
|
||||
end
|
||||
```
|
||||
|
||||
## Notifications
|
||||
|
||||
Send list change notifications:
|
||||
|
||||
```ruby
|
||||
server = MCP::Server.new(name: 'my_server')
|
||||
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)
|
||||
server.transport = transport
|
||||
|
||||
# Notify when tools change
|
||||
server.define_tool(name: 'new_tool') { |**args| { result: 'ok' } }
|
||||
server.notify_tools_list_changed
|
||||
|
||||
# Notify when prompts change
|
||||
server.define_prompt(name: 'new_prompt') { |args, **_| MCP::Prompt::Result.new(...) }
|
||||
server.notify_prompts_list_changed
|
||||
|
||||
# Notify when resources change
|
||||
server.notify_resources_list_changed
|
||||
```
|
||||
|
||||
## Resource Templates
|
||||
|
||||
Define dynamic resources with URI templates:
|
||||
|
||||
```ruby
|
||||
resource_template = MCP::ResourceTemplate.new(
|
||||
uri_template: 'users://{user_id}/profile',
|
||||
name: 'user-profile',
|
||||
description: 'User profile data',
|
||||
mime_type: 'application/json'
|
||||
)
|
||||
|
||||
server = MCP::Server.new(
|
||||
name: 'my_server',
|
||||
resource_templates: [resource_template]
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Handle errors properly in tools:
|
||||
|
||||
```ruby
|
||||
class RiskyTool < MCP::Tool
|
||||
def self.call(data:, server_context:)
|
||||
begin
|
||||
result = risky_operation(data)
|
||||
MCP::Tool::Response.new([{ type: 'text', text: result }])
|
||||
rescue ValidationError => e
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: "Invalid input: #{e.message}" }],
|
||||
is_error: true
|
||||
)
|
||||
rescue => e
|
||||
# Will be caught and reported by exception_reporter
|
||||
raise
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Write tests for your MCP server:
|
||||
|
||||
```ruby
|
||||
require 'minitest/autorun'
|
||||
require 'mcp'
|
||||
|
||||
class MyToolTest < Minitest::Test
|
||||
def test_greet_tool
|
||||
response = GreetTool.call(name: 'Ruby', server_context: {})
|
||||
|
||||
assert_equal 1, response.content.length
|
||||
assert_match(/Ruby/, response.content.first[:text])
|
||||
refute response.is_error
|
||||
end
|
||||
|
||||
def test_invalid_input
|
||||
response = CalculateTool.call(operation: 'divide', a: 10, b: 0, server_context: {})
|
||||
|
||||
assert response.is_error
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Client Usage
|
||||
|
||||
Build MCP clients to connect to servers:
|
||||
|
||||
```ruby
|
||||
require 'mcp'
|
||||
require 'faraday'
|
||||
|
||||
# HTTP transport
|
||||
http_transport = MCP::Client::HTTP.new(
|
||||
url: 'https://api.example.com/mcp',
|
||||
headers: { 'Authorization' => "Bearer #{token}" }
|
||||
)
|
||||
|
||||
client = MCP::Client.new(transport: http_transport)
|
||||
|
||||
# List tools
|
||||
tools = client.tools
|
||||
tools.each do |tool|
|
||||
puts "Tool: #{tool.name}"
|
||||
puts "Description: #{tool.description}"
|
||||
end
|
||||
|
||||
# Call a tool
|
||||
response = client.call_tool(
|
||||
tool: tools.first,
|
||||
arguments: { message: 'Hello, world!' }
|
||||
)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use classes for complex tools** - Better organization and testability
|
||||
2. **Define input/output schemas** - Ensure type safety and validation
|
||||
3. **Add annotations** - Help clients understand tool behavior
|
||||
4. **Include structured content** - Provide both text and structured data
|
||||
5. **Use server_context** - Pass authentication and request context
|
||||
6. **Configure exception reporting** - Monitor errors in production
|
||||
7. **Implement instrumentation** - Track performance metrics
|
||||
8. **Send notifications** - Keep clients updated on changes
|
||||
9. **Validate inputs** - Check parameters before processing
|
||||
10. **Follow Ruby conventions** - Use snake_case, proper indentation
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Authenticated Tool
|
||||
|
||||
```ruby
|
||||
class AuthenticatedTool < MCP::Tool
|
||||
def self.call(**args, server_context:)
|
||||
user_id = server_context[:user_id]
|
||||
raise 'Unauthorized' unless user_id
|
||||
|
||||
# Process authenticated request
|
||||
MCP::Tool::Response.new([{ type: 'text', text: 'Success' }])
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Paginated Resource
|
||||
|
||||
```ruby
|
||||
server.resources_read_handler do |params|
|
||||
uri = params[:uri]
|
||||
page = params[:page] || 1
|
||||
|
||||
data = fetch_paginated_data(page)
|
||||
|
||||
[{
|
||||
uri: uri,
|
||||
mimeType: 'application/json',
|
||||
text: data.to_json
|
||||
}]
|
||||
end
|
||||
```
|
||||
|
||||
### Dynamic Prompt
|
||||
|
||||
```ruby
|
||||
class DynamicPrompt < MCP::Prompt
|
||||
def self.template(args, server_context:)
|
||||
user_id = server_context[:user_id]
|
||||
user_data = User.find(user_id)
|
||||
|
||||
MCP::Prompt::Result.new(
|
||||
description: "Personalized prompt for #{user_data.name}",
|
||||
messages: generate_messages_for(user_data)
|
||||
)
|
||||
end
|
||||
end
|
||||
```
|
||||
660
prompts/ruby-mcp-server-generator.prompt.md
Normal file
660
prompts/ruby-mcp-server-generator.prompt.md
Normal file
@ -0,0 +1,660 @@
|
||||
---
|
||||
description: 'Generate a complete Model Context Protocol server project in Ruby using the official MCP Ruby SDK gem.'
|
||||
mode: agent
|
||||
---
|
||||
|
||||
# Ruby MCP Server Generator
|
||||
|
||||
Generate a complete, production-ready MCP server in Ruby using the official Ruby SDK.
|
||||
|
||||
## Project Generation
|
||||
|
||||
When asked to create a Ruby MCP server, generate a complete project with this structure:
|
||||
|
||||
```
|
||||
my-mcp-server/
|
||||
├── Gemfile
|
||||
├── Rakefile
|
||||
├── lib/
|
||||
│ ├── my_mcp_server.rb
|
||||
│ ├── my_mcp_server/
|
||||
│ │ ├── server.rb
|
||||
│ │ ├── tools/
|
||||
│ │ │ ├── greet_tool.rb
|
||||
│ │ │ └── calculate_tool.rb
|
||||
│ │ ├── prompts/
|
||||
│ │ │ └── code_review_prompt.rb
|
||||
│ │ └── resources/
|
||||
│ │ └── example_resource.rb
|
||||
├── bin/
|
||||
│ └── mcp-server
|
||||
├── test/
|
||||
│ ├── test_helper.rb
|
||||
│ └── tools/
|
||||
│ ├── greet_tool_test.rb
|
||||
│ └── calculate_tool_test.rb
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Gemfile Template
|
||||
|
||||
```ruby
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'mcp', '~> 0.4.0'
|
||||
|
||||
group :development, :test do
|
||||
gem 'minitest', '~> 5.0'
|
||||
gem 'rake', '~> 13.0'
|
||||
gem 'rubocop', '~> 1.50'
|
||||
end
|
||||
```
|
||||
|
||||
## Rakefile Template
|
||||
|
||||
```ruby
|
||||
require 'rake/testtask'
|
||||
require 'rubocop/rake_task'
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'test'
|
||||
t.libs << 'lib'
|
||||
t.test_files = FileList['test/**/*_test.rb']
|
||||
end
|
||||
|
||||
RuboCop::RakeTask.new
|
||||
|
||||
task default: %i[test rubocop]
|
||||
```
|
||||
|
||||
## lib/my_mcp_server.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'mcp'
|
||||
require_relative 'my_mcp_server/server'
|
||||
require_relative 'my_mcp_server/tools/greet_tool'
|
||||
require_relative 'my_mcp_server/tools/calculate_tool'
|
||||
require_relative 'my_mcp_server/prompts/code_review_prompt'
|
||||
require_relative 'my_mcp_server/resources/example_resource'
|
||||
|
||||
module MyMcpServer
|
||||
VERSION = '1.0.0'
|
||||
end
|
||||
```
|
||||
|
||||
## lib/my_mcp_server/server.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
module MyMcpServer
|
||||
class Server
|
||||
attr_reader :mcp_server
|
||||
|
||||
def initialize(server_context: {})
|
||||
@mcp_server = MCP::Server.new(
|
||||
name: 'my_mcp_server',
|
||||
version: MyMcpServer::VERSION,
|
||||
tools: [
|
||||
Tools::GreetTool,
|
||||
Tools::CalculateTool
|
||||
],
|
||||
prompts: [
|
||||
Prompts::CodeReviewPrompt
|
||||
],
|
||||
resources: [
|
||||
Resources::ExampleResource.resource
|
||||
],
|
||||
server_context: server_context
|
||||
)
|
||||
|
||||
setup_resource_handler
|
||||
end
|
||||
|
||||
def handle_json(json_string)
|
||||
mcp_server.handle_json(json_string)
|
||||
end
|
||||
|
||||
def start_stdio
|
||||
transport = MCP::Server::Transports::StdioTransport.new(mcp_server)
|
||||
transport.open
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def setup_resource_handler
|
||||
mcp_server.resources_read_handler do |params|
|
||||
Resources::ExampleResource.read(params[:uri])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## lib/my_mcp_server/tools/greet_tool.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
module MyMcpServer
|
||||
module Tools
|
||||
class GreetTool < MCP::Tool
|
||||
tool_name 'greet'
|
||||
description 'Generate a greeting message'
|
||||
|
||||
input_schema(
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name to greet'
|
||||
}
|
||||
},
|
||||
required: ['name']
|
||||
)
|
||||
|
||||
output_schema(
|
||||
properties: {
|
||||
message: { type: 'string' },
|
||||
timestamp: { type: 'string', format: 'date-time' }
|
||||
},
|
||||
required: ['message', 'timestamp']
|
||||
)
|
||||
|
||||
annotations(
|
||||
read_only_hint: true,
|
||||
idempotent_hint: true
|
||||
)
|
||||
|
||||
def self.call(name:, server_context:)
|
||||
timestamp = Time.now.iso8601
|
||||
message = "Hello, #{name}! Welcome to MCP."
|
||||
|
||||
structured_data = {
|
||||
message: message,
|
||||
timestamp: timestamp
|
||||
}
|
||||
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: message }],
|
||||
structured_content: structured_data
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## lib/my_mcp_server/tools/calculate_tool.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
module MyMcpServer
|
||||
module Tools
|
||||
class CalculateTool < MCP::Tool
|
||||
tool_name 'calculate'
|
||||
description 'Perform mathematical calculations'
|
||||
|
||||
input_schema(
|
||||
properties: {
|
||||
operation: {
|
||||
type: 'string',
|
||||
description: 'Operation to perform',
|
||||
enum: ['add', 'subtract', 'multiply', 'divide']
|
||||
},
|
||||
a: {
|
||||
type: 'number',
|
||||
description: 'First operand'
|
||||
},
|
||||
b: {
|
||||
type: 'number',
|
||||
description: 'Second operand'
|
||||
}
|
||||
},
|
||||
required: ['operation', 'a', 'b']
|
||||
)
|
||||
|
||||
output_schema(
|
||||
properties: {
|
||||
result: { type: 'number' },
|
||||
operation: { type: 'string' }
|
||||
},
|
||||
required: ['result', 'operation']
|
||||
)
|
||||
|
||||
annotations(
|
||||
read_only_hint: true,
|
||||
idempotent_hint: true
|
||||
)
|
||||
|
||||
def self.call(operation:, a:, b:, server_context:)
|
||||
result = case operation
|
||||
when 'add' then a + b
|
||||
when 'subtract' then a - b
|
||||
when 'multiply' then a * b
|
||||
when 'divide'
|
||||
return error_response('Division by zero') if b.zero?
|
||||
a / b.to_f
|
||||
else
|
||||
return error_response("Unknown operation: #{operation}")
|
||||
end
|
||||
|
||||
structured_data = {
|
||||
result: result,
|
||||
operation: operation
|
||||
}
|
||||
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: "Result: #{result}" }],
|
||||
structured_content: structured_data
|
||||
)
|
||||
end
|
||||
|
||||
def self.error_response(message)
|
||||
MCP::Tool::Response.new(
|
||||
[{ type: 'text', text: message }],
|
||||
is_error: true
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## lib/my_mcp_server/prompts/code_review_prompt.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
module MyMcpServer
|
||||
module Prompts
|
||||
class CodeReviewPrompt < MCP::Prompt
|
||||
prompt_name 'code_review'
|
||||
description 'Generate a code review prompt'
|
||||
|
||||
arguments [
|
||||
MCP::Prompt::Argument.new(
|
||||
name: 'language',
|
||||
description: 'Programming language',
|
||||
required: true
|
||||
),
|
||||
MCP::Prompt::Argument.new(
|
||||
name: 'focus',
|
||||
description: 'Review focus area (e.g., performance, security)',
|
||||
required: false
|
||||
)
|
||||
]
|
||||
|
||||
meta(
|
||||
version: '1.0',
|
||||
category: 'development'
|
||||
)
|
||||
|
||||
def self.template(args, server_context:)
|
||||
language = args['language'] || 'Ruby'
|
||||
focus = args['focus'] || 'general quality'
|
||||
|
||||
MCP::Prompt::Result.new(
|
||||
description: "Code review for #{language} with focus on #{focus}",
|
||||
messages: [
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'user',
|
||||
content: MCP::Content::Text.new(
|
||||
"Please review this #{language} code with focus on #{focus}."
|
||||
)
|
||||
),
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'assistant',
|
||||
content: MCP::Content::Text.new(
|
||||
"I'll review the code focusing on #{focus}. Please share the code."
|
||||
)
|
||||
),
|
||||
MCP::Prompt::Message.new(
|
||||
role: 'user',
|
||||
content: MCP::Content::Text.new(
|
||||
'[paste code here]'
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## lib/my_mcp_server/resources/example_resource.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
module MyMcpServer
|
||||
module Resources
|
||||
class ExampleResource
|
||||
RESOURCE_URI = 'resource://data/example'
|
||||
|
||||
def self.resource
|
||||
MCP::Resource.new(
|
||||
uri: RESOURCE_URI,
|
||||
name: 'example-data',
|
||||
description: 'Example resource data',
|
||||
mime_type: 'application/json'
|
||||
)
|
||||
end
|
||||
|
||||
def self.read(uri)
|
||||
return [] unless uri == RESOURCE_URI
|
||||
|
||||
data = {
|
||||
message: 'Example resource data',
|
||||
timestamp: Time.now.iso8601,
|
||||
version: MyMcpServer::VERSION
|
||||
}
|
||||
|
||||
[{
|
||||
uri: uri,
|
||||
mimeType: 'application/json',
|
||||
text: data.to_json
|
||||
}]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## bin/mcp-server Template
|
||||
|
||||
```ruby
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../lib/my_mcp_server'
|
||||
|
||||
begin
|
||||
server = MyMcpServer::Server.new
|
||||
server.start_stdio
|
||||
rescue Interrupt
|
||||
warn "\nShutting down server..."
|
||||
exit 0
|
||||
rescue StandardError => e
|
||||
warn "Error: #{e.message}"
|
||||
warn e.backtrace.join("\n")
|
||||
exit 1
|
||||
end
|
||||
```
|
||||
|
||||
Make the file executable:
|
||||
```bash
|
||||
chmod +x bin/mcp-server
|
||||
```
|
||||
|
||||
## test/test_helper.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
||||
require 'my_mcp_server'
|
||||
require 'minitest/autorun'
|
||||
```
|
||||
|
||||
## test/tools/greet_tool_test.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
module MyMcpServer
|
||||
module Tools
|
||||
class GreetToolTest < Minitest::Test
|
||||
def test_greet_with_name
|
||||
response = GreetTool.call(
|
||||
name: 'Ruby',
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
refute response.is_error
|
||||
assert_equal 1, response.content.length
|
||||
assert_match(/Ruby/, response.content.first[:text])
|
||||
|
||||
assert response.structured_content
|
||||
assert_equal 'Hello, Ruby! Welcome to MCP.', response.structured_content[:message]
|
||||
end
|
||||
|
||||
def test_output_schema_validation
|
||||
response = GreetTool.call(
|
||||
name: 'Test',
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
assert response.structured_content.key?(:message)
|
||||
assert response.structured_content.key?(:timestamp)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## test/tools/calculate_tool_test.rb Template
|
||||
|
||||
```ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
module MyMcpServer
|
||||
module Tools
|
||||
class CalculateToolTest < Minitest::Test
|
||||
def test_addition
|
||||
response = CalculateTool.call(
|
||||
operation: 'add',
|
||||
a: 5,
|
||||
b: 3,
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
refute response.is_error
|
||||
assert_equal 8, response.structured_content[:result]
|
||||
end
|
||||
|
||||
def test_subtraction
|
||||
response = CalculateTool.call(
|
||||
operation: 'subtract',
|
||||
a: 10,
|
||||
b: 4,
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
refute response.is_error
|
||||
assert_equal 6, response.structured_content[:result]
|
||||
end
|
||||
|
||||
def test_multiplication
|
||||
response = CalculateTool.call(
|
||||
operation: 'multiply',
|
||||
a: 6,
|
||||
b: 7,
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
refute response.is_error
|
||||
assert_equal 42, response.structured_content[:result]
|
||||
end
|
||||
|
||||
def test_division
|
||||
response = CalculateTool.call(
|
||||
operation: 'divide',
|
||||
a: 15,
|
||||
b: 3,
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
refute response.is_error
|
||||
assert_equal 5.0, response.structured_content[:result]
|
||||
end
|
||||
|
||||
def test_division_by_zero
|
||||
response = CalculateTool.call(
|
||||
operation: 'divide',
|
||||
a: 10,
|
||||
b: 0,
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
assert response.is_error
|
||||
assert_match(/Division by zero/, response.content.first[:text])
|
||||
end
|
||||
|
||||
def test_unknown_operation
|
||||
response = CalculateTool.call(
|
||||
operation: 'modulo',
|
||||
a: 10,
|
||||
b: 3,
|
||||
server_context: {}
|
||||
)
|
||||
|
||||
assert response.is_error
|
||||
assert_match(/Unknown operation/, response.content.first[:text])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## README.md Template
|
||||
|
||||
```markdown
|
||||
# My MCP Server
|
||||
|
||||
A Model Context Protocol server built with Ruby and the official MCP Ruby SDK.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ Tools: greet, calculate
|
||||
- ✅ Prompts: code_review
|
||||
- ✅ Resources: example-data
|
||||
- ✅ Input/output schemas
|
||||
- ✅ Tool annotations
|
||||
- ✅ Structured content
|
||||
- ✅ Full test coverage
|
||||
|
||||
## Requirements
|
||||
|
||||
- Ruby 3.0 or later
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bundle install
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Stdio Transport
|
||||
|
||||
Run the server:
|
||||
|
||||
```bash
|
||||
bundle exec bin/mcp-server
|
||||
```
|
||||
|
||||
Then send JSON-RPC requests:
|
||||
|
||||
```bash
|
||||
{"jsonrpc":"2.0","id":"1","method":"ping"}
|
||||
{"jsonrpc":"2.0","id":"2","method":"tools/list"}
|
||||
{"jsonrpc":"2.0","id":"3","method":"tools/call","params":{"name":"greet","arguments":{"name":"Ruby"}}}
|
||||
```
|
||||
|
||||
### Rails Integration
|
||||
|
||||
Add to your Rails controller:
|
||||
|
||||
```ruby
|
||||
class McpController < ApplicationController
|
||||
def index
|
||||
server = MyMcpServer::Server.new(
|
||||
server_context: { user_id: current_user.id }
|
||||
)
|
||||
render json: server.handle_json(request.body.read)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Run tests:
|
||||
|
||||
```bash
|
||||
bundle exec rake test
|
||||
```
|
||||
|
||||
Run linter:
|
||||
|
||||
```bash
|
||||
bundle exec rake rubocop
|
||||
```
|
||||
|
||||
Run all checks:
|
||||
|
||||
```bash
|
||||
bundle exec rake
|
||||
```
|
||||
|
||||
## Integration with Claude Desktop
|
||||
|
||||
Add to `claude_desktop_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"my-mcp-server": {
|
||||
"command": "bundle",
|
||||
"args": ["exec", "bin/mcp-server"],
|
||||
"cwd": "/path/to/my-mcp-server"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
my-mcp-server/
|
||||
├── Gemfile # Dependencies
|
||||
├── Rakefile # Build tasks
|
||||
├── lib/ # Source code
|
||||
│ ├── my_mcp_server.rb # Main entry point
|
||||
│ └── my_mcp_server/ # Module namespace
|
||||
│ ├── server.rb # Server setup
|
||||
│ ├── tools/ # Tool implementations
|
||||
│ ├── prompts/ # Prompt templates
|
||||
│ └── resources/ # Resource handlers
|
||||
├── bin/ # Executables
|
||||
│ └── mcp-server # Stdio server
|
||||
├── test/ # Test suite
|
||||
│ ├── test_helper.rb # Test configuration
|
||||
│ └── tools/ # Tool tests
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
```
|
||||
|
||||
## Generation Instructions
|
||||
|
||||
1. **Ask for project name and description**
|
||||
2. **Generate all files** with proper naming and module structure
|
||||
3. **Use classes for tools and prompts** for better organization
|
||||
4. **Include input/output schemas** for type safety
|
||||
5. **Add tool annotations** for behavior hints
|
||||
6. **Include structured content** in responses
|
||||
7. **Implement comprehensive tests** for all tools
|
||||
8. **Follow Ruby conventions** (snake_case, modules, frozen_string_literal)
|
||||
9. **Add proper error handling** with is_error flag
|
||||
10. **Provide both stdio and HTTP** usage examples
|
||||
Loading…
x
Reference in New Issue
Block a user