scout_apm_mcp 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d91170a4429338139e7e846a48e093665085269fa1c230dbdd8c06507acafa81
4
- data.tar.gz: cc4767697140de54fc4ed7d5e08b3c097b7a1d6e89b5d945882c4490926c2670
3
+ metadata.gz: 3e4f9717b9ae8caf19fa92e364acc8fd7183a27ca686b8c587748ec017bb1764
4
+ data.tar.gz: 7c8261b3a2f17d320d69051c67e152d851e0fe701c93fca62cd68c92f069475b
5
5
  SHA512:
6
- metadata.gz: a96e42d3f8a07f71bc339ea551cc6eb8eb5b1179492c596843a8aebd10a857d04dae8a04b810e78aea08c12a23462ec0987bccd42f66f548d7d468d416240b19
7
- data.tar.gz: 885b0d0d1feae986a0f054aa4138d2525ea730d77476480c3b8d0af9f24b66acd49fd8f97d1d6669e7565712e7e235265c8e138701df34a4a9f17463f47d67e9
6
+ metadata.gz: ba2f1f24479d17fb119c08c1ca14b22a2059e9ee0f3ca5047fc47c2a57b8eece7e2fb6541036434a8e623fb8781c2eeb95a9b91ce3dfe576ae615a8a1ba6bf5e
7
+ data.tar.gz: 94291c406ff5d7d5755349de80e03e6ca7001201c8d3642d613404ec2e1a0dcb0d96641439fca0ef5442a2738f5f20168fbee38219de6578ffe7551edf398c6e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.1.6 (2026-03-29)
4
+
5
+ - Background jobs API support: `list_jobs`, `list_job_metrics`, `get_job_metrics`, `list_job_traces` on the client, matching MCP tools, and URL parsing / `FetchScoutURLTool` handling for job and job-trace links.
6
+ - Refreshed bundled OpenAPI fixture from Scout’s live schema (includes jobs paths).
7
+ - Extracted MCP JSON-RPC error-id monkey patch into `lib/scout_apm_mcp/mcp_error_id_patch.rb` (excluded from coverage metrics).
8
+ - Expanded test suite: `Server.start`, `NullLogger`, batch tool dispatch, `FetchScoutURLTool` / `FetchOpenAPISchemaTool` branches, and list endpoints/jobs timeframe edge cases
9
+
3
10
  ## 0.1.5 (2026-02-10)
4
11
 
5
12
  - Fix range handling in calculate_range method
data/bin/scout_apm_mcp CHANGED
@@ -1,6 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
2
  # Suppress all output to prevent breaking JSON parsing in MCP clients
5
3
  # STDOUT is used for MCP protocol communication (JSON-RPC), so we must not output anything
6
4
  # STDERR is also suppressed to prevent any error messages from breaking JSON parsing
@@ -25,6 +25,9 @@ module ScoutApmMcp
25
25
  # Valid insight types
26
26
  VALID_INSIGHTS = %w[n_plus_one memory_bloat slow_query].freeze
27
27
 
28
+ # Valid job metric types (distinct from application endpoint metrics)
29
+ VALID_JOB_METRICS = %w[throughput execution_time latency errors allocations].freeze
30
+
28
31
  # @param api_key [String] ScoutAPM API key
29
32
  # @param api_base [String] API base URL (default: https://scoutapm.com/api/v0)
30
33
  # @raise [ArgumentError] if api_key is nil or empty
@@ -191,6 +194,106 @@ module ScoutApmMcp
191
194
  response.dig("results", "traces") || []
192
195
  end
193
196
 
