Skip to main content
Glama
donliggett

mcp-filesystem

by donliggett

mcp-filesystem

Un servidor MCP de sistema de archivos endurecido. Proporciona a un modelo local acceso de lectura y escritura a un conjunto de directorios que tú elijas — y nada más.

Construido sobre el MCP TypeScript SDK v2 contra la revisión de protocolo 2026-07-28, con compatibilidad hacia atrás para clientes de la era 2025 en el mismo endpoint. Se ejecuta sobre stdio (para LM Studio, Claude Desktop y cualquier otra cosa que lance un proceso local) o HTTP Streamable (para un endpoint compartido en contenedor).


Por qué este

La mayoría de los servidores MCP de sistema de archivos comprueban que una ruta comienza con un prefijo permitido y lo dan por bueno. Eso pasa por alto tres cosas que importan:

  • Enlaces simbólicos. Un enlace plantado dentro del sandbox que apunte a /etc anula por completo una comprobación de prefijo.

  • Escrituras a través de directorios con enlaces simbólicos. realpath lanza una excepción en rutas que aún no existen, por lo que los servidores que solo resuelven archivos existentes crearán felizmente sandbox/linkdir/payload.sh fuera del sandbox.

  • Colisiones de prefijos. /data-secrets comienza con /data.

Este servidor resuelve cada ruta a su ubicación física antes de decidir — subiendo hasta el ancestro existente más profundo cuando el destino aún no existe — y compara contra raíces resueltas con realpath usando coincidencia sensible a separadores. La suite de pruebas verifica que cada uno de estos escapes falla.


Related MCP server: MCP Filesystem Server

Herramientas

Herramienta

Propósito

read_file

Leer un archivo de texto, con números de línea, paginación (offset/limit) y tail

read_multiple_files

Leer hasta 50 archivos en una sola llamada, compartiendo un presupuesto de bytes

get_file_info

Tamaño, tipo, marcas de tiempo, permisos, detección de texto/binario

list_allowed_directories

Qué es accesible y los límites activos

list_directory

Un nivel, directorios primero, tamaños y marcas de tiempo opcionales

directory_tree

Árbol recursivo indentado, omitiendo node_modules/.git/dist/…

search_files

