mcp_toolkit 0.4.0 → 0.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 +4 -4
- data/CHANGELOG.md +231 -0
- data/config/routes.rb +1 -1
- data/lib/mcp_toolkit/authority/controller_methods.rb +15 -0
- data/lib/mcp_toolkit/authority/registry_tool_provider.rb +9 -10
- data/lib/mcp_toolkit/authority/single_tool_provider.rb +25 -0
- data/lib/mcp_toolkit/authority/tools/base.rb +31 -3
- data/lib/mcp_toolkit/authority/tools/get.rb +2 -1
- data/lib/mcp_toolkit/authority/tools/list.rb +49 -1
- data/lib/mcp_toolkit/authority/tools/resource_schema.rb +10 -2
- data/lib/mcp_toolkit/authority/tools/resources.rb +26 -4
- data/lib/mcp_toolkit/configuration.rb +161 -7
- data/lib/mcp_toolkit/dispatcher.rb +17 -3
- data/lib/mcp_toolkit/engine.rb +5 -2
- data/lib/mcp_toolkit/engine_controllers.rb +11 -3
- data/lib/mcp_toolkit/filtering.rb +168 -23
- data/lib/mcp_toolkit/gateway/aggregator.rb +25 -5
- data/lib/mcp_toolkit/list_executor.rb +48 -4
- data/lib/mcp_toolkit/resource.rb +55 -6
- data/lib/mcp_toolkit/resource_schema.rb +125 -16
- data/lib/mcp_toolkit/serializer/association_descriptor.rb +11 -0
- data/lib/mcp_toolkit/serializer/target_ref.rb +7 -0
- data/lib/mcp_toolkit/session.rb +2 -2
- data/lib/mcp_toolkit/tool_reference_rewriter.rb +33 -0
- data/lib/mcp_toolkit/tools/authority_base.rb +23 -2
- data/lib/mcp_toolkit/tools/base.rb +23 -3
- data/lib/mcp_toolkit/tools/get.rb +1 -1
- data/lib/mcp_toolkit/tools/list.rb +27 -9
- data/lib/mcp_toolkit/tools/resource_schema.rb +12 -3
- data/lib/mcp_toolkit/tools/resources.rb +30 -7
- data/lib/mcp_toolkit/usage_metering/recorder.rb +28 -2
- data/lib/mcp_toolkit/version.rb +1 -1
- metadata +5 -1
|
@@ -5,9 +5,10 @@ class McpToolkit::Tools::Resources < McpToolkit::Tools::Base
|
|
|
5
5
|
tool_name "resources"
|
|
6
6
|
description <<~DESC.strip
|
|
7
7
|
List all read-only resources available via the `list` and `get` tools. Returns each
|
|
8
|
-
resource's name
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
resource's name, a short description, whether it accepts filters (`filterable`) and — when
|
|
9
|
+
present — a usage `note` (read it before interpreting the resource's data). Call this once
|
|
10
|
+
at the start of a session to learn what exists, then use `resource_schema` for a specific
|
|
11
|
+
resource's attributes, relationships and filters.
|
|
11
12
|
DESC
|
|
12
13
|
|
|
13
14
|
input_schema(properties: {})
|
|
@@ -16,12 +17,34 @@ class McpToolkit::Tools::Resources < McpToolkit::Tools::Base
|
|
|
16
17
|
config = config_from(server_context)
|
|
17
18
|
# Discovery requires the registry-level default scope (the satellite's
|
|
18
19
|
# app-wide scope); per-resource scopes are enforced by `get` / `list`.
|
|
19
|
-
with_authentication(server_context,
|
|
20
|
+
with_authentication(server_context,
|
|
21
|
+
required_scope: config.registry.default_required_permissions_scope) do |introspection|
|
|
20
22
|
{
|
|
21
|
-
resources: config.registry.resources
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
resources: config.registry.resources
|
|
24
|
+
.reject { |resource| resource.superusers_only? && !introspection.superuser? }
|
|
25
|
+
.map do |resource|
|
|
26
|
+
{
|
|
27
|
+
name: resource.name,
|
|
28
|
+
description: resource.description,
|
|
29
|
+
filterable: filterable?(resource, config),
|
|
30
|
+
note: resource.note
|
|
31
|
+
}.compact
|
|
32
|
+
end
|
|
24
33
|
}
|
|
25
34
|
end
|
|
26
35
|
end
|
|
36
|
+
|
|
37
|
+
# Whether the resource can be filtered at all — via the generic allowlist OR a
|
|
38
|
+
# resource-specific custom filter. Mirrors the authority-path resources tool:
|
|
39
|
+
# resolving a lazily-declared allowlist may run host code, and one resource's
|
|
40
|
+
# failing resolution must not take down the whole discovery index, so a raise
|
|
41
|
+
# degrades to nil (the key is omitted) and the source is retried on the next
|
|
42
|
+
# read (see Resource#filterable).
|
|
43
|
+
def self.filterable?(resource, config)
|
|
44
|
+
resource.filterable_columns.any? || resource.custom_filters.any?
|
|
45
|
+
rescue StandardError => e
|
|
46
|
+
config.logger&.warn("mcp_toolkit: filterable resolution failed for #{resource.name}: #{e.message}")
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
private_class_method :filterable?
|
|
27
50
|
end
|
|
@@ -65,18 +65,44 @@ class McpToolkit::UsageMetering::Recorder
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# `config.usage_flusher` target. Persists the request's accumulated events via the
|
|
68
|
-
# sink in one shot. No-op when nothing was accumulated.
|
|
68
|
+
# sink in one shot. No-op when nothing was accumulated. If the batch write fails,
|
|
69
|
+
# falls back to per-event writes so one un-persistable ("poison") event can't drop
|
|
70
|
+
# metering for the whole request.
|
|
69
71
|
def flush(controller:)
|
|
70
72
|
events = buffer_for(controller)
|
|
71
73
|
return if events.empty?
|
|
72
74
|
|
|
73
75
|
@sink.call(events)
|
|
74
76
|
rescue StandardError => e
|
|
75
|
-
|
|
77
|
+
flush_individually(events, e)
|
|
76
78
|
end
|
|
77
79
|
|
|
78
80
|
private
|
|
79
81
|
|
|
82
|
+
# The batch write failed. Retry each event on its own so a single un-persistable
|
|
83
|
+
# event (a constraint violation, bad encoding) loses ONLY itself instead of
|
|
84
|
+
# dropping every sibling call's metering — which a caller could otherwise
|
|
85
|
+
# exploit to evade billing for a whole batch by appending one poison call.
|
|
86
|
+
# Assumes the batch sink is atomic (nothing persisted on failure — true for
|
|
87
|
+
# `insert_all`); a non-atomic sink could double-write the events that did land,
|
|
88
|
+
# so this stays a fallback, not the default path.
|
|
89
|
+
def flush_individually(events, batch_error)
|
|
90
|
+
@logger&.warn(
|
|
91
|
+
"MCP usage tracking: batch flush of #{events.size} event(s) failed " \
|
|
92
|
+
"(#{batch_error.message}), retrying individually"
|
|
93
|
+
)
|
|
94
|
+
events.each do |event|
|
|
95
|
+
@sink.call([event])
|
|
96
|
+
rescue StandardError => e
|
|
97
|
+
report("dropped 1 unpersistable usage event", e)
|
|
98
|
+
end
|
|
99
|
+
rescue StandardError
|
|
100
|
+
# Metering MUST NEVER affect the MCP response. `flush` already runs this from
|
|
101
|
+
# its rescue, so a raise here (e.g. a misbehaving logger or error_reporter)
|
|
102
|
+
# would escape into the after_action. Swallow it as the last resort.
|
|
103
|
+
nil
|
|
104
|
+
end
|
|
105
|
+
|
|
80
106
|
def scrub(arguments)
|
|
81
107
|
hash = arguments.to_h
|
|
82
108
|
@parameter_filter ? @parameter_filter.filter(hash) : hash
|
data/lib/mcp_toolkit/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mcp_toolkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Karol Galanciak
|
|
@@ -109,6 +109,7 @@ files:
|
|
|
109
109
|
- lib/mcp_toolkit/authority/context.rb
|
|
110
110
|
- lib/mcp_toolkit/authority/controller_methods.rb
|
|
111
111
|
- lib/mcp_toolkit/authority/registry_tool_provider.rb
|
|
112
|
+
- lib/mcp_toolkit/authority/single_tool_provider.rb
|
|
112
113
|
- lib/mcp_toolkit/authority/token.rb
|
|
113
114
|
- lib/mcp_toolkit/authority/tools/base.rb
|
|
114
115
|
- lib/mcp_toolkit/authority/tools/get.rb
|
|
@@ -139,11 +140,14 @@ files:
|
|
|
139
140
|
- lib/mcp_toolkit/resource.rb
|
|
140
141
|
- lib/mcp_toolkit/resource_schema.rb
|
|
141
142
|
- lib/mcp_toolkit/serialization.rb
|
|
143
|
+
- lib/mcp_toolkit/serializer/association_descriptor.rb
|
|
142
144
|
- lib/mcp_toolkit/serializer/base.rb
|
|
145
|
+
- lib/mcp_toolkit/serializer/target_ref.rb
|
|
143
146
|
- lib/mcp_toolkit/server.rb
|
|
144
147
|
- lib/mcp_toolkit/session.rb
|
|
145
148
|
- lib/mcp_toolkit/sql_sanitizer.rb
|
|
146
149
|
- lib/mcp_toolkit/token_kinds.rb
|
|
150
|
+
- lib/mcp_toolkit/tool_reference_rewriter.rb
|
|
147
151
|
- lib/mcp_toolkit/tools/authority_base.rb
|
|
148
152
|
- lib/mcp_toolkit/tools/base.rb
|
|
149
153
|
- lib/mcp_toolkit/tools/get.rb
|