# FAQ

Distilled from the issue tracker: the questions that keep arriving, answered the way the
maintainers actually answered them, with the thread linked so you can read the reasoning in
full. Knowing these saves everyone a round trip — several are settled design decisions, and
knowing the reasoning saves you from re-arguing them by accident.

## Contributing

### Can I add support for language X?
Yes — this is the contribution the project is built to receive, and it needs no issue first.
Follow [the language-support path](030_adding-a-language); the maintainers' answer to "would
you accept this?" has consistently been yes when the work follows the established pattern
([#1598](https://github.com/oraios/serena/issues/1598),
[#1709](https://github.com/oraios/serena/issues/1709)). A request with no volunteer attached
tends to sit — the path is walked by whoever wants the language.

### Can my agent or CLI be supported as a hooks client?
Also a welcomed PR ([#1837](https://github.com/oraios/serena/issues/1837),
[#1869](https://github.com/oraios/serena/issues/1869)). The accepted shape is small and
established: a client enum entry in `src/serena/hooks.py`, a handler branch in
`src/serena/config/client_setup.py`, a context YAML under
`src/serena/resources/config/contexts/`, and docs — around 170 lines across four files
([#1581](https://github.com/oraios/serena/pull/1581) is the precedent).

### What does a fast-merging pull request look like here?
The tracker's record is consistent: a scoped fix with the root cause named in the title; an
issue first and then the PR that closes it; a language server that follows the template; a
docs correction. PRs of these shapes routinely merge within hours. Two mechanical points help:
keep **"Allow edits by maintainers"** enabled on your fork branch
([#1720](https://github.com/oraios/serena/pull/1720) had to be merged out-of-band without it),
and keep reports brief and structured — a summary first, detail beneath.

### My fix was closed and a maintainer landed a different one. Did I waste my time?
No — this is a normal outcome for fixes that touch `solidlsp` internals or bend a design
principle. The pattern in the record: the diagnosis and the test survive into the maintainer's
deeper fix, sometimes with explicit co-author credit
([#1719](https://github.com/oraios/serena/pull/1719) →
[#1726](https://github.com/oraios/serena/pull/1726)). The way to make your work land intact is
to fix the cause the design wants fixed, not the symptom in front of you — and when in doubt,
that is exactly what an issue-first conversation is for.

### Is there work I should not pick up?
Issues labeled `for core team only` are design work the maintainers have reserved — spec
discussions that end in maintainer commits, not calls for PRs. Anything beyond
`CONTRIBUTING.md`'s three welcome categories (isolated additions along existing lines, small
bug fixes, documentation) wants an issue first. And a few things are settled as out of scope:
directory badges, monetization layers, and hardening added for problems that have not been
diagnosed ([#1790](https://github.com/oraios/serena/pull/1790) carries the fullest statement
of that principle).

### My PR has had no review for days — is something wrong?
No — a few quiet days are normal here and say nothing about your PR's fate
([D1655](https://github.com/oraios/serena/discussions/1655)). Critical fixes move at once;
everything else waits for the attention it deserves rather than the first free minute.
Unhurried is not unwatched.

### Do I need an issue before sending a pull request?
For the three welcome categories — isolated additions along existing lines, small bug fixes,
documentation — no. For everything else yes, and it is enforced: design-first is house
doctrine, and code-first PRs are closed regardless of quality, up to multi-thousand-line
features ("4150 loc of changes is the limit of PRs that we accept before prior discussion in
an issue... Jokes aside", [#1330](https://github.com/oraios/serena/issues/1330); "It's not a
comment on the quality of the code", [#1234](https://github.com/oraios/serena/issues/1234)).
The maintainers frame the rule as protecting your time as much as theirs: "Our prior
discussion rule serves to ensure an optimal outcome from the get-go. Serena is not a
vibe-coded project" ([#1651](https://github.com/oraios/serena/issues/1651)); "We really
cannot skip the software design phase for changes like this"
([#1629](https://github.com/oraios/serena/issues/1629)). And expect an agreed idea to
sometimes come back smaller from a maintainer's keyboard: the polyglot proposal of
[#703](https://github.com/oraios/serena/issues/703) shipped as a net addition of under 200
lines in [#704](https://github.com/oraios/serena/issues/704).

### Why was my defensive-hardening fix or tiny config option rejected?
Because the first review question is whether the problem is real, and a hypothetical does not
count. Hardening gets asked "Has this actually happened to you?" — and an unanswered question
ends in "No response from OP, therefore closing"
([#1649](https://github.com/oraios/serena/issues/1649)). Speculative robustness is quantified
bluntly: "That's not a diagnosed problem — that's an undiagnosed CI flake, and this is 245
lines of production hardening against it"
([#1790](https://github.com/oraios/serena/issues/1790)). Config options face the same test
from the other side: the use case is interrogated ("Do you actually need the per-project
override?", [#1067](https://github.com/oraios/serena/issues/1067)) and the complexity must
pay for itself — "we can't merge something that increases complexity just to support it"
([#1016](https://github.com/oraios/serena/issues/1016)). Stopgaps for problems with a known
proper design are refused outright: "We have to do this properly or not at all"
([#932](https://github.com/oraios/serena/issues/932)). So reproduce the failure or defend the
use case in the thread — and answer review questions promptly.

### My PR was closed unmerged — or has sat open for months. What does either mean?
Often neither means what it looks like. Closed frequently means the author went quiet ("No
reaction, closing", [#1352](https://github.com/oraios/serena/issues/1352)) or closed it
themselves to resubmit a cleaner branch — and the maintainers visibly regret losing people
("may I ask why you decided to close and delete the code? :(",
[#1409](https://github.com/oraios/serena/issues/1409)). Closed can even mean *merged*: work
lands as a manually squashed commit or inside a maintainer's PR with co-author credit. Open,
conversely, is deliberate: there is no stale bot, because "We want the closing of issues/PRs
to be a deliberate decision" ([#596](https://github.com/oraios/serena/issues/596)), and some
PRs are kept open purely as design reference
([#896](https://github.com/oraios/serena/issues/896)). Age alone signals nothing; respond to
pings and keep the branch alive.

### I fixed one language server — why is it on hold, or redone at a different layer?
"On hold" here usually means "being generalised", not ignored. The maintainers consistently
prefer the general mechanism over a per-language special case: a per-LS feature gets parked
— "This is on hold as we consider centralising this in order to support this for all
language servers" ([#1544](https://github.com/oraios/serena/issues/1544), which then landed
for every server) — and a narrow fix gets replaced by one at the right layer ("a more
general fix was needed to unblock the dispatcher thread for all tool executions",
[#1746](https://github.com/oraios/serena/issues/1746)). Before adding a per-LS knob, check
whether `ls_specific_settings` or the initialization-options passthrough already covers it.
Dependency bumps follow the same logic: JDTLS version PRs were parked while downloads gained
pinning and checksum verification
([#1219](https://github.com/oraios/serena/issues/1219),
[#1238](https://github.com/oraios/serena/issues/1238)) — comment in the design issue rather
than PRing ahead of it.

### What happens to low-effort AI-generated pull requests?
They are closed without detailed review, and bluntly — "Stop submitting this AI slop"
([#1661](https://github.com/oraios/serena/issues/1661)). The tell the maintainers cite is a
description that does not match the content: "The module `mcp.server.global_check` does not
exist, the PR content is not doing what the PR description states"
([#1689](https://github.com/oraios/serena/issues/1689)). Using AI assistance is not the
offense — submitting changes you have not understood and verified is, and incoherent volume
costs you standing for everything you send afterwards.

### Can I add a tool exposing another LSP capability — hover, completions, inlay hints?
Tools are judged by whether their output helps an LLM and what it costs in tokens — not by
whether the LSP offers the data. Completions were rejected on exactly that ground
("requesting completions [is] unlikely to be useful to LLMs",
[#896](https://github.com/oraios/serena/issues/896)). Capabilities the maintainers do want,
they design and ship themselves, initially as opt-in tools — a contributed diagnostics tool
was closed with "the diagnostic feature we will incorporate is significantly more extensive"
([#661](https://github.com/oraios/serena/issues/661)), and hover docs went the same way
([#873](https://github.com/oraios/serena/issues/873)). So propose the capability in an
issue, make the LLM-utility case, and expect the core team to take the implementation over.

## Settled design decisions

### Why is Serena an MCP server rather than a CLI?
"Because language servers are stateful and so is serena"
([#1772](https://github.com/oraios/serena/issues/1772)). The session holds live language-server
processes, caches and project state; a stateless invocation model would rebuild that on every
call.

### One missing language runtime makes all symbolic tools fail — is that a bug?
Intentional, and defended when challenged ([#1670](https://github.com/oraios/serena/issues/1670)):
the configured language list expresses intent, so an unavailable server fails fast rather than
degrading silently. The per-machine escape hatch is `project.local.yml`, which can narrow the
language list without touching the shared project config.

### Can I point Serena at my own language-server binary — or plug in an external LSP client?
Custom binaries: partially, and per-language by design — the language-server-specific
settings can override the server path where a wrapper implements it, and the
dependency-provider redesign ([#917](https://github.com/oraios/serena/issues/917)) lets any
server be adapted; missing overrides get added on request, sometimes same-day
([#977](https://github.com/oraios/serena/issues/977)). External LSP *clients* — driving
Serena's servers from Neovim, say — no, and that is a position, not a gap: "Serena is a
fully integrated system where everything is finely tuned to work in unison. This is
precisely what makes Serena work so well"
([#1089](https://github.com/oraios/serena/issues/1089)).

### Can memories be shared across projects, grouped into folders, or stored outside the repo?
Yes to all three, and each ask became a shipped feature: global cross-project memories
([#1006](https://github.com/oraios/serena/issues/1006)), directory grouping
([#1055](https://github.com/oraios/serena/issues/1055)), and relocating the directory via
symlink — which works because Serena dropped symlink resolution rather than adding a
special flag ("It's unnecessarily complicated to give special treatment to symlinks",
[#936](https://github.com/oraios/serena/issues/936)). The through-line is the design:
memories are plain markdown on disk, and flexibility arrives in that shape rather than as
machinery.

## Security: what counts, and what does not

Serena's security model is documented at [Security](../02-usage/070_security), and it draws
one line worth understanding before you file anything: **what you configure is trusted.**
Your config, your projects, the tools you enable — Serena assumes you meant it.

### A scanner flagged the shell tool / gave the MCP server a low grade.

Not a security issue, and the maintainers have answered it consistently
([#1585](https://github.com/oraios/serena/issues/1585) among others): an agent's shell tool
is inherently arbitrary code execution — that is what it is for — and meaningful confinement
comes from sandboxing, not from warnings or opt-outs inside Serena. The security page says
it plainly: reports amounting to "Serena's tools can execute commands or modify files"
describe intended functionality, and advisories that fail to recognise this are rejected.

### So what does count?

Anything that crosses the trust line: a way for input you did *not* choose to trust to cause
effects you did not ask for. The verified-download machinery is a concrete example of the
model defending itself — every fetched dependency is checked against the checksum database,
because a tampered download is exactly the kind of untrusted input the model exists to
refuse. If the scenario requires you to have already trusted the thing doing the damage, it
is the documented model at work; if it does not, the maintainers want to hear about it.

### How do I report one?

Privately. The repository has GitHub's private vulnerability reporting enabled — use it
rather than a public issue, name the trust boundary being crossed, and show the crossing.
The security page's own words: advisories are welcome for issues that violate the model it
describes.

## Gotchas while working on Serena

### I changed a config file and nothing happened.
Configuration is read at startup; changes take effect after a restart
([#1798](https://github.com/oraios/serena/issues/1798)). To add a language to a running
instance, use the dashboard's add-language button. An explicitly empty language-server list is
treated as intentional, not repaired.

### I restarted the server — why is my harness still talking to the old one?
With the default `stdio` transport, your MCP client owns the server process: Serena starts
when the client connects and ends with it, so "restart the server" is a client-side act.
Tell your harness to reconnect its MCP servers — in Claude Code, `/mcp` lists them and
offers a reconnect; other clients have an equivalent — or restart the session. The reconnect
runs the launch command again, which is exactly what re-reads configuration and picks up a
rebuilt branch.

Over `sse` or `streamable-http`, the server runs on its own and the client merely attaches —
there, restarting really does mean restarting the server process yourself.

### A language has several server implementations — which one runs?
Languages are configured per project, not globally, and server priorities are configurable in
`serena_config.yml` ([#1736](https://github.com/oraios/serena/pull/1736),
[D1735](https://github.com/oraios/serena/discussions/1735)).

## Running Serena: the questions the tracker keeps answering

These are user-side rather than contributor-side, but they account for more tracker volume
than everything above combined — worth knowing whichever side you are on.

### Does Serena support monorepos and multiple languages in one project?
Yes, fully, since the `LanguageServerManager` redesign
([#704](https://github.com/oraios/serena/issues/704)): list them under `languages:` in
`.serena/project.yml`, pass several to `serena project create`, or add one at runtime from
the dashboard — "Serena now has full monorepo support, you just need to set the languages in
your project.yml" ([D542](https://github.com/oraios/serena/discussions/542)). Detection at
creation is deliberately conservative (every language is another running server), so if
symbol tools return nothing, check the detected language in `project.yml` first. One live
nuance ([#1260](https://github.com/oraios/serena/issues/1260)): activating the monorepo root
gives repo-wide symbols with the root's memories; activating a nested subproject isolates
its memories but narrows scope to that child. Older refusals of multi-server support predate
the redesign — don't cite them as current.

### Symbolic tools hang or time out while file tools keep working. What's wrong?
That split *is* the diagnosis: "If the symbolic tools do not work, it means something went
seriously wrong and the language server is not reacting"
([#336](https://github.com/oraios/serena/issues/336)). Triage in the maintainers' order:
check for an open duplicate, check `project.yml` detected the right language, and run
`serena project index` as the smoke test — if indexing does not run through, the language
server is the problem. Use the right context (`ide-assistant` for Claude Code), and for
diagnosis run with `--log-level DEBUG --trace-lsp-communication True`
([#240](https://github.com/oraios/serena/issues/240)). Years of reports carry one triage
signal: Python is stable, so if only language X hangs, it is X's server — and for old C# or
TypeScript complaints, upgrade first, because both servers were wholesale replaced.

### Serena is slow or eats RAM on my large project. What can I actually do?
Separate the first call from steady state. First call: "if a project was not previously
indexed, the first call will perform indexing of the entire project"
([#731](https://github.com/oraios/serena/issues/731)) — so pre-index with
`serena project index`, raise `--timeout` (it is per file), and shrink the surface with
`ignored_paths`. Steady state: the cost is almost always the language server itself, which
Serena cannot make faster — clangd on an llvm-scale tree projected six-plus hours, "a
limitation of the clangd language server, which is, unfortunately, slow"
([#890](https://github.com/oraios/serena/issues/890)) — so enable only the languages you
need. On Windows, exclude development directories from antivirus scanning: that, not the
file walk, was the culprit in slow-indexing reports
([#1628](https://github.com/oraios/serena/issues/1628)).

### Does Serena respect .gitignore — and why is vendor/ still being scanned?
Serena ignores everything your project's `.gitignore` ignores, plus `ignored_paths` in
`.serena/project.yml` ([#299](https://github.com/oraios/serena/issues/299)). Two deliberate
boundaries explain the surprises. The *global* gitignore is intentionally not parsed
("We discussed internally, and decided not to parse the global gitignore, at least for now",
[#577](https://github.com/oraios/serena/issues/577)). And Serena's ignore handling governs
only Serena's own tools — the language server is a separate program that scans files by its
own rules ("It is the PHP language server... which will read these files. At the Serena
level, the settings are respected", [#577](https://github.com/oraios/serena/issues/577));
tune the server itself through `ls_specific_settings`.

### Serena fails to connect or times out in my client but runs fine standalone.
The standard triage: start the launch command manually in a terminal, run
`serena project health-check`, and read `~/.serena/logs` — "If they work, the only sources
of errors can be in [the client's] MCP config or in some side effects due to many MCP
Servers being present. Maybe you need a global path to uvx…"
([#635](https://github.com/oraios/serena/issues/635)). Common culprits: a non-absolute
`uvx` path, other MCP servers interfering, a config the agent wrote for itself instead of
the readme's command, and — in headless or container setups — the dashboard trying to open
a browser (`--enable-web-dashboard false`,
[#648](https://github.com/oraios/serena/issues/648)). First-run timeouts are activation
running synchronously at startup: pre-index the project, raise the client's MCP timeout, or
run SSE mode, where the server is started once, by you
([#494](https://github.com/oraios/serena/issues/494)).

### Serena can't see files that clearly exist.
Work down the list. Gitignored files are not symbol-indexed, by design and by
recommendation ("you can adjust a corresponding setting in the config — though I wouldn't
recommend it", [#1361](https://github.com/oraios/serena/issues/1361)). Blanket ignoring of
dot-directories was removed in [#1203](https://github.com/oraios/serena/issues/1203) — only
VCS directories are skipped now, so upgrade if dot-folders still come back empty. And some
older per-language hard-coded ignore lists (Java's `dist`/`lib`/`classes`/`out`,
TypeScript's `coverage`) silently hid real code — the maintainer position is that those
lists were a mistake and `.gitignore` patterns should govern
([#1645](https://github.com/oraios/serena/issues/1645)); several are gone, so again:
upgrade.

### My agent barely uses Serena's tools and keeps reaching for grep.
Two setup steps get skipped. A project must be activated — "You cannot even use any of its
actual tools without activating a project"
([#241](https://github.com/oraios/serena/issues/241)) — and the agent should read Serena's
initial instructions at session start and again after every context compaction, "since
there is no way to know which information will get lost as a result of compacting" (same
thread). Claude Code adds a third factor: it truncates each MCP server's instructions, and
the supported fix is the serena-hooks CLI — "With this, the instructions are always fully
read and claude code uses Serena consistently"
([#1303](https://github.com/oraios/serena/issues/1303)). Beyond that, some fumbling is
model behaviour Serena cannot fix ("we're at the mercy of Anthropic here",
[#1398](https://github.com/oraios/serena/issues/1398)) — and the cap on oversized search
results is deliberate context protection, "a feature, not a bug"
([#237](https://github.com/oraios/serena/issues/237)).

### The first symbol query returns empty — or results go stale after outside edits.
Two timing bugs, now largely closed — upgrade first. Early-session emptiness came from
fixed readiness waits instead of the server's actual signal, fixed per server (pyright:
"Fixed by 30c84f15e", [#1681](https://github.com/oraios/serena/issues/1681); Scala's wait
replaced in [#1859](https://github.com/oraios/serena/issues/1859)) — on older versions,
treat an early empty as "not indexed yet", never as a real no. Post-edit staleness came
from `didChangeWatchedFiles` being advertised but never sent, fixed by syncing in the
manager ([#1718](https://github.com/oraios/serena/issues/1718)) — with the maintainer's
scoping that `find_symbol` and `get_symbols_overview` were never affected; the gap hit
`find_referencing_symbols` with an explicit path. A restart clears it on pre-fix versions.
One report in this class remains open and unreproduced
([#1593](https://github.com/oraios/serena/issues/1593)) — "it was a real phenomenon."

### Language-server processes pile up after my client exits.
Not expected — but two things are true at once. The MCP client owns the server lifecycle by
design, and "Serena already kills the language server itself in the case of regular
termination" ([#1490](https://github.com/oraios/serena/issues/1490)). What people actually
hit were leak classes on *abnormal* exits, each since fixed: the pre-stdio project scan
blind to client death ([#1685](https://github.com/oraios/serena/issues/1685)), and a
per-session zombie child ([#1488](https://github.com/oraios/serena/issues/1488)). Upgrade
first; the one still-open case is Scala's Bloop daemon surviving session kills
([#1816](https://github.com/oraios/serena/issues/1816)). If you still see orphans, report
the exact spawn-and-kill circumstances — "it ate my RAM" alone is not actionable.

### Java via Eclipse JDT-LS keeps failing. What is the recommended setup?
JDT-LS is the most fragile backend Serena wraps — "It's a fickle beast"
([#1174](https://github.com/oraios/serena/issues/1174)): slow first start, ~500 MB of
first-activation downloads, a bundled JRE that can mismatch newer source levels, and
corruptible workspace metadata whose real error hides in `.metadata/.log`. The maintainers'
standing recommendation: "I would highly recommend using Serena through the JetBrains
plugin for Java and similar languages. All such issues and many other then disappear"
([#1469](https://github.com/oraios/serena/issues/1469)). Failing that, upgrade — many
JDT-LS fixes landed on main.

### How does the JetBrains plugin relate to all this?
It is Serena's paid, more capable backend — "the Jetbrains symbol indexing is more powerful
than the LSP variant... the small fee for the plugin is so far the only way for us to get
some income from Serena" ([D903](https://github.com/oraios/serena/discussions/903)). You
still register Serena as an MCP server, selecting the backend with
`--language-backend JetBrains` or in `serena_config.yml` (per-project override exists too,
[#1031](https://github.com/oraios/serena/issues/1031)). Each new IDE release needs a new
marketplace build — approval ranges from hours to about a week, slower around holidays
([#856](https://github.com/oraios/serena/issues/856)); interim builds are on the
maintainers' release page ([#1032](https://github.com/oraios/serena/issues/1032)). Rider is
not supported ("Supporting it would effectively double all implementation efforts",
[#964](https://github.com/oraios/serena/issues/964) — though they may reconsider). And as
of early 2026, JetBrains' built-in Claude Agent could not be given MCP servers at all — a
JetBrains-side limitation ([D1045](https://github.com/oraios/serena/discussions/1045)).

### Should I install Serena through Anthropic's official Claude Code plugin?
No — configure it directly as an MCP server per Serena's docs. The maintainers' words: "The
plugin does *not* add anything extra... There's no point in using the plugin"
([#910](https://github.com/oraios/serena/issues/910)); "There are 0 benefits to installing
it as a Claude code plugin" ([#961](https://github.com/oraios/serena/issues/961)). The
wrapper lags the launch command, and Oraios cannot fix it — their PR to the plugin registry
was auto-closed because it accepts no outside contributions
([D877](https://github.com/oraios/serena/discussions/877)). It also has nothing to do with
Serena's own JetBrains plugin, whatever the similar names suggest.

### Do I need to re-run indexing to keep the cache fresh? Should .serena/cache be committed?
No and no. "The cache is always updated when file content changes... information from the
cache is never stale" ([D678](https://github.com/oraios/serena/discussions/678)) — so
`serena project index` is a startup-speed optimization for large repos, never a freshness
requirement (the one gap: the cache is not pruned, so it grows). The transient parts are
git-ignored automatically since [#283](https://github.com/oraios/serena/issues/283), and a
maintainer's own habit is ignoring the whole of `.serena`, force-adding memories when
needed ([D362](https://github.com/oraios/serena/discussions/362)). The contrast worth
remembering: the cache maintains itself; your memories do not.

---

Have a question this page should carry? Ask it on the tracker — that is where every entry
above came from.
