|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +## Project overview |
| 4 | + |
| 5 | +This is the official Ruby SDK for the Model Context Protocol (MCP), implementing both server and client functionality for JSON-RPC 2.0 based communication between LLM applications and context providers. |
| 6 | + |
| 7 | +## Dev environment setup |
| 8 | + |
| 9 | +- Ruby 3.2.0+ required |
| 10 | +- Run `bundle install` to install dependencies |
| 11 | +- Dependencies: `json_rpc_handler` ~> 0.1, `json-schema` >= 4.1 |
| 12 | + |
| 13 | +## Build and test commands |
| 14 | + |
| 15 | +- `bundle install` - Install dependencies |
| 16 | +- `rake test` - Run all tests |
| 17 | +- `rake rubocop` - Run linter |
| 18 | +- `rake` - Run tests and linting (default task) |
| 19 | +- `ruby -I lib -I test test/path/to/specific_test.rb` - Run single test file |
| 20 | +- `gem build mcp.gemspec` - Build the gem |
| 21 | + |
| 22 | +## Testing instructions |
| 23 | + |
| 24 | +- Test files are in `test/` directory with `_test.rb` suffix |
| 25 | +- Run full test suite with `rake test` |
| 26 | +- Run individual tests with `ruby -I lib -I test test/path/to/file_test.rb` |
| 27 | +- Tests should pass before submitting PRs |
| 28 | + |
| 29 | +## Code style guidelines |
| 30 | + |
| 31 | +- Follow RuboCop rules (run `rake rubocop`) |
| 32 | +- Use frozen string literals |
| 33 | +- Follow Ruby community conventions |
| 34 | +- Keep dependencies minimal |
| 35 | + |
| 36 | +## Commit message conventions |
| 37 | + |
| 38 | +- Use conventional commit format when possible |
| 39 | +- Include clear, descriptive commit messages |
| 40 | +- Releases are triggered by updating version in `lib/mcp/version.rb` and merging to main |
| 41 | + |
| 42 | +## Release process |
| 43 | + |
| 44 | +- Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format in CHANGELOG.md |
| 45 | +- Update CHANGELOG.md before cutting releases |
| 46 | +- Use git history and PR merge commits to construct changelog entries |
| 47 | +- Format entries as: "Terse description of the change (#nnn)" |
| 48 | +- Keep entries in flat list format (no nesting) |
| 49 | +- Git tags mark commits that cut new releases |
| 50 | +- Exclude maintenance PRs that don't concern end users |
| 51 | +- Check upstream remote for PRs if available |
| 52 | + |
| 53 | +## Architecture overview |
| 54 | + |
| 55 | +### Core Components |
| 56 | + |
| 57 | +**MCP::Server** (`lib/mcp/server.rb`): |
| 58 | + |
| 59 | +- Main server class handling JSON-RPC requests |
| 60 | +- Implements MCP protocol methods: initialize, ping, tools/list, tools/call, prompts/list, prompts/get, resources/list, resources/read |
| 61 | +- Supports custom method registration via `define_custom_method` |
| 62 | +- Handles instrumentation, exception reporting, and notifications |
| 63 | +- Uses JsonRpcHandler for request processing |
| 64 | + |
| 65 | +**MCP::Client** (`lib/mcp/client.rb`): |
| 66 | + |
| 67 | +- Client interface for communicating with MCP servers |
| 68 | +- Transport-agnostic design with pluggable transport layers |
| 69 | +- Supports tool listing and invocation |
| 70 | + |
| 71 | +**Transport Layer**: |
| 72 | + |
| 73 | +- `MCP::Server::Transports::StdioTransport` - Command-line stdio transport |
| 74 | +- `MCP::Server::Transports::StreamableHttpTransport` - HTTP with streaming support |
| 75 | +- `MCP::Client::HTTP` - HTTP client transport (requires faraday gem) |
| 76 | + |
| 77 | +**Protocol Components**: |
| 78 | + |
| 79 | +- `MCP::Tool` - Tool definition with input/output schemas and annotations |
| 80 | +- `MCP::Prompt` - Prompt templates with argument validation |
| 81 | +- `MCP::Resource` - Resource registration and retrieval |
| 82 | +- `MCP::Configuration` - Global configuration with exception reporting and instrumentation |
| 83 | + |
| 84 | +### Key Patterns |
| 85 | + |
| 86 | +**Three Ways to Define Components**: |
| 87 | + |
| 88 | +1. Class inheritance (e.g., `class MyTool < MCP::Tool`) |
| 89 | +2. Define methods (e.g., `MCP::Tool.define(name: "my_tool") { ... }`) |
| 90 | +3. Server registration (e.g., `server.define_tool(name: "my_tool") { ... }`) |
| 91 | + |
| 92 | +**Schema Validation**: |
| 93 | + |
| 94 | +- Tools support input_schema and output_schema for JSON Schema validation |
| 95 | +- Protocol version 2025-03-26+ supports tool annotations (destructive_hint, idempotent_hint, etc.) |
| 96 | +- Validation is configurable via `configuration.validate_tool_call_arguments` |
| 97 | + |
| 98 | +**Context Passing**: |
| 99 | + |
| 100 | +- `server_context` hash passed through tool/prompt calls for request-specific data |
| 101 | +- Methods can accept `server_context:` keyword argument for accessing context |
| 102 | + |
| 103 | +### Dependencies |
| 104 | + |
| 105 | +- `json_rpc_handler` ~> 0.1 - JSON-RPC 2.0 message handling |
| 106 | +- `json-schema` >= 4.1 - Schema validation |
| 107 | +- Ruby 3.2.0+ required |
| 108 | + |
| 109 | +### Integration patterns |
| 110 | + |
| 111 | +- **Rails controllers**: Use `server.handle_json(request.body.read)` for HTTP endpoints |
| 112 | +- **Command-line tools**: Use `StdioTransport.new(server).open` for CLI applications |
| 113 | +- **HTTP services**: Use `StreamableHttpTransport` for web-based servers |
| 114 | + |
| 115 | +### Component definition patterns |
| 116 | + |
| 117 | +1. **Class inheritance**: `class MyTool < MCP::Tool` |
| 118 | +2. **Define methods**: `MCP::Tool.define(name: "my_tool") { ... }` |
| 119 | +3. **Server registration**: `server.define_tool(name: "my_tool") { ... }` |
0 commit comments