Buscar por glob (**/*.ts)

grep_files

Buscar contenido de archivos por regex, con líneas de contexto

write_file

Escritura atómica de archivo completo

append_file

Añadir, con normalización opcional de nuevas líneas

edit_file

Reemplazo de cadena exacta, devuelve un diff unificado, soporta dry_run

create_directory

mkdir -p

move_file

Mover/renombrar, seguro entre sistemas de archivos

copy_file

Copiar archivo o árbol

delete_file

Eliminar, con una compuerta explícita recursive

Las escrituras son atómicas: el contenido va a un archivo temporal en el mismo directorio, se hace fsync, y luego se renombra sobre el destino. Un bloqueo o un disco lleno dejan el original intacto en lugar de truncado.


Inicio rápido

npm install
npm run build
npm test

Luego apunta un cliente a él:

node dist/index.js --root ./workspace

O pruébalo interactivamente sin configurar un cliente:

npx @modelcontextprotocol/inspector node dist/index.js --root ./workspace

LM Studio

LM Studio lee ~/.lmstudio/mcp.json (en Windows, C:\Users\<tu>\.lmstudio\mcp.json). Ábrelo desde Programa → Instalar → Editar mcp.json, añade una entrada bajo mcpServers y luego recarga LM Studio.

Ejecutarlo de forma nativa

La opción de menor fricción, y con la que empezar.

{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": [
        "/absolute/path/to/mcp-file-system/dist/index.js",
        "--root", "/absolute/path/to/your/project",
        "--read-only"
      ]
    }
  }
}

Añade --read-only una vez que confíes en él. Añade más banderas --root para más directorios.

Estas dos rutas deben ser absolutas. El host lanza el servidor como un proceso hijo con un directorio de trabajo impredecible, por lo que una ruta relativa no se resolverá. En la línea de comandos, donde controlas el directorio de trabajo, rutas relativas como --root ./workspace están bien.

En Windows, escribe barras inclinadas (C:/Users/tu/proyectos) o duplica las barras invertidas, ya que una sola \ es un carácter de escape dentro de una cadena JSON.

Ejecutarlo en Docker

Docker te da un límite impuesto por el kernel debajo de las propias comprobaciones del servidor, que es el argumento real para usarlo: incluso un error en el código del sandbox no puede alcanzar nada que no hayas montado.

docker build -t mcp-filesystem:latest .
{
  "mcpServers": {
    "filesystem": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm", "--init",
        "--network", "none",
        "-v", "/absolute/path/to/your/project:/data:ro",
        "mcp-filesystem:latest",
        "--stdio", "--read-only"
      ]
    }
  }
}

Notas:

  • -i es obligatorio. Sin él, el contenedor no recibe stdin y el apretón de manos JSON-RPC nunca ocurre — esta es la configuración incorrecta más común.

  • --network none vale la pena configurarlo: este servidor no tiene razón para alcanzar la red, y eliminar la interfaz elimina toda una clase de exfiltración.

  • :ro en el montaje hace que la aplicación de solo lectura sea trabajo del kernel. Para permitir escrituras, quita :ro y quita --read-only.

  • Docker requiere que el lado del host de -v sea una ruta absoluta.

  • En Docker Desktop para Windows, la unidad desde la que montas debe estar compartida en Configuración → Recursos → Uso compartido de archivos.

  • En un host Linux, añade --user "$(id -u):$(id -g)" para que los archivos escritos sean tuyos en lugar de del uid 1000.

Monta varios directorios repitiendo -v y pasando banderas --root coincidentes:

"-v", "/absolute/path/to/your/code:/data/code:ro",
"-v", "/absolute/path/to/your/notes:/data/notes",
"mcp-filesystem:latest",
"--stdio", "--root", "/data/code", "--root", "/data/notes"

Transporte HTTP

Para un contenedor de larga duración que varios clientes compartan:

docker compose up -d
curl http://127.0.0.1:3000/health

Apunta un cliente a http://127.0.0.1:3000/.

Este servidor no tiene autenticación. Cualquiera que pueda alcanzar el puerto tiene el acceso al sistema de archivos que tenga el servidor. docker-compose.yml publica solo en 127.0.0.1. Si lo vinculas a cualquier otro lugar, pon un proxy inverso autenticador delante y espera que el registro de inicio te avise.

Cuando está vinculado a loopback, el servidor valida las cabeceras Host y Origin para bloquear el rebinding de DNS — una página web que visitas resolviendo un dominio controlado por un atacante a 127.0.0.1 y haciendo POST a este puerto.


Configuración

Cada bandera tiene un equivalente en variable de entorno, que es lo que usa el contenedor. Las banderas de CLI ganan.

Bandera

Env

Predeterminado

Significado

--root <dir>

FS_ALLOWED_ROOTS (separadas por comas)

obligatorio

Directorio permitido. Repetible.

--read-only

FS_READ_ONLY

false

Rechazar todas las herramientas de mutación

--deny <glob>

FS_DENY_PATTERNS

ver abajo

Patrones bloqueados adicionales

--allow-default-denied

FS_ALLOW_DEFAULT_DENIED

false

Eliminar la lista de denegación integrada

--follow-symlinks

FS_FOLLOW_SYMLINKS

false

Permitir enlaces simbólicos que permanezcan en el sandbox

--max-read-bytes <n>

FS_MAX_READ_BYTES

10485760

Límite de lectura por archivo

--max-write-bytes <n>

FS_MAX_WRITE_BYTES

10485760

Límite de escritura por archivo

--max-results <n>

FS_MAX_RESULTS

1000

Límite en resultados de listar/buscar/grep

--max-depth <n>

FS_MAX_DEPTH

20

Profundidad de recursión

--stdio / --http

FS_TRANSPORT

stdio

Transporte

--host / --port

FS_HTTP_HOST / FS_HTTP_PORT

127.0.0.1 / 3000

Enlace HTTP

--audit / --no-audit

FS_AUDIT

true

Línea de auditoría JSON por llamada en stderr

El servidor se niega a iniciar sin raíces configuradas. Un servidor de sistema de archivos sin sandbox no es un valor predeterminado seguro, y predeterminar al directorio de trabajo solo hace que el error sea silencioso.

Lista de denegación predeterminada

Bloqueado a menos que pases --allow-default-denied: .env y .env.*, *.pem, *.key, *.p12, *.pfx, *.keystore, id_rsa/id_dsa/id_ecdsa/id_ed25519, .ssh/, .aws/, .gnupg/, .kube/config, .npmrc, .netrc, .pypirc, .docker/config.json, .git/, .svn/, .hg/, shadow.

Esto existe para que un descuidado -v $HOME:/data sea sobrevivible. Es una red de seguridad, no un sustituto de montar el directorio correcto.


Modelo de seguridad

Lo que se aplica

  • Resolución de ruta física (realpath) antes de cada decisión de contención, incluyendo rutas que aún no existen

  • Coincidencia de raíz sensible a separadores (/data nunca coincide con /data-secrets)

  • Enlaces simbólicos rechazados por defecto, en cualquier posición de la ruta — no solo en la hoja

  • Rechazo de bytes NUL (safe.txt\0/../../etc/passwd se trunca en la llamada al sistema)

  • Windows: flujos de datos alternativos (file:stream), nombres de dispositivos reservados (CON, NUL, COM1…), rutas de espacio de nombres de dispositivos (\\?\, \\.\) y contención insensible a mayúsculas

  • El modo de solo lectura bloquea las herramientas de mutación antes de que se ejecute el manejador

  • Ambos operandos se comprueban en move/copy — una comprobación solo de origen es una primitiva de escritura para todo el host

  • Las raíces permitidas no pueden ser eliminadas ni movidas

  • Los límites de tamaño se comprueban mediante stat antes de asignar

  • Detección binaria, para que los binarios no se devuelvan como basura que quema tokens

  • Cribado de regex y un plazo de tiempo real en grep_files

  • Los mensajes de error nunca reflejan rutas del host; SecurityError devuelve un mensaje vago al modelo y registra la razón real en el flujo de auditoría, para que el sandbox no sea un oráculo para mapear tu sistema de archivos

Lo que no se aplica

  • TOCTOU. Entre resolver una ruta y abrirla, un atacante local que pueda escribir dentro de tus raíces permitidas podría intercambiar un archivo por un enlace simbólico. Cerrar esto necesita openat2(RESOLVE_BENEATH) en Linux, que Node no expone. La mitigación práctica es el límite del contenedor — monta solo lo que pretendes exponer.

  • Autenticación. Ningún transporte autentica. stdio hereda la confianza de quien haya lanzado el proceso; HTTP es solo loopback por esa razón.

  • Agotamiento de recursos. Los límites y plazos acotan la mayoría de las cosas, pero un regex patológico aún puede quemar un plazo de 15 segundos de CPU. El archivo compose establece límites de memoria y CPU.

  • Inyección de prompts. Si un archivo dentro de tu sandbox contiene instrucciones y tu modelo las sigue, este servidor ejecutará fielmente cualquier herramienta que el modelo llame a continuación. El modo de solo lectura es la mitigación que realmente funciona.

Endurecimiento del contenedor (en docker-compose.yml): usuario no root, sistema de archivos raíz read_only, todas las capacidades eliminadas, no-new-privileges, tmpfs /tmp, límites de memoria y CPU.


Registro de auditoría

Un objeto JSON por línea en stderr — nunca en stdout, que es el canal JSON-RPC bajo stdio. console.log está parcheado para redirigir a stderr al inicio, para que una declaración de depuración perdida no pueda corromper el flujo del protocolo.

{"ts":"2026-08-21T19:12:03.441Z","tool":"read_file","outcome":"ok","durationMs":3,"paths":["src/index.ts"],"bytes":4821}
{"ts":"2026-08-21T19:12:07.882Z","tool":"read_file","outcome":"denied","durationMs":1,"detail":"physical containment failed: /data/../etc/passwd -> /etc/passwd"}

Las rutas registradas son relativas al sandbox. El campo detail lleva la razón completa y solo se escribe aquí, nunca se devuelve al modelo.

docker compose logs -f filesystem | jq 'select(.outcome=="denied")'

Pruebas

npm run build && npm test

test/sandbox.test.ts es la suite que importa — cada caso es un intento de alcanzar un archivo fuera de la raíz. Si uno de ellos empieza a pasar cuando debería lanzar una excepción, el servidor está roto de la única manera que es genuinamente peligrosa.

Las pruebas de enlaces simbólicos se omiten en Windows a menos que el Modo Desarrollador esté activado, ya que crear enlaces simbólicos de otro modo requiere derechos de administrador.


Estructura del proyecto

src/
  index.ts              entrypoint, transport selection, shutdown
  config.ts             CLI + env parsing, root resolution
  security/
    sandbox.ts          path resolution and containment — the security core
    audit.ts            structured stderr logging, stdout protection
  tools/
    context.ts          registration wrapper: read-only gate, errors, audit
    read.ts             read_file, read_multiple_files, get_file_info, ...
    write.ts            write_file, append_file, edit_file
    listing.ts          list_directory, directory_tree
    manage.ts           create_directory, move_file, copy_file, delete_file
    search.ts           search_files, grep_files
  util/
    walk.ts             sandbox-aware directory traversal with cycle guard
    binary.ts           binary detection, BOM handling
    errors.ts           error taxonomy and fs error translation
    format.ts           output formatting for model consumption

Licencia

MIT

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables secure filesystem operations with directory sandboxing and optional read-only mode. Supports file reading/writing, directory management, file searching, and text operations while restricting access to specified directories.
    12
  • A
    license
    A
    quality
    D
    maintenance
    Provides secure filesystem access for AI models through the Model Context Protocol with strict path validation, file operations, directory management, and system command execution within predefined directories.
    16
    7
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides sandboxed access to local filesystem operations including directory and file management, content search with glob and regex patterns, and binary file support with configurable safety limits.
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a secure, constrained filesystem workspace for LLM agents to manage files, notes, and code artifacts via stdio or remote HTTP. It features granular access controls, including extension whitelisting, storage quotas, and immutable paths for safe automated file operations.
    BSD 3-Clause

View all related MCP servers

Related MCP Connectors

  • Securely search and manage workspace context files for AI agents and teams.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

  • Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/donliggett/mcp-file-system'

If you have feedback or need assistance with the MCP directory API, please join our Discord server