fast-mcp-annotations 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +115 -0
- data/LICENSE +21 -0
- data/README.md +440 -0
- data/lib/fast_mcp.rb +189 -0
- data/lib/generators/fast_mcp/install/install_generator.rb +50 -0
- data/lib/generators/fast_mcp/install/templates/application_resource.rb +5 -0
- data/lib/generators/fast_mcp/install/templates/application_tool.rb +5 -0
- data/lib/generators/fast_mcp/install/templates/fast_mcp_initializer.rb +42 -0
- data/lib/generators/fast_mcp/install/templates/sample_resource.rb +12 -0
- data/lib/generators/fast_mcp/install/templates/sample_tool.rb +23 -0
- data/lib/mcp/logger.rb +32 -0
- data/lib/mcp/railtie.rb +45 -0
- data/lib/mcp/resource.rb +210 -0
- data/lib/mcp/server.rb +499 -0
- data/lib/mcp/server_filtering.rb +80 -0
- data/lib/mcp/tool.rb +867 -0
- data/lib/mcp/transports/authenticated_rack_transport.rb +71 -0
- data/lib/mcp/transports/base_transport.rb +40 -0
- data/lib/mcp/transports/rack_transport.rb +627 -0
- data/lib/mcp/transports/stdio_transport.rb +62 -0
- data/lib/mcp/version.rb +5 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ddaba3ef64b7de702a99838d754db8ec6e0547dab5fd2b93976ec577815ede99
|
4
|
+
data.tar.gz: db201990959c70008017c59d702d386665c02275fb2240609e86a0dbca06094a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e648222c9b9f7c863b2e0c24e9dc92c71de5d482bdd25223cf5ec2fb0d02d121834deca97d21ac0932472c712cddfe9a0ae62444aa8d581231c41fcb4b68e973
|
7
|
+
data.tar.gz: 88da2a2f108debc58adb1252c5e3e87e906278183c307b1b4c63e7b5e2b774b2b2a63bd944135457480c69206b16eed179a8fe2da87344afc09f555c05ef7bd9
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
### Added
|
10
|
+
- Tool annotations support for providing hints about tool behavior (readOnlyHint, destructiveHint, etc.)
|
11
|
+
|
12
|
+
## [1.5.0] - 2025-06-01
|
13
|
+
### Added
|
14
|
+
- Handle filtering tools and resources [#85 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/85)
|
15
|
+
- Support for resource templates π₯³ Big thanks to @danielcooper for the contribution [#84 co-authored by @danielcooper and @yjacquin](https://github.com/yjacquin/fast-mcp/pull/84)
|
16
|
+
- Possibility to authorize requests before tool calls [#79 @EuanEdgar](https://github.com/yjacquin/fast-mcp/pull/79)
|
17
|
+
- Possibility to read request headers in tool calls [#78 @EuanEdgar](https://github.com/yjacquin/fast-mcp/pull/78)
|
18
|
+
### Changed
|
19
|
+
- Bump Dependencies [#86 @aothelal](https://github.com/yjacquin/fast-mcp/pull/86)
|
20
|
+
- β οΈ Resources are now stateless, meaning that in-memory resources won't work anymore, they require an external data source such as database, file to read and write too, etc. This was needed for a refactoring of the resource class for the [resource template PR](https://github.com/yjacquin/fast-mcp/pull/84)
|
21
|
+
### Fixed
|
22
|
+
- Stop overriding log level to info [#91 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/91)
|
23
|
+
- Properly handle ping request responses from clients [#89 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/89)
|
24
|
+
- Add Thread Safety to RackTransport sse_clients [#82 @Kevin-K](https://github.com/yjacquin/fast-mcp/pull/82)
|
25
|
+
|
26
|
+
## [1.4.0] - 2025-05-10
|
27
|
+
### Added
|
28
|
+
- Conditionnally hidden properties for tool calls (#70) [#70 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/70)
|
29
|
+
- Metadata to tool call results (#69) [#69 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/69)
|
30
|
+
- Link to official Discord Server in README.md
|
31
|
+
|
32
|
+
## [1.3.2] - 2025-05-08
|
33
|
+
### Changed
|
34
|
+
- Logs are now less verbose by default [#64 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/64)
|
35
|
+
### Fixed
|
36
|
+
- Fix undefined method `call' for an instance of String error log [#61 @radwo](https://github.com/yjacquin/fast-mcp/pull/61)
|
37
|
+
|
38
|
+
## [1.3.1] - 2025-04-30
|
39
|
+
### Fixed
|
40
|
+
- Allow ipv4 mapped to ipv6 (#56) [#56 @josevalim](https://github.com/yjacquin/fast-mcp/pull/56)
|
41
|
+
- Add items to array (#55) [#55 @josevalim](https://github.com/yjacquin/fast-mcp/pull/56)
|
42
|
+
- Ping is a regular message event (#54) [#56 @josevalim](https://github.com/yjacquin/fast-mcp/pull/56)
|
43
|
+
|
44
|
+
## [1.3.0] - 2025-04-28
|
45
|
+
### Added
|
46
|
+
- Added automatic forwarding of query params from to the messages endpoint [@yjacquin](https://github.com/yjacquin/fast-mcp/commit/011d968ac982d0b0084f7753dcac5789f66339ee)
|
47
|
+
|
48
|
+
### Fixed
|
49
|
+
- Declare rack as an explicit dependency [#49 @subelsky](https://github.com/yjacquin/fast-mcp/pull/49)
|
50
|
+
- Fix notifications/initialized response [#51 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/51)
|
51
|
+
|
52
|
+
## [1.2.0] - 2025-04-21
|
53
|
+
### Added
|
54
|
+
- Security enhancement: Bing only to localhost by default [#44 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/44)
|
55
|
+
- Prevent AuthenticatedRackMiddleware from blocking other rails routes[#35 @JulianPasquale](https://github.com/yjacquin/fast-mcp/pull/35)
|
56
|
+
- Stop Forcing reconnections after 30 pings [#42 @zoedsoupe](https://github.com/yjacquin/fast-mcp/pull/42)
|
57
|
+
|
58
|
+
|
59
|
+
## [1.1.0] - 2025-04-13
|
60
|
+
### Added
|
61
|
+
- Security enhancement: Added DNS rebinding protection by validating Origin headers [#32 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/32/files)
|
62
|
+
- Added configuration options for allowed origins in rack middleware [#32 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/32/files)
|
63
|
+
- Allow to change the SSE and Messages route [#23 @pedrofurtado](https://github.com/yjacquin/fast-mcp/pull/23)
|
64
|
+
- Fix invalid return value when processing notifications/initialized request [#31 @abMatGit](https://github.com/yjacquin/fast-mcp/pull/31)
|
65
|
+
|
66
|
+
|
67
|
+
## [1.0.0] - 2025-03-30
|
68
|
+
|
69
|
+
### Added
|
70
|
+
- Rails integration improvements via enhanced Railtie support
|
71
|
+
- Automatic tool and resource registration in Rails applications
|
72
|
+
- Extended Rails autoload paths for tools and resources directories
|
73
|
+
- Sample generator templates for resources and tools
|
74
|
+
- MCP Client configuration documentation as reported by [#8 @sivag-csod](https://github.com/yjacquin/fast-mcp/issues/8)
|
75
|
+
- Example Ruby on Rails app in the documentation
|
76
|
+
- `FastMcp.server` now exposes the MCP server to apps that may need it to access resources
|
77
|
+
- Automated Github Releases through Github Workflow
|
78
|
+
|
79
|
+
### Fixed
|
80
|
+
- Fixed bug with Rack middlewares not being initialized properly.
|
81
|
+
- Fixed bug with STDIO logging preventing a proper connection with clients [# 11 @cs3b](https://github.com/yjacquin/fast-mcp/issues/11)
|
82
|
+
- Fixed Rails SSE streaming detection and handling
|
83
|
+
- Improved error handling in client reconnection scenarios
|
84
|
+
- Namespace consistency correction (FastMCP -> FastMcp) throughout the codebase
|
85
|
+
|
86
|
+
### Improved
|
87
|
+
- β οΈ [Breaking] Resource content declaration changes
|
88
|
+
- Now resources implement `content` over `default_content`
|
89
|
+
- `content` is dynamically called when calling a resource, this implies we can declare dynamic resource contents like:
|
90
|
+
```ruby
|
91
|
+
class HighestScoringUsersResource < FastMcp::Resource
|
92
|
+
...
|
93
|
+
def content
|
94
|
+
User.order(score: :desc).last(5).map(&:as_json)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
- More robust SSE connection lifecycle management
|
99
|
+
- Optimized test suite with faster execution times
|
100
|
+
- Better logging for debugging connection issues
|
101
|
+
- Documentation had outdated examples
|
102
|
+
|
103
|
+
## [0.1.0] - 2025-03-12
|
104
|
+
|
105
|
+
### Added
|
106
|
+
|
107
|
+
- Initial release of the Fast MCP library
|
108
|
+
- FastMcp::Tool class with multiple definition styles
|
109
|
+
- FastMcp::Server class with STDIO transport and HTTP / SSE transport
|
110
|
+
- Rack Integration with authenticated and standard middleware options
|
111
|
+
- Resource management with subscription capabilities
|
112
|
+
- Binary resource support
|
113
|
+
- Examples with STDIO Transport, HTTP & SSE, Rack app
|
114
|
+
- Initialize lifecycle with capabilities
|
115
|
+
- Comprehensive test suite with RSpec
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Yorick Jacquin
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,440 @@
|
|
1
|
+
# Fast MCP π
|
2
|
+
|
3
|
+
<div align="center">
|
4
|
+
<h3>Connect AI models to your Ruby applications with ease</h3>
|
5
|
+
<p>No complex protocols, no integration headaches, no compatibility issues β just beautiful, expressive Ruby code.</p>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<p align="center">
|
9
|
+
<a href="https://badge.fury.io/rb/fast-mcp"><img src="https://badge.fury.io/rb/fast-mcp.svg" alt="Gem Version" /></a>
|
10
|
+
<a href="https://github.com/yjacquin/fast-mcp/workflows/CI/badge.svg"><img src="https://github.com/yjacquin/fast-mcp/workflows/CI/badge.svg" alt="CI Status" /></a>
|
11
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
|
12
|
+
<a href="code_of_conduct.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg" alt="Contributor Covenant" /></a>
|
13
|
+
<a href="https://discord.gg/9HHfAtY3HF"><img src = "https://dcbadge.limes.pink/api/server/https://discord.gg/9HHfAtY3HF?style=flat" alt="Discord invite link" /></a>
|
14
|
+
</p>
|
15
|
+
|
16
|
+
## π Interface your Servers with LLMs in minutes !
|
17
|
+
|
18
|
+
AI models are powerful, but they need to interact with your applications to be truly useful. Traditional approaches mean wrestling with:
|
19
|
+
|
20
|
+
- π Complex communication protocols and custom JSON formats
|
21
|
+
- π Integration challenges with different model providers
|
22
|
+
- π§© Compatibility issues between your app and AI tools
|
23
|
+
- π§ Managing the state between AI interactions and your data
|
24
|
+
|
25
|
+
Fast MCP solves all these problems by providing a clean, Ruby-focused implementation of the [Model Context Protocol](https://github.com/modelcontextprotocol), making AI integration a joy, not a chore.
|
26
|
+
|
27
|
+
## β¨ Features
|
28
|
+
|
29
|
+
- π οΈ **Tools API** - Let AI models call your Ruby functions securely, with in-depth argument validation through [Dry-Schema](https://github.com/dry-rb/dry-schema).
|
30
|
+
- π **Resources API** - Share data between your app and AI models
|
31
|
+
- π **Multiple Transports** - Choose from STDIO, HTTP, or SSE based on your needs
|
32
|
+
- π§© **Framework Integration** - Works seamlessly with Rails, Sinatra or any Rack app.
|
33
|
+
- π **Authentication Support** - Secure your AI-powered endpoints with ease
|
34
|
+
- π **Real-time Updates** - Subscribe to changes for interactive applications
|
35
|
+
- π― **Dynamic Filtering** - Control tool/resource access based on request context (permissions, API versions, etc.)
|
36
|
+
|
37
|
+
|
38
|
+
## π What Makes FastMCP Great
|
39
|
+
```ruby
|
40
|
+
# Define tools for AI models to use
|
41
|
+
server = FastMcp::Server.new(name: 'popular-users', version: '1.0.0')
|
42
|
+
|
43
|
+
# Define a tool by inheriting from FastMcp::Tool
|
44
|
+
class CreateUserTool < FastMcp::Tool
|
45
|
+
description "Create a user"
|
46
|
+
# These arguments will generate the needed JSON to be presented to the MCP Client
|
47
|
+
# And they will be validated at run time.
|
48
|
+
# The validation is based off Dry-Schema, with the addition of the description.
|
49
|
+
arguments do
|
50
|
+
required(:first_name).filled(:string).description("First name of the user")
|
51
|
+
optional(:age).filled(:integer).description("Age of the user")
|
52
|
+
required(:address).hash do
|
53
|
+
optional(:street).filled(:string)
|
54
|
+
optional(:city).filled(:string)
|
55
|
+
optional(:zipcode).filled(:string)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def call(first_name:, age: nil, address: {})
|
60
|
+
User.create!(first_name:, age:, address:)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Register the tool with the server
|
65
|
+
server.register_tool(CreateUserTool)
|
66
|
+
|
67
|
+
# Share data resources with AI models by inheriting from FastMcp::Resource
|
68
|
+
class PopularUsers < FastMcp::Resource
|
69
|
+
uri "myapp:///users/popular"
|
70
|
+
resource_name "Popular Users"
|
71
|
+
mime_type "application/json"
|
72
|
+
|
73
|
+
def content
|
74
|
+
JSON.generate(User.popular.limit(5).as_json)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class User < FastMcp::Resource
|
79
|
+
uri "myapp:///users/{id}" # This is a resource template
|
80
|
+
resource_name "user"
|
81
|
+
mime_type "application/json"
|
82
|
+
|
83
|
+
def content
|
84
|
+
id = params[:id] # params are computed from the uri pattern
|
85
|
+
|
86
|
+
JSON.generate(User.find(id).as_json)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Register the resource with the server
|
91
|
+
server.register_resources(PopularUsers, User)
|
92
|
+
|
93
|
+
# Accessing the resource through the server
|
94
|
+
server.read_resource(PopularUsers.uri)
|
95
|
+
|
96
|
+
# Notify the resource content has been updated to clients
|
97
|
+
server.notify_resource_updated(PopularUsers.variabilized_uri)
|
98
|
+
|
99
|
+
# Notifiy the content of a resource from a template has been updated to clients
|
100
|
+
server.notify_resource_updated(User.variabilized_uri(id: 1))
|
101
|
+
```
|
102
|
+
|
103
|
+
### π― Dynamic Tool Filtering
|
104
|
+
|
105
|
+
Control which tools and resources are available based on request context:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
# Tag your tools for easy filtering
|
109
|
+
class AdminTool < FastMcp::Tool
|
110
|
+
tags :admin, :dangerous
|
111
|
+
description "Perform admin operations"
|
112
|
+
|
113
|
+
def call
|
114
|
+
# Admin only functionality
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Filter tools based on user permissions
|
119
|
+
server.filter_tools do |request, tools|
|
120
|
+
user_role = request.params['role']
|
121
|
+
|
122
|
+
case user_role
|
123
|
+
when 'admin'
|
124
|
+
tools # Admins see all tools
|
125
|
+
when 'user'
|
126
|
+
tools.reject { |t| t.tags.include?(:admin) }
|
127
|
+
else
|
128
|
+
tools.select { |t| t.tags.include?(:public) }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
### π Fast Ruby on Rails implementation
|
134
|
+
```shell
|
135
|
+
bundle add fast-mcp
|
136
|
+
bin/rails generate fast_mcp:install
|
137
|
+
```
|
138
|
+
|
139
|
+
This will add a configurable `fast_mcp.rb` initializer
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
require 'fast_mcp'
|
143
|
+
|
144
|
+
FastMcp.mount_in_rails(
|
145
|
+
Rails.application,
|
146
|
+
name: Rails.application.class.module_parent_name.underscore.dasherize,
|
147
|
+
version: '1.0.0',
|
148
|
+
path_prefix: '/mcp', # This is the default path prefix
|
149
|
+
messages_route: 'messages', # This is the default route for the messages endpoint
|
150
|
+
sse_route: 'sse', # This is the default route for the SSE endpoint
|
151
|
+
# Add allowed origins below, it defaults to Rails.application.config.hosts
|
152
|
+
# allowed_origins: ['localhost', '127.0.0.1', 'example.com', /.*\.example\.com/],
|
153
|
+
# localhost_only: true, # Set to false to allow connections from other hosts
|
154
|
+
# whitelist specific ips to if you want to run on localhost and allow connections from other IPs
|
155
|
+
# allowed_ips: ['127.0.0.1', '::1']
|
156
|
+
# authenticate: true, # Uncomment to enable authentication
|
157
|
+
# auth_token: 'your-token' # Required if authenticate: true
|
158
|
+
) do |server|
|
159
|
+
Rails.application.config.after_initialize do
|
160
|
+
# FastMcp will automatically discover and register:
|
161
|
+
# - All classes that inherit from ApplicationTool (which uses ActionTool::Base)
|
162
|
+
# - All classes that inherit from ApplicationResource (which uses ActionResource::Base)
|
163
|
+
server.register_tools(*ApplicationTool.descendants)
|
164
|
+
server.register_resources(*ApplicationResource.descendants)
|
165
|
+
# alternatively, you can register tools and resources manually:
|
166
|
+
# server.register_tool(MyTool)
|
167
|
+
# server.register_resource(MyResource)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
```
|
171
|
+
The install script will also:
|
172
|
+
- add app/resources folder
|
173
|
+
- add app/tools folder
|
174
|
+
- add app/tools/sample_tool.rb
|
175
|
+
- add app/resources/sample_resource.rb
|
176
|
+
- add ApplicationTool to inherit from
|
177
|
+
- add ApplicationResource to inherit from as well
|
178
|
+
|
179
|
+
#### Rails-friendly class naming conventions
|
180
|
+
|
181
|
+
For Rails applications, FastMCP provides Rails-style class names to better fit with Rails conventions:
|
182
|
+
|
183
|
+
- `ActionTool::Base` - An alias for `FastMcp::Tool`
|
184
|
+
- `ActionResource::Base` - An alias for `FastMcp::Resource`
|
185
|
+
|
186
|
+
These are automatically set up in Rails applications. You can use either naming convention in your code:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
# Using Rails-style naming:
|
190
|
+
class MyTool < ActionTool::Base
|
191
|
+
description "My awesome tool"
|
192
|
+
|
193
|
+
arguments do
|
194
|
+
required(:input).filled(:string)
|
195
|
+
end
|
196
|
+
|
197
|
+
def call(input:)
|
198
|
+
# Your implementation
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Using standard FastMcp naming:
|
203
|
+
class AnotherTool < FastMcp::Tool
|
204
|
+
# Both styles work interchangeably in Rails apps
|
205
|
+
end
|
206
|
+
```
|
207
|
+
|
208
|
+
When creating new tools or resources, the generators will use the Rails naming convention by default:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
# app/tools/application_tool.rb
|
212
|
+
class ApplicationTool < ActionTool::Base
|
213
|
+
# Base methods for all tools
|
214
|
+
end
|
215
|
+
|
216
|
+
# app/resources/application_resource.rb
|
217
|
+
class ApplicationResource < ActionResource::Base
|
218
|
+
# Base methods for all resources
|
219
|
+
end
|
220
|
+
```
|
221
|
+
|
222
|
+
### Easy Sinatra setup
|
223
|
+
I'll let you check out the dedicated [sinatra integration docs](./docs/sinatra_integration.md).
|
224
|
+
|
225
|
+
## π Quick Start
|
226
|
+
|
227
|
+
### Create a Server with Tools and Resources and STDIO transport
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
require 'fast_mcp'
|
231
|
+
|
232
|
+
# Create an MCP server
|
233
|
+
server = FastMcp::Server.new(name: 'my-ai-server', version: '1.0.0')
|
234
|
+
|
235
|
+
# Define a tool by inheriting from FastMcp::Tool
|
236
|
+
class SummarizeTool < FastMcp::Tool
|
237
|
+
description "Summarize a given text"
|
238
|
+
|
239
|
+
arguments do
|
240
|
+
required(:text).filled(:string).description("Text to summarize")
|
241
|
+
optional(:max_length).filled(:integer).description("Maximum length of summary")
|
242
|
+
end
|
243
|
+
|
244
|
+
def call(text:, max_length: 100)
|
245
|
+
# Your summarization logic here
|
246
|
+
text.split('.').first(3).join('.') + '...'
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# Register the tool with the server
|
251
|
+
server.register_tool(SummarizeTool)
|
252
|
+
|
253
|
+
# Create a resource by inheriting from FastMcp::Resource
|
254
|
+
class StatisticsResource < FastMcp::Resource
|
255
|
+
uri "data/statistics"
|
256
|
+
resource_name "Usage Statistics"
|
257
|
+
description "Current system statistics"
|
258
|
+
mime_type "application/json"
|
259
|
+
|
260
|
+
def content
|
261
|
+
JSON.generate({
|
262
|
+
users_online: 120,
|
263
|
+
queries_per_minute: 250,
|
264
|
+
popular_topics: ["Ruby", "AI", "WebDev"]
|
265
|
+
})
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Register the resource with the server
|
270
|
+
server.register_resource(StatisticsResource)
|
271
|
+
|
272
|
+
# Start the server
|
273
|
+
server.start
|
274
|
+
```
|
275
|
+
|
276
|
+
## π§ͺ Testing with the inspector
|
277
|
+
|
278
|
+
MCP has developed a very [useful inspector](https://github.com/modelcontextprotocol/inspector).
|
279
|
+
You can use it to validate your implementation. I suggest you use the examples I provided with this project as an easy boilerplate.
|
280
|
+
Clone this project, then give it a go !
|
281
|
+
|
282
|
+
```shell
|
283
|
+
npx @modelcontextprotocol/inspector examples/server_with_stdio_transport.rb
|
284
|
+
```
|
285
|
+
Or to test with an SSE transport using a rack middleware:
|
286
|
+
```shell
|
287
|
+
npx @modelcontextprotocol/inspector examples/rack_middleware.rb
|
288
|
+
```
|
289
|
+
|
290
|
+
Or to test over SSE with an authenticated rack middleware:
|
291
|
+
```shell
|
292
|
+
npx @modelcontextprotocol/inspector examples/authenticated_rack_middleware.rb
|
293
|
+
```
|
294
|
+
|
295
|
+
You can test your custom implementation with the official MCP inspector by using:
|
296
|
+
```shell
|
297
|
+
# Test with a stdio transport:
|
298
|
+
npx @modelcontextprotocol/inspector path/to/your_ruby_file.rb
|
299
|
+
|
300
|
+
# Test with an HTTP / SSE server. In the UI select SSE and input your address.
|
301
|
+
npx @modelcontextprotocol/inspector
|
302
|
+
```
|
303
|
+
|
304
|
+
#### Sinatra
|
305
|
+
|
306
|
+
```ruby
|
307
|
+
# app.rb
|
308
|
+
require 'sinatra'
|
309
|
+
require 'fast_mcp'
|
310
|
+
|
311
|
+
use FastMcp::RackMiddleware.new(name: 'my-ai-server', version: '1.0.0') do |server|
|
312
|
+
# Register tools and resources here
|
313
|
+
server.register_tool(SummarizeTool)
|
314
|
+
end
|
315
|
+
|
316
|
+
get '/' do
|
317
|
+
'Hello World!'
|
318
|
+
end
|
319
|
+
```
|
320
|
+
|
321
|
+
### Integrating with Claude Desktop
|
322
|
+
|
323
|
+
Add your server to your Claude Desktop configuration at:
|
324
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
325
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
326
|
+
|
327
|
+
```json
|
328
|
+
{
|
329
|
+
"mcpServers": {
|
330
|
+
"my-great-server": {
|
331
|
+
"command": "ruby",
|
332
|
+
"args": [
|
333
|
+
"/Users/path/to/your/awesome/fast-mcp/server.rb"
|
334
|
+
]
|
335
|
+
}
|
336
|
+
}
|
337
|
+
}
|
338
|
+
```
|
339
|
+
|
340
|
+
## How to add a MCP server to Claude, Cursor, or other MCP clients?
|
341
|
+
Please refer to [configuring_mcp_clients](docs/configuring_mcp_clients.md)
|
342
|
+
|
343
|
+
## π Supported Specifications
|
344
|
+
|
345
|
+
| Feature | Status |
|
346
|
+
|---------|--------|
|
347
|
+
| β
**JSON-RPC 2.0** | Full implementation for communication |
|
348
|
+
| β
**Tool Definition & Calling** | Define and call tools with rich argument types |
|
349
|
+
| β
**Resource & Resource Templates Management** | Create, read, update, and subscribe to resources |
|
350
|
+
| β
**Transport Options** | STDIO, HTTP, and SSE for flexible integration |
|
351
|
+
| β
**Framework Integration** | Rails, Sinatra, Hanami, and any Rack-compatible framework |
|
352
|
+
| β
**Authentication** | Secure your AI endpoints with token authentication |
|
353
|
+
| β
**Schema Support** | Full JSON Schema for tool arguments with validation |
|
354
|
+
|
355
|
+
## πΊοΈ Use Cases
|
356
|
+
|
357
|
+
- π€ **AI-powered Applications**: Connect LLMs to your Ruby app's functionality
|
358
|
+
- π **Real-time Dashboards**: Build dashboards with live AI-generated insights
|
359
|
+
- π **Microservice Communication**: Use MCP as a clean protocol between services
|
360
|
+
- π **Interactive Documentation**: Create AI-enhanced API documentation
|
361
|
+
- π¬ **Chatbots and Assistants**: Build AI assistants with access to your app's data
|
362
|
+
|
363
|
+
## π Security Features
|
364
|
+
|
365
|
+
Fast MCP includes built-in security features to protect your applications:
|
366
|
+
|
367
|
+
### DNS Rebinding Protection
|
368
|
+
|
369
|
+
The HTTP/SSE transport validates the Origin header on all incoming connections to prevent DNS rebinding attacks, which could allow malicious websites to interact with local MCP servers.
|
370
|
+
|
371
|
+
```ruby
|
372
|
+
# Configure allowed origins (defaults to ['localhost', '127.0.0.1'])
|
373
|
+
FastMcp.rack_middleware(app,
|
374
|
+
allowed_origins: ['localhost', '127.0.0.1', 'your-domain.com', /.*\.your-domain\.com/],
|
375
|
+
localhost_only: false,
|
376
|
+
allowed_ips: ['192.168.1.1', '10.0.0.1'],
|
377
|
+
# other options...
|
378
|
+
)
|
379
|
+
```
|
380
|
+
|
381
|
+
### Authentication
|
382
|
+
|
383
|
+
Fast MCP supports token-based authentication for all connections:
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
# Enable authentication
|
387
|
+
FastMcp.authenticated_rack_middleware(app,
|
388
|
+
auth_token: 'your-secret-token',
|
389
|
+
# other options...
|
390
|
+
)
|
391
|
+
```
|
392
|
+
|
393
|
+
## π Documentation
|
394
|
+
|
395
|
+
- [π Getting Started Guide](docs/getting_started.md)
|
396
|
+
- [π§© Integration Guide](docs/integration_guide.md)
|
397
|
+
- [π€οΈ Rails Integration](docs/rails_integration.md)
|
398
|
+
- [π Sinatra Integration](docs/sinatra_integration.md)
|
399
|
+
- [π Resources](docs/resources.md)
|
400
|
+
- [π οΈ Tools](docs/tools.md)
|
401
|
+
- [π Security](docs/security.md)
|
402
|
+
- [π― Dynamic Filtering](docs/filtering.md)
|
403
|
+
|
404
|
+
## π» Examples
|
405
|
+
|
406
|
+
Check out the [examples directory](examples) for more detailed examples:
|
407
|
+
|
408
|
+
- **π¨ Basic Examples**:
|
409
|
+
- [Simple Server](examples/server_with_stdio_transport.rb)
|
410
|
+
- [Tool Examples](examples/tool_examples.rb)
|
411
|
+
|
412
|
+
- **π Web Integration**:
|
413
|
+
- [Rack Middleware](examples/rack_middleware.rb)
|
414
|
+
- [Authenticated Endpoints](examples/authenticated_rack_middleware.rb)
|
415
|
+
|
416
|
+
## π§ͺ Requirements
|
417
|
+
|
418
|
+
- Ruby 3.2+
|
419
|
+
|
420
|
+
## π₯ Contributing
|
421
|
+
|
422
|
+
We welcome contributions to Fast MCP! Here's how you can help:
|
423
|
+
|
424
|
+
1. Fork the repository
|
425
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
426
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
427
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
428
|
+
5. Create a new Pull Request
|
429
|
+
|
430
|
+
Please read our [Contributing Guide](CONTRIBUTING.md) for more details.
|
431
|
+
|
432
|
+
## π License
|
433
|
+
|
434
|
+
This project is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
435
|
+
|
436
|
+
## π Acknowledgments
|
437
|
+
|
438
|
+
- The [Model Context Protocol](https://github.com/modelcontextprotocol) team for creating the specification
|
439
|
+
- The [Dry-Schema](https://github.com/dry-rb/dry-schema) team for the argument validation.
|
440
|
+
- All contributors to this project
|