Make Cursor agents actually use Serena symbolic tools instead of defaulting to Read/Grep/SemanticSearch. Adapted from Serena's Claude Code client docs.
This is a user-global setup (~/.cursor/). It applies to every project you open in Cursor.
-
Install Serena (do not use marketplace/plugin installers):
uv tool install --python 3.13 serena-agent serena init
-
Verify CLI:
which serena serena-hooks serena start-mcp-server --help
-
Per-repo (once per project): initialize Serena in the repo root:
cd your-repo serena project init # creates .serena/project.yml
Edit
.serena/project.ymland setlanguages:for your stack (e.g.python,typescript).
Merge with any existing servers. If you already have other MCP entries, add the serena block only.
See mcp.json in this gist.
Replace /home/you/.local/bin/serena with the output of which serena. Use the full path — Cursor's MCP subprocess often does not inherit your shell PATH, so bare serena may fail even when it works in a terminal.
Key flags:
--context=ide— Serena defers file/shell tools to Cursor; exposes symbolic LSP tools (recommended for Cursor per Serena client docs)--project-from-cwd— auto-detects.serena/project.ymlin the opened workspace
Copy these four files into ~/.cursor/hooks/ and make the .sh files executable:
mkdir -p ~/.cursor/hooks
cp serena_bridge.py serena-*.sh ~/.cursor/hooks/
chmod +x ~/.cursor/hooks/serena-*.sh| File | Role |
|---|---|
serena_bridge.py |
Translates Cursor hook JSON ↔ Serena serena-hooks CLI |
serena-activate.sh |
Session start: activate project + read Serena instructions |
serena-remind.sh |
After repeated Read/Grep/SemanticSearch/Shell: nudge toward symbolic tools |
serena-cleanup.sh |
Session end: clean hook state |
See hooks.json. Merge with your existing hooks if you already have a hooks.json (e.g. other preToolUse entries).
Hook paths are relative to ~/.cursor/ (not the project root).
The preToolUse matcher includes SemanticSearch — Cursor agents often use that instead of Grep, and it must be tracked for the remind counter to work.
Global .mdc rules in ~/.cursor/rules/ are not supported. Paste the contents of user-rules.txt into:
Cursor Settings → Rules → User Rules
This is the most important step. Hooks nudge and occasionally deny overuse, but User Rules counteract Cursor's built-in tool bias (the same problem Serena documents for Claude Code and VSCode). Without this paste, agents will keep defaulting to Read / Grep / SemanticSearch on code files.
Optional: keep a local copy for re-paste after Cursor updates:
cp user-rules.txt ~/.cursor/serena-user-rules.txt- Restart Cursor completely.
- Settings → Tools & MCP — Serena shows connected (green).
- Settings → Hooks — three Serena hooks listed, no validation errors.
- New Agent chat — ask: "What MCP tools do you have?" — Serena tools should appear.
- In a repo with
.serena/project.yml, the agent should callinitial_instructionsat session start (injected by thesessionStarthook) and preferget_symbols_overview/find_symbolover full-fileReadfor code.
Test hooks from a terminal:
echo '{"session_id":"test"}' | python3 ~/.cursor/hooks/serena_bridge.py activate
# Should print additional_context about activate_project + initial_instructions| Mechanism | Problem solved |
|---|---|
Full path in mcp.json |
MCP subprocess can't find serena on PATH |
--context=ide + --project-from-cwd |
Right tool set; project auto-detected per workspace |
sessionStart hook |
Agent drift — forgets to activate Serena |
preToolUse remind hook |
Agent overuses Read/Grep/SemanticSearch instead of find_symbol / get_symbols_overview |
| User Rules (pasted in Settings) | Built-in tool docs override Serena guidance |
sessionEnd cleanup |
Stale hook counters between sessions |
| Symptom | Fix |
|---|---|
| Agent still uses Read/Grep on code files | Paste user-rules.txt into Cursor Settings → Rules → User Rules and restart |
| Serena tools green in UI but agent can't see them | New chat; ask agent to list MCP tools. Try Settings → Network → HTTP Compatibility Mode → HTTP/1.1. Restart Cursor. |
serena not found in MCP |
Use full path in mcp.json: output of which serena (e.g. /home/you/.local/bin/serena) |
| Hooks don't load | Ensure "version": 1 at top of hooks.json. Restart Cursor. Check Settings → Hooks output channel. |
| Remind hook never fires | Ensure matcher includes SemanticSearch if agent uses semantic search; merge hooks don't drop the Serena entry |
| Serena starts but wrong project | Run serena project init in repo root; ensure workspace root contains .serena/project.yml |
| MCP timeout on slow machines | Increase Cursor MCP startup timeout if available |
- Serena repo: https://github.com/oraios/serena
- Client setup: https://oraios.github.io/serena/02-usage/030_clients.html
- Claude Code hooks (same
serena-hooksCLI we bridge): https://oraios.github.io/serena/02-usage/030_clients.html#claude-code
If a repo needs stricter Serena enforcement (e.g. alwaysApply + globs), add .cursor/rules/serena.mdc in that repo only. The global User Rules above are enough for most teams.