plugins-claude/serena/skills/serena-cheatsheet/SKILL.md
Quirks and pitfalls for the Serena MCP server. Use before calling any `mcp__serena__*` tool, or when planning code navigation, refactors, or renames in a Serena-active project. Covers Rust impl-method syntax, 0-based lines, replace_symbol_body doc-comment hazard, and rename semantics.
npx skillsauth add st0nefish/claude-toolkit serena-cheatsheetInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Serena exposes language-server-driven code intelligence over MCP. It's genuinely better than grep for symbol-aware operations — but it has sharp edges that aren't in the official docs. This skill documents them.
name_path matches the symbol tree within a source file. Conventions vary
by language:
| Language | Pattern | Example |
|----------|---------|---------|
| Python | Class/method | MyClass/__init__ |
| Java | Class/method[i] (overload index) | MyClass/format[1] |
| Rust | impl Type/method | impl App/select_next_running |
Rust gotcha: the impl prefix is required. Querying App/select_next_running
returns empty even though the method exists. This is not in Serena's docs — it
only surfaces from the name_path field in find_referencing_symbols output.
Free functions and types are bare:
find_symbol("ComposeCmd") — returns the enumfind_symbol("run_compose") — returns the free functionEvery line number Serena emits — in body_location, content_around_reference,
or safe_delete_symbol refusal output — is 0-based. Everything else
(grep, cargo errors, your editor, git blame) is 1-based.
When cross-referencing with other tools, add 1.
replace_symbol_body silently deletes doc commentsThis is the highest-impact pitfall. Reading a symbol via find_symbol with
include_body=true returns the body without preceding doc comments — the docs
explicitly state this. But replace_symbol_body's replacement scope does
include the doc comment. So a "round-trip" replace (read body → write body
back) silently destroys any rustdoc, Python docstring before a function (in
some languages), or ///-style comment block.
Before calling replace_symbol_body:
Verify with git diff after every replace_symbol_body call.
rename_symbol is identifier-aware (not text-aware)This is the biggest win over grep-based rename. rename_symbol updates the
target identifier across the codebase via the language server, so:
print_summary everywhere it's used as a complete identifierprint_summary_to (different identifier)test_print_summary_* test functionsAlways verify with two checks:
grep -rn '<old_name>' src/ # any survivors?
cargo check # or your language's typecheck
Test function names and rustdoc references usually need a follow-up pass.
The "N changes applied" return count is files modified, not sites updated.
safe_delete_symbol returns 0-based references on refusalWhen a symbol still has references, safe_delete_symbol refuses and returns:
{"src/runner.rs": [390, 405], "src/main.rs": [21, 291]}
These are 0-based line numbers. Add 1 to match grep / editor output.
find_referencing_symbols is verbose — every reference in a match arm or
repeated test call gets its own entry with surrounding context. A query for a
heavily-used symbol can return 30KB+ of JSON.
Bound output up front:
| Param | Use case |
|-------|----------|
| relative_path | Restrict to one file/dir — single biggest reduction |
| max_matches | Cap result count; result indicates "more available" |
| max_answer_chars | Hard cap; returns nothing if exceeded (forces refinement) |
When you genuinely just want a count or simple list, drop to grep. Serena's
own instruction manual permits grep/glob for discovery — use them.
For verbose meta-analysis questions ("blast radius of renaming X", "call graph
of run_compose two levels deep"), spawn the serena-explorer subagent —
it absorbs the verbose output and returns a concise synthesis.
Serena's instruction manual (loaded when its tools first activate) declares
Read and Edit "FORBIDDEN" for code files in favor of symbolic tools. In
practice this is mostly correct but situational:
The forbidden framing in Serena's manual is overzealous — judgment still applies.
This installation has Serena's memory tools (write_memory, read_memory,
list_memories, etc.) explicitly disabled. The onboarding flow is also
disabled.
Project context lives in source-controlled files (CLAUDE.md, README.md,
.serena/project.yml). Do not try to invoke memory tools — they will not
appear in the available tool list.
| Want to | Tool |
|---------|------|
| See symbols in a file | get_symbols_overview |
| Read a symbol's body | find_symbol with include_body=true |
| Find callers / references | find_referencing_symbols |
| Rename across files | rename_symbol |
| Add code after a symbol | insert_after_symbol |
| Replace a symbol's definition | replace_symbol_body (⚠️ doc comments) |
| Delete an unreferenced symbol | safe_delete_symbol |
| Edit a few lines inside a symbol | replace_content (regex) |
| Count usages of a string | grep -c |
| Heavy meta-analysis | spawn serena-explorer agent |
development
Start work from your description — explore the codebase and plan
data-ai
Multi-phase, multi-agent feature workflow: spec → plan → refine → divide → execute → review. Invoke when the user escalates a session-start/session-issue flow to orchestration, or asks to run a non-trivial feature (multiple files, design ambiguity, cross-cutting concerns, correctness-critical paths) through the full multi-agent workflow. For small fixes, prefer session-start.
tools
Browse open issues, pick one, and start work on it
tools
Interact with GitHub and Gitea issue trackers and CI systems. List and show issues, file bugs, comment on issues or PRs, list and show pull requests, and fetch CI run logs — all from any repo context without leaving the session.