@@ -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