sidekiq-mcp 0.1.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/README.md +207 -0
- data/Rakefile +8 -0
- data/lib/sidekiq/mcp/middleware.rb +105 -0
- data/lib/sidekiq/mcp/railtie.rb +21 -0
- data/lib/sidekiq/mcp/routes.rb +17 -0
- data/lib/sidekiq/mcp/server.rb +101 -0
- data/lib/sidekiq/mcp/sse_middleware.rb +181 -0
- data/lib/sidekiq/mcp/tool.rb +56 -0
- data/lib/sidekiq/mcp/tools/clear_queue_tool.rb +30 -0
- data/lib/sidekiq/mcp/tools/dead_jobs_tool.rb +39 -0
- data/lib/sidekiq/mcp/tools/failed_jobs_tool.rb +40 -0
- data/lib/sidekiq/mcp/tools/job_class_stats_tool.rb +56 -0
- data/lib/sidekiq/mcp/tools/job_details_tool.rb +74 -0
- data/lib/sidekiq/mcp/tools/kill_job_tool.rb +40 -0
- data/lib/sidekiq/mcp/tools/list_retry_jobs_tool.rb +40 -0
- data/lib/sidekiq/mcp/tools/list_scheduled_jobs_tool.rb +36 -0
- data/lib/sidekiq/mcp/tools/process_set_tool.rb +43 -0
- data/lib/sidekiq/mcp/tools/queue_details_tool.rb +40 -0
- data/lib/sidekiq/mcp/tools/queue_health_tool.rb +79 -0
- data/lib/sidekiq/mcp/tools/remove_job_tool.rb +51 -0
- data/lib/sidekiq/mcp/tools/reschedule_job_tool.rb +38 -0
- data/lib/sidekiq/mcp/tools/retry_job_tool.rb +30 -0
- data/lib/sidekiq/mcp/tools/sidekiq_stats_tool.rb +32 -0
- data/lib/sidekiq/mcp/tools/stream_stats_tool.rb +45 -0
- data/lib/sidekiq/mcp/tools/workers_count_tool.rb +52 -0
- data/lib/sidekiq/mcp/tools.rb +148 -0
- data/lib/sidekiq/mcp/version.rb +7 -0
- data/lib/sidekiq/mcp.rb +42 -0
- data/sig/sidekiq/mcp.rbs +6 -0
- metadata +144 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class QueueHealthTool < Tool
|
10
|
+
description "Heuristics on whether queues are backed up or healthy"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
optional(:latency_threshold).filled(:integer).value(gteq?: 1)
|
14
|
+
optional(:size_threshold).filled(:integer).value(gteq?: 1)
|
15
|
+
end
|
16
|
+
|
17
|
+
def perform(latency_threshold: 60, size_threshold: 100)
|
18
|
+
queues_health = Sidekiq::Queue.all.map do |queue|
|
19
|
+
latency = queue.latency
|
20
|
+
size = queue.size
|
21
|
+
|
22
|
+
# Determine health status
|
23
|
+
health_issues = []
|
24
|
+
health_issues << "High latency (#{latency.round(2)}s)" if latency > latency_threshold
|
25
|
+
health_issues << "Large queue size (#{size} jobs)" if size > size_threshold
|
26
|
+
|
27
|
+
health_status = health_issues.empty? ? "healthy" : "warning"
|
28
|
+
health_status = "critical" if health_issues.size > 1
|
29
|
+
|
30
|
+
{
|
31
|
+
name: queue.name,
|
32
|
+
size: size,
|
33
|
+
latency: latency.round(2),
|
34
|
+
health_status: health_status,
|
35
|
+
issues: health_issues,
|
36
|
+
recommendations: generate_recommendations(health_issues, size, latency)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
overall_health = queues_health.any? { |q| q[:health_status] == "critical" } ? "critical" :
|
41
|
+
queues_health.any? { |q| q[:health_status] == "warning" } ? "warning" : "healthy"
|
42
|
+
|
43
|
+
{
|
44
|
+
overall_health: overall_health,
|
45
|
+
thresholds: {
|
46
|
+
latency_threshold: latency_threshold,
|
47
|
+
size_threshold: size_threshold
|
48
|
+
},
|
49
|
+
queues: queues_health
|
50
|
+
}.to_json
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def generate_recommendations(issues, size, latency)
|
56
|
+
recommendations = []
|
57
|
+
|
58
|
+
if issues.any? { |i| i.include?("latency") }
|
59
|
+
recommendations << "Consider adding more workers or optimizing job performance"
|
60
|
+
end
|
61
|
+
|
62
|
+
if issues.any? { |i| i.include?("size") }
|
63
|
+
recommendations << "Queue is backing up - check for worker issues or increase concurrency"
|
64
|
+
end
|
65
|
+
|
66
|
+
if size > 1000
|
67
|
+
recommendations << "Very large queue - consider splitting into smaller queues or adding priority"
|
68
|
+
end
|
69
|
+
|
70
|
+
if latency > 300
|
71
|
+
recommendations << "Extremely high latency - immediate attention required"
|
72
|
+
end
|
73
|
+
|
74
|
+
recommendations
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class RemoveJobTool < Tool
|
10
|
+
description "Remove a job from any set (queue/schedule/retry/dead) by JID"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
required(:jid).filled(:string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform(jid:)
|
17
|
+
# Try to find and remove from retry set
|
18
|
+
retry_set = Sidekiq::RetrySet.new
|
19
|
+
if (job = retry_set.find_job(jid))
|
20
|
+
job.delete
|
21
|
+
return "Job #{jid} removed from retry set"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Try to find and remove from scheduled set
|
25
|
+
scheduled_set = Sidekiq::ScheduledSet.new
|
26
|
+
if (job = scheduled_set.find_job(jid))
|
27
|
+
job.delete
|
28
|
+
return "Job #{jid} removed from scheduled set"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Try to find and remove from dead set
|
32
|
+
dead_set = Sidekiq::DeadSet.new
|
33
|
+
if (job = dead_set.find_job(jid))
|
34
|
+
job.delete
|
35
|
+
return "Job #{jid} removed from dead set"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Try to find and remove from queues
|
39
|
+
Sidekiq::Queue.all.each do |queue|
|
40
|
+
if (job = queue.find_job(jid))
|
41
|
+
job.delete
|
42
|
+
return "Job #{jid} removed from queue '#{queue.name}'"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
"Job #{jid} not found in any queue or set"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class RescheduleJobTool < Tool
|
10
|
+
description "Reschedule a job in the scheduled set to a new time"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
required(:jid).filled(:string)
|
14
|
+
required(:new_time).filled(:string) # ISO 8601 format
|
15
|
+
end
|
16
|
+
|
17
|
+
def perform(jid:, new_time:)
|
18
|
+
begin
|
19
|
+
new_timestamp = Time.parse(new_time)
|
20
|
+
rescue ArgumentError
|
21
|
+
return "Invalid time format. Please use ISO 8601 format (e.g., '2024-12-25T10:00:00Z')"
|
22
|
+
end
|
23
|
+
|
24
|
+
scheduled_set = Sidekiq::ScheduledSet.new
|
25
|
+
job = scheduled_set.find_job(jid)
|
26
|
+
|
27
|
+
if job
|
28
|
+
old_time = job.at
|
29
|
+
job.reschedule(new_timestamp)
|
30
|
+
"Job #{jid} rescheduled from #{old_time} to #{new_timestamp}"
|
31
|
+
else
|
32
|
+
"Job #{jid} not found in scheduled set"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class RetryJobTool < Tool
|
10
|
+
description "Retry a specific failed job by its JID"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
required(:jid).filled(:string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform(jid:)
|
17
|
+
retry_set = Sidekiq::RetrySet.new
|
18
|
+
job = retry_set.find_job(jid)
|
19
|
+
|
20
|
+
if job
|
21
|
+
job.retry
|
22
|
+
"Job #{jid} has been retried successfully"
|
23
|
+
else
|
24
|
+
"Job #{jid} not found in retry set"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class SidekiqStatsTool < Tool
|
10
|
+
description "Get general Sidekiq statistics including processed, failed, busy, enqueued counts"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
# No arguments needed for general stats
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform
|
17
|
+
stats = Sidekiq::Stats.new
|
18
|
+
{
|
19
|
+
processed: stats.processed,
|
20
|
+
failed: stats.failed,
|
21
|
+
busy: stats.workers_size,
|
22
|
+
enqueued: stats.enqueued,
|
23
|
+
scheduled: stats.scheduled_size,
|
24
|
+
retry: stats.retry_size,
|
25
|
+
dead: stats.dead_size,
|
26
|
+
default_queue_latency: stats.default_queue_latency
|
27
|
+
}.to_json
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class StreamStatsTool < Tool
|
10
|
+
description "Start streaming real-time Sidekiq statistics (use with SSE)"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
optional(:interval).filled(:integer).value(gteq?: 1, lteq?: 300) # 1-300 seconds
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform(interval: 5)
|
17
|
+
# This tool is designed to work with SSE streaming
|
18
|
+
# In a real implementation, this would start a background task
|
19
|
+
# For now, we'll return the current stats with streaming info
|
20
|
+
|
21
|
+
stats = Sidekiq::Stats.new
|
22
|
+
current_stats = {
|
23
|
+
timestamp: Time.now.utc.iso8601,
|
24
|
+
processed: stats.processed,
|
25
|
+
failed: stats.failed,
|
26
|
+
busy: stats.workers_size,
|
27
|
+
enqueued: stats.enqueued,
|
28
|
+
scheduled: stats.scheduled_size,
|
29
|
+
retry: stats.retry_size,
|
30
|
+
dead: stats.dead_size,
|
31
|
+
processes: stats.processes_size,
|
32
|
+
default_queue_latency: stats.default_queue_latency
|
33
|
+
}
|
34
|
+
|
35
|
+
{
|
36
|
+
message: "Stats streaming initiated with #{interval}s interval",
|
37
|
+
current_stats: current_stats,
|
38
|
+
sse_endpoint: "/sidekiq-mcp/sse",
|
39
|
+
note: "Connect to SSE endpoint to receive real-time updates"
|
40
|
+
}.to_json
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../tool"
|
4
|
+
require "sidekiq/api"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Mcp
|
8
|
+
module Tools
|
9
|
+
class WorkersCountTool < Tool
|
10
|
+
description "Show how many workers are running and busy"
|
11
|
+
|
12
|
+
arguments do
|
13
|
+
# No arguments needed
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform
|
17
|
+
processes = Sidekiq::ProcessSet.new
|
18
|
+
|
19
|
+
total_workers = 0
|
20
|
+
busy_workers = 0
|
21
|
+
processes_info = []
|
22
|
+
|
23
|
+
processes.each do |process|
|
24
|
+
process_workers = process["concurrency"] || 0
|
25
|
+
process_busy = process["busy"] || 0
|
26
|
+
|
27
|
+
total_workers += process_workers
|
28
|
+
busy_workers += process_busy
|
29
|
+
|
30
|
+
processes_info << {
|
31
|
+
hostname: process["hostname"],
|
32
|
+
pid: process["pid"],
|
33
|
+
concurrency: process_workers,
|
34
|
+
busy: process_busy,
|
35
|
+
utilization: process_workers > 0 ? ((process_busy.to_f / process_workers) * 100).round(2) : 0,
|
36
|
+
started_at: process["started_at"]
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
{
|
41
|
+
total_processes: processes.size,
|
42
|
+
total_workers: total_workers,
|
43
|
+
busy_workers: busy_workers,
|
44
|
+
idle_workers: total_workers - busy_workers,
|
45
|
+
overall_utilization: total_workers > 0 ? ((busy_workers.to_f / total_workers) * 100).round(2) : 0,
|
46
|
+
processes: processes_info
|
47
|
+
}.to_json
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Mcp
|
5
|
+
module Tools
|
6
|
+
end
|
7
|
+
|
8
|
+
class ToolsRegistry
|
9
|
+
def initialize
|
10
|
+
register_all_tools
|
11
|
+
end
|
12
|
+
|
13
|
+
def list
|
14
|
+
@tools.values
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(tool_name, arguments)
|
18
|
+
tool_class = @tool_classes[tool_name]
|
19
|
+
return "Unknown tool: #{tool_name}" unless tool_class
|
20
|
+
|
21
|
+
begin
|
22
|
+
tool_instance = tool_class.new
|
23
|
+
tool_instance.call(**arguments.transform_keys(&:to_sym))
|
24
|
+
rescue => e
|
25
|
+
"Error executing tool #{tool_name}: #{e.message}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def register_all_tools
|
32
|
+
@tools = {}
|
33
|
+
@tool_classes = {}
|
34
|
+
|
35
|
+
# Auto-discover all tool classes
|
36
|
+
tool_classes = [
|
37
|
+
Tools::SidekiqStatsTool,
|
38
|
+
Tools::QueueDetailsTool,
|
39
|
+
Tools::RetryJobTool,
|
40
|
+
Tools::FailedJobsTool,
|
41
|
+
Tools::JobClassStatsTool,
|
42
|
+
Tools::JobDetailsTool,
|
43
|
+
Tools::ListScheduledJobsTool,
|
44
|
+
Tools::ListRetryJobsTool,
|
45
|
+
Tools::DeadJobsTool,
|
46
|
+
Tools::WorkersCountTool,
|
47
|
+
Tools::QueueHealthTool,
|
48
|
+
Tools::RemoveJobTool,
|
49
|
+
Tools::ClearQueueTool,
|
50
|
+
Tools::RescheduleJobTool,
|
51
|
+
Tools::KillJobTool,
|
52
|
+
Tools::ProcessSetTool,
|
53
|
+
Tools::StreamStatsTool
|
54
|
+
]
|
55
|
+
|
56
|
+
# Also register original legacy tools
|
57
|
+
register_legacy_tools
|
58
|
+
|
59
|
+
tool_classes.each do |tool_class|
|
60
|
+
tool_def = tool_class.to_tool_definition
|
61
|
+
@tools[tool_def[:name]] = tool_def
|
62
|
+
@tool_classes[tool_def[:name]] = tool_class
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def register_legacy_tools
|
67
|
+
# List queues tool
|
68
|
+
@tools["list_queues"] = {
|
69
|
+
name: "list_queues",
|
70
|
+
description: "List all Sidekiq queues with their sizes and latency information",
|
71
|
+
inputSchema: {
|
72
|
+
type: "object",
|
73
|
+
properties: {},
|
74
|
+
required: []
|
75
|
+
}
|
76
|
+
}
|
77
|
+
@tool_classes["list_queues"] = Class.new(Tool) do
|
78
|
+
def perform
|
79
|
+
queues = Sidekiq::Queue.all.map do |queue|
|
80
|
+
{
|
81
|
+
name: queue.name,
|
82
|
+
size: queue.size,
|
83
|
+
latency: queue.latency
|
84
|
+
}
|
85
|
+
end
|
86
|
+
queues.to_json
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Busy workers tool
|
91
|
+
@tools["busy_workers"] = {
|
92
|
+
name: "busy_workers",
|
93
|
+
description: "List currently busy workers and their job details",
|
94
|
+
inputSchema: {
|
95
|
+
type: "object",
|
96
|
+
properties: {},
|
97
|
+
required: []
|
98
|
+
}
|
99
|
+
}
|
100
|
+
@tool_classes["busy_workers"] = Class.new(Tool) do
|
101
|
+
def perform
|
102
|
+
workers = Sidekiq::Workers.new.map do |process_id, thread_id, work|
|
103
|
+
{
|
104
|
+
process_id: process_id,
|
105
|
+
thread_id: thread_id,
|
106
|
+
queue: work["queue"],
|
107
|
+
class: work["payload"]["class"],
|
108
|
+
args: work["payload"]["args"],
|
109
|
+
jid: work["payload"]["jid"],
|
110
|
+
run_at: work["run_at"]
|
111
|
+
}
|
112
|
+
end
|
113
|
+
workers.to_json
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Delete failed job tool
|
118
|
+
@tools["delete_failed_job"] = {
|
119
|
+
name: "delete_failed_job",
|
120
|
+
description: "Delete a specific failed job by its JID",
|
121
|
+
inputSchema: {
|
122
|
+
type: "object",
|
123
|
+
properties: {
|
124
|
+
jid: {
|
125
|
+
type: "string",
|
126
|
+
description: "Job ID of the failed job to delete"
|
127
|
+
}
|
128
|
+
},
|
129
|
+
required: ["jid"]
|
130
|
+
}
|
131
|
+
}
|
132
|
+
@tool_classes["delete_failed_job"] = Class.new(Tool) do
|
133
|
+
def perform(jid:)
|
134
|
+
retry_set = Sidekiq::RetrySet.new
|
135
|
+
job = retry_set.find_job(jid)
|
136
|
+
|
137
|
+
if job
|
138
|
+
job.delete
|
139
|
+
"Job #{jid} has been deleted successfully"
|
140
|
+
else
|
141
|
+
"Job #{jid} not found in retry set"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
data/lib/sidekiq/mcp.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "mcp/version"
|
4
|
+
require_relative "mcp/tool"
|
5
|
+
require_relative "mcp/server"
|
6
|
+
require_relative "mcp/tools"
|
7
|
+
require_relative "mcp/middleware"
|
8
|
+
require_relative "mcp/sse_middleware"
|
9
|
+
require_relative "mcp/routes"
|
10
|
+
|
11
|
+
# Load all tool classes
|
12
|
+
Dir[File.join(__dir__, "mcp/tools/*.rb")].each { |file| require file }
|
13
|
+
|
14
|
+
if defined?(Rails)
|
15
|
+
require_relative "mcp/railtie"
|
16
|
+
end
|
17
|
+
|
18
|
+
module Sidekiq
|
19
|
+
module Mcp
|
20
|
+
class Error < StandardError; end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_accessor :configuration
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.configure
|
27
|
+
self.configuration ||= Configuration.new
|
28
|
+
yield(configuration)
|
29
|
+
end
|
30
|
+
|
31
|
+
class Configuration
|
32
|
+
attr_accessor :enabled, :path, :auth_token, :sse_enabled
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
@enabled = true
|
36
|
+
@path = "/sidekiq-mcp"
|
37
|
+
@auth_token = nil
|
38
|
+
@sse_enabled = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/sig/sidekiq/mcp.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sidekiq-mcp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Nesbitt
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: sidekiq
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '6.0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '6.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rack
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: base64
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: dry-schema
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.13'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.13'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rack-test
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
description: A Sidekiq plugin that provides an MCP (Model Context Protocol) server
|
83
|
+
for LLMs to interact with Sidekiq queues, stats, and failed jobs
|
84
|
+
email:
|
85
|
+
- andrewnez@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- CHANGELOG.md
|
91
|
+
- CODE_OF_CONDUCT.md
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- lib/sidekiq/mcp.rb
|
95
|
+
- lib/sidekiq/mcp/middleware.rb
|
96
|
+
- lib/sidekiq/mcp/railtie.rb
|
97
|
+
- lib/sidekiq/mcp/routes.rb
|
98
|
+
- lib/sidekiq/mcp/server.rb
|
99
|
+
- lib/sidekiq/mcp/sse_middleware.rb
|
100
|
+
- lib/sidekiq/mcp/tool.rb
|
101
|
+
- lib/sidekiq/mcp/tools.rb
|
102
|
+
- lib/sidekiq/mcp/tools/clear_queue_tool.rb
|
103
|
+
- lib/sidekiq/mcp/tools/dead_jobs_tool.rb
|
104
|
+
- lib/sidekiq/mcp/tools/failed_jobs_tool.rb
|
105
|
+
- lib/sidekiq/mcp/tools/job_class_stats_tool.rb
|
106
|
+
- lib/sidekiq/mcp/tools/job_details_tool.rb
|
107
|
+
- lib/sidekiq/mcp/tools/kill_job_tool.rb
|
108
|
+
- lib/sidekiq/mcp/tools/list_retry_jobs_tool.rb
|
109
|
+
- lib/sidekiq/mcp/tools/list_scheduled_jobs_tool.rb
|
110
|
+
- lib/sidekiq/mcp/tools/process_set_tool.rb
|
111
|
+
- lib/sidekiq/mcp/tools/queue_details_tool.rb
|
112
|
+
- lib/sidekiq/mcp/tools/queue_health_tool.rb
|
113
|
+
- lib/sidekiq/mcp/tools/remove_job_tool.rb
|
114
|
+
- lib/sidekiq/mcp/tools/reschedule_job_tool.rb
|
115
|
+
- lib/sidekiq/mcp/tools/retry_job_tool.rb
|
116
|
+
- lib/sidekiq/mcp/tools/sidekiq_stats_tool.rb
|
117
|
+
- lib/sidekiq/mcp/tools/stream_stats_tool.rb
|
118
|
+
- lib/sidekiq/mcp/tools/workers_count_tool.rb
|
119
|
+
- lib/sidekiq/mcp/version.rb
|
120
|
+
- sig/sidekiq/mcp.rbs
|
121
|
+
homepage: https://github.com/andrew/sidekiq-mcp
|
122
|
+
licenses: []
|
123
|
+
metadata:
|
124
|
+
homepage_uri: https://github.com/andrew/sidekiq-mcp
|
125
|
+
source_code_uri: https://github.com/andrew/sidekiq-mcp
|
126
|
+
changelog_uri: https://github.com/andrew/sidekiq-mcp/blob/main/CHANGELOG.md
|
127
|
+
rdoc_options: []
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 3.2.0
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
requirements: []
|
141
|
+
rubygems_version: 3.6.9
|
142
|
+
specification_version: 4
|
143
|
+
summary: Sidekiq MCP server plugin for LLM integration
|
144
|
+
test_files: []
|