197
+ # List background jobs for an application
198
+ #
199
+ # @param app_id [Integer] ScoutAPM application ID
200
+ # @param from [String, nil] Start time in ISO 8601 format
201
+ # @param to [String, nil] End time in ISO 8601 format
202
+ # @param range [String, nil] Quick time range (e.g., "30min", "1day", "3days", "7days"). If provided, calculates from/to automatically.
203
+ # @return [Array<Hash>] Array of job hashes
204
+ def list_jobs(app_id, from: nil, to: nil, range: nil)
205
+ if from.nil? && to.nil? && range.nil?
206
+ range = "7days"
207
+ end
208
+
209
+ if range
210
+ calculated = Helpers.calculate_range(range: range, to: to)
211
+ from = calculated[:from]
212
+ to = calculated[:to]
213
+ end
214
+
215
+ now = Time.now.utc
216
+ if from.nil? && to
217
+ calculated = Helpers.calculate_range(range: "7days", to: to)
218
+ from = calculated[:from]
219
+ elsif from && to.nil?
220
+ to = Helpers.format_time(now)
221
+ end
222
+
223
+ validate_time_range(from, to) if from && to
224
+ uri = URI("#{@api_base}/apps/#{app_id}/jobs")
225
+ uri.query = build_query_string(from: from, to: to)
226
+ response = make_request(uri)
227
+ response["results"] || []
228
+ end
229
+
230
+ # List available metric types for a background job
231
+ #
232
+ # @param app_id [Integer] ScoutAPM application ID
233
+ # @param job_id [String] Job ID (base64 URL-encoded, as returned by list_jobs)
234
+ # @return [Array<String>] Metric type names
235
+ def list_job_metrics(app_id, job_id)
236
+ uri = URI(@api_base)
237
+ uri.path = File.join(uri.path, "apps", app_id.to_s, "jobs", job_id, "metrics")
238
+ response = make_request(uri)
239
+ response.dig("results", "availableMetrics") || []
240
+ end
241
+
242
+ # Get time-series data for a job metric
243
+ #
244
+ # @param app_id [Integer] ScoutAPM application ID
245
+ # @param job_id [String] Job ID (base64 URL-encoded)
246
+ # @param metric_type [String] One of throughput, execution_time, latency, errors, allocations
247
+ # @param from [String, nil] Start time in ISO 8601 format
248
+ # @param to [String, nil] End time in ISO 8601 format
249
+ # @param range [String, nil] Quick time range; if provided, calculates from/to automatically.
250
+ # @return [Array] Data points for the metric
251
+ def get_job_metrics(app_id, job_id, metric_type, from: nil, to: nil, range: nil)
252
+ if range
253
+ calculated = Helpers.calculate_range(range: range, to: to)
254
+ from = calculated[:from]
255
+ to = calculated[:to]
256
+ end
257
+
258
+ validate_job_metric_params(metric_type, from, to)
259
+ uri = URI(@api_base)
260
+ uri.path = File.join(uri.path, "apps", app_id.to_s, "jobs", job_id, "metrics", metric_type)
261
+ uri.query = build_query_string(from: from, to: to)
262
+ response = make_request(uri)
263
+ series = response.dig("results", "series") || {}
264
+ series[metric_type] || []
265
+ end
266
+
267
+ # List traces for a background job (max 100, within 7 days)
268
+ #
269
+ # @param app_id [Integer] ScoutAPM application ID
270
+ # @param job_id [String] Job ID (base64 URL-encoded)
271
+ # @param from [String, nil] Start time in ISO 8601 format
272
+ # @param to [String, nil] End time in ISO 8601 format
273
+ # @param range [String, nil] Quick time range; if provided, calculates from/to automatically.
274
+ # @return [Array<Hash>] Array of trace hashes
275
+ def list_job_traces(app_id, job_id, from: nil, to: nil, range: nil)
276
+ if range
277
+ calculated = Helpers.calculate_range(range: range, to: to)
278
+ from = calculated[:from]
279
+ to = calculated[:to]
280
+ end
281
+
282
+ validate_time_range(from, to) if from && to
283
+ if from && to
284
+ from_time = Helpers.parse_time(from)
285
+ seven_days_ago = Time.now.utc - (7 * 24 * 60 * 60)
286
+ if from_time < seven_days_ago
287
+ raise ArgumentError, "from_time cannot be older than 7 days"
288
+ end
289
+ end
290
+ uri = URI(@api_base)
291
+ uri.path = File.join(uri.path, "apps", app_id.to_s, "jobs", job_id, "traces")
292
+ uri.query = build_query_string(from: from, to: to)
293
+ response = make_request(uri)
294
+ response.dig("results", "traces") || []
295
+ end
296
+
194
297
  # Fetch detailed trace information
195
298
  #
196
299
  # @param app_id [Integer] ScoutAPM application ID
@@ -460,6 +563,13 @@ module ScoutApmMcp
460
563
  validate_time_range(from, to) if from && to
461
564
  end
462
565
 
566
+ def validate_job_metric_params(metric_type, from, to)
567
+ unless VALID_JOB_METRICS.include?(metric_type)
568
+ raise ArgumentError, "Invalid metric_type. Must be one of: #{VALID_JOB_METRICS.join(", ")}"
569
+ end
570
+ validate_time_range(from, to) if from && to
571
+ end
572
+
463
573
  # Validate time ranges
