Skip to content
cd /languages
  • Concurrent BEAM
  • Programming
  • AST and symbol support

Elixir Support in Maguyva: Code Graphs for Phoenix and OTP Apps

Maguyva parses Elixir with AST, symbol, and graph support, so AI agents can follow modules, behaviours, protocols, and structs across Phoenix and OTP code.

Where Elixir trips up shallow AI tools

Almost everything in Elixir is a macro call. defmodule, def, use, alias, and @impl all parse as calls, and use GenServer brings in behaviour that never appears in the file. A tool that only sees call syntax cannot tell a definition from a dependency, or a GenServer callback from a helper.

Maguyva maps those macros onto relationships, so an agent can see which modules implement a behaviour and who calls a context function.

What Maguyva extracts in Elixir

Maguyva covers .ex and .exs files. Elixir’s macros map onto relationships:

  • alias, import, and require record imports.
  • use records an import. For OTP and framework behaviours such as GenServer, Supervisor, Agent, Task, Phoenix.Controller, Phoenix.LiveView, and Ecto.Schema, it also records that the module implements that behaviour.
  • @behaviour attributes and defimpl blocks record implementation of a behaviour or protocol.
  • Reserved module attributes such as @doc, @spec, @impl, and @callback are recorded as annotations on the function that follows. Value attributes such as @timeout 5_000 are not.
  • %User{} struct literals count as instantiation, raise records a throw, and rescue and catch record a catch.

Language macros such as def, defp, defmodule, case, and with are filtered from calls, so the call graph shows your functions.

Example agent prompts

  • “Who calls Accounts.register_user, and from which controllers?” (find_symbol, then dependency_search incoming)
  • “Which modules implement GenServer?” (dependency_search)
  • “Trace a checkout request from the controller to the database.” (get_task_context)

Known limits

  • Named def, defmodule, alias, and import forms are call nodes in the grammar, so only the functions preset in structural_search returns results, and only for anonymous fn functions. Use find_symbol for named functions and modules.
  • About 55 standard-library calls, such as IO.puts, String.*, Enum.take, and Process.*, are filtered from relationships. Use text_pattern_search for them.
  • Elixir has no class inheritance, so inheritance relationships are marked not applicable.

Next steps

Connect a repository with the quickstart, then check the support matrix on the compatibility page. For other functional codebases, read the Haskell guide.

Best fit

  • > Phoenix applications where controllers, LiveViews, contexts, and Ecto schemas call each other across many modules.
  • > OTP systems built from GenServers, supervisors, and tasks.
  • > Libraries and umbrella projects with protocols implemented for many types.

Agent workflows

  • > Find every caller of a context function before changing its return shape.
  • > List which modules implement a behaviour or protocol before adding a callback.
  • > Trace a request from a Phoenix controller into the Ecto layer.

Engine details

  • > Elixir support covers `.ex` and `.exs`. `alias`, `import`, `require`, and `use` record imports.
  • > `use GenServer` and other listed OTP and framework behaviours, `@behaviour`, and `defimpl` record implementation relationships.
  • > Reserved attributes such as `@spec` and `@impl` annotate the next function, and `%Struct{}` literals count as instantiation.

Useful MCP entry points

  • find_symbol

    Use it for a context function or module when you need the definition and callers; structural presets do not select named `def` forms.

  • dependency_search

    Use incoming traversal on a behaviour or protocol to see which modules implement it.

  • get_task_context

    Use it for prompts like “trace a checkout request from the controller to the database.”