Narsil MCP服务器Docker镜像

这是一个社区维护的多架构Docker镜像,用于容器化部署Narsil MCP服务器,为AI代理提供深度代码智能分析能力,包括符号搜索、调用图、安全分析和依赖检查等。

  • by MekayelAnik
  • Shell
  • 混合部署
  • 1 星标
  • 更新于
在 GitHub 查看 MekayelAnik/narsil-mcp-docker

使用说明

Narsil MCP Server - Docker Image

Unofficial Multi-Architecture Docker Image for Narsil MCP Server

Overview

This is an unofficial, community-maintained Docker image that packages the Narsil MCP Server for containerized deployment. It enables AI agents (Claude Code, VS Code Copilot, Cursor, Windsurf, etc.) to perform deep code intelligence via the Model Context Protocol (MCP).

Upstream: github.com/postrv/narsil-mcp (MIT OR Apache-2.0)

Key Features

  • Multi-Architecture Support - Native support for x86-64 and ARM64
  • Modern MCP Bridge - mcp-proxy stdio↔StreamableHTTP/SSE; stateful, one shared child per session (no spawn-per-request leak)
  • 90 Code Intelligence Tools - Symbol search, call graphs, security analysis, SBOM, and more
  • 32 Language Support - Rust, Python, TypeScript, Go, Java, C#, and 26 more via Tree-sitter
  • Secure by Design - API key auth (case-insensitive Bearer), CORS, TLS termination, security headers
  • High Performance - HAProxy with QUIC/HTTP3 support, ZSTD compression

Available Narsil MCP Tool Categories

Category Examples
Repository & File Management list_repos, get_project_structure, get_file, reindex
Symbol Search & Navigation find_symbols, get_symbol_definition, find_references
Code Search search_code, semantic_search, hybrid_search, find_similar_code
Call Graph Analysis get_call_graph, get_callers, get_callees, get_complexity
Security Analysis find_injection_vulnerabilities, scan_security, check_owasp_top10
Supply Chain Security generate_sbom, check_dependencies, check_licenses
Git Integration get_blame, get_file_history, get_hotspots, get_contributors
Neural Semantic Search neural_search, find_semantic_clones
Type Inference infer_types, check_type_errors
Data Flow Analysis get_data_flow, find_dead_code, find_dead_stores
SPARQL / Knowledge Graph sparql_query, get_ccg_manifest, export_ccg

Buy Me a Coffee

Your support encourages me to keep creating/supporting my open-source projects. If you found value in this project, you can buy me a coffee to keep me inspired.

Quick Start

Prerequisites

  • Docker Engine: 23.0+

CRITICAL: Do NOT expose this container directly to the internet without proper security measures (reverse proxy, SSL/TLS, authentication, firewall rules).


Docker Compose (Recommended)

services:
  narsil-mcp:
    image: mekayelanik/narsil-mcp:latest
    container_name: narsil-mcp
    restart: unless-stopped
    ports:
      - "8010:8010"
      # Optional: HTTP visualization frontend (requires NARSIL_HTTP=true)
      # - "3000:3000"
    volumes:
      - /path/to/your/repos:/data:ro
      - narsil-cache:/home/narsil/.cache         # Persist embedding model cache
    environment:
      - PORT=8010
      - INTERNAL_PORT=38011
      - PUID=1000
      - PGID=1000
      - TZ=UTC
      - NODE_ENV=production
      - PROTOCOL=SHTTP
      - ENABLE_HTTPS=false
      - HTTP_VERSION_MODE=auto
      - DATA_DIR=/data
      - NARSIL_GIT=true
      - NARSIL_CALL_GRAPH=true
      - NARSIL_PERSIST=true
      - NARSIL_STREAMING=true
      # Optional: Neural semantic search
      # - NARSIL_NEURAL=true
      # - VOYAGE_API_KEY=your-voyage-key
      # Optional: HTTP visualization frontend
      # - NARSIL_HTTP=true
      # - NARSIL_HTTP_PORT=3000
      # Optional: require Bearer token auth at HAProxy layer
      # - API_KEY=replace-with-strong-secret
      # Optional: CORS origins
      # - CORS=*

volumes:
  narsil-cache:
    driver: local

Docker Run

docker volume create narsil-cache
docker run -d \
  --name=narsil-mcp \
  --restart=unless-stopped \
  -p 8010:8010 \
  -v /path/to/your/repos:/data:ro \
  -v narsil-cache:/home/narsil/.cache \
  -e PORT=8010 \
  -e PROTOCOL=SHTTP \
  -e NARSIL_GIT=true \
  -e NARSIL_CALL_GRAPH=true \
  -e NARSIL_PERSIST=true \
  mekayelanik/narsil-mcp:latest