464
574
  #
465
575
  # @param from [String, nil] Start time in ISO 8601 format
@@ -64,7 +64,7 @@ module ScoutApmMcp
64
64
  # @param url [String] Full ScoutAPM URL
65
65
  # @return [Hash] Hash containing resource type and extracted IDs
66
66
  # Possible keys: :url_type, :app_id, :endpoint_id, :trace_id, :error_id, :insight_type,
67
- # :query_params, :decoded_endpoint
67
+ # :job_id, :query_params, :decoded_endpoint, :decoded_job
68
68
  def self.parse_scout_url(url)
69
69
  uri = URI.parse(url)
70
70
  path_parts = uri.path.split("/").reject(&:empty?)
@@ -78,7 +78,7 @@ module ScoutApmMcp
78
78
 
79
79
  # Detect URL type and extract IDs
80
80
  # Pattern: /apps/{app_id}/endpoints/{endpoint_id}/trace/{trace_id}
81
- if path_parts.include?("trace")
81
+ if path_parts.include?("trace") && path_parts.include?("endpoints")
82
82
  result[:url_type] = :trace
83
83
  endpoints_index = path_parts.index("endpoints")
84
84
  trace_index = path_parts.index("trace")
@@ -86,6 +86,24 @@ module ScoutApmMcp
86
86
  result[:endpoint_id] = path_parts[endpoints_index + 1]
87
87
  result[:trace_id] = path_parts[trace_index + 1].to_i
88
88
  end
89
+ # Pattern: /apps/{app_id}/jobs/{job_id}/trace/{trace_id} or /apps/{app_id}/jobs/{job_id}
90
+ elsif path_parts.include?("jobs")
91
+ jobs_index = path_parts.index("jobs")
92
+ if jobs_index && path_parts[jobs_index + 1]
93
+ result[:job_id] = path_parts[jobs_index + 1]
94
+ if path_parts.include?("trace")
95
+ trace_index = path_parts.index("trace")
96
+ if trace_index && path_parts[trace_index + 1]
97
+ result[:url_type] = :job_trace
98
+ result[:trace_id] = path_parts[trace_index + 1].to_i
99
+ else
100
+ result[:url_type] = :job
101
+ end
102
+ else
103
+ result[:url_type] = :job
104
+ end
105
+ result[:decoded_job] = decode_endpoint_id(result[:job_id])
106
+ end
89
107
  # Pattern: /apps/{app_id}/endpoints/{endpoint_id}
90
108
  elsif path_parts.include?("endpoints")
91
109
  result[:url_type] = :endpoint
@@ -161,6 +179,14 @@ module ScoutApmMcp
161
179
  link.split("/").last || ""
162
180
  end
163
181
 
182
+ # Job ID from a job hash returned by the jobs API
183
+ #
184
+ # @param job [Hash] Job dictionary from list_jobs
185
+ # @return [String] job_id for path parameters, or empty string
186
+ def self.get_job_id(job)
187
+ job["job_id"] || job[:job_id] || ""
188
+ end
189
+
164
190
  # Format datetime to ISO 8601 string for API
165
191
  #
166
192
  # Relies on UTC timezone. Converts the time to UTC if it's not already.
@@ -226,8 +252,10 @@ module ScoutApmMcp
226
252
  value * 60 * 60
227
253
  when /^day/
228
254
  value * 24 * 60 * 60
255
+ # :nocov:
229
256
  else
230
257
  raise ArgumentError, "Unknown time unit: #{unit}"
258
+ # :nocov:
231
259
  end
232
260
  end
233
261
 
@@ -0,0 +1,29 @@
1
+ require "securerandom"
2
+
3
+ # Monkey-patch fast-mcp so JSON-RPC error responses always include a non-nil id (strict MCP clients).
4
+ # Loaded from server only; excluded.from SimpleCov — see spec_helper.
5
+ module MCP
6
+ module Transports
7
+ class StdioTransport
8
+ if method_defined?(:send_error)
9
+ alias_method :original_send_error, :send_error
10
+
11
+ def send_error(code, message, id = nil)
12
+ id = "error_#{SecureRandom.hex(8)}" if id.nil?
13
+ original_send_error(code, message, id)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class Server
20
+ if method_defined?(:send_error)
21
+ alias_method :original_send_error, :send_error
22
+
23
+ def send_error(code, message, id = nil)
24
+ id = "error_#{SecureRandom.hex(8)}" if id.nil?
25
+ original_send_error(code, message, id)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,48 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
2
  require "fast_mcp"
