Skip to main content
Glama
hypnwtykvmpr

filesystem-ts

by hypnwtykvmpr

filesystem-ts

Standalone TypeScript server implementing the Model Context Protocol (MCP) for filesystem operations with robust security, encoding support, and cross-platform path handling.

Provenance

Originally derived from modelcontextprotocol/servers/src/filesystem. This fork is maintained independently and is not affiliated with or published by the upstream MCP servers project.

Maintenance Policy

This repository is public for source availability and transparency. It is offered as-is and is not maintained as a public project.

External pull requests are not accepted. Changes may be made by the repository owner at the owner's discretion, but no support, roadmap, compatibility commitment, release cadence, or ongoing maintenance is promised. If you want different behavior, policy, packaging, or maintenance priorities, fork the project under the MIT License and maintain your own version.

Features

  • Read/write/append files with encoding support, BOM detection, binary content warnings, parent directory creation, and safe overwrite via atomic writes

  • Line-aware reading and editing with ranges, head/tail, around-line context, match extraction, numbered output, line-range replacement, and insertion

  • Edit files with exact match, whitespace-trimmed match (indentation-preserving), fuzzy matching with actionable feedback, and optional hash guards

  • Read media files as MCP image/audio content with automatic MIME type detection for supported raster/audio formats

  • Create/list directories recursively, with metadata, sorting, depth limits, hidden-file filtering, structured entries, and summary statistics

  • Directory trees as JSON with glob-based exclusion patterns and depth limiting

  • Rename files/directories within the same allowed directory root with destination-exists protection

  • Search files and contents by substring, regex, or glob with case sensitivity, max results, path/content targeting, context lines, and truncation warnings

  • Get file metadata including batch metadata, symlink detection, MIME type, and line count

  • Assistant-friendly structured output on core tools, while preserving text-first defaults for existing clients

  • MCP Roots protocol support for dynamic allowed root updates (file:// directories and files)

  • Cross-platform path normalization (macOS, Linux, Windows, UNC, WSL)

Security: The server only allows operations within configured filesystem roots. Directory roots allow their descendants, file roots allow that exact file, symlink targets are validated before content reads and metadata reads, Unix device/system paths are blocked, null bytes are rejected, and atomic writes prevent data corruption when a directory root permits safe temporary files.

Crash Cleanup and Memory Handling

  • The server does not keep a persistent cache of file contents. Allowed roots are kept in process memory; file data read from disk is held only for the active tool call and is then released to normal JavaScript garbage collection.

  • Full-file reads, read_multiple_files, edits, diffs, and media responses may hold complete file contents in memory for that request. head, tail, file line counting, and directory/content search use chunking or limits where practical; content search skips files above max_file_bytes.

  • Overwrites use same-directory temporary files followed by rename when the target is inside an allowed directory root. Temporary files are tracked while in flight, removed on write/rename failure, and cleaned up best-effort on SIGHUP, SIGINT, SIGTERM, Windows SIGBREAK, uncaught exceptions, and unhandled rejections.

  • Hard termination such as SIGKILL, process abort, OS crash, or power loss cannot run cleanup handlers. In those cases an in-flight atomic write may leave a sibling file matching target.<random>.tmp; the original target should remain intact unless the filesystem itself failed during rename.

  • The public tools do not expose file deletion. Internal cleanup only unlinks temp files that the server created and tracked for an active atomic write. rename_file uses rename only; cross-root renames and cross-device copy/delete emulation are refused.

  • create_backup: true backups are intentionally persistent and are not cleaned up automatically.

Architecture

The server is modularized into four source files:

Module

Purpose

constants.ts

Error codes, supported encodings, thresholds

path-utils.ts

Path normalization, comparison, home expansion

lib.ts

State management, validation, file operations, helpers

index.ts

Server setup, schemas, tool registrations, MCP Roots, startup

Error Codes

When a tool call results in an error (isError: true), the result object contains an errorCode field:

  • INVALID_ARGS — Input arguments failed validation or contained logical inconsistencies

  • INVALID_ENCODING — Unsupported encoding specified

  • ACCESS_DENIED — Path outside allowed roots or symlink restriction

  • PERMISSION_DENIED — Insufficient filesystem permissions

  • PATH_NOT_FOUND — Specified path or parent does not exist

  • DESTINATION_EXISTS — Target path already exists (for rename_file or write_file without overwrite: true)

  • EDIT_MATCH_UNCERTAIN — Fuzzy match found (>=80% similarity) but no exact/trimmed match; includes context snippet

  • EDIT_MATCH_NOT_FOUND — No match found at all; includes file line count and searched text

  • ENCODING_ERROR — File content could not be decoded with the requested encoding

  • FILESYSTEM_ERROR — Generic underlying filesystem error

Tools

Most text-returning tools include structuredContent.content with the same text shown in the MCP content block. Newer assistant-facing options add richer structured fields such as entries, files, matches, lines, and truncation metadata. The optional output_format flag accepts:

  • text (default): keep the normal human-readable text response

  • structured: render the structured object as JSON text

  • both: keep normal text and return structured fields

The structuredContent object is returned regardless of output_format; the flag only changes the rendered text block.

read_file

Read file contents. Supports full file, line range, head (first N lines), tail (last N lines), around-line context, and match extraction.

  • Inputs: path, mode?, start_line?, end_line?, head?, tail?, line?, before?, after?, pattern?, search_mode?, case_sensitive?, max_matches?, max_bytes?, max_lines?, show_line_numbers?, output_format?, encoding?

  • Constraints: head/tail are mutually exclusive with start_line/end_line and with each other

  • Mode inference: if mode is omitted, the server infers head, tail, range, or full from the legacy arguments

  • Around-line read: mode: "around", line, optional before/after

  • Match read: mode: "matches", pattern, search_mode (substring/regex), optional context controls

  • Structured fields: lines for line-based reads, matches for match reads, lineCount, startLine, endLine

  • Result: may include warningCode: 'END_OUT_OF_BOUNDS', CONTENT_TRUNCATED, bomDetected, or 'BINARY_CONTENT_DETECTED'

read_text_file

Read a text file with optional head/tail line limiting. Simpler interface than read_file.

  • Inputs: path, head?, tail?

read_media_file

Read a supported raster image or audio file as MCP image/audio content with automatic MIME type detection.

  • Inputs: path

  • Returns: MCP content with type (image or audio), data (base64), and mimeType

  • Unknown or active-content file types: returns a text notice plus structured { mimeType, size }; arbitrary binary data is not read into the response or exposed through this tool

read_multiple_files

Read multiple files simultaneously. Individual errors are reported inline without stopping the batch.

  • Inputs: paths, encoding?, output_format?

  • Structured fields: files array with { path, success, content? } or { path, success: false, errorCode, error }

write_file

Create, append, or overwrite files with atomic writes and wx flag safety.

  • Inputs: path, content, encoding?, append?, create_parents?, overwrite?, dryRun?, expected_hash?, expected_modified?, create_backup?, return_diff?, output_format?

  • Error: DESTINATION_EXISTS if file exists and overwrite is not true (message includes file size and modification time)

  • Dry run: validates and returns the proposed diff without writing

  • Hash/time guards: reject the write if the current SHA-256 hash or modified timestamp does not match

  • Backups: create_backup: true creates a sibling backup before changing an existing file; exact-file roots cannot create backup siblings unless a directory root also allows them

edit_file

Make edits with exact text matching, line-range replacement, or line insertion.

  • Inputs: path, edits, encoding?, dryRun?, expected_hash?, show_line_numbers_on_error?, output_format?

  • Text edit form: { oldText, newText } tries exact match, whitespace-trimmed match, then fuzzy match

  • Line replacement form: { start_line, end_line, newText } replaces the inclusive 1-based line range

  • Insertion form: { insert_at_line, newText } inserts before the given 1-based line

  • Returns: Git-style diff on success

  • Errors: EDIT_MATCH_UNCERTAIN (with context), EDIT_MATCH_NOT_FOUND (with line count)

create_directory

Create a directory, including parents. Succeeds silently if exists.

  • Inputs: path

list_directory

List directory contents with optional recursion, metadata, sorting, and summary.

  • Inputs: path, recursive?, include_metadata?, include_hidden?, include_errors?, maxDepth?, fields?, sortBy? (name/size/modified), order? (asc/desc), output_format?

  • Defaults: hidden files are included by default to preserve existing behavior; set include_hidden: false to hide dotfiles

  • Depth: with recursive listing, maxDepth: 1 lists direct children only

  • Structured fields: entries array with path, relative path, type, depth, optional size/modified, and error details

  • Summary line (when include_metadata is true): total files, directories, and size

list_directory_with_sizes

List directory contents with file sizes and modification times.

  • Inputs: path, sortBy? (name/size)

directory_tree

Get a recursive directory tree as JSON with exclusion patterns and depth limiting.

  • Inputs: path, excludePatterns?, maxDepth?

rename_file

Rename files/directories within the same allowed directory root. Fails if destination exists. Cross-root renames are refused so the tool cannot be used to remove a file from one root as a delete workaround. Cross-device renames are also refused because the server does not emulate rename with copy/delete.

  • Inputs: source, destination

search_files

Recursively search file/directory names, relative paths, file contents, or all targets.

  • Inputs: path, pattern, search_mode? (substring/regex/glob), excludePatterns?, case_sensitive?, max_results? (default 1000), match_path?, target?, content_pattern?, include_context?, before?, after?, show_line_numbers?, max_file_bytes?, max_matches_per_file?, binary_policy?, output_format?

  • Targets: name, path, content, or all; default is name, or path when legacy match_path: true is used

  • Content search: supports substring and regex; glob remains for path/name matching

  • Structured fields: matches, paths, contentMatches, totalMatches, truncated, and skippedFiles

  • Result: May include warningCode: 'RESULTS_TRUNCATED' with totalMatches

get_file_info

Get detailed file/directory metadata including symlink detection and MIME type. Supports single-path and batch metadata calls.

  • Inputs: path?, paths?, resolve?, explain_access?, include_line_count?, include_mime?, include_symlink?, output_format?

  • Single path: behaves like the legacy call and errors at the top level if metadata cannot be read

  • Batch paths: returns structured per-path success/error entries without failing the whole batch

  • Returns: size, dates, permissions, isSymlink?, symlinkTarget?, resolvedPath?, mimeType?, lineCount?

list_allowed_directories

Returns the list of filesystem roots the server is allowed to access. The tool keeps the standard name for client compatibility, but roots may be directories or exact-file roots.

  • Inputs: None

Supported Encodings

utf8, utf-8, ascii, latin1, base64, hex, ucs2, utf16le

BOM detection and stripping is automatic for UTF-8, UTF-16 BE, and UTF-16 LE.

Usage

This fork is intended to run from a local checkout. Do not configure clients to fetch it from a public package registry.

Build The Local Checkout

From this repository:

npm run build

This writes the runnable server to dist/index.js.

MCP Client Configuration

{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": [
        "/path/to/filesystem-ts/dist/index.js",
        "/Users/username/Desktop",
        "/path/to/other/allowed/dir"
      ]
    }
  }
}

If your MCP client supplies roots through the MCP Roots protocol, omit the filesystem root arguments and point the client at the local built server:

{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": [
        "/path/to/filesystem-ts/dist/index.js"
      ]
    }
  }
}

MCP Roots Protocol

If no command-line directories are provided, the server waits for the client to supply roots via the MCP roots protocol. MCP roots must use file:// URIs and may refer to directories or files. Directory roots allow operations within the directory; file roots allow operations on that exact file. Relative tool paths resolve against configured directory roots. The server also supports dynamic updates via roots/list_changed notifications.

License

This MCP server is licensed under the MIT License. The original filesystem server code was derived from the Model Context Protocol servers project; see Provenance and LICENSE.

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

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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/hypnwtykvmpr/filesystem-ts'

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