# With HTTP visualization frontend enabled:
docker volume create narsil-cache
docker run -d \
  --name=narsil-mcp \
  --restart=unless-stopped \
  -p 8010:8010 \
  -p 3000:3000 \
  -v /path/to/your/repos:/data:ro \
  -v narsil-cache:/home/narsil/.cache \
  -e PORT=8010 \
  -e PROTOCOL=SHTTP \
  -e NARSIL_GIT=true \
  -e NARSIL_CALL_GRAPH=true \
  -e NARSIL_PERSIST=true \
  -e NARSIL_HTTP=true \
  mekayelanik/narsil-mcp:latest

Access Endpoints

Service Endpoint Description
MCP (SHTTP) http://host-ip:8010/mcp Streamable HTTP MCP endpoint (recommended)
MCP (SSE) http://host-ip:8010/sse Server-Sent Events MCP endpoint
HTTP Frontend http://host-ip:3000 Visualization frontend (requires NARSIL_HTTP=true)
Health http://host-ip:8010/healthz Health check endpoint

When HTTPS is enabled (ENABLE_HTTPS=true), use TLS endpoints:

Service Endpoint
MCP (SHTTP) https://host-ip:8010/mcp
MCP (SSE) https://host-ip:8010/sse
MCP (WS) wss://host-ip:8010/message

Security Warning: The container defaults to HTTP (ENABLE_HTTPS=false) for easier local setup. Use ENABLE_HTTPS=true with your own certificates for production. See CERTIFICATE_SETUP_GUIDE.md for instructions.


Configuration

Complete Environment Variables Reference

Core Settings

