首页 / 文章

Serena MCP服务器:面向AI助手的符号感知代码编辑功能

通过 Docker 和 SSE 为 Serena 做好配置,从而使 Claude Code、VS Code 和 OpenCode 能够获得基于 LSP 的符号搜索功能、安全的重命名能力,同时以更少的令牌使用量实现持久化内存。

发布者:REACTAPP.TOP阅读约 9 分钟2020 词

来源: Serena MCP: Giving Your AI Coding Tools an IDE Brain

Serena 是一款开源的 MCP 服务器,它让 AI 编码助手能够以类似 IDE 的方式理解代码库。在 TypeScript 单体仓库上试用后,其效果十分显著:助手对代码的理解更加深入,且所需消耗的算力也更少。

普通助手只能看到满是文本的文件,而 Serena 能接入语言服务器协议后端——该后端是编辑器中“跳转到定义”“查找所有引用”以及安全重命名功能背后的引擎——并将这些功能作为 MCP 工具提供给所有兼容的客户端。所有操作都在本地机器上完成,支持 30 多种编程语言,兼容的客户端包括 Claude Code、VS Code、Cursor、OpenCode 和 Claude Desktop。

纯文本搜索的弊端

如果让助手找出所有处理身份验证的函数,常规的操作流程是:

  1. 使用 grep 或 ripgrep 对 “authentication” 这个词进行文本搜索。
  2. 读取匹配到的文件,有时是整个文件,将数千行内容放入上下文中查看。
  3. 返回包含该字符串的每一行,包括注释、字符串字面量以及无关的匹配结果。

对于小型项目来说这还可行,但随着代码库规模的扩大就会出现问题。以下四项日常任务就能体现出其中的差距:

+----------------------------+-------------------------------------+--------------------------------------------+
| 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                        |
+----------------------------+-------------------------------------+--------------------------------------------+

令牌成本加剧了这一问题。在没有语义分析工具的情况下,助手需要读取整个文件以理解其结构,然后再将这些文本置于上下文中使用。而借助Serena,只需一次find_symbol("UserService")调用就能获取所需信息。

在符号层面工作

