scout_apm_mcp 0.1.0 → 0.1.2
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 +15 -1
- data/README.md +12 -33
- data/lib/scout_apm_mcp/client.rb +25 -1
- data/lib/scout_apm_mcp/helpers.rb +40 -15
- data/lib/scout_apm_mcp/server.rb +100 -13
- data/lib/scout_apm_mcp/version.rb +1 -1
- metadata +11 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fe2bbad61c1acff6ae4c31b52a7e820acdc64449be4ae998a574c1937ac4775c
|
|
4
|
+
data.tar.gz: a2c68cf35aa37975a99cf98b68fa29a91673c449f983bbb96547b6403df8401f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e591d27a417285348f7257f150aeb11a9fa4390227893fc996fadf65d08dd856fd4121f3780e7d5403ecb3e985d5c3f2389dce5a99c3d4f57ad9f47bb4123876
|
|
7
|
+
data.tar.gz: 6112164513df8a51d4e0c039f9245621869ea4533a54ad493df3ec3e4aa67b738fd4952a0507c740a35a1c8568705ed72f8c2cf9d927603bd85fb9080b671f46
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.1.2 (2025-11-21)
|
|
4
|
+
|
|
5
|
+
- Enhanced SSL certificate handling with support for `SSL_CERT_FILE` environment variable and automatic fallback to system certificates
|
|
6
|
+
- Improved error handling for SSL verification failures with clearer error messages
|
|
7
|
+
- Extended `Helpers.parse_scout_url` to support parsing multiple URL types (endpoints, error_groups, insights, apps) beyond just traces
|
|
8
|
+
- Added `FetchScoutURLTool` MCP tool for automatically detecting and fetching data from any ScoutAPM URL
|
|
9
|
+
- Fixed MCP error handling to ensure error responses always have valid IDs for strict MCP client validation
|
|
10
|
+
- Improved URL parsing to return `url_type` field for better resource type detection
|
|
11
|
+
|
|
12
|
+
## 0.1.1 (2025-11-21)
|
|
13
|
+
|
|
14
|
+
- Fixed `NullLogger` missing `set_client_initialized` method that caused MCP initialization errors
|
|
15
|
+
- Added `set_client_initialized` method with optional argument to match fast-mcp logger interface
|
|
16
|
+
|
|
3
17
|
## 0.1.0 (2025-11-20)
|
|
4
18
|
|
|
5
19
|
- Initial release
|
|
@@ -9,5 +23,5 @@
|
|
|
9
23
|
- Support for environment variables and 1Password integration (via optional `opdotenv` gem)
|
|
10
24
|
- Complete RBS type signatures for all public APIs
|
|
11
25
|
- Comprehensive test suite with RSpec
|
|
12
|
-
- Requires Ruby 3.
|
|
26
|
+
- Requires Ruby 3.1 or higher
|
|
13
27
|
- All dependencies use latest compatible versions with pessimistic versioning for security
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# scout_apm_mcp
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/scout_apm_mcp) [](https://github.com/amkisko/scout_apm_mcp.rb/actions/workflows/test.yml) [](https://codecov.io/gh/amkisko/scout_apm_mcp.rb)
|
|
3
|
+
[](https://badge.fury.io/rb/scout_apm_mcp) [](https://github.com/amkisko/scout_apm_mcp.rb/actions/workflows/test.yml) [](https://codecov.io/gh/amkisko/scout_apm_mcp.rb)
|
|
4
4
|
|
|
5
5
|
Ruby gem providing ScoutAPM API client and MCP (Model Context Protocol) server tools for fetching traces, endpoints, metrics, errors, and insights. Integrates with MCP-compatible clients like Cursor IDE, Claude Desktop, and other MCP-enabled tools.
|
|
6
6
|
|
|
@@ -24,22 +24,6 @@ Sponsored by [Kisko Labs](https://www.kiskolabs.com).
|
|
|
24
24
|
|
|
25
25
|
For Cursor IDE, create or update `.cursor/mcp.json` in your project:
|
|
26
26
|
|
|
27
|
-
```json
|
|
28
|
-
{
|
|
29
|
-
"mcpServers": {
|
|
30
|
-
"scout-apm": {
|
|
31
|
-
"command": "bundle",
|
|
32
|
-
"args": ["exec", "scout_apm_mcp"],
|
|
33
|
-
"env": {
|
|
34
|
-
"OP_ENV_ENTRY_PATH": "op://Vault Name/Item Name"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Or if installed globally:
|
|
42
|
-
|
|
43
27
|
```json
|
|
44
28
|
{
|
|
45
29
|
"mcpServers": {
|
|
@@ -64,21 +48,10 @@ For Claude Desktop, edit the MCP configuration file:
|
|
|
64
48
|
{
|
|
65
49
|
"mcpServers": {
|
|
66
50
|
"scout-apm": {
|
|
67
|
-
"command": "
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Or if installed globally:
|
|
76
|
-
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"mcpServers": {
|
|
80
|
-
"scout-apm": {
|
|
81
|
-
"command": "scout_apm_mcp"
|
|
51
|
+
"command": "scout_apm_mcp",
|
|
52
|
+
"env": {
|
|
53
|
+
"OP_ENV_ENTRY_PATH": "op://Vault Name/Item Name"
|
|
54
|
+
}
|
|
82
55
|
}
|
|
83
56
|
}
|
|
84
57
|
}
|
|
@@ -316,7 +289,13 @@ Review policy:
|
|
|
316
289
|
- It might take up to 6 calendar months to review and merge pull request
|
|
317
290
|
- It might take up to 1 calendar year to review an issue
|
|
318
291
|
|
|
292
|
+
For more information, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
293
|
+
|
|
294
|
+
## Security
|
|
295
|
+
|
|
296
|
+
If you discover a security vulnerability, please report it responsibly. See [SECURITY.md](SECURITY.md) for details.
|
|
297
|
+
|
|
319
298
|
## License
|
|
320
299
|
|
|
321
|
-
The gem is available as open source under the terms of the [MIT License](
|
|
300
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
322
301
|
|
data/lib/scout_apm_mcp/client.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "uri"
|
|
2
2
|
require "net/http"
|
|
3
|
+
require "openssl"
|
|
3
4
|
require "json"
|
|
4
5
|
require "base64"
|
|
5
6
|
|
|
@@ -254,6 +255,10 @@ module ScoutApmMcp
|
|
|
254
255
|
else
|
|
255
256
|
raise "API request failed: #{response.code} #{response.message}"
|
|
256
257
|
end
|
|
258
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
259
|
+
raise "SSL verification failed: #{e.message}. This may be due to system certificate configuration issues."
|
|
260
|
+
rescue => e
|
|
261
|
+
raise "Request failed: #{e.class} - #{e.message}"
|
|
257
262
|
end
|
|
258
263
|
|
|
259
264
|
private
|
|
@@ -264,9 +269,24 @@ module ScoutApmMcp
|
|
|
264
269
|
# @return [Net::HTTP] Configured HTTP client
|
|
265
270
|
def build_http_client(uri)
|
|
266
271
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
267
|
-
http.use_ssl = uri.scheme == "https"
|
|
268
272
|
http.read_timeout = 10
|
|
269
273
|
http.open_timeout = 10
|
|
274
|
+
|
|
275
|
+
if uri.scheme == "https"
|
|
276
|
+
http.use_ssl = true
|
|
277
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
278
|
+
|
|
279
|
+
# Set ca_file directly - this is the simplest and most reliable approach
|
|
280
|
+
# Try SSL_CERT_FILE first, then default cert file
|
|
281
|
+
ca_file = if ENV["SSL_CERT_FILE"] && File.file?(ENV["SSL_CERT_FILE"])
|
|
282
|
+
ENV["SSL_CERT_FILE"]
|
|
283
|
+
elsif File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE)
|
|
284
|
+
OpenSSL::X509::DEFAULT_CERT_FILE
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
http.ca_file = ca_file if ca_file
|
|
288
|
+
end
|
|
289
|
+
|
|
270
290
|
http
|
|
271
291
|
end
|
|
272
292
|
|
|
@@ -297,6 +317,10 @@ module ScoutApmMcp
|
|
|
297
317
|
else
|
|
298
318
|
raise "API request failed: #{response.code} #{response.message}\n#{response.body}"
|
|
299
319
|
end
|
|
320
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
321
|
+
raise "SSL verification failed: #{e.message}. This may be due to system certificate configuration issues."
|
|
322
|
+
rescue => e
|
|
323
|
+
raise "Request failed: #{e.class} - #{e.message}"
|
|
300
324
|
end
|
|
301
325
|
end
|
|
302
326
|
end
|
|
@@ -63,30 +63,55 @@ module ScoutApmMcp
|
|
|
63
63
|
"or provide OP_ENV_ENTRY_PATH, or op_vault and op_item parameters for 1Password integration"
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
# Parse a ScoutAPM
|
|
66
|
+
# Parse a ScoutAPM URL and extract resource information
|
|
67
67
|
#
|
|
68
|
-
# @param url [String] Full ScoutAPM
|
|
69
|
-
# @return [Hash] Hash containing
|
|
68
|
+
# @param url [String] Full ScoutAPM URL
|
|
69
|
+
# @return [Hash] Hash containing resource type and extracted IDs
|
|
70
|
+
# Possible keys: :url_type, :app_id, :endpoint_id, :trace_id, :error_id, :insight_type,
|
|
71
|
+
# :query_params, :decoded_endpoint
|
|
70
72
|
def self.parse_scout_url(url)
|
|
71
73
|
uri = URI.parse(url)
|
|
72
74
|
path_parts = uri.path.split("/").reject(&:empty?)
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
result = {}
|
|
75
77
|
app_index = path_parts.index("apps")
|
|
76
|
-
endpoints_index = path_parts.index("endpoints")
|
|
77
|
-
trace_index = path_parts.index("trace")
|
|
78
78
|
|
|
79
|
-
result
|
|
79
|
+
return result unless app_index
|
|
80
|
+
|
|
81
|
+
result[:app_id] = path_parts[app_index + 1].to_i
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
result[:
|
|
83
|
+
# Detect URL type and extract IDs
|
|
84
|
+
# Pattern: /apps/{app_id}/endpoints/{endpoint_id}/trace/{trace_id}
|
|
85
|
+
if path_parts.include?("trace")
|
|
86
|
+
result[:url_type] = :trace
|
|
87
|
+
endpoints_index = path_parts.index("endpoints")
|
|
88
|
+
trace_index = path_parts.index("trace")
|
|
89
|
+
if endpoints_index && trace_index
|
|
90
|
+
result[:endpoint_id] = path_parts[endpoints_index + 1]
|
|
91
|
+
result[:trace_id] = path_parts[trace_index + 1].to_i
|
|
92
|
+
end
|
|
93
|
+
# Pattern: /apps/{app_id}/endpoints/{endpoint_id}
|
|
94
|
+
elsif path_parts.include?("endpoints")
|
|
95
|
+
result[:url_type] = :endpoint
|
|
96
|
+
endpoints_index = path_parts.index("endpoints")
|
|
97
|
+
result[:endpoint_id] = path_parts[endpoints_index + 1] if endpoints_index
|
|
98
|
+
# Pattern: /apps/{app_id}/error_groups/{error_id}
|
|
99
|
+
elsif path_parts.include?("error_groups")
|
|
100
|
+
result[:url_type] = :error_group
|
|
101
|
+
error_groups_index = path_parts.index("error_groups")
|
|
102
|
+
result[:error_id] = path_parts[error_groups_index + 1].to_i if error_groups_index
|
|
103
|
+
# Pattern: /apps/{app_id}/insights or /apps/{app_id}/insights/{insight_type}
|
|
104
|
+
elsif path_parts.include?("insights")
|
|
105
|
+
result[:url_type] = :insight
|
|
106
|
+
insights_index = path_parts.index("insights")
|
|
107
|
+
if insights_index && path_parts.length > insights_index + 1
|
|
108
|
+
result[:insight_type] = path_parts[insights_index + 1]
|
|
109
|
+
end
|
|
110
|
+
# Pattern: /apps/{app_id}
|
|
111
|
+
elsif path_parts.length == 2 && path_parts[0] == "apps"
|
|
112
|
+
result[:url_type] = :app
|
|
85
113
|
else
|
|
86
|
-
|
|
87
|
-
result[:app_id] = path_parts[1].to_i if path_parts[0] == "apps"
|
|
88
|
-
result[:endpoint_id] = path_parts[3] if path_parts[2] == "endpoints"
|
|
89
|
-
result[:trace_id] = path_parts[5].to_i if path_parts[4] == "trace"
|
|
114
|
+
result[:url_type] = :unknown
|
|
90
115
|
end
|
|
91
116
|
|
|
92
117
|
# Parse query parameters
|
data/lib/scout_apm_mcp/server.rb
CHANGED
|
@@ -16,6 +16,21 @@ FastMcp = MCP unless defined?(FastMcp)
|
|
|
16
16
|
module MCP
|
|
17
17
|
module Transports
|
|
18
18
|
class StdioTransport
|
|
19
|
+
if method_defined?(:send_error)
|
|
20
|
+
alias_method :original_send_error, :send_error
|
|
21
|
+
|
|
22
|
+
def send_error(code, message, id = nil)
|
|
23
|
+
# Use placeholder id if nil to satisfy strict MCP client validation
|
|
24
|
+
# JSON-RPC 2.0 allows null for notifications, but MCP clients require valid id
|
|
25
|
+
id = "error_#{SecureRandom.hex(8)}" if id.nil?
|
|
26
|
+
original_send_error(code, message, id)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Server
|
|
33
|
+
if method_defined?(:send_error)
|
|
19
34
|
alias_method :original_send_error, :send_error
|
|
20
35
|
|
|
21
36
|
def send_error(code, message, id = nil)
|
|
@@ -26,17 +41,6 @@ module MCP
|
|
|
26
41
|
end
|
|
27
42
|
end
|
|
28
43
|
end
|
|
29
|
-
|
|
30
|
-
class Server
|
|
31
|
-
alias_method :original_send_error, :send_error
|
|
32
|
-
|
|
33
|
-
def send_error(code, message, id = nil)
|
|
34
|
-
# Use placeholder id if nil to satisfy strict MCP client validation
|
|
35
|
-
# JSON-RPC 2.0 allows null for notifications, but MCP clients require valid id
|
|
36
|
-
id = "error_#{SecureRandom.hex(8)}" if id.nil?
|
|
37
|
-
original_send_error(code, message, id)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
module ScoutApmMcp
|
|
@@ -82,6 +86,10 @@ module ScoutApmMcp
|
|
|
82
86
|
@client_initialized
|
|
83
87
|
end
|
|
84
88
|
|
|
89
|
+
def set_client_initialized(value = true)
|
|
90
|
+
@client_initialized = value
|
|
91
|
+
end
|
|
92
|
+
|
|
85
93
|
def stdio_transport?
|
|
86
94
|
@transport == :stdio
|
|
87
95
|
end
|
|
@@ -137,6 +145,7 @@ module ScoutApmMcp
|
|
|
137
145
|
server.register_tool(GetInsightsHistoryTool)
|
|
138
146
|
server.register_tool(GetInsightsHistoryByTypeTool)
|
|
139
147
|
server.register_tool(ParseScoutURLTool)
|
|
148
|
+
server.register_tool(FetchScoutURLTool)
|
|
140
149
|
server.register_tool(FetchOpenAPISchemaTool)
|
|
141
150
|
end
|
|
142
151
|
|
|
@@ -423,10 +432,10 @@ module ScoutApmMcp
|
|
|
423
432
|
|
|
424
433
|
# Utility Tools
|
|
425
434
|
class ParseScoutURLTool < BaseTool
|
|
426
|
-
description "Parse a ScoutAPM
|
|
435
|
+
description "Parse a ScoutAPM URL and extract resource information (app_id, endpoint_id, trace_id, etc.)"
|
|
427
436
|
|
|
428
437
|
arguments do
|
|
429
|
-
required(:url).filled(:string).description("Full ScoutAPM
|
|
438
|
+
required(:url).filled(:string).description("Full ScoutAPM URL (e.g., https://scoutapm.com/apps/123/endpoints/.../trace/456)")
|
|
430
439
|
end
|
|
431
440
|
|
|
432
441
|
def call(url:)
|
|
@@ -434,6 +443,84 @@ module ScoutApmMcp
|
|
|
434
443
|
end
|
|
435
444
|
end
|
|
436
445
|
|
|
446
|
+
class FetchScoutURLTool < BaseTool
|
|
447
|
+
description "Fetch data from a ScoutAPM URL by automatically detecting the resource type and fetching the appropriate data"
|
|
448
|
+
|
|
449
|
+
arguments do
|
|
450
|
+
required(:url).filled(:string).description("Full ScoutAPM URL (e.g., https://scoutapm.com/apps/123/endpoints/.../trace/456)")
|
|
451
|
+
optional(:include_endpoint).filled(:bool).description("For trace URLs, also fetch endpoint details for context (default: false)")
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def call(url:, include_endpoint: false)
|
|
455
|
+
parsed = Helpers.parse_scout_url(url)
|
|
456
|
+
client = get_client
|
|
457
|
+
|
|
458
|
+
result = {
|
|
459
|
+
url: url,
|
|
460
|
+
parsed: parsed,
|
|
461
|
+
data: nil
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
case parsed[:url_type]
|
|
465
|
+
when :trace
|
|
466
|
+
if parsed[:app_id] && parsed[:trace_id]
|
|
467
|
+
trace_data = client.fetch_trace(parsed[:app_id], parsed[:trace_id])
|
|
468
|
+
result[:data] = {trace: trace_data}
|
|
469
|
+
|
|
470
|
+
if include_endpoint && parsed[:endpoint_id]
|
|
471
|
+
endpoint_data = client.get_endpoint(parsed[:app_id], parsed[:endpoint_id])
|
|
472
|
+
result[:data][:endpoint] = endpoint_data
|
|
473
|
+
result[:data][:decoded_endpoint] = parsed[:decoded_endpoint]
|
|
474
|
+
end
|
|
475
|
+
else
|
|
476
|
+
raise "Invalid trace URL: missing app_id or trace_id"
|
|
477
|
+
end
|
|
478
|
+
when :endpoint
|
|
479
|
+
if parsed[:app_id] && parsed[:endpoint_id]
|
|
480
|
+
endpoint_data = client.get_endpoint(parsed[:app_id], parsed[:endpoint_id])
|
|
481
|
+
result[:data] = {
|
|
482
|
+
endpoint: endpoint_data,
|
|
483
|
+
decoded_endpoint: parsed[:decoded_endpoint]
|
|
484
|
+
}
|
|
485
|
+
else
|
|
486
|
+
raise "Invalid endpoint URL: missing app_id or endpoint_id"
|
|
487
|
+
end
|
|
488
|
+
when :error_group
|
|
489
|
+
if parsed[:app_id] && parsed[:error_id]
|
|
490
|
+
error_data = client.get_error_group(parsed[:app_id], parsed[:error_id])
|
|
491
|
+
result[:data] = {error_group: error_data}
|
|
492
|
+
else
|
|
493
|
+
raise "Invalid error group URL: missing app_id or error_id"
|
|
494
|
+
end
|
|
495
|
+
when :insight
|
|
496
|
+
if parsed[:app_id]
|
|
497
|
+
if parsed[:insight_type]
|
|
498
|
+
insight_data = client.get_insight_by_type(parsed[:app_id], parsed[:insight_type])
|
|
499
|
+
result[:data] = {insight: insight_data, insight_type: parsed[:insight_type]}
|
|
500
|
+
else
|
|
501
|
+
insights_data = client.get_all_insights(parsed[:app_id])
|
|
502
|
+
result[:data] = {insights: insights_data}
|
|
503
|
+
end
|
|
504
|
+
else
|
|
505
|
+
raise "Invalid insight URL: missing app_id"
|
|
506
|
+
end
|
|
507
|
+
when :app
|
|
508
|
+
if parsed[:app_id]
|
|
509
|
+
app_data = client.get_app(parsed[:app_id])
|
|
510
|
+
result[:data] = {app: app_data}
|
|
511
|
+
else
|
|
512
|
+
raise "Invalid app URL: missing app_id"
|
|
513
|
+
end
|
|
514
|
+
when :unknown
|
|
515
|
+
raise "Unknown or unsupported ScoutAPM URL format: #{url}"
|
|
516
|
+
else
|
|
517
|
+
raise "Unable to determine URL type from: #{url}"
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
result
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
|
|
437
524
|
class FetchOpenAPISchemaTool < BaseTool
|
|
438
525
|
description "Fetch the ScoutAPM OpenAPI schema from the API and optionally validate it"
|
|
439
526
|
|
metadata
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scout_apm_mcp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: fast-mcp
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
18
|
version: '0.1'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '2.0'
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
25
|
requirements:
|
|
24
|
-
- - "
|
|
26
|
+
- - ">="
|
|
25
27
|
- !ruby/object:Gem::Version
|
|
26
28
|
version: '0.1'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '2.0'
|
|
27
32
|
- !ruby/object:Gem::Dependency
|
|
28
33
|
name: base64
|
|
29
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -242,7 +247,6 @@ metadata:
|
|
|
242
247
|
homepage_uri: https://github.com/amkisko/scout_apm_mcp.rb
|
|
243
248
|
documentation_uri: https://github.com/amkisko/scout_apm_mcp.rb#readme
|
|
244
249
|
rubygems_mfa_required: 'true'
|
|
245
|
-
post_install_message:
|
|
246
250
|
rdoc_options: []
|
|
247
251
|
require_paths:
|
|
248
252
|
- lib
|
|
@@ -257,8 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
257
261
|
- !ruby/object:Gem::Version
|
|
258
262
|
version: '0'
|
|
259
263
|
requirements: []
|
|
260
|
-
rubygems_version: 3.
|
|
261
|
-
signing_key:
|
|
264
|
+
rubygems_version: 3.6.9
|
|
262
265
|
specification_version: 4
|
|
263
266
|
summary: ScoutAPM MCP (Model Context Protocol) server for Cursor IDE integration
|
|
264
267
|
test_files: []
|