5
3
  require "scout_apm_mcp"
6
4
  require "logger"
7
5
  require "stringio"
8
- require "securerandom"
6
+ require_relative "mcp_error_id_patch"
9
7
 
10
8
  # Alias MCP to FastMcp for compatibility
11
9
  FastMcp = MCP unless defined?(FastMcp)
12
10
 
13
- # Monkey-patch fast-mcp to ensure error responses always have a valid id
14
- # JSON-RPC 2.0 allows id: null for notifications, but MCP clients (Cursor/Inspector)
15
- # use strict Zod validation that requires id to be a string or number
16
- module MCP
17
- module Transports
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)
34
- alias_method :original_send_error, :send_error
35
-
36
- def send_error(code, message, id = nil)
37
- # Use placeholder id if nil to satisfy strict MCP client validation
38
- # JSON-RPC 2.0 allows null for notifications, but MCP clients require valid id
39
- id = "error_#{SecureRandom.hex(8)}" if id.nil?
40
- original_send_error(code, message, id)
41
- end
42
- end
43
- end
44
- end
45
-
46
11
  module ScoutApmMcp
47
12
  # MCP Server for ScoutAPM integration
48
13
  #
@@ -135,6 +100,10 @@ module ScoutApmMcp
135
100
  server.register_tool(ListEndpointsTool)
136
101
  server.register_tool(GetEndpointMetricsTool)
137
102
  server.register_tool(ListEndpointTracesTool)
103
+ server.register_tool(ListJobsTool)
104
+ server.register_tool(ListJobMetricsTool)
105
+ server.register_tool(GetJobMetricsTool)
106
+ server.register_tool(ListJobTracesTool)
138
107
  server.register_tool(FetchTraceTool)
139
108
  server.register_tool(ListErrorGroupsTool)
140
109
  server.register_tool(GetErrorGroupTool)
@@ -363,6 +332,83 @@ module ScoutApmMcp
363
332
  end
364
333
  end
365
334
 
335
+ class ListJobsTool < BaseTool
336
+ description <<~DESC
337
+ List background jobs for an application with performance metrics (throughput, execution time, etc.).
338
+
339
+ Time range: same as ListEndpointsTool — use range and/or from/to. If none are given, defaults to the last 7 days.
340
+
341
+ Each job includes a `job_id` (base64) for ListJobMetricsTool, GetJobMetricsTool, and ListJobTracesTool.
342
+ DESC
343
+
344
+ arguments do
345
+ required(:app_id).filled(:integer).description("ScoutAPM application ID")
346
+ optional(:range).maybe(:string).description("Quick time range: 30min, 60min, 3hrs, 6hrs, 12hrs, 1day, 3days, 7days")
347
+ optional(:from).maybe(:string).description("Start time ISO 8601. Ignored if range is provided.")
348
+ optional(:to).maybe(:string).description("End time ISO 8601; anchor for range if range is provided.")
349
+ end
350
+
351
+ def call(app_id:, range: nil, from: nil, to: nil)
352
+ get_client.list_jobs(app_id, from: from, to: to, range: range)
353
+ end
354
+ end
355
+
356
+ class ListJobMetricsTool < BaseTool
357
+ description "List available metric types for a specific background job (throughput, execution_time, latency, errors, allocations)"
358
+
359
+ arguments do
360
+ required(:app_id).filled(:integer).description("ScoutAPM application ID")
361
+ required(:job_id).filled(:string).description("Job ID (base64 URL-encoded) from list_jobs results")
362
+ end
363
+
364
+ def call(app_id:, job_id:)
365
+ get_client.list_job_metrics(app_id, job_id)
366
+ end
367
+ end
368
+
369
+ class GetJobMetricsTool < BaseTool
370
+ description <<~DESC
371
+ Get time-series data for a background job metric.
372
+
373
+ Metric types: throughput, execution_time, latency, errors, allocations (not the same set as HTTP endpoint metrics).
374
+
375
+ Use range or explicit from/to, same as GetEndpointMetricsTool.
376
+ DESC
377
+
378
+ arguments do
379
+ required(:app_id).filled(:integer).description("ScoutAPM application ID")
380
+ required(:job_id).filled(:string).description("Job ID (base64 URL-encoded)")
381
+ required(:metric_type).filled(:string).description("Job metric: throughput, execution_time, latency, errors, allocations")
382
+ optional(:range).maybe(:string).description("Quick time range template")
383
+ optional(:from).maybe(:string).description("Start time ISO 8601. Ignored if range is provided.")
384
+ optional(:to).maybe(:string).description("End time ISO 8601.")
385
+ end
386
+
387
+ def call(app_id:, job_id:, metric_type:, range: nil, from: nil, to: nil)
388
+ get_client.get_job_metrics(app_id, job_id, metric_type, from: from, to: to, range: range)
389
+ end
390
+ end
391
+
392
+ class ListJobTracesTool < BaseTool
393
+ description <<~DESC
394
+ List traces for a background job (max 100, within 7 days). Same time constraints as ListEndpointTracesTool.
395
+
396
+ Use FetchTraceTool with a trace id from results for full span detail.
397
+ DESC
398
+
399
+ arguments do
400
+ required(:app_id).filled(:integer).description("ScoutAPM application ID")
401
+ required(:job_id).filled(:string).description("Job ID (base64 URL-encoded)")
402
+ optional(:range).maybe(:string).description("Quick time range template")
403
+ optional(:from).maybe(:string).description("Start time ISO 8601; must be within last 7 days if used with to.")
404
+ optional(:to).maybe(:string).description("End time ISO 8601.")
405
+ end
406
+
407
+ def call(app_id:, job_id:, range: nil, from: nil, to: nil)
408
+ get_client.list_job_traces(app_id, job_id, from: from, to: to, range: range)
409
+ end
410
+ end
411
+
366
412
  class FetchTraceTool < BaseTool
