airbrake_mcp 1.0.3 → 1.0.4

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: 722e5cf91d2f23f4723ce52aecf454c9e4dd6371e6388dbcd9d2dfb4703cf9f8
4
- data.tar.gz: df24d6787c6ee9abb46783e58c87cc4b7c56a6999db39b657ee556099f7ca674
3
+ metadata.gz: 7ed4e827382daeb7329a9b383855ae55ab2c26e337585c753d80aaddeebf5179
4
+ data.tar.gz: 4b96efeffd6206d6cee8f5459f32e8a61cdba1b2ba03985a2b1767c51ef6c689
5
5
  SHA512:
6
- metadata.gz: e078d5b0fb0435dd004ddb9ddf8654ac705a265469ea19025a8a01e7b9ea5cc1b6fde09ba457887efbafa54bf3f7386962ccd61497db9cc910f4bcbe77184b7b
7
- data.tar.gz: 9fd4a9aefc16035ef2c0633a54a5083c6c0e2100fe3a6fb695cae8c3218dbcf6a0862fb5adde30269c0d5885afa2ea0bf8a31bef3eed6ad1b42f04587611dc9c
6
+ metadata.gz: 21e39e8a19ba4f93d450cb6029cc42075ae270ed86bedae141ca59bd62c7ca34aa7ab4e051e2d86a19e7f0342440a4e389481657aa733ff49ae8e789a12e0775
7
+ data.tar.gz: 795083e21d0151602d6bbefc6a28c3b33659594370497e574e3c2f8c66721312d069c4824828ebf4c63c863ac05532793ccb8ac277020b8c42c4f20a019d2899
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.4] - 2026-01-06
4
+
5
+ ### Fixed
6
+ - Fixed API URL path construction (removed leading slashes causing requests to bypass /api/v4 path)
7
+ - Fixed MCP response serialization (workaround for MCP gem bug where Content objects aren't converted to hashes)
8
+
3
9
  ## [1.0.3] - 2026-01-06
4
10
 
5
11
  ### Fixed
@@ -15,36 +15,36 @@ module AirbrakeMcp
15
15
  attr_reader :project_id
16
16
 
17
17
  def projects
18
- get('/projects')['projects']
18
+ get('projects')['projects']
19
19
  end
20
20
 
21
21
  def groups(project_id: @project_id, page: 1, limit: 20)
22
- get("/projects/#{project_id}/groups", { page: page, limit: limit })
22
+ get("projects/#{project_id}/groups", { page: page, limit: limit })
23
23
  end
24
24
 
25
25
  def group(group_id, project_id: @project_id)
26
- get("/projects/#{project_id}/groups/#{group_id}")
26
+ get("projects/#{project_id}/groups/#{group_id}")
27
27
  end
28
28
 
29
29
  def notices(group_id, project_id: @project_id, page: 1, limit: 10)
30
- get("/projects/#{project_id}/groups/#{group_id}/notices", { page: page, limit: limit })
30
+ get("projects/#{project_id}/groups/#{group_id}/notices", { page: page, limit: limit })
31
31
  end
32
32
 
33
33
  # Write operations
34
34
  def resolve_group(group_id, project_id: @project_id)
35
- put("/projects/#{project_id}/groups/#{group_id}/resolved")
35
+ put("projects/#{project_id}/groups/#{group_id}/resolved")
36
36
  end
37
37
 
38
38
  def unresolve_group(group_id, project_id: @project_id)
39
- put("/projects/#{project_id}/groups/#{group_id}/unresolved")
39
+ put("projects/#{project_id}/groups/#{group_id}/unresolved")
40
40
  end
41
41
 
42
42
  def mute_group(group_id, project_id: @project_id)
43
- put("/projects/#{project_id}/groups/#{group_id}/muted")
43
+ put("projects/#{project_id}/groups/#{group_id}/muted")
44
44
  end
45
45
 
46
46
  def unmute_group(group_id, project_id: @project_id)
47
- put("/projects/#{project_id}/groups/#{group_id}/unmuted")
47
+ put("projects/#{project_id}/groups/#{group_id}/unmuted")
48
48
  end
49
49
 
50
50
  private
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AirbrakeMcp
4
+ module ResponseHelper
5
+ # Workaround for MCP gem bug where Content objects aren't converted to hashes
6
+ # in Response#to_h. This creates responses with pre-converted content.
7
+ def self.text_response(text, error: false)
8
+ MCP::Tool::Response.new([{ type: "text", text: text }], error: error)
9
+ end
10
+ end
11
+ end
@@ -19,24 +19,16 @@ module AirbrakeMcp
19
19
  pid = project_id || client.project_id
20
20
 
21
21
  unless pid
22
- return MCP::Tool::Response.new([
23
- MCP::Content::Text.new("Error: No project_id specified and no default configured")
24
- ], error: true)
22
+ return ResponseHelper.text_response("Error: No project_id specified and no default configured", error: true)
25
23
  end
26
24
 
27
25
  group = client.group(group_id, project_id: pid)
28
26
 
29
- MCP::Tool::Response.new([
30
- MCP::Content::Text.new(Formatters.format_group_detail(group))
31
- ])
27
+ ResponseHelper.text_response(Formatters.format_group_detail(group))
32
28
  rescue Client::NotFoundError
33
- MCP::Tool::Response.new([
34
- MCP::Content::Text.new("Error: Error group #{group_id} not found")
35
- ], error: true)
29
+ ResponseHelper.text_response("Error: Error group #{group_id} not found", error: true)
36
30
  rescue Client::ApiError => e
37
- MCP::Tool::Response.new([
38
- MCP::Content::Text.new("Error: #{e.message}")
39
- ], error: true)
31
+ ResponseHelper.text_response("Error: #{e.message}", error: true)
40
32
  end
41
33
  end
42
34
  end
@@ -21,9 +21,7 @@ module AirbrakeMcp
21
21
  pid = project_id || client.project_id
22
22
 
23
23
  unless pid
24
- return MCP::Tool::Response.new([
25
- MCP::Content::Text.new("Error: No project_id specified and no default configured")
26
- ], error: true)
24
+ return ResponseHelper.text_response("Error: No project_id specified and no default configured", error: true)
27
25
  end
28
26
 
29
27
  result = client.groups(project_id: pid, page: page, limit: limit)
@@ -33,13 +31,9 @@ module AirbrakeMcp
33
31
  result['groups'] = result['groups'].select { |g| g['resolved'] == resolved }
34
32
  end
35
33
 
36
- MCP::Tool::Response.new([
37
- MCP::Content::Text.new(Formatters.format_groups(result))
38
- ])
34
+ ResponseHelper.text_response(Formatters.format_groups(result))
39
35
  rescue Client::ApiError => e
40
- MCP::Tool::Response.new([
41
- MCP::Content::Text.new("Error: #{e.message}")
42
- ], error: true)
36
+ ResponseHelper.text_response("Error: #{e.message}", error: true)
43
37
  end
44
38
  end
45
39
  end
@@ -21,24 +21,16 @@ module AirbrakeMcp
21
21
  pid = project_id || client.project_id
22
22
 
23
23
  unless pid
24
- return MCP::Tool::Response.new([
25
- MCP::Content::Text.new("Error: No project_id specified and no default configured")
26
- ], error: true)
24
+ return ResponseHelper.text_response("Error: No project_id specified and no default configured", error: true)
27
25
  end
28
26
 
29
27
  result = client.notices(group_id, project_id: pid, page: page, limit: limit)
30
28
 
31
- MCP::Tool::Response.new([
32
- MCP::Content::Text.new(Formatters.format_notices(result))
33
- ])
29
+ ResponseHelper.text_response(Formatters.format_notices(result))
34
30
  rescue Client::NotFoundError
35
- MCP::Tool::Response.new([
36
- MCP::Content::Text.new("Error: Error group #{group_id} not found")
37
- ], error: true)
31
+ ResponseHelper.text_response("Error: Error group #{group_id} not found", error: true)
38
32
  rescue Client::ApiError => e
39
- MCP::Tool::Response.new([
40
- MCP::Content::Text.new("Error: #{e.message}")
41
- ], error: true)
33
+ ResponseHelper.text_response("Error: #{e.message}", error: true)
42
34
  end
43
35
  end
44
36
  end
@@ -10,13 +10,9 @@ module AirbrakeMcp
10
10
  client = server_context[:client]
11
11
  projects = client.projects
12
12
 
13
- MCP::Tool::Response.new([
14
- MCP::Content::Text.new(Formatters.format_projects(projects))
15
- ])
13
+ ResponseHelper.text_response(Formatters.format_projects(projects))
16
14
  rescue Client::ApiError => e
17
- MCP::Tool::Response.new([
18
- MCP::Content::Text.new("Error: #{e.message}")
19
- ], error: true)
15
+ ResponseHelper.text_response("Error: #{e.message}", error: true)
20
16
  end
21
17
  end
22
18
  end
@@ -20,9 +20,7 @@ module AirbrakeMcp
20
20
  pid = project_id || client.project_id
21
21
 
22
22
  unless pid
23
- return MCP::Tool::Response.new([
24
- MCP::Content::Text.new("Error: No project_id specified and no default configured")
25
- ], error: true)
23
+ return ResponseHelper.text_response("Error: No project_id specified and no default configured", error: true)
26
24
  end
27
25
 
28
26
  if mute
@@ -33,17 +31,11 @@ module AirbrakeMcp
33
31
  action = "unmuted"
34
32
  end
35
33
 
36
- MCP::Tool::Response.new([
37
- MCP::Content::Text.new("Error group ##{group_id} #{action}")
38
- ])
34
+ ResponseHelper.text_response("Error group ##{group_id} #{action}")
39
35
  rescue Client::NotFoundError
40
- MCP::Tool::Response.new([
41
- MCP::Content::Text.new("Error: Error group #{group_id} not found")
42
- ], error: true)
36
+ ResponseHelper.text_response("Error: Error group #{group_id} not found", error: true)
43
37
  rescue Client::ApiError => e
44
- MCP::Tool::Response.new([
45
- MCP::Content::Text.new("Error: #{e.message}")
46
- ], error: true)
38
+ ResponseHelper.text_response("Error: #{e.message}", error: true)
47
39
  end
48
40
  end
49
41
  end
@@ -20,9 +20,7 @@ module AirbrakeMcp
20
20
  pid = project_id || client.project_id
21
21
 
22
22
  unless pid
23
- return MCP::Tool::Response.new([
24
- MCP::Content::Text.new("Error: No project_id specified and no default configured")
25
- ], error: true)
23
+ return ResponseHelper.text_response("Error: No project_id specified and no default configured", error: true)
26
24
  end
27
25
 
28
26
  if resolved
@@ -33,17 +31,11 @@ module AirbrakeMcp
33
31
  action = "unresolved"
34
32
  end
35
33
 
36
- MCP::Tool::Response.new([
37
- MCP::Content::Text.new("Error group ##{group_id} marked as #{action}")
38
- ])
34
+ ResponseHelper.text_response("Error group ##{group_id} marked as #{action}")
39
35
  rescue Client::NotFoundError
40
- MCP::Tool::Response.new([
41
- MCP::Content::Text.new("Error: Error group #{group_id} not found")
42
- ], error: true)
36
+ ResponseHelper.text_response("Error: Error group #{group_id} not found", error: true)
43
37
  rescue Client::ApiError => e
44
- MCP::Tool::Response.new([
45
- MCP::Content::Text.new("Error: #{e.message}")
46
- ], error: true)
38
+ ResponseHelper.text_response("Error: #{e.message}", error: true)
47
39
  end
48
40
  end
49
41
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AirbrakeMcp
4
- VERSION = '1.0.3'
4
+ VERSION = '1.0.4'
5
5
  end
data/lib/airbrake_mcp.rb CHANGED
@@ -5,6 +5,7 @@ require 'mcp'
5
5
  require_relative 'airbrake_mcp/version'
6
6
  require_relative 'airbrake_mcp/client'
7
7
  require_relative 'airbrake_mcp/formatters'
8
+ require_relative 'airbrake_mcp/response_helper'
8
9
  require_relative 'airbrake_mcp/tools/list_projects'
9
10
  require_relative 'airbrake_mcp/tools/list_errors'
10
11
  require_relative 'airbrake_mcp/tools/get_error'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airbrake_mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - httplab
@@ -95,6 +95,7 @@ files:
95
95
  - lib/airbrake_mcp.rb
96
96
  - lib/airbrake_mcp/client.rb
97
97
  - lib/airbrake_mcp/formatters.rb
98
+ - lib/airbrake_mcp/response_helper.rb
98
99
  - lib/airbrake_mcp/tools/get_error.rb
99
100
  - lib/airbrake_mcp/tools/list_errors.rb
100
101
  - lib/airbrake_mcp/tools/list_notices.rb