Serena通过真实的语言服务器对项目进行索引,并构建出关系图:哪些函数调用了哪些函数、类型定义在何处以及哪些模块导入了什么。当助手需要理解或修改代码时,它会使用这些工具而非直接读取和写入文件:

  • find_symbol可按名称定位符号,并能返回其完整内容。
  • get_symbols_overview无需读取源代码即可列出文件或目录中的所有符号。
  • find_referencing_symbols能列出代码库中所有调用该符号的位置及使用方式。
  • rename_symbol 通过 LSP 进行重命名,同时更新所有引用。
  • replace_symbol_body 会替换函数或类的主体内容,而不会影响周围的代码。
  • insert_before_symbol 和 insert_after_symbol 可以在精确的语义位置插入代码。
  • 大语言模型不会逐行编辑,以免遗漏某些引用。它会将编辑任务交给 Serena,后者基于索引数据及语言服务器进行处理,因此能够准确处理各种引用关系。如果在20个地方使用了同一个符号,它会在所有20个位置同时得到更新。项目文档中列出了所有的语言服务器工具。

    内存与控制面板

    每个项目还拥有一个持久化内存存储空间。随着助手逐渐了解各种惯例、注意事项以及架构决策,它可以将这些信息保存为笔记。这些笔记不会因对话重置而丢失,可在下次会话中继续使用,从而无需从头开始工作。

    默认情况下,http://localhost:24282/dashboard/index.html 上的网页控制面板处于开启状态,可显示 Serena 的当前操作:

    • 会话概览及正在处理的项目
    • 工具调用日志,包含各工具的运行情况、频率及时长统计
    • 实时服务器日志
    • 配置编辑器,无需重启即可修改设置
    • 内存管理器,用于查看和编辑累积的项目笔记
    • 服务器控制功能

    在 macOS 和 Windows 系统上还有原生的系统托盘界面,而 Linux 系统则仅通过浏览器使用。

    上下文决定工具列表

    预定义的上下文决定了哪些工具会被展示。其原理是客户端可能已经具备某些原生功能,如文件读取或命令行执行,因此 Serena 会避免重复实现这些功能,从而保持工具列表的简洁性。

    +---------------------+------------------------------+------------------------------------------------+
    | 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).                              |
    +---------------------+------------------------------+------------------------------------------------+
    

    若需一个 Docker 容器同时运行 Claude Code、VS Code 和 OpenCode,应使用其上位概念 desktop-app。当 Serena 按客户端本地运行时,则需选择与该工具匹配的上下文。

    安装

    请使用 uv 工具。Serena 的官方文档警告不要使用 MCP 市场,因为这些市场提供的命令往往已经过时:

    uv tool install -p 3.13 serena-agent@latest --prerelease=allow
    serena init
    

    这将全局安装 serena CLI 并启动设置向导,接下来将配置客户端。

    Claude Code,全局模式(推荐):

    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:

    claude mcp add serena -- serena start-mcp-server --context claude-code --project "$(pwd)"
    

    VS Code,位于项目根目录下的 .vscode/mcp.json 文件中:

    {
      "servers": {
        "serena": {
          "type": "stdio",
          "command": "serena",
          "args": [
            "start-mcp-server",
            "--context", "ide",
            "--project", "${workspaceFolder}"
          ]
        }
      }
    }
    

    Claude Desktop的配置文件位于Linux系统的~/.config/claude_desktop_config.json,或MacOS系统的~/Library/Application Support/Claude/claude_desktop_config.json中:

    {
      "mcpServers": {
        "serena": {
          "command": "serena",
          "args": ["start-mcp-server", "--context", "desktop-app"]
        }
      }
    }
    

    在 Docker 中运行

    对于隔离机制,Serena 的文档推荐使用 Docker,尤其是在允许代理进行编辑的情况下。在容器中,它只能看到被挂载进来的目录。一个 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
    

    关于该配置的说明:

    • --transport sse 需要在 Docker 内部设置,因为只有当客户端以子进程方式启动 Serena 时,stdio 才能正常工作。
    • --context desktop-app 能提供最完整的工具集,适用于 Claude Code、VS Code 扩展以及 OpenCode 等应用。而 claude-code 这类更具体的上下文会关闭其他客户端所依赖的工具。
    • --project /workspace/myproject 必须是容器内部用于挂载代码的路径。请避免使用 --project-from-cwd,因为容器的当前工作目录是 Serena 的安装位置,而非项目目录。
    • 使用非标准的主机端口(10121 和 34282)可以让多个项目各自运行独立的 Serena,从而避免冲突。

    当设置 SERENA_DOCKER=1 时,Serena 会意识到自己处于容器内部。全局配置文件 ~/.serena/serena_config.yml 应被挂载或内置在系统中,其中需包含适合容器环境的配置项:

    gui_log_window: false
    web_dashboard_listen_address: "0.0.0.0"
    web_dashboard_open_on_launch: false
    

    要挂载主机配置,需添加一个卷映射 ~/.serena:/root/.serena。然后启动该服务:

    docker compose up -d serena
    

    将客户端与容器连接

    所有客户端都连接到同一个SSE端点,仅有配置格式不同。Claude Code可以全局注册该端点:

    claude mcp add serena --transport sse --url http://localhost:10121/sse
    

    或者该项目可以包含一个 .mcp.json 文件:

    {
      "mcpServers": {
        "serena": {
          "type": "sse",
          "url": "http://localhost:10121/sse"
        }
      }
    }
    

    VS Code 会读取 .vscode/mcp.json 文件:

    {
      "servers": {
        "serena": {
          "type": "sse",
          "url": "http://localhost:10121/sse"
        }
      }
    }
    

    OpenCode 使用 opencode.jsonc:

    {
      "mcp": {
        "serena": {
          "type": "remote",
          "url": "http://localhost:10121/sse",
          "enabled": true
        }
      }
    }
    

    Codex、Kilo Code以及其他MCP兼容客户端的工作原理类似。

    项目配置

    Serena会读取项目根目录下的.serena/project.yml文件。一个实用的TypeScript配置始于该文件中的名称设置:

    project_name: "myproject"
    

    然后是语言及忽略规则:

    languages:
      - typescript   # uses typescript-language-serverencoding: "utf-8"
    ignore_all_files_in_gitignore: trueignored_paths:
      - "node_modules"
      - "dist"
      - "build"
      - "coverage"
      - ".next"
      - "out"
      - ".cache"
    

    ignored_paths 列表是针对 .gitignore 的额外安全保障。仅 node_modules 目录就可能包含超过80,000个文件,对它们进行索引会极大拖慢程序启动速度,还会让符号搜索被各种第三方内部文件干扰。

    哪些内容应该提交,哪些应该忽略:

    .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)
    

    实际应用中的变化

    在包含前端、API以及共享包的 Deno 2 和 TypeScript 单体仓库中,有四点尤为突出:

    • 跨包解析功能。由于整个单体仓库被作为一个工作区加载,Serena 能够一步将类型从 packages/ 定位到 apps/api/ 中的使用位置,而以往的辅助工具需要逐个读取文件再手动拼接信息。
    • 更安全的代码重构功能。一次涉及约20个文件的操作,即重命名一个共享接口时,通过 rename_symbol 功能即可完成且不会遗漏任何内容。而文本搜索替换功能总会有某个动态使用场景被隐藏在模板字符串中而未被处理。
  • 自然语言提问。要求解释认证流程时,系统会直接返回带有上下文的相关符号,而无需助手在文件中逐个查找。这样得到的答案更快、更准确,且使用的上下文更少。
  • 节省令牌。虽难以精确衡量,但效果确实存在。查找定义时只需调用find_symbol即可直接获取内容,而且由于由Serena负责撰写,修改内容也不会脱离上下文。
  • Makefile快捷指令能让这一工作流程成为习惯:

    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
    

    结论

    推理与代码生成是AI编程工具的优势所在,而处理庞大的代码库则是其薄弱环节。专为处理此类任务设计的语言服务器能够提升响应质量并降低成本。那些在文件读取上投入大量精力,但在大型代码库中进行重构时仍表现粗疏的团队,会发现花些时间进行设置是值得的。Docker让一切更加井然有序:Serena在其余技术栈旁边运行,保留自身的索引,并为团队中的每个客户端提供一个SSE端点。