Class: McpToolkit::Configuration
- Inherits:
-
Object
- Object
- McpToolkit::Configuration
- Defined in:
- lib/mcp_toolkit/configuration.rb
Overview
The single, injectable configuration object for an app's MCP server.
Generic but OPINIONATED: every setting has a sensible, vendor-neutral default,
so a satellite needs to override only a handful of values. The two things an
app almost always sets are
server_name and the auth wiring (central_app_url for a satellite, or
token_authenticator for the authority).
Whether ANY scope is required is decided PER TOOL, not per app: a resource
declares required_permissions_scope "notifications__read" (or the registry
declares default_required_permissions_scope once for all resources). There is
no app-wide permission setting here.
Accessed through McpToolkit.config (or MCPToolkit.config) and mutated in a
McpToolkit.configure { |c| ... } block.
Instance Attribute Summary collapse
- #account_id_header ⇒ String
-
#account_meta_key ⇒ String
Header / meta-key constants.
-
#account_resolver ⇒ #call
Resolves the central account id to the satellite's LOCAL scope root.
-
#auth_role ⇒ Symbol
:satellite (introspect tokens against a central app) or :authority (be the introspection provider + authenticate local tokens).
-
#cache_store ⇒ ActiveSupport::Cache::Store, #read
The cache store backing sessions and introspection results.
-
#central_app_url ⇒ String?
Base URL of the central auth app.
-
#introspect_path ⇒ String?
The introspect path appended to
central_app_url. -
#introspection_cache_ttl ⇒ Integer
Seconds to cache an introspection result (positive AND negative) so a burst of tool calls does not hammer the central app.
-
#introspection_timeout ⇒ Integer
HTTP open/read timeout for the introspection call.
-
#parent_controller ⇒ String
The parent class (as a String, resolved via
constantize) of the gem-provided McpToolkit::ServerController that McpToolkit::Engine mounts. -
#protocol_version ⇒ String?
Protocol version to pin on the underlying MCP::Server.
-
#registry ⇒ McpToolkit::Registry
The resource registry for this configuration.
-
#serializer_base ⇒ Object
The serializer base, lazily defaulting to the gem's bundled DSL base.
-
#server_instructions ⇒ String?
Human-readable
instructionsreturned oninitialize. -
#server_name ⇒ String
The MCP server name advertised in
initialize. -
#server_version ⇒ String
The MCP server version advertised in
initialize. -
#session_ttl ⇒ Integer
Session sliding-TTL in seconds.
-
#sql_sanitizer ⇒ #sanitize_sql_like
Escapes LIKE wildcards in
matches/does_not_matchfilter values so they match literally. -
#token_authenticator ⇒ #call?
Looks up + verifies a plaintext bearer token locally, returning a token object (duck-typed, see below) or nil.
Instance Method Summary collapse
-
#authority? ⇒ Boolean
Whether this app authenticates tokens locally / answers introspection.
-
#initialize ⇒ Configuration
constructor
Vendor-neutral defaults; apps override the auth wiring + identity as needed.
-
#introspect_url ⇒ Object
Full introspection URL the satellite POSTs to.
-
#satellite? ⇒ Boolean
Whether this app introspects tokens against a central app.
Constructor Details
#initialize ⇒ Configuration
Vendor-neutral defaults; apps override the auth wiring + identity as needed.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/mcp_toolkit/configuration.rb', line 155 def initialize @server_name = "mcp-server" @server_version = "1.0.0" @server_instructions = nil @serializer_base = nil # set lazily in #serializer_base to avoid load-order issues @auth_role = :satellite @central_app_url = nil @introspect_path = "/mcp/tokens/introspect" @introspection_cache_ttl = 45 @introspection_timeout = 10 @account_resolver = ->(synced_account_id) { synced_account_id } @token_authenticator = nil @cache_store = ActiveSupport::Cache::MemoryStore.new @session_ttl = 3600 # 1 hour @sql_sanitizer = McpToolkit::SqlSanitizer.new @protocol_version = nil @parent_controller = "ActionController::Base" @account_meta_key = "mcp-toolkit/account-id" @account_id_header = "X-MCP-Account-ID" @registry = McpToolkit::Registry.new end |
Instance Attribute Details
#account_id_header ⇒ String
144 145 146 |
# File 'lib/mcp_toolkit/configuration.rb', line 144 def account_id_header @account_id_header end |
#account_meta_key ⇒ String
Header / meta-key constants. Vendor-neutral defaults; an app on a specific central authority can rename them to match that authority's convention. These are the selectors a superuser/multi-account token uses to pin the active account.
142 143 144 |
# File 'lib/mcp_toolkit/configuration.rb', line 142 def @account_meta_key end |
#account_resolver ⇒ #call
Resolves the central account id to the satellite's LOCAL scope root.
A satellite stores rows keyed by the central app's account id (synced via
Kafka etc.). This callable receives the resolved central account_id and
MUST return the object that Resource#scope blocks root on (typically the
local Account). Return nil to signal "no local account" (=> Unauthorized).
c.account_resolver = ->(synced_account_id) { Account.find_by(synced_id: synced_account_id) }
Defaults to the identity function: the resolved central account id is used directly as the scope root (suitable for an app whose scope blocks key on the central id, or for the authority itself).
78 79 80 |
# File 'lib/mcp_toolkit/configuration.rb', line 78 def account_resolver @account_resolver end |
#auth_role ⇒ Symbol
Returns :satellite (introspect tokens against a central app) or
:authority (be the introspection provider + authenticate local tokens).
A single app MAY be both — set :authority and still configure a
central_app_url if it also exposes its own tools as a satellite.
49 50 51 |
# File 'lib/mcp_toolkit/configuration.rb', line 49 def auth_role @auth_role end |
#cache_store ⇒ ActiveSupport::Cache::Store, #read
The cache store backing sessions and introspection results. Must satisfy the
ActiveSupport::Cache::Store contract (read/write/delete with
expires_in:). Defaults to an in-process MemoryStore; a real deployment
should set this to Rails.cache (or any shared store) so sessions survive
across Puma workers.
106 107 108 |
# File 'lib/mcp_toolkit/configuration.rb', line 106 def cache_store @cache_store end |
#central_app_url ⇒ String?
Returns base URL of the central auth app.
The satellite POSTs <central_app_url>/mcp/tokens/introspect.
55 56 57 |
# File 'lib/mcp_toolkit/configuration.rb', line 55 def central_app_url @central_app_url end |
#introspect_path ⇒ String?
Returns the introspect path appended to central_app_url.
57 58 59 |
# File 'lib/mcp_toolkit/configuration.rb', line 57 def introspect_path @introspect_path end |
#introspection_cache_ttl ⇒ Integer
Returns seconds to cache an introspection result (positive AND negative) so a burst of tool calls does not hammer the central app.
60 61 62 |
# File 'lib/mcp_toolkit/configuration.rb', line 60 def introspection_cache_ttl @introspection_cache_ttl end |
#introspection_timeout ⇒ Integer
Returns HTTP open/read timeout for the introspection call.
62 63 64 |
# File 'lib/mcp_toolkit/configuration.rb', line 62 def introspection_timeout @introspection_timeout end |
#parent_controller ⇒ String
The parent class (as a String, resolved via constantize) of the
gem-provided McpToolkit::ServerController that McpToolkit::Engine mounts.
Doorkeeper-style indirection so a satellite mounting the engine can keep
ActionController::Base (NOT ::API) — e.g. for a logstasher helper_method
hook — by setting c.parent_controller = "ApplicationController".
134 135 136 |
# File 'lib/mcp_toolkit/configuration.rb', line 134 def parent_controller @parent_controller end |
#protocol_version ⇒ String?
Returns protocol version to pin on the underlying MCP::Server. nil lets the gem negotiate (recommended). Set only to force an older spec.
125 126 127 |
# File 'lib/mcp_toolkit/configuration.rb', line 125 def protocol_version @protocol_version end |
#registry ⇒ McpToolkit::Registry
The resource registry for this configuration. Each config carries its own so
tests (and, in principle, multiple mounted servers) don't collide. The
process-wide convenience McpToolkit.registry delegates to the active
config's registry.
152 153 154 |
# File 'lib/mcp_toolkit/configuration.rb', line 152 def registry @registry end |
#serializer_base ⇒ Object
The serializer base, lazily defaulting to the gem's bundled DSL base. Lazy so
McpToolkit::Serializer::Base is referenced after it has been required,
regardless of file load order.
187 188 189 |
# File 'lib/mcp_toolkit/configuration.rb', line 187 def serializer_base @serializer_base ||= McpToolkit::Serializer::Base end |
#server_instructions ⇒ String?
Returns human-readable instructions returned on initialize.
26 27 28 |
# File 'lib/mcp_toolkit/configuration.rb', line 26 def server_instructions @server_instructions end |
#server_name ⇒ String
Returns the MCP server name advertised in initialize.
22 23 24 |
# File 'lib/mcp_toolkit/configuration.rb', line 22 def server_name @server_name end |
#server_version ⇒ String
Returns the MCP server version advertised in initialize.
24 25 26 |
# File 'lib/mcp_toolkit/configuration.rb', line 24 def server_version @server_version end |
#session_ttl ⇒ Integer
Returns session sliding-TTL in seconds.
109 110 111 |
# File 'lib/mcp_toolkit/configuration.rb', line 109 def session_ttl @session_ttl end |
#sql_sanitizer ⇒ #sanitize_sql_like
Escapes LIKE wildcards in matches / does_not_match filter values so they
match literally. Must respond to sanitize_sql_like(string). Defaults to the
ActiveRecord-backed McpToolkit::SqlSanitizer; a non-Rails host (or a test) can
inject its own.
119 120 121 |
# File 'lib/mcp_toolkit/configuration.rb', line 119 def sql_sanitizer @sql_sanitizer end |
#token_authenticator ⇒ #call?
Looks up + verifies a plaintext bearer token locally, returning a token
object (duck-typed, see below) or nil. This is the authority's
McpToken.authenticate(plaintext) equivalent. Required for the :authority
role; unused by a pure satellite.
c.token_authenticator = ->(plaintext) { McpToken.authenticate(plaintext) }
The returned token object must respond to the methods
McpToolkit::Auth::Authority#introspection_payload reads (see that module for
the contract): kind, account_id, account_ids, expires_at, scopes. A
touch_last_used! method, if present, is called.
95 96 97 |
# File 'lib/mcp_toolkit/configuration.rb', line 95 def token_authenticator @token_authenticator end |
Instance Method Details
#authority? ⇒ Boolean
Returns whether this app authenticates tokens locally / answers introspection.
198 199 200 |
# File 'lib/mcp_toolkit/configuration.rb', line 198 def auth_role.to_sym == :authority end |
#introspect_url ⇒ Object
Full introspection URL the satellite POSTs to. Raises a clear error if the central URL was never configured.
204 205 206 207 208 |
# File 'lib/mcp_toolkit/configuration.rb', line 204 def introspect_url raise McpToolkit::Errors::ConfigurationError, "central_app_url is not configured" if central_app_url.to_s.empty? "#{central_app_url.chomp("/")}#{introspect_path}" end |
#satellite? ⇒ Boolean
Returns whether this app introspects tokens against a central app.
192 193 194 |
# File 'lib/mcp_toolkit/configuration.rb', line 192 def satellite? auth_role.to_sym == :satellite || central_app_url end |