367
413
  description "Fetch detailed trace information from ScoutAPM API"
368
414
 
@@ -522,10 +568,12 @@ module ScoutApmMcp
522
568
  Useful for extracting IDs before making other API requests.
523
569
 
524
570
  Returns a hash with:
525
- - url_type: :endpoint, :trace, :error_group, :insight, :app, or :unknown
571
+ - url_type: :endpoint, :trace, :job, :job_trace, :error_group, :insight, :app, or :unknown
526
572
  - app_id: Application ID (integer)
527
573
  - endpoint_id: Base64 URL-encoded endpoint ID (if present)
574
+ - job_id: Base64 URL-encoded job ID (if present)
528
575
  - trace_id: Trace ID (if present)
576
+ - decoded_job: Human-readable queue/job name (if job_id present)
529
577
  - error_id: Error group ID (if present)
530
578
  - insight_type: Insight type (if present)
531
579
  - decoded_endpoint: Human-readable endpoint path (if endpoint_id present)
@@ -551,7 +599,9 @@ module ScoutApmMcp
551
599
  This tool automatically parses ScoutAPM URLs and fetches the corresponding data.
552
600
  Supported URL types:
553
601
  - Endpoint URLs: /apps/{app_id}/endpoints/{endpoint_id} (fetches from endpoint list)
602
+ - Job URLs: /apps/{app_id}/jobs/{job_id} (fetches from job list)
554
603
  - Trace URLs: /apps/{app_id}/endpoints/{endpoint_id}/trace/{trace_id}
604
+ - Job trace URLs: /apps/{app_id}/jobs/{job_id}/trace/{trace_id}
555
605
  - Error group URLs: /apps/{app_id}/error_groups/{error_id}
556
606
  - Insight URLs: /apps/{app_id}/insights or /apps/{app_id}/insights/{insight_type}
557
607
  - App URLs: /apps/{app_id}
@@ -561,12 +611,12 @@ module ScoutApmMcp
561
611
  - https://scoutapm.com/apps/123/endpoints/ABC123.../trace/456 (trace)
562
612
  - https://scoutapm.com/apps/123/error_groups/789 (error group)
563
613
 
564
- For trace URLs, set include_endpoint=true to also fetch endpoint context.
614
+ For endpoint or job trace URLs, set include_endpoint=true to also fetch endpoint or job summary from the last 7 days.
565
615
  DESC
566
616
 
567
617
  arguments do
568
618
  required(:url).filled(:string).description("Full ScoutAPM URL")
569
- optional(:include_endpoint).filled(:bool).description("For trace URLs, also fetch endpoint details for context (default: false)")
619
+ optional(:include_endpoint).filled(:bool).description("For trace URLs, also fetch endpoint or job context from recent list (default: false)")
570
620
  end
571
621
 
572
622
  def call(url:, include_endpoint: false)
@@ -604,6 +654,46 @@ module ScoutApmMcp
604
654
  else
