Drops into S3, Azure Blob Storage, and Google Cloud Storage with the same 14-tool interface as the standard mcp-server-filesystem, so you can swap it into existing configs without changing tool names or parameters. Adds 16 more tools on top: line-range and byte-range reads, regex search across files, presigned URLs, object metadata and tagging, version history and restore, plus AI-focused helpers like schema extraction and file summarization. Ships with a VFS layer for ETag-based concurrency control, an interactive TUI shell for exploring buckets without an MCP client, and dual runtime support for both Bun and Node.js. Supports local STDIO, remote HTTP/WebSocket, and OAuth 2.1 for production deployments. Reach for this when you need cloud-native file operations in Claude or want to give your AI assistant direct bucket access with the same semantics as local filesystem tools.
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.
📖 Read the full documentation →
Providers: Amazon S3 · Azure Blob Storage · Google Cloud Storage · MinIO · RustFS · Cloudflare R2 · Backblaze B2 · Wasabi · LocalStack · SQLite · In-Memory
@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.
--enable-dlp)get_file_schema extracts CSV/JSON structure; summarize_file returns compact head/tail previewsexpected_etag conflict detection on edit_file and patch_filepatch_file macro tool: atomic read-diff-write in a single tool call — supports unified diffs and line-range replacementsread_file_chunk fetches specific byte ranges without downloading the full objectMultiProvider serves S3 + Azure + GCS from a single server instanceDefaultAzureCredential for OIDC and federated authCloudError with typed codes and provider-specific error mapperscloud-fs): Terminal shell with cd, tab completion, and command historyskills/cloud-fs for Claude Code, Gemini CLI, and other AI assistantsnpx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket
# Bun (zero Express dependency)
bunx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket --transport http --port 3000
# Node.js (requires express peer dep)
npx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket --transport http --port 3000
bunx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket --transport ws --port 3000
bunx @nogoo9/mcp-server-cloud-fs memory mem://demo --enable-shell --seed-demo
cloud-fs)Drop into an interactive terminal for exploring and managing cloud storage — no MCP client needed:
# S3
npx -p @nogoo9/mcp-server-cloud-fs cloud-fs s3 s3://my-bucket
# In-memory demo with sample files
npx -p @nogoo9/mcp-server-cloud-fs cloud-fs memory mem://demo --seed-demo
# With a config file (cloud-fs.json in CWD)
npx -p @nogoo9/mcp-server-cloud-fs cloud-fs
cd navigation — cd data, cd .., cd / with dynamic prompt showing current directory~/.cloud-fs_history)cwd, just like a real shellls, cat, head, tail, cp, mv, rm, mkdir, touch, stat, find, grep, wc, du, echo, tee, diff, jq, cdcat config.json | jq '.database', echo hello > file.txtbun src/cli-tui.ts memory mem://demo --seed-demo
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 |
Implements the MCP Streamable HTTP specification with a single /mcp endpoint for POST (requests), GET (SSE notifications), and DELETE (session termination).
Dual runtime support:
WebStandardStreamableHTTPServerTransport with Bun.serve() directly — zero Express dependency, maximum performance.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.
# Basic HTTP server
cloud-fs-mcp s3 s3://my-bucket --transport http --port 3000
# With authentication
cloud-fs-mcp s3 s3://my-bucket --transport http --port 3000 --auth builtin --auth-issuer https://my-server.example.com
# Production deployment
cloud-fs-mcp s3 s3://my-bucket \
--transport http --port 3000 --host 0.0.0.0 \
--auth external --auth-jwks-uri https://login.example.com/.well-known/jwks.json \
--cors-origin https://app.example.com \
--rate-limit 60 --rate-limit-burst 10 \
--security-headers \
--request-logging
Bun-native WebSocket transport using Bun.serve() with WebSocket upgrade handling. Provides lower latency than HTTP for high-frequency tool invocations.
cloud-fs-mcp s3 s3://my-bucket --transport ws --port 3000
Authentication is disabled by default and only applies to HTTP/WS transports. STDIO mode never requires auth.
| Mode | Flag | Description |
|---|---|---|
none | --auth none (default) | No authentication. Suitable for local/trusted networks. |
builtin | --auth builtin | Self-hosted OAuth 2.1 Authorization Server. The MCP server acts as both AS and RS. |
external | --auth external | Validate bearer tokens against an external IdP (Okta, Auth0, Keycloak, Azure AD). |
--auth builtin)The server runs a full OAuth 2.1 Authorization Server using the MCP SDK's mcpAuthRouter():
/.well-known/oauth-authorization-server (RFC 8414) and /.well-known/oauth-protected-resource (RFC 9728)cloud-fs-mcp s3 s3://my-bucket \
--transport http --port 3000 \
--auth builtin --auth-issuer https://my-server.example.com
--auth external)The server only validates bearer tokens — it does not issue tokens. Use this when you have an existing identity provider.
cloud-fs-mcp s3 s3://my-bucket \
--transport http --port 3000 \
--auth external \
--auth-jwks-uri https://login.example.com/.well-known/jwks.json \
--auth-audience https://cloud-fs.example.com
Implements the MCP Client Credentials extension for machine-to-machine authentication without user interaction. Designed for CI/CD pipelines, background services, and automated workflows.
private_key_jwt per RFC 7523) — recommendedclient_secret_basic) — simpler but less securecloud-fs-mcp s3 s3://my-bucket \
--transport http --port 3000 \
--auth builtin --auth-issuer https://my-server.example.com \
--auth-client-credentials
Implements the MCP Enterprise-Managed Authorization extension for seamless SSO via your organization's Identity Provider.
How it works:
Benefits:
cloud-fs-mcp s3 s3://my-bucket \
--transport http --port 3000 \
--auth builtin --auth-issuer https://my-server.example.com \
--auth-enterprise-idp https://acme.okta.com
When auth is enabled, tool access is controlled by granular scopes:
| Scope | Tools |
|---|---|
cloud-fs:read | read_file, read_text_file, read_media_file, read_multiple_files, read_file_range, read_file_chunk, get_presigned_url, get_object_metadata, list_versions, get_file_schema, summarize_file |
cloud-fs:write | write_file, edit_file, create_directory, set_object_tags, restore_version, patch_file |
cloud-fs:delete | delete_file |
cloud-fs:search | search_files, grep_file, grep_files, list_directory, list_directory_with_sizes, directory_tree, search_by_tag |
cloud-fs:shell | shell |
cloud-fs:admin | 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.
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.
Token bucket rate limiting protects against abuse. Disabled by default.
ioredis peer dep)429 Too Many Requests with Retry-After header when limits are exceeded# 60 requests/minute with burst of 10
cloud-fs-mcp s3 s3://my-bucket --transport http \
--rate-limit 60 --rate-limit-burst 10
Cross-Origin Resource Sharing for browser-based MCP clients:
Mcp-Session-Id and Mcp-Protocol-Version headers* when --host 127.0.0.1 (dev convenience)cloud-fs-mcp s3 s3://my-bucket --transport http \
--cors-origin https://app.example.com \
--cors-origin https://staging.example.com
JSON audit trail to stderr for compliance and debugging:
{"ts":"2026-05-12T12:00:00Z","sessionId":"019...","tool":"read_file","user":"alice@example.com","latencyMs":42,"status":200}
Enable with --request-logging.
Automatically applied when binding to localhost addresses. Validates the Host header against allowed hostnames to prevent DNS rebinding attacks.
Opt-in HTTP response hardening via nosecone — a framework-agnostic security headers library. Works with both Bun-native and Node/Express transports.
When enabled, every HTTP response includes standard security headers:
Content-Security-PolicyStrict-Transport-SecurityX-Content-Type-Options: nosniffX-Frame-OptionsCross-Origin-Opener-PolicyCross-Origin-Resource-PolicyReferrer-Policy# Enable with defaults
cloud-fs-mcp s3 s3://my-bucket --transport http --security-headers
# Custom configuration via inline JSON
cloud-fs-mcp s3 s3://my-bucket --transport http \
--security-headers-config '{"contentSecurityPolicy":false}'
# Custom configuration via file
cloud-fs-mcp s3 s3://my-bucket --transport http \
--security-headers-config-file ./nosecone.json
Note: Requires the
noseconepeer dependency:npm install nosecone
cloud-fs-mcp <provider> <root-uri> [root-uri...] [options]
| Provider | URI format | Description |
|---|---|---|
s3 | s3://bucket[/prefix] | 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) |
| 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) |
| 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 |
| 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 |
| 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) |
| 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.
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.
cloud-fs-mcp s3 s3://my-bucket --region us-east-1
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 |
| Backblaze B2 | https://s3.<region>.backblazeb2.com | Use B2 application key ID / key |
| Wasabi | https://s3.<region>.wasabisys.com | Compatible, no egress fees |
| DigitalOcean Spaces | https://<region>.digitaloceanspaces.com | Use a Spaces access key |
| Scaleway | https://s3.<region>.scw.cloud | Use a Scaleway access key |
| Ceph RGW | http://<rgw-host>:<port> | Enterprise self-hosted; supports all S3 APIs |
| SeaweedFS | http://<master>:8333 | High-throughput distributed FS with S3 API |
| Garage | http://<node>:3900 | Lightweight distributed S3 for homelabs |
# MinIO
export AWS_ACCESS_KEY_ID=minioadmin
export AWS_SECRET_ACCESS_KEY=minioadmin
cloud-fs-mcp s3 s3://my-bucket --endpoint http://minio:9000
# Cloudflare R2
export AWS_ACCESS_KEY_ID=<r2-access-key-id>
export AWS_SECRET_ACCESS_KEY=<r2-secret-access-key>
cloud-fs-mcp s3 s3://my-bucket --endpoint https://<account-id>.r2.cloudflarestorage.com --region auto
# Backblaze B2
export AWS_ACCESS_KEY_ID=<b2-key-id>
export AWS_SECRET_ACCESS_KEY=<b2-application-key>
cloud-fs-mcp s3 s3://my-bucket --endpoint https://s3.us-west-004.backblazeb2.com --region us-west-004
# LocalStack
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
cloud-fs-mcp s3 s3://my-bucket --endpoint http://localhost:4566 --region us-east-1
TLS with private CA: For MinIO, RustFS, or Ceph with a self-signed certificate, add
--ca-file /path/to/ca.pem.
Uses DefaultAzureCredential — works with AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET env vars, managed identity, az login, and so on.
cloud-fs-mcp azure az://my-container
Uses Application Default Credentials (ADC). Set GOOGLE_APPLICATION_CREDENTIALS or run gcloud auth application-default login.
cloud-fs-mcp gcs gs://my-bucket
Zero-config, zero-dependency provider. All data lives in a Map and is lost when the process exits.
cloud-fs-mcp memory mem://demo --enable-shell
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).
cloud-fs-mcp sqlite sqlite://my-bucket --sqlite-db /tmp/cloud-fs.db --enable-shell
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"cloud-fs": {
"command": "npx",
"args": ["-y", "@nogoo9/mcp-server-cloud-fs", "s3", "s3://my-bucket"]
}
}
}
.mcp.json in your project root:
{
"mcpServers": {
"cloud-fs": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@nogoo9/mcp-server-cloud-fs", "s3", "s3://my-bucket"]
}
}
}
{
"mcpServers": {
"cloud-fs": {
"type": "streamable-http",
"url": "https://cloud-fs.example.com/mcp"
}
}
}
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.
| 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. |
| Tool | Parameters | Description |
|---|---|---|
write_file | path, content | Write/overwrite a file. Flushed after debounce window. |
edit_file | path, edits[], dryRun?, expected_etag? | Apply { oldText, newText } edits. Preview with dryRun. Optional ETag conflict detection. |
| Tool | Parameters | Description |
|---|---|---|
create_directory | path | Create a directory placeholder and parent prefixes. |
list_directory | path | List immediate children (like ls). |
list_directory_with_sizes | path, sortBy?, limit? | List children with sizes. Sort by size or name. |
directory_tree | path, excludePatterns? | Recursive directory tree with glob exclusions. |
| Tool | Parameters | Description |
|---|---|---|
move_file | source, destination | Move file. Server-side copy + delete for same-bucket. |
copy_file ✨ | source, destination | Copy file. Server-side for same-bucket. |
delete_file ✨ | path | Delete file. Requires --enable-delete. |
| Tool | Parameters | Description |
|---|---|---|
search_files | path, pattern, excludePatterns? | Glob-based object key search. |
grep_file ✨ | path, pattern, case_insensitive? | Regex search in a single file with line numbers. |
grep_files ✨ | path, pattern, glob?, case_insensitive?, output_mode?, max_objects? | Regex search across all objects under a path. |
| Tool | Parameters | Description |
|---|---|---|
get_file_info | path | File metadata: size, last-modified, content type. |
list_allowed_directories | (none) | List configured root URIs. |
✨ = Extended tool
| Tool | Parameters | Description |
|---|---|---|
get_presigned_url ☁️ | path, operation?, expires_in? | Generate a temporary access URL (default: GET, 1 hour). |
get_object_metadata ☁️ | path | Size, content type, last modified, custom metadata, and tags. |
set_object_tags ☁️ | path, tags | Replace object tags with key-value pairs. |
search_by_tag ☁️ | path, tags, recursive? | Find objects matching tag filters (AND logic). |
list_versions ☁️ | path, max_results?, page_token? | Version history with timestamps, sizes, and markers. |
restore_version ☁️ | path, version_id | Restore a previous object version (copies over current). |
☁️ = Cloud-native tool (requires provider support)
| Tool | Parameters | Description |
|---|---|---|
get_file_schema 🧠 | path | Extract structural schema: CSV column names/types/samples, JSON shape, or text line/byte counts. |
summarize_file 🧠 | path, max_lines? | Compact head/tail preview with file size, line count, and content type. |
🧠 = AI-native tool (reduces LLM context token waste)
| Tool | Parameters | Description |
|---|---|---|
patch_file 🩹 | path, patch, format?, expected_etag? | Apply unified diffs or line-range replacements atomically in a single tool call. |
🩹 = Macro tool (combines read + transform + write)
| Tool | Parameters | Description |
|---|---|---|
shell ⚡ | command | Execute POSIX-like commands. Supports pipes, redirects. Requires --enable-shell. |
Built-in commands: ls, cat, head, tail, cp, mv, rm, mkdir, touch, stat, find, grep, wc, du, echo, tee, diff, jq, cd
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:
# 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.
# 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.rmandmvadditionally require--enable-delete.
All tool operations are mediated through a Virtual Filesystem (VFS) layer inspired by FUSE.
┌─────────────────────────────────────────────────────────┐
│ MCP Tool Handlers (read, write, list, stat, …) │
├─────────────────────────────────────────────────────────┤
│ VirtualFS │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Inodes │ │ DirIndex │ │ Tombstones│ │
│ │ (metadata)│ │ (parents) │ │ (deleted) │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ └──────────────┴─────────────┘ │
│ ⇣ Overlay (in-memory, persisted to CacheStore) │
├─────────────────────────────────────────────────────────┤
│ CacheStore (Memory / Filesystem / Redis) │
├─────────────────────────────────────────────────────────┤
│ StorageProvider (S3 / Azure Blob / GCS / Memory / SQL) │
└─────────────────────────────────────────────────────────┘
| Operation | Resolution |
|---|---|
get() | Cache hit → return. Tombstoned → throw. Else → provider fallback. |
stat() | Inode overlay → cached content size → provider headObject. |
list() | Provider listing – tombstones + overlay dirIndex entries. |
put() | Cache set + markDirty + inode update + dirIndex. Immediate visibility. |
remove() | Provider deleteObject + cache evict + tombstone. Immediate invisibility. |
VFS metadata is persisted to the CacheStore under __vfs__/* keys. On startup, VirtualFS.hydrate() restores state; corrupted data is silently discarded.
| 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_URLuses unencryptedredis://. Userediss://for TLS-encrypted connections in production.
Use --ca-file <path> to supply a PEM CA bundle for S3-compatible endpoints (MinIO, RustFS) and Redis running with a private CA:
# 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:
NODE_EXTRA_CA_CERTS=/etc/ssl/certs/my-ca.pem cloud-fs-mcp s3 s3://my-bucket
import {
createMcpServer, VirtualFS, MemoryStore,
S3Provider, parseUri,
} from "@nogoo9/mcp-server-cloud-fs";
const roots = [parseUri("s3://my-bucket")];
const provider = new S3Provider({ region: "us-east-1" });
const cache = new MemoryStore(provider, { ttlMs: 60_000, syncDebounceMs: 2000 });
const vfs = new VirtualFS(provider, cache);
await vfs.hydrate();
const server = createMcpServer({ vfs, roots });
| Export | Description |
|---|---|
createMcpServer(ctx) | Create a configured MCP server instance |
executeShell(command, ctx) | Run POSIX-like commands against the VFS |
VirtualFS | FUSE-inspired write-back overlay |
MemoryStore, FilesystemStore, createRedisStore, PassThroughCache | Cache backends |
S3Provider, AzureProvider, GcsProvider, MemoryProvider, SqliteProvider, MultiProvider | Storage providers |
CloudError, CloudErrorCode | Structured cloud-aware error handling |
checkHealth, formatHealthReport | Connection health-check utilities |
AuditLogger, StderrAuditSink, FileAuditSink | Tool invocation audit logging |
parseUri, toCacheKey, resolveToolPath | Path utilities |
ShellContext, ShellCommandHandler | Shell extension types |
# Quick demo (no credentials needed)
bun run inspect:memory
# Custom configuration
bun run inspect -- s3 s3://my-bucket --region us-east-1 --enable-shell
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.
See CONTRIBUTING.md for full setup instructions.
AI agent skills are installed separately after cloning via bun x skills add semgrep/skills — see CONTRIBUTING.md for details.
| 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 |
The CI workflow runs on every push/PR:
HTTP E2E tests use the in-memory provider and need zero infrastructure, making them fast and reliable for every CI run.
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.
mcp__cloud-fs__* tools and maps user intents to the right tool callsls, 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# 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
See CONTRIBUTING.md for details on the skill system.
Full documentation is available at nogoo9.github.io/mcp-server-cloud-fs.
To run the documentation site locally:
bun run docs:dev # start dev server at http://localhost:5173
bun run docs:build # build static site
bun run docs:preview # preview production build
PolyForm Shield 1.0.0. Free for any non-competitive use.
AZURE_STORAGE_CONNECTION_STRINGsecretAzure Blob Storage connection string (required when using the azure provider)
GOOGLE_CLOUD_PROJECTGoogle Cloud project ID (optional when using the gcs provider)
AWS_ACCESS_KEY_IDsecretAWS Access Key ID (optional for S3 — falls back to ~/.aws/credentials or IAM role)
AWS_SECRET_ACCESS_KEYsecretAWS Secret Access Key (optional for S3 — falls back to ~/.aws/credentials or IAM role)
REDIS_URLRedis connection URL (required when --cache-store redis, defaults to redis://localhost:6379)
silenceper/mcp-k8s
azure/containerization-assist
io.github.evozim/aws-builder
reza-gholizade/k8s-mcp-server
flux159/mcp-server-kubernetes