Class: McpToolkit::Registry
- Inherits:
-
Object
- Object
- McpToolkit::Registry
- Defined in:
- lib/mcp_toolkit/registry.rb
Overview
Central registry of read-only resources exposed via the MCP server. Resources
are registered at boot (in a to_prepare initializer) and consumed by the
generic resources / resource_schema / get / list tools.
Instances are addressable so tests (and, in principle, multiple mounted
servers) don't collide; the app-facing convenience is McpToolkit.registry,
which returns the process-wide instance.
Defined Under Namespace
Classes: UnknownResource
Instance Attribute Summary collapse
-
#resource_extension ⇒ Module?
A Module MIXED INTO every Resource before its registration block runs, so a host can add its OWN declaration DSL (its "extras") on top of the gem's built-in
model/scope/serializer/filterable/superusers_only!/note/filter. -
#resource_finalizer ⇒ #call?
A callable run against each Resource AFTER its registration block, so a host can derive gem-native fields from its declared extras — e.g.
Instance Method Summary collapse
-
#default_required_permissions_scope(scope = nil) ⇒ Object
Registry-wide DEFAULT required scope, so a satellite declares its scope ONCE for every resource instead of repeating it per resource:.
- #fetch(name) ⇒ Object
- #find(name) ⇒ Object
-
#initialize ⇒ Registry
constructor
A new instance of Registry.
- #register(name) ⇒ Object
-
#required_scope_for(resource) ⇒ Object
The scope a token must carry to reach
resourcevia the generic tools: the resource's own declared scope, else the registry default, else nil (no check). -
#reset! ⇒ Object
Clears registered resources for a dev reload (the satellite re-declares them in
to_prepare). - #resource_names ⇒ Object
- #resources ⇒ Object
Constructor Details
#initialize ⇒ Registry
Returns a new instance of Registry.
13 14 15 16 17 18 |
# File 'lib/mcp_toolkit/registry.rb', line 13 def initialize @resources = {} @default_required_permissions_scope = nil @resource_extension = nil @resource_finalizer = nil end |
Instance Attribute Details
#resource_extension ⇒ Module?
A Module MIXED INTO every Resource before its registration block runs, so a host
can add its OWN declaration DSL (its "extras") on top of the gem's built-in
model / scope / serializer / filterable / superusers_only! / note /
filter. The host method typically stores into the generic Resource#extra
bag; the resource_finalizer reads it back. nil (the default) mixes in nothing,
so a host with no extras is unaffected. Set ONCE in configure (not per reload),
since reset! preserves it.
McpToolkit.registry.resource_extension = MyApp::ResourceExtension # adds `dependencies`
31 32 33 |
# File 'lib/mcp_toolkit/registry.rb', line 31 def resource_extension @resource_extension end |
#resource_finalizer ⇒ #call?
A callable run against each Resource AFTER its registration block, so a host can
derive gem-native fields from its declared extras — e.g. build a serializer
from the model + declared dependencies, or a lazy filterable. ->(resource).
nil (the default) is a no-op. This is the hook that lets a host avoid a parallel
registration system: it declares resources DIRECTLY against the gem registry and
fills the derived pieces here. Set ONCE in configure; preserved across reset!.
41 42 43 |
# File 'lib/mcp_toolkit/registry.rb', line 41 def resource_finalizer @resource_finalizer end |
Instance Method Details
#default_required_permissions_scope(scope = nil) ⇒ Object
Registry-wide DEFAULT required scope, so a satellite declares its scope ONCE for every resource instead of repeating it per resource:
McpToolkit.registry. "notifications__read"
A resource's own required_permissions_scope overrides this. Default nil = no
scope required unless a resource declares its own. Read with no arg.
Declared in the satellite's configure block (NOT inside to_prepare), so it
survives reset! and stays set across dev reloads.
53 54 55 56 |
# File 'lib/mcp_toolkit/registry.rb', line 53 def (scope = nil) @default_required_permissions_scope = scope if scope @default_required_permissions_scope end |
#fetch(name) ⇒ Object
72 73 74 |
# File 'lib/mcp_toolkit/registry.rb', line 72 def fetch(name) find(name) or raise(UnknownResource, McpToolkit::UnknownResourceMessage.new(name, resource_names).build) end |
#find(name) ⇒ Object
76 77 78 |
# File 'lib/mcp_toolkit/registry.rb', line 76 def find(name) @resources[name.to_s] end |
#register(name) ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/mcp_toolkit/registry.rb', line 58 def register(name, &) resource = McpToolkit::Resource.new(name) resource.extend(@resource_extension) if @resource_extension resource.instance_eval(&) @resource_finalizer&.call(resource) @resources[name.to_s] = resource end |
#required_scope_for(resource) ⇒ Object
The scope a token must carry to reach resource via the generic tools: the
resource's own declared scope, else the registry default, else nil (no check).
68 69 70 |
# File 'lib/mcp_toolkit/registry.rb', line 68 def required_scope_for(resource) resource.(@default_required_permissions_scope) end |
#reset! ⇒ Object
Clears registered resources for a dev reload (the satellite re-declares them
in to_prepare). The default_required_permissions_scope, resource_extension
and resource_finalizer are PRESERVED, since they're declared once in
configure rather than per-reload.
92 93 94 |
# File 'lib/mcp_toolkit/registry.rb', line 92 def reset! @resources = {} end |
#resource_names ⇒ Object
84 85 86 |
# File 'lib/mcp_toolkit/registry.rb', line 84 def resource_names @resources.keys end |
#resources ⇒ Object
80 81 82 |
# File 'lib/mcp_toolkit/registry.rb', line 80 def resources @resources.values end |