TL;DR: My Claude Code agent kept inventing function names that looked plausible but didn't exist ( getUserByEmail , parseConfigFile , validateInput — all fake in my codebase). Adding a local MCP server that gives the agent a real symbol graph and ranked code search cut hallucinations to roughly zero on the same repo. Below: the bug, the cause, the fix, the bench numbers, and the cases where it still doesn't help. The bug I was refactoring a logging middleware in a 4,000-file TypeScript monorepo. The agent's task: rename logRequest to logHttpRequest everywhere it's called, including transitive callers. What Claude Code generated, paraphrased: // src/middleware/auth.ts import { logRequest } from " ../logging/logger " export function withAuth ( handler : Handler ) { return async ( req , res ) => { logRequest ( req ) // ← real if ( ! req . session ) { return res . status ( 401 ).…