Security Considerations When Deploying the Code-Graph-RAG MCP Server

The MCP server binds only to loopback interfaces by default and requires a bearer token for remote exposure, with all secrets consumed exclusively via environment variables and tool operations sandboxed to the project root.

Deploying the Model Context Protocol (MCP) server from the vitali87/code-graph-rag repository requires careful attention to trust boundaries, as it serves as the primary integration point for Claude Code and other MCP clients. The codebase implements defense-in-depth controls ranging from network-layer restrictions to application-level sandboxing, but operational security depends on proper configuration of environment variables and network policies.

Network Exposure and Authentication Controls

The HTTP transport layer represents the most critical attack surface. By default, the server refuses to bind to non-loopback interfaces without explicit authentication credentials.

Loopback-Only Binding by Default

In codebase_rag/mcp/server.py, the _validate_http_exposure function (lines 10‑18) enforces that the server only accepts connections from 127.0.0.1, ::1, or localhost unless additional safeguards are in place. This prevents accidental exposure of the MCP endpoint to the local network or internet.

Bearer Token Authentication for Remote Access

When you must expose the server beyond localhost, the code requires the MCP_HTTP_AUTH_TOKEN environment variable. The _require_bearer_auth middleware (lines 20‑53) performs constant-time comparison of the Bearer token, returning HTTP 401 for invalid or missing credentials. This mitigation addresses drive-by attack vectors (issue #808).

Start the server with authentication for remote hosts:

export MCP_HTTP_AUTH_TOKEN="s3cr3t-token"
python -m codebase_rag.cli mcp-server --http --host 0.0.0.0 --port 9000

Attempting to bind to 0.0.0.0 without the token raises a ValueError:

python -m codebase_rag.cli mcp-server --http --host 0.0.0.0

# → ValueError: MCP HTTP exposure refused for host 0.0.0.0

Secret Management and Credential Protection

The architecture strictly separates secrets from persisted data to prevent credential leakage into the knowledge graph.

Environment-Variable-Only Secrets

According to the security requirements documented in docs/architecture/security.md (lines 15‑17), all sensitive values—including LLM API keys and the MCP HTTP token—must be read from environment variables (MCPEnvVar). The system never writes these values to the graph database or source files, ensuring that repository indexing does not capture authentication material.

No Bespoke Cryptography

The codebase delegates transport encryption to httpx, which defaults to TLS with certificate verification. No custom cryptographic implementations are present, reducing the risk of algorithmic vulnerabilities.

Tool Sandboxing and File System Access

The MCP server exposes tools capable of editing files and executing shell commands, necessitating strict sandboxing.

Project-Root Confinement

In codebase_rag/mcp/tools.py, the create_mcp_tools_registry function scopes all file-system operations to the project_root returned by get_project_root. Path-traversal checks prevent tools from escaping the indexed repository boundary.

Permission Modes

The default permission mode runs a whitelist of safe operations. Destructive operations require explicit user opt-in via YOLO mode, with all invocations logged via lg.MCP_SERVER_CALLING_TOOL for audit trails.

Parsing Untrusted Code

When indexing third-party repositories, the parsing frontend selection impacts security.

Frontend-Specific Risks

As noted in docs/architecture/security.md (lines 23‑24), the C# frontend utilizes Roslyn, which executes dotnet restore and source generators during analysis. For untrusted codebases, set CSHARP_FRONTEND=treesitter to avoid arbitrary code execution during the build phase. Tree-sitter parsers provide memory-safe analysis without invoking build tools.

Infrastructure Hardening

Supporting infrastructure requires additional hardening beyond the MCP server itself.

Database Container Exposure

By default, Docker publishes Memgraph and Qdrant ports on all network interfaces. According to the security documentation, these should be bound to loopback (issue #1012) and treated with the same confidentiality as source code, as they contain the indexed graph structure and embeddings.

Configuration Safety

Environment variables such as CGR_EMBEDDING_PROVIDER and TARGET_REPO_PATH determine whether code snippets leave the local machine. Review these settings in README.md and docs/guide/mcp-server.md to ensure data residency requirements are met.

Summary

  • Loopback-only HTTP binding prevents unintended network exposure by default in codebase_rag/mcp/server.py.
  • Bearer-token authentication is mandatory for non-loopback binds, enforced by _require_bearer_auth with constant-time comparison.
  • Environment-variable isolation keeps secrets out of the graph database, satisfying the security model defined in docs/architecture/security.md.
  • Project-root sandboxing constrains tool operations to the indexed repository, with destructive actions gated behind YOLO mode.
  • Frontend selection mitigates arbitrary code execution risks when parsing untrusted C# repositories.

Frequently Asked Questions

What happens if I try to expose the MCP server without setting MCP_HTTP_AUTH_TOKEN?

The server will raise a ValueError during startup. The _validate_http_exposure function in codebase_rag/mcp/server.py checks the bind address against a whitelist of loopback interfaces (127.0.0.1, ::1, localhost) and refuses to start if the host is non-loopback and no token is present.

How does the server protect against credential leakage into the graph?

The security model explicitly forbids persisting secrets in the graph. All credentials—including LLM keys and the MCP HTTP token—are read from environment variables at runtime and are never written to disk or the graph database, as documented in docs/architecture/security.md lines 15‑17.

Can MCP tools delete files outside the indexed repository?

No. Tools are sandboxed to the project_root directory resolved by get_project_root. The tool registry in codebase_rag/mcp/tools.py implements path-escape checks to prevent traversal attacks. Destructive operations require explicit YOLO mode activation and are logged for audit purposes.

Is it safe to analyze untrusted repositories with the C# frontend?

You should set CSHARP_FRONTEND=treesitter for untrusted code. The default Roslyn frontend executes dotnet restore and source generators during parsing, which may run arbitrary build scripts. The Tree-sitter frontend performs static analysis without invoking the build system, eliminating this execution risk.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →