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

> Learn vital security considerations for deploying the Code-Graph-RAG MCP server. Understand default configurations, token authentication, environment variable secrets, and sandboxed operations for secure deployment.

- Repository: [Vitali Avagyan/code-graph-rag](https://github.com/vitali87/code-graph-rag)
- Tags: security-guide
- Published: 2026-08-13

---

**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`](https://github.com/vitali87/code-graph-rag/blob/main/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:

```bash
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`:

```bash
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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/README.md) and [`docs/guide/mcp-server.md`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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`](https://github.com/vitali87/code-graph-rag/blob/main/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.