Skip to content

Commit 9b6449b

Browse files
committed
fix(mcp): correct package and release data mapping in MCP tools
- Fix package.repository -> package.repository_name field reference - Fix release.metadata -> release.meta with proper map/JSON string handling - Fix release.retirement -> release.retired (boolean to retirement info map) - Add normalize_meta/1 helper to handle both map and JSON string meta formats - Add format_retirement_info/1 to convert boolean retired status to info map - Update format_release/1 to use format_retirement_info(release.retired) - Update get_meta_field/3 to handle both map and JSON string meta types - Remove unused get_retirement_info/1 function
1 parent e3f0ee6 commit 9b6449b

File tree

1 file changed

+44
-18
lines changed

1 file changed

+44
-18
lines changed

lib/hex_hub/mcp/tools/packages.ex

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ defmodule HexHub.MCP.Tools.Packages do
6060
releases: formatted_releases,
6161
total_releases: length(releases),
6262
latest_version: get_latest_version(releases),
63-
repository: get_repository_info(package.repository)
63+
repository: get_repository_info(package.repository_name)
6464
}
6565

6666
{:ok, result}
@@ -124,15 +124,16 @@ defmodule HexHub.MCP.Tools.Packages do
124124

125125
case Packages.get_release(name, version) do
126126
{:ok, release} ->
127-
metadata = Jason.decode!(release.metadata || "{}")
127+
# Release has `meta` field which can be a map or JSON string
128+
metadata = normalize_meta(release.meta)
128129

129130
result = %{
130131
name: name,
131132
version: release.version,
132133
metadata: metadata,
133134
requirements: parse_requirements(release.requirements),
134135
has_docs: release.has_docs,
135-
retirement_info: get_retirement_info(release)
136+
retirement_info: format_retirement_info(release.retired)
136137
}
137138

138139
{:ok, result}
@@ -170,7 +171,7 @@ defmodule HexHub.MCP.Tools.Packages do
170171
defp format_package(package) do
171172
%{
172173
name: package.name,
173-
repository: package.repository,
174+
repository: package.repository_name,
174175
description: get_meta_field(package.meta, "description"),
175176
licenses: get_meta_field(package.meta, "licenses", []),
176177
links: get_meta_field(package.meta, "links", %{}),
@@ -187,19 +188,42 @@ defmodule HexHub.MCP.Tools.Packages do
187188
version: release.version,
188189
has_docs: release.has_docs,
189190
inserted_at: release.inserted_at,
190-
retirement_info: get_retirement_info(release),
191+
retirement_info: format_retirement_info(release.retired),
191192
url: build_release_url(release),
192193
html_url: build_release_html_url(release)
193194
}
194195
end
195196

196197
defp get_meta_field(meta, field, default \\ nil) do
197-
case Jason.decode(meta || "{}") do
198-
{:ok, decoded} -> Map.get(decoded, field, default)
199-
{:error, _} -> default
198+
cond do
199+
# Meta is already a map (most common case in HexHub)
200+
is_map(meta) ->
201+
Map.get(meta, field) || Map.get(meta, String.to_atom(field)) || default
202+
203+
# Meta is a JSON string
204+
is_binary(meta) ->
205+
case Jason.decode(meta || "{}") do
206+
{:ok, decoded} -> Map.get(decoded, field, default)
207+
{:error, _} -> default
208+
end
209+
210+
# Meta is nil or other
211+
true ->
212+
default
200213
end
201214
end
202215

216+
defp normalize_meta(meta) when is_map(meta), do: meta
217+
218+
defp normalize_meta(meta) when is_binary(meta) do
219+
case Jason.decode(meta) do
220+
{:ok, decoded} -> decoded
221+
{:error, _} -> %{}
222+
end
223+
end
224+
225+
defp normalize_meta(_), do: %{}
226+
203227
defp get_latest_version([]), do: nil
204228

205229
defp get_latest_version(releases) do
@@ -229,17 +253,19 @@ defmodule HexHub.MCP.Tools.Packages do
229253

230254
defp parse_requirements(requirements) when is_map(requirements), do: requirements
231255

232-
defp get_retirement_info(release) do
233-
case release.retirement do
234-
nil ->
235-
nil
256+
# Format retirement info from release.retired (boolean or map)
257+
defp format_retirement_info(false), do: nil
258+
defp format_retirement_info(nil), do: nil
236259

237-
retirement ->
238-
%{
239-
reason: retirement.reason,
240-
message: retirement.message
241-
}
242-
end
260+
defp format_retirement_info(true) do
261+
%{reason: "unknown", message: "This release has been retired"}
262+
end
263+
264+
defp format_retirement_info(retirement) when is_map(retirement) do
265+
%{
266+
reason: Map.get(retirement, :reason) || Map.get(retirement, "reason"),
267+
message: Map.get(retirement, :message) || Map.get(retirement, "message")
268+
}
243269
end
244270

245271
# URL builders

0 commit comments

Comments
 (0)