mcp_toolkit 0.3.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/.github/workflows/ci.yml +43 -0
- data/.rubocop.yml +98 -0
- data/CHANGELOG.md +123 -0
- data/LICENSE.txt +21 -0
- data/README.md +301 -0
- data/Rakefile +21 -0
- data/app/controllers/mcp_toolkit/server_controller.rb +19 -0
- data/config/routes.rb +18 -0
- data/lib/mcp_toolkit/auth/authenticator.rb +99 -0
- data/lib/mcp_toolkit/auth/authority.rb +75 -0
- data/lib/mcp_toolkit/auth/authority_server_client.rb +50 -0
- data/lib/mcp_toolkit/auth/introspection.rb +162 -0
- data/lib/mcp_toolkit/configuration.rb +209 -0
- data/lib/mcp_toolkit/engine.rb +21 -0
- data/lib/mcp_toolkit/errors/base.rb +10 -0
- data/lib/mcp_toolkit/errors/configuration_error.rb +5 -0
- data/lib/mcp_toolkit/errors/invalid_params.rb +5 -0
- data/lib/mcp_toolkit/errors/unauthorized.rb +5 -0
- data/lib/mcp_toolkit/field_selection.rb +93 -0
- data/lib/mcp_toolkit/filtering.rb +152 -0
- data/lib/mcp_toolkit/get_executor.rb +32 -0
- data/lib/mcp_toolkit/list_executor.rb +137 -0
- data/lib/mcp_toolkit/registry.rb +67 -0
- data/lib/mcp_toolkit/resource.rb +129 -0
- data/lib/mcp_toolkit/resource_schema.rb +163 -0
- data/lib/mcp_toolkit/serialization.rb +62 -0
- data/lib/mcp_toolkit/serializer/base.rb +285 -0
- data/lib/mcp_toolkit/server.rb +44 -0
- data/lib/mcp_toolkit/session.rb +46 -0
- data/lib/mcp_toolkit/sql_sanitizer.rb +14 -0
- data/lib/mcp_toolkit/token_kinds.rb +14 -0
- data/lib/mcp_toolkit/tools/base.rb +100 -0
- data/lib/mcp_toolkit/tools/get.rb +57 -0
- data/lib/mcp_toolkit/tools/list.rb +83 -0
- data/lib/mcp_toolkit/tools/resource_schema.rb +40 -0
- data/lib/mcp_toolkit/tools/resources.rb +27 -0
- data/lib/mcp_toolkit/transport/controller_methods.rb +226 -0
- data/lib/mcp_toolkit/unknown_resource_message.rb +75 -0
- data/lib/mcp_toolkit/version.rb +5 -0
- data/lib/mcp_toolkit.rb +118 -0
- data/sig/mcp_toolkit.rbs +4 -0
- metadata +147 -0
data/lib/mcp_toolkit.rb
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "zeitwerk"
|
|
4
|
+
|
|
5
|
+
# Stdlib + external gems the toolkit's own code calls. Zeitwerk autoloads the
|
|
6
|
+
# gem's `lib/mcp_toolkit/**` tree, but NOT these third-party / stdlib constants,
|
|
7
|
+
# so they are required here once (centralized) rather than scattered across the
|
|
8
|
+
# subfiles that happen to touch them:
|
|
9
|
+
#
|
|
10
|
+
# json - JSON.parse / JSON.generate (introspection parse, tools, transport)
|
|
11
|
+
# digest - Digest::SHA256 (introspection cache key)
|
|
12
|
+
# time - Time.iso8601 / Time.parse (introspection expiry parsing)
|
|
13
|
+
# securerandom - SecureRandom.uuid (Session ids)
|
|
14
|
+
# mcp - the official MCP SDK (Server wraps it; Tools::Base subclasses MCP::Tool)
|
|
15
|
+
# active_support/concern - Transport::ControllerMethods is an includable concern
|
|
16
|
+
# active_support/cache - the default MemoryStore cache_store
|
|
17
|
+
#
|
|
18
|
+
# `faraday` is the one exception: it is required alongside its sole owner,
|
|
19
|
+
# Auth::AuthorityServerClient, which is the only object that builds an HTTP
|
|
20
|
+
# connection.
|
|
21
|
+
require "json"
|
|
22
|
+
require "digest"
|
|
23
|
+
require "time"
|
|
24
|
+
require "securerandom"
|
|
25
|
+
require "mcp"
|
|
26
|
+
require "active_support/concern"
|
|
27
|
+
require "active_support/cache"
|
|
28
|
+
|
|
29
|
+
# External dependencies (NOT autoloaded by Zeitwerk — only the gem's own tree is).
|
|
30
|
+
# ActiveSupport's specific core extensions are required up front (rather than full
|
|
31
|
+
# Rails) so the gem works in any host. Each line below earns its place; they were
|
|
32
|
+
# audited against actual usage:
|
|
33
|
+
#
|
|
34
|
+
# object/blank - blank? / present? / presence (used throughout)
|
|
35
|
+
# hash/keys - deep_symbolize_keys (ListExecutor#initialize)
|
|
36
|
+
# array/wrap - Array.wrap (Transport::ControllerMethods)
|
|
37
|
+
# enumerable - compact_blank (ListExecutor#apply_ids)
|
|
38
|
+
# time/conversions - Time#iso8601 (Serializer::Base timestamps;
|
|
39
|
+
# Time.zone.parse in ListExecutor)
|
|
40
|
+
# date_time/conversions - DateTime#iso8601 (token expires_at may be a DateTime)
|
|
41
|
+
# string/inflections - String#pluralize (ResourceSchema resolves a link's
|
|
42
|
+
# singular name to the plural registered resource name)
|
|
43
|
+
require "active_support"
|
|
44
|
+
require "active_support/core_ext/object/blank"
|
|
45
|
+
require "active_support/core_ext/hash/keys"
|
|
46
|
+
require "active_support/core_ext/array/wrap"
|
|
47
|
+
require "active_support/core_ext/enumerable"
|
|
48
|
+
require "active_support/core_ext/time/conversions"
|
|
49
|
+
require "active_support/core_ext/date_time/conversions"
|
|
50
|
+
require "active_support/core_ext/string/inflections"
|
|
51
|
+
|
|
52
|
+
# The version constant is needed eagerly by the gemspec (before the loader is set
|
|
53
|
+
# up), so it stays an explicit require rather than an autoload.
|
|
54
|
+
require_relative "mcp_toolkit/version"
|
|
55
|
+
|
|
56
|
+
loader = Zeitwerk::Loader.for_gem
|
|
57
|
+
# `version.rb` is loaded manually above; let Zeitwerk ignore it so it doesn't try
|
|
58
|
+
# to manage the already-defined constant.
|
|
59
|
+
loader.ignore("#{__dir__}/mcp_toolkit/version.rb")
|
|
60
|
+
# `engine.rb` subclasses ::Rails::Engine, which is absent in a non-Rails host (and
|
|
61
|
+
# in the gem's own unit suite). Keep it out of the autoloadable set and require it
|
|
62
|
+
# explicitly below only when Rails is present. The gem-internal controller lives
|
|
63
|
+
# under `app/controllers` (outside this lib-rooted loader), so it needs no ignore;
|
|
64
|
+
# it is loaded by Rails' autoloader via the engine when mounted.
|
|
65
|
+
loader.ignore("#{__dir__}/mcp_toolkit/engine.rb")
|
|
66
|
+
loader.setup
|
|
67
|
+
|
|
68
|
+
# The toolkit for building account-scoped, read-only MCP servers on top of the
|
|
69
|
+
# official `mcp` gem. See README.md for the satellite + authority quickstarts.
|
|
70
|
+
#
|
|
71
|
+
# Entry points:
|
|
72
|
+
# McpToolkit.configure { |c| ... } # set up the server
|
|
73
|
+
# McpToolkit.config # the active Configuration
|
|
74
|
+
# McpToolkit.registry # the active config's resource registry
|
|
75
|
+
#
|
|
76
|
+
# `MCPToolkit` is provided as an alias for the same module.
|
|
77
|
+
module McpToolkit
|
|
78
|
+
# The toolkit's own base error (kept distinct from tool-level Errors::*).
|
|
79
|
+
class Error < StandardError; end
|
|
80
|
+
|
|
81
|
+
# Yields the active configuration for mutation, returning it.
|
|
82
|
+
#
|
|
83
|
+
# McpToolkit.configure do |c|
|
|
84
|
+
# c.server_name = "my-app-mcp"
|
|
85
|
+
# c.central_app_url = ENV.fetch("MCP_CENTRAL_APP_URL")
|
|
86
|
+
# c.registry.default_required_permissions_scope "my_app__read"
|
|
87
|
+
# end
|
|
88
|
+
def self.configure
|
|
89
|
+
yield(config) if block_given?
|
|
90
|
+
config
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# The active Configuration (created on first access).
|
|
94
|
+
def self.config
|
|
95
|
+
@config ||= Configuration.new
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# The active config's resource registry. Register resources against this in a
|
|
99
|
+
# boot initializer.
|
|
100
|
+
def self.registry
|
|
101
|
+
config.registry
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Replaces the active configuration with a fresh default. Primarily for tests.
|
|
105
|
+
def self.reset_config!
|
|
106
|
+
@config = Configuration.new
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Karol's requested entry-point spelling. `MCPToolkit.configure { ... }` and
|
|
111
|
+
# `MCPToolkit.config` work identically to `McpToolkit.*`.
|
|
112
|
+
MCPToolkit = McpToolkit unless defined?(MCPToolkit)
|
|
113
|
+
|
|
114
|
+
# The mountable engine is ADDITIVE and Rails-only: a satellite can either mount
|
|
115
|
+
# `McpToolkit::Engine` (engine + gem controller) OR keep including
|
|
116
|
+
# `McpToolkit::Transport::ControllerMethods` in its own controller. Loaded only
|
|
117
|
+
# when Rails::Engine is present (it was ignored by the loader above).
|
|
118
|
+
require_relative "mcp_toolkit/engine" if defined?(Rails::Engine)
|
data/sig/mcp_toolkit.rbs
ADDED
metadata
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mcp_toolkit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.3.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Karol Galanciak
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: zeitwerk
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2.6'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mcp
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.18'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.18'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: activesupport
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '6.1'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '6.1'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: faraday
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '1.0'
|
|
68
|
+
description: |
|
|
69
|
+
mcp_toolkit extracts the shared MCP-server framework that Smily's apps grew
|
|
70
|
+
independently: a Streamable-HTTP transport, cache-backed sessions, central-app
|
|
71
|
+
token introspection (satellite + authority roles), a registry-driven
|
|
72
|
+
"generic tools over N resources" dispatcher, and an injectable serializer DSL.
|
|
73
|
+
It wraps the official `mcp` gem as the JSON-RPC core so each app ships only its
|
|
74
|
+
serializers, resource registrations, and scope blocks.
|
|
75
|
+
email:
|
|
76
|
+
- karol.galanciak@gmail.com
|
|
77
|
+
executables: []
|
|
78
|
+
extensions: []
|
|
79
|
+
extra_rdoc_files: []
|
|
80
|
+
files:
|
|
81
|
+
- ".github/workflows/ci.yml"
|
|
82
|
+
- ".rubocop.yml"
|
|
83
|
+
- CHANGELOG.md
|
|
84
|
+
- LICENSE.txt
|
|
85
|
+
- README.md
|
|
86
|
+
- Rakefile
|
|
87
|
+
- app/controllers/mcp_toolkit/server_controller.rb
|
|
88
|
+
- config/routes.rb
|
|
89
|
+
- lib/mcp_toolkit.rb
|
|
90
|
+
- lib/mcp_toolkit/auth/authenticator.rb
|
|
91
|
+
- lib/mcp_toolkit/auth/authority.rb
|
|
92
|
+
- lib/mcp_toolkit/auth/authority_server_client.rb
|
|
93
|
+
- lib/mcp_toolkit/auth/introspection.rb
|
|
94
|
+
- lib/mcp_toolkit/configuration.rb
|
|
95
|
+
- lib/mcp_toolkit/engine.rb
|
|
96
|
+
- lib/mcp_toolkit/errors/base.rb
|
|
97
|
+
- lib/mcp_toolkit/errors/configuration_error.rb
|
|
98
|
+
- lib/mcp_toolkit/errors/invalid_params.rb
|
|
99
|
+
- lib/mcp_toolkit/errors/unauthorized.rb
|
|
100
|
+
- lib/mcp_toolkit/field_selection.rb
|
|
101
|
+
- lib/mcp_toolkit/filtering.rb
|
|
102
|
+
- lib/mcp_toolkit/get_executor.rb
|
|
103
|
+
- lib/mcp_toolkit/list_executor.rb
|
|
104
|
+
- lib/mcp_toolkit/registry.rb
|
|
105
|
+
- lib/mcp_toolkit/resource.rb
|
|
106
|
+
- lib/mcp_toolkit/resource_schema.rb
|
|
107
|
+
- lib/mcp_toolkit/serialization.rb
|
|
108
|
+
- lib/mcp_toolkit/serializer/base.rb
|
|
109
|
+
- lib/mcp_toolkit/server.rb
|
|
110
|
+
- lib/mcp_toolkit/session.rb
|
|
111
|
+
- lib/mcp_toolkit/sql_sanitizer.rb
|
|
112
|
+
- lib/mcp_toolkit/token_kinds.rb
|
|
113
|
+
- lib/mcp_toolkit/tools/base.rb
|
|
114
|
+
- lib/mcp_toolkit/tools/get.rb
|
|
115
|
+
- lib/mcp_toolkit/tools/list.rb
|
|
116
|
+
- lib/mcp_toolkit/tools/resource_schema.rb
|
|
117
|
+
- lib/mcp_toolkit/tools/resources.rb
|
|
118
|
+
- lib/mcp_toolkit/transport/controller_methods.rb
|
|
119
|
+
- lib/mcp_toolkit/unknown_resource_message.rb
|
|
120
|
+
- lib/mcp_toolkit/version.rb
|
|
121
|
+
- sig/mcp_toolkit.rbs
|
|
122
|
+
homepage: https://github.com/BookingSync/mcp_toolkit
|
|
123
|
+
licenses:
|
|
124
|
+
- MIT
|
|
125
|
+
metadata:
|
|
126
|
+
homepage_uri: https://github.com/BookingSync/mcp_toolkit
|
|
127
|
+
source_code_uri: https://github.com/BookingSync/mcp_toolkit
|
|
128
|
+
changelog_uri: https://github.com/BookingSync/mcp_toolkit/blob/master/CHANGELOG.md
|
|
129
|
+
rubygems_mfa_required: 'true'
|
|
130
|
+
rdoc_options: []
|
|
131
|
+
require_paths:
|
|
132
|
+
- lib
|
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: 3.2.0
|
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
|
+
requirements:
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: '0'
|
|
143
|
+
requirements: []
|
|
144
|
+
rubygems_version: 3.6.9
|
|
145
|
+
specification_version: 4
|
|
146
|
+
summary: Opinionated toolkit for building account-scoped, read-only MCP servers.
|
|
147
|
+
test_files: []
|