Setting it up with a coding agent

Copy Markdown View Source

A checklist a coding agent (Claude Code, Codex, Cursor...) can follow to install the toolbar in a Phoenix app, with its MCP server, agent skill and usage rules. Point your agent at this page: "install phoenix_dev_toolbar following https://hexdocs.pm/phoenix_dev_toolbar/agent-setup.html".

Each step says what to change and how to check it. Stop and ask the user when a check fails or a step needs a choice they did not make.

0. Read the app first

Find, without changing anything:

  • The Elixir, Phoenix and LiveView versions (mix.exs, mix.lock). Required: Elixir 1.17+, Phoenix 1.8+, LiveView 1.1+.
  • The endpoint module (lib/<app>_web/endpoint.ex) and its if code_reloading? do block.
  • The Ecto repos (config :<app>, ecto_repos: [...]), if any.
  • The dev server's address and port: http: [ip: ..., port: ...] for the endpoint in config/dev.exs, or a PORT read in config/runtime.exs. Default localhost:4000. Call it <host>:<port> below.
  • Any existing phoenix_dev_toolbar dependency (often a github: or path: one), plug or config: update those instead of adding duplicates.
  • The agent instructions file (AGENTS.md or CLAUDE.md) and whether it holds a <!-- usage-rules-start --> ... <!-- usage-rules-end --> block (apps generated by phx.new 1.8 do).

1. Dependency

# mix.exs, deps/0: replace any github: or path: entry
{:phoenix_dev_toolbar, "~> 0.0.2", only: :dev}

Run mix deps.get. Keep only: :dev: the toolbar must not exist in prod or test builds.

2. The plug

Inside the endpoint's existing if code_reloading? do block, next to Phoenix.LiveReloader:

if code_reloading? do
  # ...
  plug PhoenixDevToolbar.Plug
end

This is the only code change. Do not add a router route, an import, a layout change or an app.js change: none is needed, and anything outside that block breaks the production build.

3. Config

In config/dev.exs:

# Only when the app has no :ecto_repos, or the toolbar should watch other repos
config :phoenix_dev_toolbar, repos: [MyApp.Repo]

# On each repo's existing dev config: shows the code line behind each query
config :my_app, MyApp.Repo, stacktrace: true

Everything else is optional (README, "Configuration"). Leave it out unless the user asks.

4. Check the install

  1. mix compile --warnings-as-errors passes.

  2. MIX_ENV=prod mix compile still passes (the dependency is absent there). Skip it if the app cannot compile in prod locally (missing prod secrets) and say so.

  3. With the dev server running (the user's, or one you start), load a page as HTML:

    curl -s -H "Accept: text/html" http://<host>:<port>/ | grep -c "data-pdt-sid"
    

    1 means the toolbar's loader was injected. 0 on a page that answered 200 HTML means the plug is not reached: recheck step 2 and that MIX_ENV=dev.

5. MCP server

The toolbar serves MCP at http://<host>:<port>/__pdt/mcp while the dev server runs. Add it to the project config of the agent in use:

# Claude Code: writes .mcp.json
claude mcp add --transport http --scope project phoenix-dev-toolbar http://<host>:<port>/__pdt/mcp

# Codex: writes ~/.codex/config.toml
codex mcp add phoenix-dev-toolbar --url http://<host>:<port>/__pdt/mcp

Other clients (Cursor, VS Code) and the JSON forms are in the README, "MCP server". If the project already has an .mcp.json, add the phoenix-dev-toolbar entry to its mcpServers instead of replacing the file.

Check it, with the dev server running:

curl -s -X POST -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"ping"}' http://<host>:<port>/__pdt/mcp

A JSON result means it works. A 403 or a refused connection: README, "Troubleshooting". The agent picks up a new MCP server only after a restart or a reconnect (/mcp in Claude Code, which also asks the user to approve a project server once): tell the user.

6. Agent skill and usage rules

The package ships a skill, phoenix-dev-toolbar-report (measure a page before and after a change), and usage-rules.md (how to read the toolbar's data). Install the skill with one of these.

With usage_rules (keeps them in sync on upgrades). Add the dependency and a skills-only config:

# mix.exs, deps/0
{:usage_rules, "~> 1.3", only: :dev}

# mix.exs, project/0
usage_rules: [skills: [package_skills: [:phoenix_dev_toolbar]]]

If the app already has a usage_rules: config, add :phoenix_dev_toolbar to its skills: [package_skills: [...]] list instead. Then mix deps.get and mix usage_rules.sync. It writes .claude/skills/phoenix-dev-toolbar-report/SKILL.md (change the directory with skills: [location: ...]). Commit it.

Without usage_rules: copy the skill directory from the dependency, and repeat the copy after each upgrade:

mkdir -p .claude/skills
cp -r deps/phoenix_dev_toolbar/usage-rules/skills/phoenix-dev-toolbar-report .claude/skills/

For the usage rules, add one line to the agent instructions file, outside any usage-rules block:

- Before checking how a page behaves at runtime (queries, N+1, LiveView timings, errors), read `deps/phoenix_dev_toolbar/usage-rules.md`.

Do not add file: and usage_rules: [:phoenix_dev_toolbar] to the usage_rules config unless the user asks: mix usage_rules.sync then rewrites the whole block between <!-- usage-rules-start --> and <!-- usage-rules-end -->, and drops every section not listed (the Phoenix rules phx.new put there, and any hand edits). When the user wants it, list every package whose rules the block should keep, and review the diff of the instructions file after the sync.

7. Done when

  • The dependency is only: :dev, the plug sits inside if code_reloading?, and both compiles of step 4 pass.
  • The page curl shows the toolbar and the MCP ping answers.
  • The skill is in the agent's skills directory, and the instructions file points at the usage rules.
  • You told the user to restart or reconnect the agent for the MCP server, and which files changed.