Serena MCP Server: Edycja kodu z uwzględnieniem symboli dla asystentów AI
Ustaw Serena za pomocą Dockera i SSE, aby Claude Code, VS Code oraz OpenCode mogły korzystać z wyszukiwania symboli wspieranego przez LSP, bezpiecznego przemianowywania nazw oraz pamięci trwałej przy mniejszej liczbie tokenów.
Źródła: Serena MCP: Giving Your AI Coding Tools an IDE Brain
Serena to serwer MCP o otwartym kodzie źródłowym, który zapewnia asystentom do programowania opartym na AI zrozumienie bazy kodu w stylu IDE. Próbowano go w monorepo z TypeScript i efekt jest wyraźny: asystent lepiej rozumie kod i potrzebuje na to mniej tokenów.
Podczas gdy typowy asystent widzi pliki pełne tekstu, Serena łączy się z backendem protokołu Language Server Protocol – silnikiem odpowiedzialnym za funkcje takie jak „Idź do definicji”, „Znajdź wszystkie odniesienia” oraz bezpieczne przemiany nazw w edytorze – i udostępnia te funkcje jako narzędzia MCP dla dowolnego kompatybilnego klienta. Wszystko działa na lokalnym komputerze, obsługiwane są ponad 30 języków, a do kompatybilnych klientów należą Claude Code, VS Code, Cursor, OpenCode oraz Claude Desktop.
Co idzie nie tak przy zwykłym wyszukiwaniu w tekście
Jeśli poprosisz asystenta o znalezienie wszystkich funkcji zajmujących się autoryzacją, standardowa procedura wygląda następująco:
- Przeprowadź wyszukiwanie tekstowe za pomocą
greplubripgreppod kątem słowa „authentication”. - Przeczytaj odpowiadające pliki, czasami całe, wprowadzając tysiące wierszy do kontekstu.
- Zwróć każdy wiersz zawierający tę sekwencję, włączając komentarze, literale tekstowe oraz niepowiązane wyniki.
To jest w porządku dla małego projektu, ale staje się trudne w miarę rozwoju bazy kodu. Cztery codzienne zadania pokazują tę różnicę:
+----------------------------+-------------------------------------+--------------------------------------------+
| Task | Without Serena | With Serena |
+============================+=====================================+============================================+
| **Semantic search** | Text match on "auth" - returns | Returns `authenticateUser()`, |
| "find auth functions" | false positives, misses functions | `login()`, `verifyCredentials()` |
| | named `verifyCredentials` | with file locations and line numbers |
+----------------------------+-------------------------------------+--------------------------------------------+
| **Go to definition** | Searches files for "User" and | Jumps directly to the `User` |
| "show me the User schema" | "schema" - returns every reference | class/interface definition with |
| | | full import tree |
+----------------------------+-------------------------------------+--------------------------------------------+
| **Find references** | Text search for "PaymentProcessor" | Returns all usages with context: |
| "where is | - misses dynamic usages | imports, instantiations, method calls |
| PaymentProcessor used?" | | |
+----------------------------+-------------------------------------+--------------------------------------------+
| **Cross-file refactoring** | Text search and replace - misses | Semantic rename via LSP - updates |
| "rename UserService | string interpolations or aliased | every reference correctly across |
| to AccountService" | imports, breaks things | the entire codebase |
+----------------------------+-------------------------------------+--------------------------------------------+
Koszt tokenów pogłębia ten problem. Bez narzędzi semantycznych asystent czyta całe pliki, aby zrozumieć ich strukturę, a następnie przechowuje ten tekst w kontekście. Dzięki Serena pojedyncze wywołanie find_symbol("UserService") zwraca dokładnie to, co jest potrzebne.
Praca na poziomie symboli
Serena indeksuje projekt za pomocą prawdziwego serwera językowego i tworzy mapę relacyjną: które funkcje wywołują które, gdzie są definiowane typy oraz co importuje co. Gdy asystent musi zrozumieć lub zmienić kod, korzysta z tych narzędzi zamiast prostego czytania i zapisywania plików:
find_symbollokalizuje symbol podając jego nazwę i może zwrócić jego pełny tekst.get_symbols_overviewtworzy mapę symboli w pliku lub katalogu bez konieczności czytania źródła.find_referencing_symbolswyświetla wszystkie miejsca wywołania i użycia danego symbolu w całym kodzie.
rename_symbol zmienia nazwę za pośrednictwem LSP, aktualizując każdą odniesienie.replace_symbol_body zastępuje treść funkcji lub klasy, pozostawiając bez zmian otaczający kod.insert_before_symbol oraz insert_after_symbol dodają kod w dokładnie określonej pozycji semantycznej.LLM nie edytuje linijka po linijce, unikając w ten sposób ryzyka utraty jakiegoś odniesienia. Przekazuje edycję Serenie, która pracuje na podstawie zindeksowanych danych oraz serwera językowego, dzięki czemu edycje uwzględniają wszystkie odniesienia. Symbol użyty w 20 miejscach jest aktualizowany we wszystkich 20. Dokumentacja projektu wymienia każde narzędzie serwera językowego.
Pamięć i panel sterowania
Każdy projekt posiada również trwałe miejsce przechowywania pamięci. W miarę jak asystent poznaje konwencje, pułapki i decyzje architektoniczne, może je zapisywać jako notatki. Przetrwają one ponowne uruchomienie rozmowy i będą dostępne w następnej sesji, dzięki czemu praca nie musi zaczynać się od zera.
Panel internetowy dostępny pod adresem http://localhost:24282/dashboard/index.html jest włączony domyślnie i pokazuje, co robi Serena:
- Przegląd sesji i aktywnych projektów
- Rejestr wywołań narzędzi z statystykami dotyczącymi tych narzędzi, jak często i przez jak długi czas były używane
- Łączne logi serwera
- Edytor konfiguracji, dzięki któremu ustawienia można zmieniać bez restartu
- Menedżer pamięci do przeglądania i edytowania gromadzonych notatek projektowych
- Kontrolery serwera
Na macOS i Windows dostępny jest również natywny element menu systemowego, natomiast w Linux funkcjonuje wyłącznie w przeglądarce.
Lista narzędzi jest określana przez konteksty
Z góry zdefiniowane konteksty decydują, które narzędzia są dostępne. Chodzi o to, że klient może już sam obsługiwać niektóre funkcje w sposób natywny, takie jak czytanie plików lub wykonywanie poleceń w shellu, więc Serena unika ich duplikowania i utrzymuje listę narzędzi uporządkowaną.
+---------------------+------------------------------+------------------------------------------------+
| Context | Designed for | What it does |
+=====================+==============================+================================================+
| `desktop-app` | Claude Desktop, general use | **Full toolset** - everything Serena offers. |
| | | Use this when the client has no built-in |
| | | coding capabilities. This is also the right |
| | | choice for a shared Docker instance serving |
| | | multiple different clients. |
+---------------------+------------------------------+------------------------------------------------+
| `claude-code` | Claude Code | Disables tools that overlap with Claude |
| | | Code's built-in capabilities (file edits, |
| | | shell commands, etc.) to avoid conflicts. |
| | | Single-project context. |
+---------------------+------------------------------+------------------------------------------------+
| `ide` | VS Code, Cursor, Cline, Kilo | Generic IDE augmentation - focuses on |
| | | semantic tools, assumes the IDE already |
| | | handles basic file operations. |
| | | Single-project context. |
+---------------------+------------------------------+------------------------------------------------+
| `agent` | Agno, autonomous agents | Broader autonomy for agents that drive the |
| | | full workflow independently. |
+---------------------+------------------------------+------------------------------------------------+
| `codex` | OpenAI Codex | Optimized for Codex's tool calling format. |
+---------------------+------------------------------+------------------------------------------------+
| NOTE: The `claude-code` and `ide` contexts are **single-project**: when you pass a project |
| path at startup, those contexts lock down to only the tools relevant to that project and |
| disable the project-switching tool entirely (since you won't need it). |
+---------------------+------------------------------+------------------------------------------------+
Dla jednego kontenera Docker obsługującego jednocześnie Claude Code, VS Code i OpenCode należy użyć desktop-app, który jest ich supersetem. Gdy Serena jest uruchamiana lokalnie dla każdego klienta, należy wybrać kontekst odpowiadający temu narzędziu.
Instalacja
Należy użyć uv. Własna dokumentacja Sereny ostrzega przed marketplacami MCP, które często dostarczają przestarzałe polecenia:
uv tool install -p 3.13 serena-agent@latest --prerelease=allow
serena init
To instaluje serena CLI globalnie i uruchamia przewodnik konfiguracji. Następnie konfigurowane są klienci.
Claude Code, globalnie (zalecane):
claude mcp add --scope user serena -- serena start-mcp-server \
--context claude-code --project-from-cwdlaude mcp add serena -- serena start-mcp-server --context claude-code --project "$(pwd)"
Claude Code, według projektu:
claude mcp add serena -- serena start-mcp-server --context claude-code --project "$(pwd)"
VS Code, w pliku .vscode/mcp.json znajdującym się w korzeniu projektu:
{
"servers": {
"serena": {
"type": "stdio",
"command": "serena",
"args": [
"start-mcp-server",
"--context", "ide",
"--project", "${workspaceFolder}"
]
}
}
}
Claude Desktop, w pliku ~/.config/claude_desktop_config.json w systemie Linux lub ~/Library/Application Support/Claude/claude_desktop_config.json w systemie macOS:
{
"mcpServers": {
"serena": {
"command": "serena",
"args": ["start-mcp-server", "--context", "desktop-app"]
}
}
}
Uruchamianie w Dockerze
Docker to podejście preferowane przez dokumentację Serena do izolacji, szczególnie gdy agent ma dostęp do edycji. W kontenerze może on widzieć jedynie katalogi zamontowane w nim. Przykład wpisu w compose.yml:
services:
serena:
image: ghcr.io/oraios/serena:latest
container_name: myproject-serena
restart: unless-stopped
environment:
- SERENA_DOCKER=1
ports:
- "10121:9121" # SSE endpoint
- "34282:24282" # Web dashboard
volumes:
- .:/workspace/myproject
command: >
serena start-mcp-server
--transport sse
--port 9121
--host 0.0.0.0
--context desktop-app
--project /workspace/myproject
Uwagi dotyczące tej konfiguracji:
--transport ssemusi być ustawiony wewnątrz Dockera, ponieważstdiomoże działać tylko wtedy, gdy klient uruchamia samą Serena jako proces potomny.--context desktop-appudostępnia najszerszy zestaw narzędzi i nadaje się zarówno dla Claude Code, rozszerzeń VS Code, jak i OpenCode. Szersze konteksty, takie jakclaude-code, wyłączają narzędzia, od których zależą inne klienci.--project /workspace/myprojectmusi być ścieżką wewnątrz kontenera, gdzie montowany jest kod. Unikaj tutaj użycia--project-from-cwd, ponieważ katalog roboczy kontenera to lokalizacja instalacji Sereny, a nie projekt.- Niezwykłe porty hosta (
10121i34282) umożliwiają kilku projektom uruchamianie własnych instancji Sereny bez konfliktów.
Gdy ustawiono SERENA_DOCKER=1, Serena wie, że znajduje się w kontenerze. Globalny plik ~/.serena/serena_config.yml, zamontowany w ramach konfiguracji lub włączony do niej, powinien zawierać ustawienia przyjazne dla kontenerów:
gui_log_window: false
web_dashboard_listen_address: "0.0.0.0"
web_dashboard_open_on_launch: false
Aby zainstalować konfigurację hosta, dodaj mapowanie wolumenu ~/.serena:/root/.serena. Uruchom usługę:
docker compose up -d serena
Łączenie klientów z kontenerem
Każdy klient komunikuje się z tym samym punktem końcowym SSE, a różni się jedynie formatem konfiguracji. Claude Code może go zarejestrować globalnie:
claude mcp add serena --transport sse --url http://localhost:10121/sse
Lub projekt może zawierać plik .mcp.json:
{
"mcpServers": {
"serena": {
"type": "sse",
"url": "http://localhost:10121/sse"
}
}
}
VS Code oczekuje pliku .vscode/mcp.json:
{
"servers": {
"serena": {
"type": "sse",
"url": "http://localhost:10121/sse"
}
}
}
OpenCode używa opencode.jsonc:
{
"mcp": {
"serena": {
"type": "remote",
"url": "http://localhost:10121/sse",
"enabled": true
}
}
}
Codex, Kilo Code oraz inne klienty kompatybilne z MCP działają w podobny sposób.
Konfiguracja projektu
Serena czyta plik .serena/project.yml znajdujący się w korzeniu projektu. Praktyczna konfiguracja TypeScript zaczyna się od określenia nazwy:
project_name: "myproject"
Następnie języki i zignoruj zasady:
languages:
- typescript # uses typescript-language-serverencoding: "utf-8"
ignore_all_files_in_gitignore: trueignored_paths:
- "node_modules"
- "dist"
- "build"
- "coverage"
- ".next"
- "out"
- ".cache"
Lista ignored_paths stanowi dodatkową ochronę obok pliku .gitignore. Sam folder node_modules może zawierać ponad 80 000 plików, a ich indeksowanie powoduje bardzo wolne uruchamianie aplikacji oraz zasłanianie wyników wyszukiwania symboli elementami wewnętrznymi zewnętrznych bibliotek.
Co komitować, a co ignorować:
.serena/project.yml ← commit this (shared config)
.serena/memories/ ← commit this (AI-generated project notes, useful for everyone)
.serena/cache/ ← gitignore (rebuilt per machine)
.serena/project.local.yml ← gitignore (per-developer overrides)
Jakie zmiany w praktyce
W monorepo Deno 2 i TypeScript z interfejsem użytkownika, API oraz wspólnymi pakietami wyróżniają się cztery aspekty:
- Rozwiązywanie problemów pomiędzy pakietami. Dzięki temu, że całe monorepo jest montowane jako jeden obszar pracy, Serena w jednym kroku śledzi typ z katalogu
packages/aż do jego użycia w plikach podapps/api/, podczas gdy wcześniej asystent musiał czytać plik po pliku i łączyć informacje ręcznie. - Bezpieczniejsze refaktoryzacje. Zadanie polegające na zmianie nazwy wspólnej interfejsu, obejmujące około 20 plików, zostało przeprowadzone za pomocą funkcji
rename_symbolbez pominięcia żadnego elementu. Funkcja wyszukiwania i zastępowania tekstu zawsze pomija jedno dynamiczne użycie, które znajduje się wewnątrz ciągu szablonowego. - Pytania w języku naturalnym. Prośba o wyjaśnienie procesu autoryzacji powoduje, że otrzymuje się odpowiednie symbole wraz z kontekstem, zamiast tego, by asystent przeglądał pliki. Odpowiedź przychodzi szybciej, z większą dokładnością i przy mniejszym zużyciu kontekstu.
- Oszczędność tokenów. Trudno to dokładnie zmierzyć, ale efekt jest rzeczywisty. Aby znaleźć definicję, wystarczy wywołać funkcję
find_symboli otrzymać treść bezpośrednio, a edycje nie są wprowadzane poza kontekstem, ponieważ to Serena pisze odpowiedzi.
Skróty w Makefile sprawiają, że ten proces staje się nawykiem:
make serena-up # Start the Serena container
make serena-stop # Stop it
make serena-logs # Tail logs
make serena-index # Force re-index after big changes
make serena-health # Health check the workspace
Wynik
Uzasadnianie decyzji i generowanie kodu to mocne strony narzędzi do programowania opartych na AI. Praca z dużymi bazami kodu stanowi natomiast ich słabszy punkt. Serwer językowy stworzony specjalnie do tego celu poprawia zarówno jakość rozwiązań, jak i koszty. Zespoły, które poświęcają dużo czasu na czytanie plików, a mimo to dokonują niedbalich modyfikacji w dużych repozytoriach, ocenią jako wartościową całe popołudnie poświęcone na konfigurację. Docker utrzymuje porządek: Serena działa obok reszty stacku, przechowuje swój indeks i udostępnia jeden endpoint SSE każdemu klientowi w zespole.