/ Directory / Playground / Serena
● Community oraios ⚡ Instant

Serena

by oraios · oraios/serena

Serena bolts language-server-powered semantic search and symbolic edits onto your agent — so rename/refactor/find-references actually work across huge codebases.

Serena is the 'IDE for your agent.' Instead of grepping files and praying, it uses real LSP backends for 40+ languages to answer symbol-level questions: 'where is this function called?', 'what's the type hierarchy?', 'rename this symbol everywhere it's used'. It then ships symbolic editing tools so the agent can replace a function body, delete a symbol safely, or insert code relative to an AST node. The memory system persists context across sessions — Claude picks up where it left off last week.

Why use it

Key features

Live Demo

What it looks like in practice

serena.replay ▶ ready
0/0

Install

Pick your client

~/Library/Application Support/Claude/claude_desktop_config.json  · Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "serena": {
      "command": "uvx",
      "args": [
        "--from",
        "serena-agent",
        "serena",
        "start-mcp-server",
        "--context=claude-desktop"
      ]
    }
  }
}

Open Claude Desktop → Settings → Developer → Edit Config. Restart after saving.

~/.cursor/mcp.json · .cursor/mcp.json
{
  "mcpServers": {
    "serena": {
      "command": "uvx",
      "args": [
        "--from",
        "serena-agent",
        "serena",
        "start-mcp-server",
        "--context=claude-desktop"
      ]
    }
  }
}

Cursor uses the same mcpServers schema as Claude Desktop. Project config wins over global.

VS Code → Cline → MCP Servers → Edit
{
  "mcpServers": {
    "serena": {
      "command": "uvx",
      "args": [
        "--from",
        "serena-agent",
        "serena",
        "start-mcp-server",
        "--context=claude-desktop"
      ]
    }
  }
}

Click the MCP Servers icon in the Cline sidebar, then "Edit Configuration".

~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "serena": {
      "command": "uvx",
      "args": [
        "--from",
        "serena-agent",
        "serena",
        "start-mcp-server",
        "--context=claude-desktop"
      ]
    }
  }
}

Same shape as Claude Desktop. Restart Windsurf to pick up changes.

~/.continue/config.json
{
  "mcpServers": [
    {
      "name": "serena",
      "command": "uvx",
      "args": [
        "--from",
        "serena-agent",
        "serena",
        "start-mcp-server",
        "--context=claude-desktop"
      ]
    }
  ]
}

Continue uses an array of server objects rather than a map.

~/.config/zed/settings.json
{
  "context_servers": {
    "serena": {
      "command": {
        "path": "uvx",
        "args": [
          "--from",
          "serena-agent",
          "serena",
          "start-mcp-server",
          "--context=claude-desktop"
        ]
      }
    }
  }
}

Add to context_servers. Zed hot-reloads on save.

claude mcp add serena -- uvx --from serena-agent serena start-mcp-server --context=claude-desktop

One-liner. Verify with claude mcp list. Remove with claude mcp remove.

Use Cases

Real-world ways to use Serena

Find every caller of a function across a 1M-line codebase

👤 Engineers working in mature, large repos ⏱ ~10 min intermediate

When to use: You need a complete, correct list of callers — grep gives false positives (comments, strings, similarly-named functions in other scopes) and misses overloads.

Prerequisites
  • uv installed — curl -LsSf https://astral.sh/uv/install.sh | sh
  • Project opened in a language Serena's LSP supports — Most mainstream languages work out of the box
Flow
  1. Open the project
    Open /abs/path/to/repo with Serena. Confirm the LSP index built.✓ Copied
    → Serena reports the project root and the LSP that loaded
  2. Find symbol references
    Find every call site of PaymentService.chargeCustomer. Include overloads and overrides, exclude tests.✓ Copied
    → Exact file:line list, no false positives from comments/strings
  3. Summarize impact
    Group the call sites by module. For each group, tell me what the caller does with the return value.✓ Copied
    → Module-grouped narrative, not a flat list

Outcome: You know exactly what a change would touch — before you touch it.

Pitfalls
  • Some polyglot repos need multiple LSPs — Start Serena per sub-project if languages don't share a server
Combine with: filesystem · github

Rename a public API symbol without breaking dependents

👤 Library/framework maintainers ⏱ ~15 min intermediate

When to use: You're renaming a function or class that might be used outside the file — you need LSP-accurate rename, not text replace.

Prerequisites
  • Clean git tree — git status clean so you can review the diff before committing
Flow
  1. Dry-run the rename
    Rename getUser to fetchUserById in src/api/users.ts. Use Serena's symbolic rename. Preview the diff — do not apply yet.✓ Copied
    → Diff preview across every affected file
  2. Review and apply
    Apply the rename. Tell me any file Serena flagged as ambiguous.✓ Copied
    → Rename applied, ambiguity list (if any)
  3. Run the suite
    Run the tests and report failures, focusing on anything that references the old name.✓ Copied
    → Tests green, or a precise failure list

Outcome: Rename is clean across the repo, including public re-exports, index.ts barrels, and stale JSDoc references.

Pitfalls
  • Dynamic access (obj['getUser']) isn't caught by LSP rename — After symbolic rename, do one grep for the old name string; Serena surfaces any it couldn't statically resolve
Combine with: filesystem · git

Replace a function body without disturbing surrounding code