605
655
  raise "Invalid trace URL: missing app_id or trace_id"
606
656
  end
657
+ when :job_trace
658
+ if parsed[:app_id] && parsed[:trace_id]
659
+ trace_data = client.fetch_trace(parsed[:app_id], parsed[:trace_id])
660
+ result[:data] = {trace: trace_data}
661
+
662
+ if include_endpoint && parsed[:job_id]
663
+ begin
664
+ jobs = client.list_jobs(parsed[:app_id], range: "7days")
665
+ job_data = jobs.find { |j| Helpers.get_job_id(j) == parsed[:job_id] }
666
+
667
+ if job_data
668
+ result[:data][:job] = job_data
669
+ else
670
+ result[:data][:job_error] = "Job not found in the last 7 days"
671
+ end
672
+ result[:data][:decoded_job] = parsed[:decoded_job]
673
+ rescue => e
674
+ result[:data][:job_error] = "Failed to fetch job: #{e.message}"
675
+ result[:data][:decoded_job] = parsed[:decoded_job]
676
+ end
677
+ end
678
+ else
679
+ raise "Invalid job trace URL: missing app_id or trace_id"
680
+ end
681
+ when :job
682
+ if parsed[:app_id] && parsed[:job_id]
683
+ jobs = client.list_jobs(parsed[:app_id], range: "7days")
684
+ job_data = jobs.find { |j| Helpers.get_job_id(j) == parsed[:job_id] }
685
+
686
+ if job_data
687
+ result[:data] = {
688
+ job: job_data,
689
+ decoded_job: parsed[:decoded_job]
690
+ }
691
+ else
692
+ raise "Job not found in the last 7 days. Try using ListJobsTool with a longer time range."
693
+ end
694
+ else
695
+ raise "Invalid job URL: missing app_id or job_id"
696
+ end
607
697
  when :endpoint
608
698
  if parsed[:app_id] && parsed[:endpoint_id]
609
699
  endpoints = client.list_endpoints(parsed[:app_id], range: "7days")
@@ -1,3 +1,3 @@
1
1
  module ScoutApmMcp
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -5,6 +5,7 @@ module ScoutApmMcp
5
5
  def self.get_api_key: (?api_key: String?, ?op_vault: String, ?op_item: String, ?op_field: String) -> String
6
6
  def self.parse_scout_url: (String url) -> Hash[Symbol, untyped]
7
7
  def self.decode_endpoint_id: (String endpoint_id) -> String
8
+ def self.get_job_id: (Hash[String, untyped] | Hash[Symbol, untyped] job) -> String
8
9
  end
9
10
 
10
11
  class Client
@@ -18,6 +19,10 @@ module ScoutApmMcp
18
19
  def list_endpoints: (Integer app_id, ?from: String?, ?to: String?) -> Hash[String, untyped]
19
20
  def get_endpoint_metrics: (Integer app_id, String endpoint_id, String metric_type, ?from: String?, ?to: String?) -> Hash[String, untyped]
20
21
  def list_endpoint_traces: (Integer app_id, String endpoint_id, ?from: String?, ?to: String?) -> Hash[String, untyped]
22
+ def list_jobs: (Integer app_id, ?from: String?, ?to: String?, ?range: String?) -> untyped
23
+ def list_job_metrics: (Integer app_id, String job_id) -> untyped
24
+ def get_job_metrics: (Integer app_id, String job_id, String metric_type, ?from: String?, ?to: String?, ?range: String?) -> untyped
25
+ def list_job_traces: (Integer app_id, String job_id, ?from: String?, ?to: String?, ?range: String?) -> untyped
21
26
  def fetch_trace: (Integer app_id, Integer trace_id) -> Hash[String, untyped]
22
27
  def list_error_groups: (Integer app_id, ?from: String?, ?to: String?, ?endpoint: String?) -> Hash[String, untyped]
23
28
  def get_error_group: (Integer app_id, Integer error_id) -> Hash[String, untyped]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_apm_mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Makarov
@@ -305,6 +305,7 @@ files:
305
305
  - lib/scout_apm_mcp/client.rb
306
306
  - lib/scout_apm_mcp/errors.rb
307
307
  - lib/scout_apm_mcp/helpers.rb
308
+ - lib/scout_apm_mcp/mcp_error_id_patch.rb
308
309
  - lib/scout_apm_mcp/server.rb
309
310
  - lib/scout_apm_mcp/version.rb
310
311
  - sig/scout_apm_mcp.rbs