Changelog
See the full CHANGELOG.md on GitHub.
Changelog
All notable changes to this project will be documented in this file.
The format follows Keep a Changelog.
[0.7.0] — 2026-05-18
Added
- Dynamic tool surface reduction — when
grantedScopesis provided inServerContext, only tools matching the session's OAuth scopes are registered. Read-only clients no longer seewrite_file,delete_file, orshellintools/list, reducing prompt token overhead and preventing tool hallucination. Backwards-compatible: omitting scopes registers all tools. (#22) - DLP content sanitization middleware — opt-in regex-based redaction of sensitive content (AWS keys, emails, SSN, credit cards, JWTs, API keys) from tool responses before they reach the MCP client. Ships 9 default patterns. Enabled via
--enable-dlpCLI flag. (#23) - AI-native tools — two new tools that extract structural metadata server-side to reduce LLM context token waste (#24):
get_file_schema— for CSV: column names, inferred types, sample values, row count; for JSON: root type, keys, shapes; for text: line/byte countssummarize_file— compact head/tail summary with size, line count, and content type without full file reads
- Optimistic concurrency control (ETags) — SHA-256 content-addressable ETags computed on every
put()and persisted in the inode overlay.edit_fileaccepts an optionalexpected_etagparameter for conflict detection.read_text_fileincludes the etag in response metadata. (#25) patch_filemacro tool — apply unified diffs or line-range replacements atomically in a single tool call, combining the read→transform→write workflow. Supports optionalexpected_etagfor concurrency safety. (#26)
Changed
VfsStatandObjectInfointerfaces extended with optionaletagfieldread_text_fileresponses now include[etag: <hash>]metadata suffixedit_fileresponses now include the new etag on success- E2E test assertions updated to accommodate etag metadata in read responses
- Scope filter helpers (
getToolsForScopes,shouldRegisterTool) exported fromsrc/auth/scopes.ts
[0.6.0] — 2026-05-15
Added
- Structured error handling —
CloudErrorclass with typed error codes (RATE_LIMITED,PERMISSION_DENIED,BUCKET_NOT_FOUND, etc.) and provider-specific mappers for S3, Azure, and GCS. Errors includeprovider,statusCode, andretryablemetadata for programmatic handling. - Byte-range reads (
read_file_chunk) — read specific byte ranges from cloud objects without downloading the entire file. Supportsutf8andbase64encodings, with a 10MB per-chunk safety limit. - Presigned URLs (
get_presigned_url) — generate temporary access URLs for cloud objects via AWS SDK presigners. Supports configurable expiration (default: 1 hour) andget/putoperations. - Structured audit logging —
AuditLoggermiddleware with pluggable sinks (StderrAuditSink,FileAuditSink). Logs tool name, arguments (sanitized), duration, scope, resource URI, and outcome as structured JSON. Enabled via--audit-log/--audit-log-fileCLI flags. - Object metadata & tag tools —
get_object_metadatareturns size, content type, custom metadata, and tags.set_object_tagsreplaces tags on an object.search_by_taglists objects matching tag filters (AND logic). - Object versioning tools —
list_versionsreturns version history with timestamps, sizes, and latest/delete markers.restore_versioncopies a previous version over the current one. Requires versioning-enabled storage. - MCP Resources — cloud storage roots and paths exposed as browsable MCP Resources. Static root resources registered per configured root; dynamic resource template (
cloud-fs://{cloudPath}) resolves to directory listings (JSON) or file content (UTF-8 / base64). - Connection health-check module —
checkHealth()probes authentication, list access, optional write access, and versioning support.formatHealthReport()produces terminal-friendly output. Server validates credentials at startup and exits with a diagnostic report on failure. - Multi-provider routing (
MultiProvider) — compositeStorageProviderthat routes operations to scheme-specific sub-providers, enabling a single server instance to serve S3 + Azure + GCS simultaneously. Zero VFS changes required. - Azure DefaultAzureCredential —
AzureProvidernow supports Managed Identity, OIDC, and other federated auth flows when onlyaccountNameis provided.@azure/identityadded as an optional peer dependency.
Changed
StorageProviderinterface extended with optional methods:getObjectMetadata,setObjectTags,getObjectTags,listObjectVersions,restoreObjectVersion,getPresignedUrl. Providers that don't support these return clear error messages.MemoryProviderimplements all optional methods (metadata, tags, versioning) for testing.- Startup credential validation added — server verifies provider connectivity before accepting MCP connections.
[0.5.0] — 2026-05-14
Added
- Interactive TUI (
cloud-fs) — new binary for terminal-based cloud storage exploration. Powered bynode:readlinewith tab completion, persistent history (~/.cloud-fs_history), ANSI-colored UI, and a command queue for correct async sequencing. Runs on both Bun and Node.js. cdcommand — navigate directories within the virtual filesystem. Supportscd <dir>,cd ..,cd /, with prompt reflecting the current working directory. All 19 shell commands resolve paths relative tocwd.jqcommand — native, zero-dependency JSON processor for the shell. Supports key extraction, array indexing, nested paths, and piping fromcat.- Relative path support — all tools and shell commands resolve paths relative to the primary root prefix.
ls,find, and other commands output relative paths by default for shell composability. - Config file support —
cloud-fs.jsonin CWD or~/.config/cloud-fs/config.jsonfor persistent TUI configuration. CLI flags override config values. --seed-demoflag — pre-populate storage with sample files (README, config, CSV, logs) for immediate exploration.--ca-file <path>— PEM CA bundle for TLS verification of S3-compatible endpoints (MinIO, RustFS) and Redis (rediss://) using a private/self-signed CA. Injected directly intoioredis(tls.ca) and the S3 client (NodeHttpHandler+https.Agent). For runtime-wide CA trust (Azure, GCS, or all providers), useNODE_EXTRA_CA_CERTSinstead.- AI agent skill (
skills/cloud-fs) — installable skill that teaches AI coding assistants (Claude Code, Gemini CLI, etc.) how to use cloud-fs as a POSIX-like virtual filesystem. Supports local installation viaskills add ./skills/cloud-fsand remote installation vianpx skills add nogoo9/mcp-server-cloud-fs. Includes MCP mode auto-detection, bootstrap flow, and POSIX-to-MCP tool mapping.
Changed
- SQLite provider: dual-runtime support — uses
bun:sqliteon Bun andbetter-sqlite3on Node.js. Constructor replaced with async factorySqliteProvider.create()(breaking for direct consumers ofSqliteProvider). - Bootstrap refactor — extracted
src/bootstrap.tsto share VFS/provider/cache initialization between the MCP server and the TUI binary. - Shell path resolution — introduced
resolveShellPath()insrc/tools/shell/resolve.tsto prependcwdto relative paths, keepingresolveToolPathunchanged for non-shell tools. isAbsoluteUriregex — fixed[a-z]+→[a-z][a-z0-9]*to correctly handle schemes likes3://.- WebSocket transport — replaced
any-typedbunServerRefwith a structural type for type safety.
Security
- Dependency audit — resolved 12 of 13
bun auditvulnerabilities:hono4.12.15 → 4.12.18 (4 moderate + 1 low)fast-uri3.1.0 → 3.1.2 (2 high)fast-xml-builder1.1.5 → 1.2.0 (1 high + 1 moderate)ip-address10.1.0 → 10.2.0 (1 moderate)vitepress1.6.4 → 2.0.0-alpha.17, pullingvite5 → 7 (path traversal in.maphandling) andesbuild0.21 → 0.27 (dev server CORS bypass)- Remaining 1 unfixable (low):
@tootallnate/once— deeply nested in GCS/Azure SDK transitive deps
- File inclusion fix — sanitized file path handling in
scripts/docs-landing.tsto prevent potential file inclusion attack; added 254-line test suite - Pinned GitHub Actions — all 3rd-party actions in CI, docs, and publish workflows pinned to full commit SHA to prevent supply-chain attacks
- Redis TLS warning — runtime
console.warnwhenREDIS_URLuses unencryptedredis://transport; recommendsrediss://for production TLS connections - SAST remediation — resolved all Semgrep findings (
p/security-audit,p/javascript,p/trailofbits,p/owasp-top-ten,p/cwe-top-25):- Extracted
DEFAULT_REDIS_URLconstant to centralize the Redis fallback and eliminate pattern-match false positives - Added
nosemgrepsuppressions for intentionalredis://string references in warning messages and E2E test fixtures - Replaced
Math.random()withcrypto.randomInt()/crypto.randomBytes()in test files for secure randomness
- Extracted
- Security headers — opt-in HTTP response hardening via nosecone (framework-agnostic, works with both Bun-native and Node/Express transports):
- Sets
Content-Security-Policy,Strict-Transport-Security,X-Content-Type-Options,X-Frame-Options, and other standard security headers --security-headersflag enables nosecone with defaults--security-headers-config <json>for inline JSON customization--security-headers-config-file <path>to load configuration from a file- Headers are resolved once at startup and applied to every response (health checks, MCP, CORS preflight)
noseconeis an optional peer dependency — only required when the flag is used
- Sets
[0.4.0] — 2026-05-12
Added
- Documentation site — VitePress-powered docs deployed to GitHub Pages with versioned releases, PR previews, full-text search, and dark mode (nogoo9.github.io/mcp-server-cloud-fs)
- Streamable HTTP transport — deploy
cloud-fs-mcpas a remote HTTP service with full MCP Streamable HTTP support:- Dual runtime: Bun-native via
WebStandardStreamableHTTPServerTransport+Bun.serve()(zero Express dependency), Node.js viaStreamableHTTPServerTransport+ Express - Runtime auto-detection at startup — falls back gracefully based on available APIs
- Stateful session management with UUID v7 (time-sortable, RFC 9562) session IDs
- SSE streaming for server-to-client notifications and tool progress
- EventStore support for resumability — clients can reconnect and resume where they left off
--transport httpCLI flag (default:stdiofor backward compatibility)--port <number>(default: 3000) and--host <address>(default: 127.0.0.1) flags
- Dual runtime: Bun-native via
- WebSocket transport — low-latency bidirectional transport using Bun-native
Bun.serve()WebSocket:- JSON-RPC message framing over WS
- Session tracking with UUID v7 assigned on WebSocket upgrade
- WS ping/pong heartbeat for connection health
--transport wsCLI flag
- OAuth 2.1 authentication — three auth modes selectable via
--auth:none(default) — no auth, same as v0.3.0builtin— self-hosted OAuth 2.1 Authorization Server using the MCP SDK'smcpAuthRouter():- Authorization Code grant with mandatory PKCE
- Refresh token rotation (single-use)
- Dynamic Client Registration
/.well-known/oauth-authorization-servermetadata discovery (RFC 8414)/.well-known/oauth-protected-resourcemetadata (RFC 9728)
external— validate bearer tokens against an external IdP (Okta, Auth0, Keycloak) via JWKS:- Remote JWKS key fetching and caching via
joselibrary - JWT signature, issuer, audience, and expiry validation
- Token introspection fallback for opaque tokens
- Remote JWKS key fetching and caching via
- ext-auth: OAuth Client Credentials (MCP ext-auth) — machine-to-machine authentication for CI/CD pipelines, background services, and automated workflows:
client_credentialsgrant type support- JWT assertion authentication (
private_key_jwtper RFC 7523) - Client secret authentication (
client_secret_basic) - Server metadata advertises
token_endpoint_auth_methods_supported --auth-client-credentialsCLI flag to enable
- ext-auth: Enterprise-Managed Authorization (MCP ext-auth) — SSO via corporate Identity Provider for zero-friction enterprise onboarding:
- Identity Assertion JWT Authorization Grant (ID-JAG) validation
- Token exchange integration (RFC 8693) with enterprise IdP
- JWT Authorization Grant processing (RFC 7523 §2.1)
- Supports both OpenID Connect ID Tokens and SAML assertions as subject tokens
--auth-enterprise-idp <url>CLI flag to enable
- Granular OAuth scopes — tool-level access control:
cloud-fs:read— read tools (read_file, read_text_file, read_media_file, etc.)cloud-fs:write— write tools (write_file, edit_file)cloud-fs:delete— delete_file toolcloud-fs:search— search and grep toolscloud-fs:shell— shell toolcloud-fs:admin— all tools
- Rate limiting — token bucket algorithm with configurable sustained rate and burst capacity:
- In-memory backend for single-process deployments
- Redis backend for distributed deployments (uses existing optional
ioredispeer dep) - Per-client / per-IP counters with automatic cleanup
- Returns
429 Too Many RequestswithRetry-Afterheader - Disabled by default — opt-in via
--rate-limit <req/min>and--rate-limit-burst <n>
- CORS — strict cross-origin request handling:
- Allowlist-based origin enforcement via
--cors-origin <origin>(repeatable) - Exposes
Mcp-Session-IdandMcp-Protocol-Versionheaders - No wildcards in production; localhost auto-allows
*for dev convenience
- Allowlist-based origin enforcement via
- Health check endpoints — Kubernetes-convention liveness and readiness probes:
/healthz— liveness probe (always200 OKif the process is alive)/readyz— readiness probe (checks VFS hydration and provider connectivity)
- Structured request logging — JSON audit trail to stderr:
- Fields: timestamp, sessionId, toolName, userId (from auth), latencyMs, statusCode
--request-loggingflag to enable
- DNS rebinding protection — automatically applied when binding to localhost addresses
Changed
expressis now an optional peer dependency (loaded only when--transport httpon Node.js)- Session IDs use UUID v7 (time-sortable) instead of UUID v4
Dependencies
- Added
jose— JWT/JWKS verification (zero native deps, works Bun + Node) - Added
uuidv7— RFC 9562 UUID v7 generation - Added optional peer:
express(for Node.js HTTP transport)
[0.3.0] — 2026-05-12
Added
shelltool — execute POSIX-like shell commands against cloud object storage, giving AI agents a familiar CLI interface on top of the VFS:- 17 built-in commands:
ls,cat,head,tail,cp,mv,rm,mkdir,touch,stat,find,grep,wc,du,echo,tee,diff - Pipe support (
|) — chain commands together, e.g.cat s3://b/f | grep pattern | wc -l - Input redirection (
<) — read a file as stdin for the first command - Output redirection (
>,>>) — write/append stdout to a cloud file - All commands run in-process against the VFS — no real shell process is spawned
ls -luses POSIX-mimic formatting with----------for permissions (cloud has no permission model)- Destructive commands (
rm,mv) are gated by--enable-delete
- 17 built-in commands:
--enable-shellCLI flag — opt-in to register theshelltool (disabled by default for safety)- Programmatic API:
executeShell(command, ctx)exported from the npm library for use without MCP ShellContextandShellCommandHandlertypes exported for custom command extensions- In-Memory provider (
MemoryProvider) — fully in-process storage for demos and tests; zero dependencies, URI formatmem://bucket-name - SQLite provider (
SqliteProvider) — persistent local storage usingbun:sqlite; zero external deps, WAL mode, URI formatsqlite://bucket-name, requires--sqlite-db <path>CLI flag - MCP App: Interactive Shell — xterm.js-based terminal UI that renders inside MCP hosts (Claude Desktop etc.) via the MCP Apps extension; Catppuccin Mocha theme, command history, auto-resize
--sqlite-db <path>CLI flag for specifying the SQLite database file locationbun run inspectandbun run inspect:memoryscripts for launching the MCP Inspectorbun run build:appscript to bundle the xterm.js shell app into a single HTML file- 74 unit tests covering providers, parser, all 17 commands, pipelines, redirects, and security
[0.2.0] — 2026-05-12
Added
- 5 extended tools inspired by claude-code's filesystem tool surface:
read_file_range— read a slice of a text file by 1-based line offset and limit; returns a header showing the range and total line countgrep_file— regex search within a single object; returns matching lines prefixed with their 1-based line numbergrep_files— regex search across all objects under a path; supports a glob filter, two output modes (files_with_matchesandcontent), and a per-callmax_objectsoverridecopy_file— server-side copy within the same bucket; falls back to get+put for cross-bucket copies; evicts the destination cache entry after copydelete_file— permanently delete an object and evict its cache entry (disabled by default — must be explicitly enabled)
--enable-deleteCLI flag — opt-in to register thedelete_filetool (default: off for safety)--grep-max-objects <n>CLI flag — server-wide cap on the number of objectsgrep_filesscans per call (default: 1000); can be overridden per-call via themax_objectsparameter- Virtual Filesystem (VFS) layer — FUSE-inspired write-back overlay providing immediate consistency:
- In-memory inode table, directory index, and tombstone set ensure that unflushed writes are immediately visible to
list,stat,get, andsearchoperations - VFS metadata is persisted to the CacheStore (
__vfs__/*keys) for warm-start recovery on server restarts (when using filesystem or Redis cache) VirtualFS.hydrate()restores state on startup; corrupted data is silently discarded
- In-memory inode table, directory index, and tombstone set ensure that unflushed writes are immediately visible to
- npm library entrypoint (
@nogoo9/mcp-server-cloud-fs):createMcpServer(),VirtualFS, all provider classes, all cache backends, and path utilities are exported for programmatic use- TypeScript declarations (
.d.ts) and source maps are included in the published package
- VFS unit tests (13 tests covering get, stat, list, copy, tombstones, persistence round-trip)
Changed
- All tool handlers refactored to use
VirtualFSexclusively —ServerContextnow providesvfsinstead ofprovider+cache - All tool unit tests updated to construct VFS-based contexts via shared
__test-helpers.ts - Build system migrated from Bun bundler to
tsc -p tsconfig.build.jsonto emit proper declarations package.jsonnow exportsmain/types/exportsfor library consumers
[0.1.0] — 2026-04-27
Added
- All 14
mcp-server-filesystemtools implemented over cloud object storage (same names, same parameter schemas) - Provider support: AWS S3, Azure Blob Storage, Google Cloud Storage, S3-compatible backends (MinIO, RustFS)
- Transparent cache layer with memory, filesystem, and Redis backends
- Write debounce: writes land in cache immediately, flushed to provider after configurable delay
- SIGTERM/SIGINT handler flushes dirty cache entries synchronously before exit
--no-cacheflag for pass-through mode (every read/write goes directly to provider)- Path validation matching
mcp-server-filesystemsecurity semantics (blocks..traversal, wrong-bucket access) - CLI:
cloud-fs-mcp <s3|azure|gcs> <root-uri> [root-uri...] [options]
