# Setting it up with a coding agent

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

```elixir
# 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`:

```elixir
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`:

```elixir
# 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:

   ```sh
   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:

```sh
# 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:

```sh
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:

```elixir
# 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:

```sh
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:

```markdown
- 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.
