Repository: tidewave-ai/tidewave_phoenix
Pull request #125 (2025-07-13 18:43:01)

Return regular text in get_ecto_schema

josevalim: If we accept this, I need to update `tidewave_rails`.

Patch:
diff --git a/lib/tidewave/mcp/tools/ecto.ex b/lib/tidewave/mcp/tools/ecto.ex
index 22b17ea..2122d1e 100644
--- a/lib/tidewave/mcp/tools/ecto.ex
+++ b/lib/tidewave/mcp/tools/ecto.ex
@@ -2,6 +2,7 @@ defmodule Tidewave.MCP.Tools.Ecto do
   @moduledoc false
 
   alias Tidewave.MCP.Tools.Source
+  @limit 50
 
   def tools do
     if repos_configured?() do
@@ -19,9 +20,9 @@ defmodule Tidewave.MCP.Tools.Ecto do
           Executes the given SQL query against the given default or specified Ecto repository.
           Returns the result as an Elixir data structure.
 
-          Note that the output is limited to 50 rows at a time. If you need to see more, perform additional calls
-          using LIMIT and OFFSET in the query. If you know that only specific columns are relevant,
-          only include those in the SELECT clause.
+          Note that the output is limited to #{@limit} rows at a time. If you need to see more,
+          perform additional calls using LIMIT and OFFSET in the query. If you know that only
+          specific columns are relevant, only include those in the SELECT clause.
 
           You can use this tool to select user data, manipulating entries, and introspect the application data domain.
           Always ensure to use the correct SQL commands for the database you are using. The description of the
@@ -89,20 +90,24 @@ defmodule Tidewave.MCP.Tools.Ecto do
         repo -> Module.concat([repo])
       end
 
-    limit = Keyword.get(assigns.inspect_opts, :limit, 50)
-
     case repo.query(query, args["arguments"] || []) do
       {:ok, result} ->
-        preamble =
+        {preamble, result} =
           case result do
-            %{num_rows: num_rows} when num_rows > limit ->
-              "Query returned #{num_rows} rows. Only the first #{limit} rows are included in the result. Use LIMIT + OFFSET in your query to show more rows if applicable.\n\n"
+            %{num_rows: num_rows, rows: rows} when num_rows > @limit ->
+              {"""
+               Query returned #{num_rows} rows. Only the first #{@limit} rows \
+               are included in the result. Use LIMIT + OFFSET in your query \
+               to show more rows if applicable.\n\n\
+               """, %{result | rows: Enum.take(rows, 50)}}
 
             _ ->
-              ""
+              {"", result}
           end
 
-        {:ok, preamble <> inspect(result, assigns.inspect_opts)}
+        # We already limited the results above
+        inspect_opts = Keyword.put(assigns.inspect_opts, :limit, :infinity)
+        {:ok, preamble <> inspect(result, inspect_opts)}
 
       {:error, reason} ->
         {:error, "Failed to execute query: #{inspect(reason, assigns.inspect_opts)}"}
@@ -119,17 +124,17 @@ defmodule Tidewave.MCP.Tools.Ecto do
           Code.ensure_loaded?(module),
           function_exported?(module, :__changeset__, 0) do
         case Source.get_source_location(%{"reference" => inspect(module)}) do
-          {:ok, source_file} ->
-            %{module: inspect(module), source_file: source_file}
+          {:ok, source_location} ->
+            "* #{inspect(module)} at #{source_location}"
 
           _ ->
-            %{module: inspect(module), source_file: nil}
+            "* #{inspect(module)}"
         end
       end
 
     case schemas do
       [] -> {:error, "No Ecto schemas found in the project"}
-      schemas -> {:ok, Jason.encode!(schemas)}
+      schemas -> {:ok, Enum.join(schemas, "\n")}
     end
   end
 


Test patch:
diff --git a/test/mcp/tools/ecto_test.exs b/test/mcp/tools/ecto_test.exs
index 17de346..c37a754 100644
--- a/test/mcp/tools/ecto_test.exs
+++ b/test/mcp/tools/ecto_test.exs
@@ -146,11 +146,11 @@ defmodule Tidewave.MCP.Tools.EctoTest do
             "query" => "SELECT lotsofrows",
             "arguments" => []
           },
-          Tidewave.init(inspect_opts: [limit: 10])
+          Tidewave.init([])
         )
 
-      assert text =~ "Query returned 100 rows. Only the first 10 rows are included in the result."
-      assert text =~ "5, 6, 7"
+      assert text =~ "Query returned 100 rows. Only the first 50 rows are included in the result."
+      refute text =~ "51"
     end
   end
 
@@ -173,10 +173,7 @@ defmodule Tidewave.MCP.Tools.EctoTest do
       end)
 
       {:ok, text} = Ecto.get_ecto_schemas(%{})
-
-      assert Jason.decode!(text) == [
-               %{"module" => "TestSchema", "source_file" => "test/mcp/tools/ecto_test.exs"}
-             ]
+      assert text == "* TestSchema at test/mcp/tools/ecto_test.exs"
     end
   end
 end