Code Navigation

mur code-nav setup gives an agent structural code search (ast-grep) and, if you ask for it, LSP-backed symbol lookup through serena: definitions, references and hover. Everything it installs lives under ~/.mur/tools/, and the agent's sandbox is granted exec only there.

mur code-nav setup --agent coach                                     # ast-grep only
mur code-nav setup --agent coach --with-serena --project ~/src/app   # add serena for one repo
mur code-nav setup --agent coach --with-serena --project ~/src/api --entry api

setup prints what it will install, grant and enable, then waits for you to type yes. Pass --yes to confirm the printed plan without a prompt; flags decide what the plan contains, --yes never adds to it. A re-run only asks about what changed since the last successful setup. If setup fails partway, nothing is recorded, so the next run asks again about everything, including steps that already succeeded.

One serena entry per repository

Each serena entry gets its own SERENA_HOME. Two serena processes sharing one home race on its project registry and drop a registration, so a second repo needs a second entry:

mur code-nav setup --agent coach --with-serena --project ~/src/api --entry api
Entry nameSERENA_HOME
serena (the default)<agent home>/serena
anything else<agent home>/serena-homes/<name>

The agent's tools are named after the entry, so a second entry's tools never overwrite the first's.

Entry-name rules

--entry takes 1–64 characters of lower-case a-z, 0-9, _ and -. Two more rules exist because the name also becomes the tool prefix (mcp__<name>__*):

  • It must survive tool-name sanitizing unchanged. No trailing _ and no __. serena_ and repo__a are refused, because they would share a prefix with serena and repo_a.
  • It must not share a tool prefix with another MCP server on the agent. code_nav and code/nav both become mcp__code_nav__*, so one would silently replace the other's tools and a call could land on the wrong repository.

setup checks all of this before it installs or writes anything. A refusal leaves your profile, the serena home and the consent record exactly as they were.

Upgrading from a shared home

Before per-entry homes, every entry shared <agent home>/serena. If you set up a custom-named entry back then (say code-nav), the agent now looks for serena-homes/code-nav, which was never created. Starting the agent fails with the exact line to run:

MCP server `code-nav` (kind: serena): its SERENA_HOME is now `…/serena-homes/code-nav`,
but only the older shared home `…/serena` exists … Re-run setup to create the entry's
own home: `mur code-nav setup --agent coach --with-serena --project '/path/to/repo' --entry code-nav`

Run it. Nothing is migrated: serena's config embeds absolute paths and an auth secret, and setup regenerates both. Names that were accepted before but break the rules above (a trailing _, for example) are now refused; give those entries a new name.

What stays locked down

  • Serena's config is checked before every launch, so a repository cannot swap in its own language server.
  • The binary the runtime executes is hash-pinned at setup. See MCP Binary Pinning.
  • High-risk language servers (Rust, TypeScript, Go, …) stay off unless you name them with --lsp <lang>.