BoundBench

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

Moderate

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.

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

Minimal 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

Moderate 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

Moderate 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

Minimal 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

Minimal 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

Minimal 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

Moderate 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

Minimal 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

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