Variable Default Possible Values Description
PORT 8010 1-65535 External HAProxy listening port
INTERNAL_PORT 38011 1-65535 Internal mcp-proxy port (do not expose)
PROTOCOL SHTTP SHTTP, SSE MCP transport. mcp-proxy exposes both /mcp and /sse simultaneously; this flag chooses the default routed path. WS removed (unsupported by mcp-proxy)
MCP_PROXY_STATELESS false true, false mcp-proxy mode. false=stateful (shared stdio child, no TTL — required for narsil's index-ready gate); true=per-request isolation (memory-hostile, breaks indexing)
NARSIL_MAX_MEM_MB 0 0-N prlimit --as MiB cap per narsil stdio child (0=off)
HAPROXY_FRONTEND_MAXCONN 0 0-N HAProxy frontend max concurrent client conns (0=off)
HAPROXY_SERVER_MAXCONN 0 0-N HAProxy→mcp-proxy max concurrent conns (0=off)
PUID 1000 Any valid UID Process user ID
PGID 1000 Any valid GID Process group ID
TZ UTC Any timezone Container timezone
NODE_ENV (empty) production, etc. Deployment mode flag (triggers HTTPS-off security warning when set to production)
DATA_DIR /data Any path Directory for mounted repositories

Narsil MCP Feature Flags

Variable Default Possible Values Description
NARSIL_GIT false true, false Enable git blame, history, contributors
NARSIL_CALL_GRAPH false true, false Enable function call graph analysis
NARSIL_PERSIST false true, false Save index to disk for fast startup
NARSIL_WATCH false true, false Auto-reindex on file changes
NARSIL_LSP false true, false Enable LSP for hover, go-to-definition
NARSIL_STREAMING false true, false Stream large result sets
NARSIL_REMOTE false true, false Enable GitHub remote repo support
NARSIL_NEURAL false true, false Enable neural semantic embeddings
NARSIL_GRAPH false true, false Enable SPARQL/RDF knowledge graph and CCG tools
NARSIL_VERBOSE false true, false Enable verbose logging
NARSIL_REINDEX false true, false Force re-index on startup (once per container lifecycle)
NARSIL_HTTP false true, false Enable visualization frontend HTTP server

Narsil MCP String Settings

Variable Default Possible Values Description
NARSIL_INDEX_PATH ~/.cache/narsil-mcp Any path Custom persistent index storage path
NARSIL_DISCOVER (empty) Directory path Auto-discover repositories in a directory path
NARSIL_REPOS_MODE auto auto, single, subdirs How DATA_DIR is interpreted. auto=single if DATA_DIR/.git exists else subdirs; subdirs=each immediate subdir is a separate --repos
NARSIL_HTTP_PORT 3000 1-65535 HTTP visualization frontend port
NARSIL_NO_CACHE false true, false Disable analysis caching
NARSIL_CACHE_TTL 1800 Integer (seconds) Cache TTL in seconds
NARSIL_GRAPH_PATH <index_path>/graph Any path Custom knowledge graph storage path
NARSIL_NEURAL_BACKEND api api, onnx Neural embedding backend
NARSIL_NEURAL_MODEL voyage-code-2 voyage-code-2, text-embedding-3-large, etc. Embedding model name
NARSIL_NEURAL_DIMENSION (auto) Integer (e.g. 3072) Override embedding dimensions
NARSIL_PRESET (empty) minimal, balanced, full, security-focused Tool preset profile
NARSIL_ENABLED_CATEGORIES (empty) Comma-separated Enable specific tool categories
NARSIL_DISABLED_TOOLS (empty) Comma-separated Disable specific tools

Neural Embedding API Keys

Variable Default Description
EMBEDDING_API_KEY (empty) Generic API key for any embedding provider
VOYAGE_API_KEY (empty) Voyage AI specific API key
OPENAI_API_KEY (empty) OpenAI specific API key
EMBEDDING_SERVER_ENDPOINT (empty) Custom embedding API endpoint URL
GITHUB_TOKEN (empty) PAT for NARSIL_REMOTE=true. repo scope enables private repos; raises GitHub API rate limit from 60/h to 5000/h

Neural Embedding Notes

Neural embeddings are optional. Without NARSIL_NEURAL=true, all 80+ core tools work (symbol search, call graphs, security scanning, SBOM, git analysis, type inference, data flow, SPARQL, etc.). Only neural_search and find_semantic_clones require embeddings.

  • API backend (default): Set NARSIL_NEURAL=true + NARSIL_NEURAL_BACKEND=api + an API key. Default model is voyage-code-2 (1024 dims).
  • ONNX backend (local, no API key): Set NARSIL_NEURAL_BACKEND=onnx. Requires manually downloading the model via optimum-cli export onnx. Does not auto-download.
  • Cache persistence: The narsil-cache volume at /home/narsil/.cache persists model files and ONNX caches across restarts.

API backend examples:

# Voyage AI
- NARSIL_NEURAL=true
- NARSIL_NEURAL_BACKEND=api
- NARSIL_NEURAL_MODEL=voyage-code-2
- VOYAGE_API_KEY=your-voyage-key

# OpenAI
- NARSIL_NEURAL=true
- NARSIL_NEURAL_BACKEND=api
- NARSIL_NEURAL_MODEL=text-embedding-3-small
- OPENAI_API_KEY=sk-your-key

# Custom OpenAI-compatible endpoint (e.g., self-hosted embedding server)
- NARSIL_NEURAL=true
- NARSIL_NEURAL_BACKEND=api
- NARSIL_NEURAL_MODEL=Snowflake/snowflake-arctic-embed-xs
- EMBEDDING_SERVER_ENDPOINT=http://your-embedder-host:port/v1
- EMBEDDING_API_KEY=your-key-or-unused
- NARSIL_NEURAL_DIMENSION=384

Narsil MCP Presets

Preset Tools Description
minimal 26 Fast, lightweight (Zed, Cursor)
balanced 51 Good defaults (VS Code, IntelliJ)
full 75+ All features (Claude Desktop, comprehensive analysis)
security-focused varies Security and supply chain tools

Security Settings

Variable Default Possible Values Description
API_KEY (empty) 5-256 printable chars Bearer token for HAProxy authentication
CORS (empty) Origins (comma-separated) or * Allowed CORS origins
ENABLE_HTTPS false true, false Enable TLS termination
TLS_CERT_PATH /etc/haproxy/certs/server.crt File path TLS certificate path
TLS_KEY_PATH /etc/haproxy/certs/server.key File path TLS private key path
TLS_MIN_VERSION TLSv1.3 TLSv1.2, TLSv1.3 Minimum TLS version
HTTP_VERSION_MODE auto auto, h1, h2, h3, h1+h2, all HTTP version negotiation
RATE_LIMIT 0 0-N Max requests per RATE_LIMIT_PERIOD per IP (0 = disabled)
RATE_LIMIT_PERIOD 10s 10s, 1m, 1h, etc. Sliding window for rate limiting
MAX_CONNECTIONS_PER_IP 0 0-N Max concurrent connections per IP (0 = disabled)
IP_ALLOWLIST (empty) Comma-separated IPs/CIDRs IPs/CIDRs to allow (all others blocked)
IP_BLOCKLIST (empty) Comma-separated IPs/CIDRs IPs/CIDRs to block

Boolean values: true, 1, yes, on are all accepted as truthy. Everything else is falsy.

Once per container lifecycle: NARSIL_REINDEX runs only once after the container is created. It is skipped on subsequent restarts (e.g., crash recovery, docker restart). To re-trigger, recreate the container (docker compose down && docker compose up -d).

Healthcheck: The container's healthcheck has a 450-second start period to accommodate the index-ready gate (see WAIT_FOR_INDEX below) plus initial indexing/model loading.

Gateway & Startup Lifecycle

Variable Default Description
WAIT_FOR_INDEX true Block HAProxy startup until narsil finishes initial indexing. Set false for empty-repo dev setups
INDEX_READY_TIMEOUT 300 Seconds to wait for indexing before giving up and starting HAProxy anyway
NARSIL_KEEPALIVE true Periodic tools/list ping to keep the embedded narsil web UI HTTP server reachable. Insurance only — mcp-proxy stateful has no server-side TTL
KEEPALIVE_INTERVAL 240 Seconds between keepalive pings

API Key Authentication Notes

  • Set API_KEY to enforce auth at the reverse proxy level.
  • Header: Authorization: Bearer <API_KEY>.
  • /healthz and CORS preflight (OPTIONS) bypass authentication.

Rate Limiting and IP Access Control

  • Rate limiting: Set RATE_LIMIT=100 to allow 100 requests per RATE_LIMIT_PERIOD (default 10s) per IP. Exceeding the limit returns HTTP 429 with a Retry-After header.
  • Connection limiting: Set MAX_CONNECTIONS_PER_IP=50 to cap concurrent connections per IP. Exceeding returns HTTP 429.
  • IP blocklist: Set IP_BLOCKLIST=192.0.2.0/24,198.51.100.5 to block specific IPs/CIDRs. Blocked IPs receive HTTP 403.
  • IP allowlist: Set IP_ALLOWLIST=10.0.0.0/8,192.168.1.0/24 to allow only listed IPs/CIDRs. All others receive HTTP 403. Localhost is always allowed.
  • All features default to disabled. Combine as needed — blocklist is checked before allowlist.

One-Shot Operations

For ad-hoc operations without setting env vars, use docker exec:

docker exec narsil-mcp narsil-mcp --repos /data --reindex   # Force full re-index

Mounting Repositories for Analysis

Mount your repository directories to /data (or the path specified by DATA_DIR). Each subdirectory becomes an indexable repository.

volumes:
  # Mount entire projects directory
  - /home/user/projects:/data:ro
  # Or mount individual repositories
  - /home/user/my-rust-app:/data/my-rust-app:ro
  - /home/user/my-node-app:/data/my-node-app:ro

Then tell your AI agent to analyze using the mounted path:

  • "Search for symbols in /data/my-rust-app"
  • "Find injection vulnerabilities in /data/my-node-app"
  • "Generate an SBOM for /data/my-rust-app"
  • "Get the call graph for main in /data/my-node-app"

MCP Client Configuration

Claude Code

Add to ~/.claude.json under mcpServers:

{
  "mcpServers": {
    "narsil": {
      "type": "sse",
      "url": "http://host-ip:8010/sse"
    }
  }
}

Or for Streamable HTTP:

{
  "mcpServers": {
    "narsil": {
      "type": "http",
      "url": "http://host-ip:8010/mcp"
    }
  }
}

VS Code / Codex / Cursor / Windsurf

All use the same JSON format. Configure in the respective config file:

  • VS Code: .vscode/settings.json (key: mcp.servers)
  • Codex: ~/.codex/config.json (key: mcpServers)
  • Cursor: ~/.cursor/mcp.json (key: mcpServers)
  • Windsurf: .codeium/mcp_settings.json (key: mcpServers)
{
  "mcpServers": {
    "narsil": {
      "transport": "http",
      "url": "http://host-ip:8010/mcp"
    }
  }
}

Available Tags

Tag Platform Description
latest amd64, arm64 Latest stable release
1.7.2 amd64, arm64 Specific version

License

This Docker image packaging is licensed under the GNU General Public License v3.0.

Upstream Licenses

  • Narsil MCP Server: MIT License OR Apache License 2.0 - Copyright (c) 2024 postrv
  • mcp-proxy: MIT License (stdio↔SHTTP/SSE bridge; replaces supergateway)
  • HAProxy: GNU General Public License v2.0

This is an unofficial community packaging. It is NOT affiliated with, endorsed by, or supported by the narsil-mcp authors. See NOTICE for full attribution.


Buy Me a Coffee

Your support encourages me to keep creating/supporting my open-source projects. If you found value in this project, you can buy me a coffee to keep me inspired.


Maintainer

Mohammad Mekayel Anik