Serena MCP Server : Édition de code sensible aux symboles pour les assistants IA
Configurez Serena avec Docker et SSE afin que Claude Code, VS Code et OpenCode disposent d’une recherche de symboles assistée par LSP, de possibilités de renommage sécurisées, ainsi que d’une mémoire persistante consommant moins de tokens.
Sources: Serena MCP: Giving Your AI Coding Tools an IDE Brain
Serena est un serveur MCP open source qui permet aux assistants de codage basés sur l’IA d’obtenir une compréhension de la base de code similaire à celle d’un IDE. Testé sur un monorepo TypeScript, l’effet est notable : l’assistant devient plus compétent pour interpréter le code et utilise moins de tokens à cette fin.
Alors qu’un assistant traditionnel ne voit que des fichiers remplis de texte, Serena se connecte à un backend basé sur le Language Server Protocol, le moteur qui permet des fonctionnalités comme « aller à la définition », « trouver toutes les références » et « renommer en toute sécurité » dans un éditeur, et publie ces fonctionnalités sous forme d’outils MCP pour tout client compatible. Tout s’exécute sur la machine locale, plus de 30 langages sont pris en charge, et les clients compatibles incluent Claude Code, VS Code, Cursor, OpenCode et Claude Desktop.
Quels sont les problèmes avec la recherche de texte brut ?
Si l’on demande à un assistant de trouver toutes les fonctions chargées de l’authentification, la procédure habituelle est la suivante :
- Effectuez une recherche de texte à l’aide de
grepouripgreppour le mot « authentication ». - Lisez les fichiers correspondants, parfois dans leur intégralité, ce qui entraîne la consultation de milliers de lignes dans le contexte.
- Renvoyez chaque ligne contenant cette chaîne de caractères, y compris les commentaires, les littéraux de chaîne ainsi que les résultats non pertinents.
Cela convient pour un petit projet, mais devient difficile à gérer à mesure que la base de code s’agrandit. Quatre tâches courantes mettent en évidence ce problème :
+----------------------------+-------------------------------------+--------------------------------------------+
| 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 |
+----------------------------+-------------------------------------+--------------------------------------------+
Le coût des tokens aggrave le problème. Sans outils sémantiques, l’assistant doit lire des fichiers entiers pour comprendre leur structure, puis garder ce texte en mémoire dans le contexte. Avec Serena, une seule appelation find_symbol("UserService") fournit exactement ce dont on a besoin.
Travail au niveau des symboles
Serena indexe un projet via un véritable serveur de langage et crée une carte relationnelle : quelles fonctions appellent lesquelles, où les types sont définis et quels éléments importent quoi. Lorsque l’assistant doit comprendre ou modifier du code, il utilise ces outils à la place de lectures et écritures directes de fichiers :
find_symbollocalise un symbole par son nom et peut restituer son contenu complet.get_symbols_overviewaffiche la liste des symboles d’un fichier ou d’un répertoire sans lire le code source.find_referencing_symbolsliste tous les endroits où un symbole est appelé ou utilisé dans l’ensemble du codebase.
rename_symbol renomme via le LSP, mettant à jour chaque référence.replace_symbol_body remplace le corps d’une fonction ou d’une classe sans toucher au code environnant.insert_before_symbol et insert_after_symbol insèrent du code à une position sémantique précise.Le LLM ne modifie pas ligne par ligne au risque d’oublier une référence quelque part. Il confie les modifications à Serena, qui travaille à partir de données indexées et du serveur de langage, ce qui permet des modifications conscientes des références. Un symbole utilisé 20 fois est mis à jour dans les 20 cas. La documentation du projet liste tous les outils du serveur de langage.
Mémoire et tableau de bord
Chaque projet dispose également d’un stockage de mémoire persistant. Au fur et à mesure que l’assistant apprend les conventions, les pièges et les décisions architecturales, il peut les enregistrer sous forme de notes. Elles survivent aux réinitialisations de conversation et sont disponibles lors de la session suivante, de sorte que le travail ne doit pas reprendre à zéro.
Un tableau de bord web accessible à http://localhost:24282/dashboard/index.html est activé par défaut et montre ce que fait Serena :
- Aperçu de la session et projets actifs
- Journal des appels d’outils avec des statistiques sur quels outils ont été utilisés, avec quelle fréquence et pendant combien de temps
- Journal en temps réel du serveur
- Éditeur de configuration, permettant de modifier les paramètres sans redémarrage
- Gestionnaire de mémoire pour visualiser et modifier les notes de projet accumulées
- Contrôles du serveur
Sur macOS et Windows, il existe également un wrapper natif dans la barre des tâches, tandis que sous Linux, l’accès se fait uniquement via un navigateur.
Les contextes déterminent la liste des outils
Des contextes prédéfinis contrôlent quels outils sont affichés. La logique est que le client peut déjà gérer certaines tâches de manière native, comme la lecture de fichiers ou l’exécution de commandes shell ; Serena évite donc de les dupliquer et maintient ainsi une liste d’outils organisée.
+---------------------+------------------------------+------------------------------------------------+
| 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). |
+---------------------+------------------------------+------------------------------------------------+
Pour un conteneur Docker qui sert à la fois Claude Code, VS Code et OpenCode, utilisez desktop-app, le super-ensemble. Lorsque Serena est exécutée localement par client, choisissez le contexte correspondant à cet outil.
Installation
Utilisez uv. La documentation officielle de Serena met en garde contre les marchés MCP, qui ont tendance à fournir des commandes obsolètes :
uv tool install -p 3.13 serena-agent@latest --prerelease=allow
serena init
Cela installe le CLI serena de manière globale et lance l’assistant de configuration. Les clients seront configurés ensuite.
Claude Code, global (recommandé) :
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, par projet :
claude mcp add serena -- serena start-mcp-server --context claude-code --project "$(pwd)"
VS Code, dans .vscode/mcp.json au niveau de la racine du projet :
{
"servers": {
"serena": {
"type": "stdio",
"command": "serena",
"args": [
"start-mcp-server",
"--context", "ide",
"--project", "${workspaceFolder}"
]
}
}
}
Claude Desktop, situé dans ~/.config/claude_desktop_config.json sous Linux ou ~/Library/Application Support/Claude/claude_desktop_config.json sous macOS :
{
"mcpServers": {
"serena": {
"command": "serena",
"args": ["start-mcp-server", "--context", "desktop-app"]
}
}
}
Exécution dans Docker
Docker est l’approche privilégiée par les documents de Serena pour l’isolation, en particulier lorsque l’agent est autorisé à effectuer des modifications. À l’intérieur d’un conteneur, il ne peut voir que les répertoires montés en son sein. Une entrée dans 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
Notes sur cette configuration :
--transport ssedoit être défini à l’intérieur de Docker, carstdione fonctionne que lorsque le client lance Serena lui-même en tant que processus enfant.--context desktop-appoffre l’ensemble d’outils le plus complet et convient à Claude Code, aux extensions de VS Code ainsi qu’à OpenCode. Des contextes plus restreints commeclaude-codedésactivent les outils dont d’autres clients ont besoin.--project /workspace/myprojectdoit correspondre au chemin interne au conteneur où le code est monté. Évitez--project-from-cwddans ce cas, car le répertoire de travail du conteneur est l’emplacement d’installation de Serena et non le projet lui-même.- Des ports hôte inhabituels (
10121et34282) permettent à plusieurs projets d’exécuter leur propre instance de Serena sans conflit.
Lorsque SERENA_DOCKER=1 est défini, Serena sait qu’elle se trouve à l’intérieur d’un conteneur. Le fichier global ~/.serena/serena_config.yml, monté ou intégré dans la configuration, doit contenir des paramètres adaptés aux conteneurs :
gui_log_window: false
web_dashboard_listen_address: "0.0.0.0"
web_dashboard_open_on_launch: false
Pour monter la configuration du hôte, ajoutez une correspondance de volume ~/.serena:/root/.serena. Démarrez le service :
docker compose up -d serena
Relier les clients au conteneur
Chaque client communique avec le même point de terminaison SSE, seuls le format de configuration diffèrent. Claude Code peut le enregistrer de manière globale :
claude mcp add serena --transport sse --url http://localhost:10121/sse
Le projet peut également contenir un .mcp.json :
{
"mcpServers": {
"serena": {
"type": "sse",
"url": "http://localhost:10121/sse"
}
}
}
VS Code prend en charge un .vscode/mcp.json :
{
"servers": {
"serena": {
"type": "sse",
"url": "http://localhost:10121/sse"
}
}
}
OpenCode utilise opencode.jsonc :
{
"mcp": {
"serena": {
"type": "remote",
"url": "http://localhost:10121/sse",
"enabled": true
}
}
}
Le Codex, Kilo Code et d’autres clients compatibles avec MCP fonctionnent de la même manière.
Configuration du projet
Serena lit .serena/project.yml situé dans la racine du projet. Une configuration pratique de TypeScript commence par le nom suivant :
project_name: "myproject"
Puis les langages et les règles à ignorer :
languages:
- typescript # uses typescript-language-serverencoding: "utf-8"
ignore_all_files_in_gitignore: trueignored_paths:
- "node_modules"
- "dist"
- "build"
- "coverage"
- ".next"
- "out"
- ".cache"
La liste ignored_paths constitue une mesure de sécurité supplémentaire par rapport à .gitignore. Rien que node_modules peut contenir plus de 80 000 fichiers, et leur indexation ralentit considérablement le démarrage tout en encombrant la recherche de symboles avec des éléments internes de tiers.
Que commiter et que ignorer :
.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)
Quelles sont les modifications en pratique
Avec un Deno 2 et un monorepo TypeScript comprenant un frontend, une API et des packages partagés, quatre éléments se distinguent :
- Résolution entre packages. Le monorepo entier étant monté comme un seul espace de travail, Serena trace un type depuis
packages/jusqu’à ses utilisations dansapps/api/en une seule étape, contrairement à l’assistant qui devait lire fichier par fichier pour reconstituer l’information. - Refacteurs plus sûrs. Une tâche impliquant une vingtaine de fichiers, visant à renommer une interface partagée, a été traitée via
rename_symbolsans oublier aucun élément. La recherche et le remplacement de texte laissent toujours une utilisation dynamique cachée à l’intérieur d’une chaîne de template. - Questions en langage naturel. En demandant une explication du flux d’authentification, les symboles pertinents accompagnés de leur contexte sont fournis, au lieu que l’assistant doive parcourir des fichiers. La réponse arrive plus rapidement, avec plus de précision et en utilisant moins de contexte.
- Économie de tokens. Difficile à mesurer avec précision, mais c’est réel. Trouver une définition signifie appeler
find_symbolpour obtenir directement le contenu, et les modifications restent hors contexte puisque c’est Serena qui rédige.
Les raccourcis Makefile aident à faire de ce flux de travail une habitude :
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
Verdict
Le raisonnement et la génération de code constituent les forces des outils de codage basés sur l’IA. Gérer une grande base de code représente en revanche leur point faible. Un serveur de langage conçu spécifiquement pour cette tâche améliore à la fois la qualité des réponses et les coûts. Les équipes qui consacrent beaucoup de temps à la lecture des fichiers mais réalisent des refactorisations négligentes dans de gros dépôts trouveront qu’une après-midi de configuration en vaut la peine. Docker maintient tout en ordre : Serena s’exécute à côté du reste de la stack, conserve son index et propose un point de terminaison SSE à chaque client de l’équipe.