👤 Engineers making surgical edits inside large files ⏱ ~10 min intermediate

When to use: You want the implementation of calculatePrice rewritten but its signature and JSDoc kept exactly. Whole-file regeneration is the wrong tool.

Flow
  1. Target the symbol
    In src/billing/pricing.ts, find calculatePrice. Show me the current body only (not the signature or doc).✓ Copied
    → Body-only snippet
  2. Replace the body
    Replace just the body with a version that handles the tax-exempt case. Keep signature and JSDoc intact.✓ Copied
    → Serena's replace-body tool is used; signature unchanged in the diff

Outcome: Minimal, reviewable diff — no incidental whitespace/formatting churn.

Pitfalls
  • Agent falls back to full-file write — Explicitly instruct 'use Serena's symbolic replace, not write_file'
Combine with: filesystem

Onboard to an unfamiliar codebase in an hour

👤 New hires, contractors, or OSS contributors ⏱ ~60 min beginner

When to use: You just cloned a 500-file repo and need a mental map before you can contribute.

Flow
  1. Get the architecture
    Open this repo with Serena. Build a map: top-level modules, their public exports, and the main entry point. Save to Serena memory as 'arch_overview'.✓ Copied
    → Structured overview; memory note created
  2. Follow a user request
    Trace what happens when a user hits POST /orders. Walk me through every file in order.✓ Copied
    → Request → handler → service → repo trail, with Serena's reference lookups
  3. Note the gotchas
    Save any patterns that look unusual (custom decorators, magic constants) to memory as 'gotchas'.✓ Copied
    → Memory note saved for next session

Outcome: Next session, Claude already knows the map — no re-onboarding cost.

Combine with: filesystem · github

Combinations

Pair with other MCPs for X10 leverage

serena + filesystem

Serena for symbol-aware navigation + filesystem for arbitrary I/O

Use Serena to find the auth module, then filesystem to write a new README for that folder.✓ Copied
serena + github

Refactor locally with Serena; push a branch and open a PR via GitHub MCP

Rename ApiClient → HttpClient with Serena, then open a PR titled 'refactor(api): rename ApiClient'.✓ Copied
serena + git

Review the diff Serena produced before committing

Show me git diff after Serena's rename. Anything suspicious, flag it before we commit.✓ Copied
serena + context7

Library-aware refactor — Serena for local moves, Context7 for matching v-next APIs

Migrate this file to Next.js 15 patterns. Use Context7 for the new APIs and Serena to apply changes symbolically.✓ Copied

Tools

What this MCP exposes

ToolInputsWhen to callCost
find_symbol name: str, scope?: str Locate a class/function/var by name with LSP precision free (local)
find_references symbol: ref All callers/usages of a symbol; vastly better than grep free
get_symbols_overview path: str File/module outline before deciding what to read free
rename_symbol symbol: ref, new_name: str, dryRun?: bool Safe rename across the whole project free
replace_symbol_body symbol: ref, new_body: str Swap a function/method body in place without touching signature free
insert_before_symbol / insert_after_symbol symbol: ref, code: str Add decorators, imports, or sibling declarations anchored to an AST node free
move_file / move_dir src: str, dst: str Relocate code and let the LSP fix up every importer free
write_memory / read_memory key: str, value?: str Persist project context (architecture map, gotchas) across sessions free
search_pattern regex: str, path: str Fallback when the target isn't a named symbol (string literals, patterns) free

Cost & Limits

What this costs to run

API quota
None — local LSP
Tokens per call
Small — Serena returns symbol-scoped snippets, not whole files
Monetary
Free
Tip
Prefer get_symbols_overview + find_symbol over read_text_file on large files — you spend 10x fewer tokens and get better signal

Security

Permissions, secrets, blast radius

Credential storage: None — everything runs locally
Data egress: None by default. Serena can run shell commands (disableable); review the tool list before granting write access in Claude.
Never grant: Access to directories outside your project

Troubleshooting

Common errors and fixes

LSP failed to start / no symbols found

Check the language server is installed for the project's language (e.g. pyright for Python, typescript-language-server for TS). Serena logs list which LSP it's using.

Verify: Run Serena in verbose mode; confirm LSP handshake succeeded
Rename skipped some files

Usually means the files aren't in the LSP's workspace. Confirm the project root is the monorepo root, not a sub-package.

Verify: Ask Serena to list its workspace roots
Agent falls back to raw file writes instead of Serena tools

Put an explicit rule in CLAUDE.md: 'For symbolic operations, always use Serena's tools; never write_file on existing .py/.ts files'

Verify: Re-run the task; inspect tool_use calls in the trace
uvx: command not found

Install uv first: curl -LsSf https://astral.sh/uv/install.sh | sh; then re-open your terminal

Verify: uvx --version

Alternatives

Serena vs others

AlternativeWhen to use it insteadTradeoff
JetBrains MCPYou already live in a JetBrains IDE and want the agent to drive its refactor toolsRequires an open IDE process; heavier
filesystemYou don't need symbol awareness — just read/write filesNo semantic search or safe rename
mcp-language-serverYou want a smaller LSP-only wrapper, not Serena's memory + shell layerFewer high-level tools; you compose the workflow yourself

More

Resources

📖 Read the official README on GitHub

🐙 Browse open issues

🔍 Browse all 400+ MCP servers and Skills