SafetyCard Request a review

codebase-memory-mcp

Local MCP server that indexes a codebase into a persistent SQLite knowledge graph and exposes 17 search, trace, query and ADR tools to coding agents.

github.com/DeusData/codebase-memory-mcp · 2026-10-05 · 268a9d8

Defense-in-depth score

5.2 / 10

A local code-graph server that holds no credentials, makes no network calls and ships accurate read-only and destructive labels on all 17 tools, so a hijacked agent can do limited damage through it. The main gap is that git, grep and find helpers run unsandboxed through a shell, with only a character filter guarding the model-supplied values they include. Any non-sensitive directory can be indexed and read back by default. ADR text and repository-supplied graph snapshots persist into later sessions without review, and the audit log records tool names but not what each call did.

Safest setup

codebase-memory-mcp holds no credentials, makes no network calls, labels every tool as read-only or destructive, and refuses to index your home directory and credential folders. As shipped it can index any other directory you can read, exposes its write tools, and runs its git, grep and find helpers unsandboxed, so the safest setup declares a root, picks a read-only tool profile and contains the process.

SetupHowWhat it gives you
A declared project rootSet CBM_ALLOWED_ROOT=<project dir> in the server's environment, or record each root with allow-root <path>Indexing and source reads stay inside the projects you named C1
A read-only tool profileAdd --tool-profile scout to the server command, or --tool-profile=analysis when the task needs code search and diffsThe write tools are left out, and scout also leaves out the tools that call git and grep C3
Its own container or VMRun the server in a container or VM with only the project mounted, a minimal environment and no networkAn outer boundary around the git, grep and find helpers, which otherwise run with your full user rights C4
Indexes you build yourselfIndex repositories you didn't write from a checkout that has no committed graph snapshotThe graph the model reads comes from the source itself, not from a file someone committed C6
Index size limitsconfig set index_max_files <n> and config set index_max_source_mb <n>Indexing an unexpectedly large tree stops at a size you chose C10
Watcher only when neededconfig set auto_watch false when you don't need automatic re-indexingNo background re-index work runs outside the calls you make C10

Approving with confidence

  • Read each prompt and approve calls one at a time; delete_project and manage_adr writes have no preview or undo.
  • ADR text is returned to the model in later sessions, so read what a manage_adr call will store before approving it.

Handling data

  • Index databases in the cache folder hold source text unencrypted; store the cache like the repositories it covers.
  • The request log records tool names and timings only; keep your host's transcript if you need to know what each call did.

Key gaps (1)

  1. Helper git, grep and find commands are built as shell strings that include model-supplied values, guarded only by a character filter, and run unsandboxed as the user with the inherited environment. C4 · Code-execution isolation

Criteria

C1 Identity & least privilege

0.47 / 1.00

The server holds no credentials and talks to no outside service; it runs as the local user and reads and writes files with that user's rights. Its main narrowing is a workspace policy that refuses to index the home directory, shallow system paths and known credential folders such as .ssh and .aws, plus an optional allowed-root setting and per-user grants managed from the command line. With nothing configured, any other directory the user can read can be indexed and its source returned, so the narrowing is a short deny list rather than a least-privilege allowlist.

C2 Approval gates

0.63 / 1.00

As a tool server it relies on the MCP host to ask the user before calls, and it gives the host accurate information to decide with: every one of its 17 tools carries hard-coded read-only and destructive labels, and only index_repository, manage_adr and delete_project are marked as writing. A server-enforced read-only tool profile exists, but it is only used when the client launches the server with that flag; the default entry exposes all tools. There is no dry-run or preview for the destructive tools, and deleting an index or replacing an ADR has no undo, though both affect only local data.

C3 Tool & action scoping

0.57 / 1.00

Tools are narrow, purpose-built graph operations rather than general shells or HTTP clients. File reads are checked against the indexed root after resolving symlinks, project names are validated, result sizes and traversal depths are clamped, and the Cypher interface accepts only a read subset. Weaker spots: arguments that reach helper commands are checked with a character deny list, the index root is not restricted beyond the sensitive-root deny list by default, and the default tool set includes the three write tools.

C4 Code-execution isolation

0.25 / 1.00

The server has no tool that runs model-written code, but several tools (search_code, detect_changes and the git-history passes) build command lines for git, grep and find as shell strings that include model-supplied values such as search scopes, file patterns and branch names. The only guard is a character filter that rejects quotes, semicolons, pipes and similar metacharacters; there is no sandbox, and the helpers run on the host as the user with the full environment apart from git's repository variables. No second layer sits behind that filter: the helpers have the same reach as the user.

C5 Untrusted input blast radius

0.42 / 1.00

Everything the server returns comes from repository content the user did not write, such as source code, comments and docstrings. Results are structured: code comes back with its file path and line numbers, and the server's own guidance sits in separate hint fields rather than mixed into the content. Nothing marks repository text as untrusted for the host. The installed hooks also push repository-derived symbol names into some agents' context outside any tool call. The server itself has no outbound channel, but its write tools and the host's own tools remain available to a hijacked model.

C6 Memory, context & configuration integrity

0.30 / 1.00

The server keeps a persistent graph per project and an architecture decision record (ADR) that the model can overwrite at will through manage_adr; that text is stored in the project database and returned in later sessions with no review or history. When a repository contains a committed graph snapshot (.codebase-memory/graph.db.zst) and there is no local index yet, it is imported automatically; the source notes that imported content is trusted as-is. The only repository file that can widen what the server indexes, a manifest of extra roots, needs an explicit approval from the command line that lapses when the file changes. The per-project config file can only map file extensions.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads no third-party code at runtime: its 158 language grammars, the embedding model and SQLite are compiled into the binary, SQLite extension loading is compiled out, and it installs no packages or plugins. Updates are done by the install script or a package manager, never by the running server.

C8 Secrets & sensitive-data protection

0.65 / 1.00

The server holds no API keys or tokens, sends nothing to any third party and has no telemetry. Its configuration scanners drop values that look like secrets before storing them in the graph, private key files are skipped during discovery, and the request log records only tool names and timings, never arguments or results. Source returned to the model is not redacted, though: search_code and get_code_snippet return whatever the files contain, and helper processes inherit the full environment.

C9 Audit & traceability

0.38 / 1.00

Every tool call handled by the shared daemon is logged with the tool name, error status and duration to an owner-only log file in the user's cache folder, outside the indexed repository. The log does not record arguments, the project acted on or which client asked, so it cannot show what a call actually did. The file is capped at 5 MB with one rotated copy, and logging failures do not stop actions.

C10 Limits & kill switch

0.50 / 1.00

The server bounds most of its own work: Cypher queries and code searches stop after 30 seconds, traversal limits and snippet sizes are clamped to hard ceilings, and in-flight indexing and searches can be cancelled when the client goes away. Indexing size limits are off by default, the stdio bridge waits up to 24 hours for a request, and asynchronous index jobs and the background watcher keep running until the shared daemon stops.