Cloud replacement for mcp-server-filesystem — 20 tools for S3, Azure Blob, and GCS
io.github.nogoo9/mcp-server-cloud-fs MCP Server
Cloud replacement for mcp-server-filesystem, providing access to cloud storage backends. The project exposes 20 tools covering S3, Azure Blob, and GCS, framed as an MCP server for cloud-based filesystem-style interactions. It is also associated with a cloudfs/virtual-filesystem use of storage.
🛠️ Key Features
Cloud replacement for mcp-server-filesystem
20 tools for S3, Azure Blob, and GCS
🚀 Use Cases
Treating object storage (S3, Azure Blob, GCS) as a filesystem via MCP
Integrating cloud storage operations into MCP-capable agents/tools
⚡ Developer Benefits
Standard MCP server interface for cloud filesystem access
Topics include filesystem, vfs, cloudfs, and mcp-server
⚠️ Limitations
The available description only specifies S3/Azure Blob/GCS and 20 tools; no additional tool behavior or configuration details are included.
Cloud replacement for mcp-server-filesystem — 30 tools for S3, Azure Blob, and GCS.
Deploy locally via STDIO or remotely over HTTP/WebSocket with OAuth 2.1 auth.
Also available as an npm library and interactive TUI.
@nogoo9/mcp-server-cloud-fs exposes all 14 tools defined by mcp-server-filesystem — same tool names, same parameter schemas — over cloud object storage. Drop it into any MCP client config that currently points at mcp-server-filesystem and your AI assistant gains read/write access to S3, Azure Blob Storage, or Google Cloud Storage buckets.
It also includes 5 extended tools inspired by claude-code's filesystem tool surface: line-range reads, byte-range chunk reads, in-process regex search (single file and multi-file), server-side copy, and opt-in deletion. Plus 6 cloud-native tools (presigned URLs, object metadata/tags, tag-based search, version history, version restore), 2 AI-native tools (schema extraction, file summarization), and 1 macro tool (patch_file for atomic diffs).
A Virtual Filesystem (VFS) layer provides FUSE-like cache coherence with ETag-based concurrency control, a shell tool lets you run POSIX-like commands (ls, grep, jq, cat | wc, etc.) against cloud storage, and the package is available as a programmatic npm library.
v0.7.0 Highlights
Dynamic tool surface reduction: scope-aware tool filtering — clients only see tools they're authorized to use
DLP content sanitization: regex-based middleware redacts PII, API keys, and credentials from tool responses (--enable-dlp)
The server supports three MCP transports, selected via --transport:
Transport
Flag
Runtime
Use case
STDIO
--transport stdio (default)
Bun, Node
Local npx, Claude Desktop, Claude Code
Streamable HTTP
--transport http
Bun ✅, Node ✅
Remote deployment, multi-user, enterprise
WebSocket
--transport ws
Bun only
Low-latency bidirectional, real-time apps
Streamable HTTP
Implements the MCP Streamable HTTP specification with a single /mcp endpoint for POST (requests), GET (SSE notifications), and DELETE (session termination).
Dual runtime support:
Bun: Uses WebStandardStreamableHTTPServerTransport with Bun.serve() directly — zero Express dependency, maximum performance.
Node.js: Falls back to StreamableHTTPServerTransport with Express. Requires express as an optional peer dependency (npm install express).
Runtime is auto-detected at startup.
Session management:
Sessions use UUID v7 (RFC 9562) — time-ordered and K-sortable, making them ideal for logging, debugging, and database indexing. Sessions are tracked via the Mcp-Session-Id header.
Resumability:
When an EventStore is configured, clients can reconnect and resume receiving messages from where they left off via the Last-Event-ID SSE header.
Bun-native WebSocket transport using Bun.serve() with WebSocket upgrade handling. Provides lower latency than HTTP for high-frequency tool invocations.
Implements the MCP Client Credentials extension for machine-to-machine authentication without user interaction. Designed for CI/CD pipelines, background services, and automated workflows.
JWT assertion auth (private_key_jwt per RFC 7523) — recommended
Client secret auth (client_secret_basic) — simpler but less secure
No user interaction required — tokens granted based on pre-registered client credentials
All tools + get_file_info, list_allowed_directories
When grantedScopes is set (via OAuth tokens), tools outside the granted scopes are not registered — they don't appear in tools/list at all, reducing LLM prompt token waste and preventing tool hallucination.
Tokens with insufficient scopes receive a clear error response indicating which scope is required.
Production Features
Health Checks
HTTP/WS transports expose Kubernetes-convention health endpoints:
Endpoint
Purpose
Success
Failure
/healthz
Liveness — is the process alive?
200 OK always
Process is dead
/readyz
Readiness — can it serve traffic?
200 OK after VFS hydration
503 during startup
Configure your orchestrator's liveness and readiness probes to use these endpoints.
Rate Limiting
Token bucket rate limiting protects against abuse. Disabled by default.
In-memory — per-IP/per-client counters for single-process deployments
AWS S3, and any S3-compatible endpoint (MinIO, RustFS, Cloudflare R2, Backblaze B2, Wasabi, LocalStack, …)
azure
az://container[/prefix]
Azure Blob Storage
gcs
gs://bucket[/prefix]
Google Cloud Storage
memory
mem://name
In-memory (ephemeral, for demos)
sqlite
sqlite://name
SQLite (persistent local)
Options
Transport & Network
Flag
Default
Description
--transport <stdio|http|ws>
stdio
Transport protocol
--port <number>
3000
Listen port (http/ws only)
--host <address>
127.0.0.1
Bind address (http/ws only)
Authentication
Flag
Default
Description
--auth <none|builtin|external>
none
Auth mode (http/ws only)
--auth-issuer <url>
—
OAuth issuer URL (builtin mode)
--auth-jwks-uri <url>
—
JWKS URI (external mode)
--auth-audience <string>
—
Expected token audience (external mode)
--auth-client-credentials
false
Enable Client Credentials ext-auth flow
--auth-enterprise-idp <url>
—
Enable Enterprise-Managed Authorization
Production
Flag
Default
Description
--cors-origin <origin>
—
Allowed CORS origin (repeatable)
--rate-limit <req/min>
0 (off)
Rate limit per client
--rate-limit-burst <n>
10
Burst allowance
--request-logging
false
Enable structured JSON request logging
--audit-log
false
Enable tool invocation audit logging to stderr
--audit-log-file <path>
—
Write audit log to file (implies --audit-log)
--security-headers
false
Enable security headers via nosecone
--security-headers-config <json>
—
Inline JSON config for nosecone
--security-headers-config-file <path>
—
Load nosecone config from a JSON file
Storage & Cache
Flag
Default
Description
--region <region>
—
Cloud region (S3, GCS)
--endpoint <url>
—
Custom endpoint for S3-compatible backends
--cache-store <memory|fs|redis>
memory
Cache backend
--cache-ttl <seconds>
60
Cache TTL in seconds
--sync-debounce <ms>
2000
Write flush delay in ms
--cache-dir <path>
—
Directory for fs cache store
--no-cache
—
Bypass cache entirely (pass-through mode)
--gcs-endpoint <url>
—
Custom endpoint for GCS
--sqlite-db <path>
—
SQLite database file path
--ca-file <path>
—
PEM CA bundle for TLS (S3-compatible + Redis)
Tools
Flag
Default
Description
--enable-delete
false
Enable the delete_file tool
--enable-shell
false
Enable the shell tool
--enable-dlp
false
Enable DLP content sanitization (redacts PII/secrets from responses)
--grep-max-objects <n>
1000
Max objects grep_files scans per call
--seed-demo
false
Seed VFS with sample files for demo
Credentials are always sourced from SDK credential chains — never CLI flags.
Provider Setup
AWS S3
Credentials are read from the standard AWS credential chain: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY env vars, ~/.aws/credentials, EC2 instance profiles, and so on.
bash
cloud-fs-mcp s3 s3://my-bucket --region us-east-1
S3-compatible storage
Any S3-compatible backend works via --endpoint. All use the standard AWS credential chain (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY).
Provider
--endpoint value
Notes
MinIO
http://minio:9000
Self-hosted; use --ca-file for TLS with a private CA
RustFS
http://rustfs:9000
Rust-native S3-compatible store
LocalStack
http://localhost:4566
Full AWS emulator for local dev and CI
Cloudflare R2
https://<account-id>.r2.cloudflarestorage.com
No egress fees; use an R2 API token as the secret key
TLS with private CA: For MinIO, RustFS, or Ceph with a self-signed certificate, add --ca-file /path/to/ca.pem.
Azure Blob Storage
Uses DefaultAzureCredential — works with AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET env vars, managed identity, az login, and so on.
bash
cloud-fs-mcp azure az://my-container
Google Cloud Storage
Uses Application Default Credentials (ADC). Set GOOGLE_APPLICATION_CREDENTIALS or run gcloud auth application-default login.
bash
cloud-fs-mcp gcs gs://my-bucket
In-Memory (ephemeral)
Zero-config, zero-dependency provider. All data lives in a Map and is lost when the process exits.
bash
cloud-fs-mcp memory mem://demo --enable-shell
SQLite (persistent local)
Persistent local storage using WAL mode. Dual-runtime: uses bun:sqlite on Bun, better-sqlite3 on Node.js (install as peer dep: npm install better-sqlite3).
All paths are cloud URIs — e.g. s3://my-bucket/path/to/file.txt. The server validates every path against the configured root URIs at startup; requests outside allowed roots are rejected.
Read tools
Tool
Parameters
Description
read_file
path
Read a file. Binary → base64; text → UTF-8.
read_text_file
path, head?, tail?
Read text file with optional head/tail line limits.
read_media_file
path
Read image/media as base64 MCP image content block.
read_multiple_files
paths
Read several files in parallel.
read_file_range ✨
path, offset, limit
Read a 1-based line range with total line count header.
read_file_chunk ✨
path, start_byte, end_byte?, encoding?
Read a byte range without downloading the entire file. Max 10MB.
Write tools
Tool
Parameters
Description
write_file
path, content
Write/overwrite a file. Flushed after debounce window.
Built-in commands:ls, cat, head, tail, cp, mv, rm, mkdir, touch, stat, find, grep, wc, du, echo, tee, diff, jq, cd
Relative paths
All shell commands (and all other tools) support relative paths — you don't need to type the full URI every time. Paths without a scheme prefix (s3://, mem://, etc.) are resolved relative to the first configured root:
bash
# With root s3://my-bucket/data, these are equivalent:
shell "cat config.json"
shell "cat s3://my-bucket/data/config.json"# Subdirectories work naturally:
shell "ls logs/"
shell "cat logs/app.log | grep ERROR"# ls with no args lists the root's contents:
shell "ls"# find with no args searches from the root:
shell "find -name '*.json'"
Standard . and .. are normalized, with .. traversal blocked at the root boundary for security.
Examples
bash
# List root contents
shell "ls -l"# JSON query with jq
shell "cat config.json | jq '.database.port'"# Search and count
shell "grep -i error server.log | wc -l"# Write files
shell "echo hello world > greeting.txt"# Copy and diff
shell "cp config.json config.backup.json"
shell "diff config.json config.backup.json"# Full URIs still work for cross-root access
shell "cat s3://other-bucket/file.txt"
⚡ Requires --enable-shell. rm and mv additionally require --enable-delete.
Architecture: Virtual Filesystem (VFS)
All tool operations are mediated through a Virtual Filesystem (VFS) layer inspired by FUSE.
VFS metadata is persisted to the CacheStore under __vfs__/* keys. On startup, VirtualFS.hydrate() restores state; corrupted data is silently discarded.
Caching
Backend
Flag
Notes
Memory (default)
--cache-store memory
In-process, fast, not shared, not persistent.
Filesystem
--cache-store fs --cache-dir <path>
Survives restarts.
Redis
--cache-store redis
Shared, persistent. Requires ioredis peer dep. REDIS_URL env var. Use rediss:// for TLS.
Writes land in cache immediately (marked dirty), flushed after debounce window (default: 2s). Graceful shutdown flushes all dirty entries before exit. Pass-through mode (--no-cache) sends every operation directly to the provider.
⚠️ Redis TLS: The server warns at startup when REDIS_URL uses unencrypted redis://. Use rediss:// for TLS-encrypted connections in production.
Custom CA Certificates
Use --ca-file <path> to supply a PEM CA bundle for S3-compatible endpoints (MinIO, RustFS) and Redis running with a private CA:
bash
# S3-compatible with self-signed CA
cloud-fs-mcp s3 s3://my-bucket \
--endpoint https://minio.internal:9000 \
--ca-file /etc/ssl/certs/my-ca.pem
# Redis with private CA
REDIS_URL=rediss://redis.internal:6380 \
cloud-fs-mcp s3 s3://my-bucket --cache-store redis \
--ca-file /etc/ssl/certs/my-ca.pem
For runtime-wide CA trust (all providers + Redis), use the standard NODE_EXTRA_CA_CERTS env var instead:
# Quick demo (no credentials needed)
bun run inspect:memory
# Custom configuration
bun run inspect -- s3 s3://my-bucket --region us-east-1 --enable-shell
MCP App: Interactive Shell (xterm.js)
Build the app: bun run build:app → outputs dist/app/shell-app.html.
Catppuccin Mocha theme, command history, auto-resize. Renders inside compatible MCP hosts (Claude Desktop) via the MCP Apps extension.
AI agent skills are installed separately after cloning via bun x skills add semgrep/skills — see CONTRIBUTING.md for details.
Test tiers
Tier
Command
Infra?
Unit
bun run test
No
E2E (HTTP)
bun run test:e2e:http
No
E2E (Infra)
bun run test:e2e:infra
Docker
Integration
bun run test:integration
Docker
All
bun run test:all
Docker
CI pipeline
The CI workflow runs on every push/PR:
ci job: lint → typecheck → unit tests (with coverage) → HTTP E2E → build
e2e job: full E2E with Docker Compose (MinIO, Redis)
HTTP E2E tests use the in-memory provider and need zero infrastructure, making them fast and reliable for every CI run.
AI Agent Skill
The skills/cloud-fs directory contains an installable AI agent skill that teaches coding assistants (Claude Code, Gemini CLI, etc.) how to use cloud-fs as a POSIX-like virtual filesystem. Install it to give your assistant fluency with cloud storage commands.
What it provides
MCP mode auto-detection — recognizes mcp__cloud-fs__* tools and maps user intents to the right tool calls
Bootstrap flow — walks the user through first-time setup when the MCP server isn't configured yet
POSIX-to-MCP mapping — translates shell commands (ls, cat, grep, find, cp, etc.) into the correct MCP tool calls
.mcp.json persistence — offers to save provider configuration so future sessions are pre-wired
Installation
bash
# Claude Code
claude mcp add-skill nogoo9/mcp-server-cloud-fs
# skills.sh
npx skills add nogoo9/mcp-server-cloud-fs
# or with bun instead
bun x skills add nogoo9/mcp-server-cloud-fs