{"_id":"@nogoo9/mcp-server-cloud-fs","_rev":"7-d36d4430ce611ca384cf3e66d6828f01","name":"@nogoo9/mcp-server-cloud-fs","dist-tags":{"latest":"0.7.0"},"versions":{"0.1.0":{"name":"@nogoo9/mcp-server-cloud-fs","version":"0.1.0","license":"PolyForm-Shield-1.0.0","_id":"@nogoo9/mcp-server-cloud-fs@0.1.0","maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"homepage":"https://github.com/nogoo0/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo0/mcp-server-cloud-fs/issues"},"bin":{"cloud-fs-mcp":"dist/index.js"},"dist":{"shasum":"2c5a81038f83e06aae9f1750ff2789413f6b7b79","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.1.0.tgz","fileCount":4,"integrity":"sha512-ek41Sp8axjteNLQS9lxwDI5fQThmNW/4DO5Ib5a4SjMiUHzvZew1Bb/UU42R6w2WRGF+A5WIZQWPXj9dvBs6pg==","signatures":[{"sig":"MEYCIQCDQrUlnR4rSYZZVSImadgRlIpV38n6ob5nFSMhYJktvwIhANibRQCUyFvQhnh4C14JuKPJEh8APD8QV+c7S4/hqAou","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1848601},"type":"module","gitHead":"af1ed87c528731ec9ea1cca57ec8ca555fabc97e","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","scripts":{"lint":"biome check src/","test":"bun test","build":"bun build src/index.ts --outfile dist/index.js --target bun --minify && chmod +x dist/index.js","check":"biome check --write src/","format":"biome format --write src/","infra:up":"docker compose -f infra/docker-compose.yml up -d","typecheck":"tsc --noEmit","infra:down":"docker compose -f infra/docker-compose.yml down","infra:setup":"bun run infra:up && docker compose -f infra/docker-compose.yml exec minio mc alias set local http://localhost:9000 minioadmin minioadmin && docker compose -f infra/docker-compose.yml exec minio mc mb local/test-bucket --ignore-existing","prepublishOnly":"bun run build","test:integration":"bun test src/providers/*.integration.test.ts"},"_npmUser":{"name":"eterna2","email":"eterna2@hotmail.com"},"repository":{"url":"git+https://github.com/nogoo0/mcp-server-cloud-fs.git","type":"git"},"_npmVersion":"11.12.1","description":"Drop-in cloud replacement for mcp-server-filesystem — all 14 MCP tools over S3, Azure Blob, and GCS","directories":{},"_nodeVersion":"25.9.0","dependencies":{"zod":"^3.0.0","minimatch":"^9.0.0","@aws-sdk/client-s3":"^3.0.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","typescript":"^5.0.0","@biomejs/biome":"^2.4.13"},"peerDependencies":{"ioredis":"^5.0.0"},"peerDependenciesMeta":{"ioredis":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-cloud-fs_0.1.0_1777305380864_0.029567275025299766","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@nogoo9/mcp-server-cloud-fs","version":"0.2.0","license":"PolyForm-Shield-1.0.0","_id":"@nogoo9/mcp-server-cloud-fs@0.2.0","maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"bin":{"cloud-fs-mcp":"dist/index.js"},"dist":{"shasum":"fb8937b0fd3cb0502fb1f8473d3cf395dd9b855d","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.2.0.tgz","fileCount":108,"integrity":"sha512-juA+w+hXqNg9KFtR7UMpUr8xLZLG2VnycJJzLJXqC03QUHmZ+7729ETL6CnNjIJYovH+rsKSGkRhjDp4myoM7w==","signatures":[{"sig":"MEUCIEEuxyvzMMIUKroo6B6l9NDjql6k97P3Amco16+q33DxAiEAteQgU6+JE1mAAc6wcZh22sM7dR3699qrbYCvlmvttTc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nogoo9%2fmcp-server-cloud-fs@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":304444},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"}},"gitHead":"6aee210b0cd56802b59b8781bf00c97a05855d96","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","scripts":{"lint":"biome check src/","test":"bun test src/cache src/providers src/tools src/path-utils.test.ts src/vfs.test.ts","build":"tsc -p tsconfig.build.json","check":"biome check --write --unsafe src/","format":"biome check --write --unsafe src/","infra:up":"docker compose -f infra/docker-compose.yml up -d","test:all":"bun test --timeout 30000","test:e2e":"bun test src/server.e2e.test.ts --timeout 30000","typecheck":"tsc --noEmit","infra:down":"docker compose -f infra/docker-compose.yml down","infra:logs":"docker compose -f infra/docker-compose.yml logs","infra:setup":"docker compose -f infra/docker-compose.yml up -d","test:coverage":"bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage","prepublishOnly":"bun run build","test:integration":"bun test src/providers/*.integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7164ac07-dd31-4d57-a032-405598369742"}},"repository":{"url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git","type":"git"},"_npmVersion":"11.11.0","description":"Cloud replacement for mcp-server-filesystem — 19 tools for S3, Azure Blob, and GCS","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.0.0","minimatch":"^9.0.0","@aws-sdk/client-s3":"^3.0.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ioredis":"^5.0.0","@types/bun":"latest","typescript":"^5.0.0","@biomejs/biome":"^2.4.13"},"peerDependencies":{"ioredis":""},"peerDependenciesMeta":{"ioredis":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-cloud-fs_0.2.0_1778521026427_0.15595050549807232","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@nogoo9/mcp-server-cloud-fs","version":"0.3.0","license":"PolyForm-Shield-1.0.0","_id":"@nogoo9/mcp-server-cloud-fs@0.3.0","maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"bin":{"cloud-fs-mcp":"dist/index.js"},"dist":{"shasum":"debc62afe82b53d9f0f009de956852be68793b30","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.3.0.tgz","fileCount":239,"integrity":"sha512-tdBl+3czZi8fIg6X3qB7irB06nZGTm09aoXedVGybBattci4TW62bUAub0VWAEEWxgGHBwLxBY2qPvGQwcd3WA==","signatures":[{"sig":"MEUCIQDt5Nx/Q+laNd87THjhsRJVE4GL8O2fUHwLA6NpqYE4qQIgHxcqbfxmWwqtumlfuob7De8CJdqwPuqjoQPgRgQ1wOg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nogoo9%2fmcp-server-cloud-fs@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":516591},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"}},"gitHead":"b07b5fcb3f25d357d67c05c50511186087d9c8f3","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","scripts":{"lint":"biome check src/","test":"bun test src/cache src/providers src/tools src/path-utils.test.ts src/vfs.test.ts","build":"tsc -p tsconfig.build.json","check":"biome check --write --unsafe src/","format":"biome check --write --unsafe src/","inspect":"npx -y @modelcontextprotocol/inspector -- bun src/index.ts","infra:up":"docker compose -f infra/docker-compose.yml up -d","test:all":"bun test --timeout 30000","test:e2e":"bun test src/server.e2e.test.ts --timeout 30000","build:app":"vite build -c src/app/vite.config.ts","typecheck":"tsc --noEmit","infra:down":"docker compose -f infra/docker-compose.yml down","infra:logs":"docker compose -f infra/docker-compose.yml logs","infra:setup":"docker compose -f infra/docker-compose.yml up -d","test:coverage":"bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage","inspect:memory":"npx -y @modelcontextprotocol/inspector -- bun src/index.ts memory mem://demo --enable-shell --seed-demo","prepublishOnly":"bun run build","test:integration":"bun test src/providers/*.integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7164ac07-dd31-4d57-a032-405598369742"}},"repository":{"url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git","type":"git"},"_npmVersion":"11.11.0","description":"Cloud replacement for mcp-server-filesystem — 20 tools for S3, Azure Blob, and GCS","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.0.0","file-type":"^22.0.1","minimatch":"^9.0.0","@aws-sdk/client-s3":"^3.0.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/sdk":"^1.29.0","@modelcontextprotocol/ext-apps":"^1.7.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.12","ioredis":"^5.0.0","@types/bun":"latest","typescript":"^5.0.0","@xterm/xterm":"^6.0.0","@biomejs/biome":"^2.4.13","@xterm/addon-fit":"^0.11.0","vite-plugin-singlefile":"^2.3.3"},"peerDependencies":{"ioredis":""},"peerDependenciesMeta":{"ioredis":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-cloud-fs_0.3.0_1778525887992_0.8916391798497763","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@nogoo9/mcp-server-cloud-fs","version":"0.4.0","author":{"name":"eterna2"},"license":"PolyForm-Shield-1.0.0","_id":"@nogoo9/mcp-server-cloud-fs@0.4.0","maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"contributors":[{"name":"eterna2"}],"homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"bin":{"cloud-fs-mcp":"dist/index.js"},"dist":{"shasum":"b7a56cc234bc5f0fe1fdfe0043f19d571dfcc4fc","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.4.0.tgz","fileCount":279,"integrity":"sha512-AF5qxt77ufWeJ1wNGZkvENmI+ZhSbnQXi95fxFvYxxg52flLSeaNEy0Gxm8GvaOBxttxieP6i0NbGis5pUYtOA==","signatures":[{"sig":"MEUCIQC9k6YKQqkpkOIussYqr6uH7F9m5eGP6tQBhkhJVnU0XwIgfoMsx1mOsnJW8GmY1+pZw9vhkOBlKemyl1jr/Y4MBQk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nogoo9%2fmcp-server-cloud-fs@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":631635},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"}},"gitHead":"392c02f75e3d9e778169c639f0c8f23157b60a4f","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","scripts":{"lint":"biome check src/","test":"bun test src/cache src/providers src/tools src/auth src/middleware src/path-utils.test.ts src/vfs.test.ts","build":"tsc -p tsconfig.build.json","check":"biome check --write --unsafe src/","format":"biome check --write --unsafe src/","inspect":"npx -y @modelcontextprotocol/inspector -- bun src/index.ts","docs:dev":"vitepress dev docs","infra:up":"docker compose -f infra/docker-compose.yml up -d","test:all":"bun test --timeout 30000","test:e2e":"bun test src/server.e2e.test.ts src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","build:app":"vite build -c src/app/vite.config.ts","typecheck":"tsc --noEmit","docs:build":"vitepress build docs","infra:down":"docker compose -f infra/docker-compose.yml down","infra:logs":"docker compose -f infra/docker-compose.yml logs","infra:setup":"docker compose -f infra/docker-compose.yml up -d","test:e2e:ws":"bun test src/transports/ws.e2e.test.ts --timeout 30000","docs:preview":"vitepress preview docs","test:coverage":"bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage","test:e2e:http":"bun test src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","inspect:memory":"npx -y @modelcontextprotocol/inspector -- bun src/index.ts memory mem://demo --enable-shell --seed-demo","prepublishOnly":"bun run build","test:e2e:infra":"bun test src/server.e2e.test.ts --timeout 30000","test:integration":"bun test src/providers/*.integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7164ac07-dd31-4d57-a032-405598369742"}},"repository":{"url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git","type":"git"},"_npmVersion":"11.11.0","description":"Cloud replacement for mcp-server-filesystem — 20 tools for S3, Azure Blob, and GCS","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.0.0","jose":"^6.2.3","uuidv7":"^1.2.1","file-type":"^22.0.1","minimatch":"^9.0.0","@aws-sdk/client-s3":"^3.0.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/sdk":"^1.29.0","@modelcontextprotocol/ext-apps":"^1.7.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.12","express":"^5.2.1","ioredis":"^5.0.0","vitepress":"^1.6.4","@types/bun":"latest","typescript":"^5.0.0","@xterm/xterm":"^6.0.0","@biomejs/biome":"^2.4.13","@types/express":"^5.0.6","@xterm/addon-fit":"^0.11.0","vite-plugin-singlefile":"^2.3.3"},"peerDependencies":{"ioredis":""},"peerDependenciesMeta":{"ioredis":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-cloud-fs_0.4.0_1778605465745_0.030863836320826676","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@nogoo9/mcp-server-cloud-fs","version":"0.5.0","keywords":["mcp","mcp-server","model-context-protocol","cloud-storage","s3","aws-s3","azure-blob","gcs","google-cloud-storage","filesystem","vfs","virtual-filesystem","ai-agent","claude-code","gemini"],"author":{"name":"eterna2"},"license":"PolyForm-Shield-1.0.0","_id":"@nogoo9/mcp-server-cloud-fs@0.5.0","maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"contributors":[{"name":"eterna2"}],"homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"bin":{"cloud-fs":"dist/cli-tui.js","cloud-fs-mcp":"dist/index.js"},"dist":{"shasum":"7695410fdf8bf4faa77b0bea1aae0943c349e342","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.5.0.tgz","fileCount":320,"integrity":"sha512-JFPKZvA3SaZbPo3h1tmIF1PIe2j3ZZJAZ4+GFHQAOtyBxL5ew3wOncfLZ4gIQCCyL7+S9TJMXQksV6BKoKoG2w==","signatures":[{"sig":"MEYCIQCRE1tqgzZGyELxqoVDF3dsZBONCnBVDv40ipNAHteezgIhAJoO5rDBoZ7mPOwyZx5T9EJSzvklDPLa6/96DHxwo3VL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nogoo9%2fmcp-server-cloud-fs@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":832558},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"}},"gitHead":"7587237afc7de92f14092f8b521fdbf662a430d9","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","scripts":{"lint":"biome check src/","test":"bun test src/cache src/providers src/tools src/auth src/middleware src/path-utils.test.ts src/vfs.test.ts","build":"tsc -p tsconfig.build.json","check":"biome check --write --unsafe src/","format":"biome check --write --unsafe src/","inspect":"bun x @modelcontextprotocol/inspector -- bun src/index.ts","docs:dev":"bun run docs:typedoc && vitepress dev docs","infra:up":"docker compose -f infra/docker-compose.yml up -d","test:all":"bun test --timeout 30000","test:e2e":"bun test src/server.e2e.test.ts src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","build:app":"vite build -c src/app/vite.config.ts","typecheck":"tsc --noEmit","docs:build":"bun run docs:typedoc && vitepress build docs","infra:down":"docker compose -f infra/docker-compose.yml down","infra:logs":"docker compose -f infra/docker-compose.yml logs","infra:setup":"docker compose -f infra/docker-compose.yml up -d","test:e2e:ws":"bun test src/transports/ws.e2e.test.ts --timeout 30000","docs:preview":"vitepress preview docs","docs:typedoc":"typedoc && typedoc --options typedoc.internals.json","test:coverage":"bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage","test:e2e:http":"bun test src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","inspect:memory":"bun x @modelcontextprotocol/inspector -- bun src/index.ts memory mem://demo --enable-shell --seed-demo","prepublishOnly":"bun run build","test:e2e:infra":"bun test src/server.e2e.test.ts --timeout 30000","test:integration":"bun test src/providers/*.integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7164ac07-dd31-4d57-a032-405598369742"}},"repository":{"url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git","type":"git"},"_npmVersion":"11.11.0","description":"High-performance MCP server and library providing a cloud-native replacement for mcp-server-filesystem. Supports S3, Azure Blob, GCS, and SQLite with VFS cache coherence.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.0.0","jose":"^6.2.3","uuidv7":"^1.2.1","file-type":"^22.0.1","minimatch":"^9.0.0","@aws-sdk/client-s3":"^3.0.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/sdk":"^1.29.0","@modelcontextprotocol/ext-apps":"^1.7.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.12","express":"^5.2.1","ioredis":"^5.0.0","typedoc":"^0.28.19","nosecone":"^1.4.0","vitepress":"^2.0.0-alpha.17","@types/bun":"latest","typescript":"^5.0.0","@xterm/xterm":"^6.0.0","@biomejs/biome":"^2.4.13","@types/express":"^5.0.6","@xterm/addon-fit":"^0.11.0","vite-plugin-singlefile":"^2.3.3","typedoc-plugin-markdown":"^4.11.0","typedoc-vitepress-theme":"^1.1.2"},"peerDependencies":{"ioredis":"","nosecone":"","better-sqlite3":""},"peerDependenciesMeta":{"ioredis":{"optional":true},"nosecone":{"optional":true},"better-sqlite3":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-cloud-fs_0.5.0_1778699300699_0.24334502195079555","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@nogoo9/mcp-server-cloud-fs","version":"0.6.0","keywords":["mcp","mcp-server","model-context-protocol","cloud-storage","s3","aws-s3","azure-blob","gcs","google-cloud-storage","filesystem","vfs","virtual-filesystem","ai-agent","claude-code","gemini"],"author":{"name":"eterna2"},"license":"PolyForm-Shield-1.0.0","_id":"@nogoo9/mcp-server-cloud-fs@0.6.0","maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"contributors":[{"name":"eterna2"}],"homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"bin":{"cloud-fs":"dist/cli-tui.js","cloud-fs-mcp":"dist/index.js"},"dist":{"shasum":"65020ba51929db523000afe7a355b4ff888cbdfe","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.6.0.tgz","fileCount":360,"integrity":"sha512-40ZrrrGxMTYXzQOYeigw5KDaWeR1FIUq5EdCH56SgSEOSSMCnJQQ8nGiskqEG32Cj8MvIvlm6RmH5/v4E8bqZQ==","signatures":[{"sig":"MEUCIQChjC2g39FTooN83LSqnPNSqbnInyiCQEZiHitINkOtGwIgXQAehLppvf6ujU0JmAB394BVYw5CJW/In+q87ZRPx9s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nogoo9%2fmcp-server-cloud-fs@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":980378},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"}},"gitHead":"37d582198730359d6d59f507b5adec78fef23f99","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","scripts":{"lint":"biome check src/","test":"bun test src/cache src/providers src/tools src/auth src/middleware src/path-utils.test.ts src/vfs.test.ts","build":"tsc -p tsconfig.build.json","check":"biome check --write --unsafe src/","format":"biome check --write --unsafe src/","inspect":"bun x @modelcontextprotocol/inspector -- bun src/index.ts","docs:dev":"bun run docs:typedoc && vitepress dev docs","infra:up":"docker compose -f infra/docker-compose.yml up -d","test:all":"bun test --timeout 30000","test:e2e":"bun test src/server.e2e.test.ts src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","build:app":"vite build -c src/app/vite.config.ts","typecheck":"tsc --noEmit","docs:build":"bun run docs:typedoc && vitepress build docs","infra:down":"docker compose -f infra/docker-compose.yml down","infra:logs":"docker compose -f infra/docker-compose.yml logs","infra:setup":"docker compose -f infra/docker-compose.yml up -d","test:e2e:ws":"bun test src/transports/ws.e2e.test.ts --timeout 30000","docs:preview":"vitepress preview docs","docs:typedoc":"typedoc && typedoc --options typedoc.internals.json","test:coverage":"bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage","test:e2e:http":"bun test src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","inspect:memory":"bun x @modelcontextprotocol/inspector -- bun src/index.ts memory mem://demo --enable-shell --seed-demo","prepublishOnly":"bun run build","test:e2e:infra":"bun test src/server.e2e.test.ts --timeout 30000","test:integration":"bun test src/providers/*.integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7164ac07-dd31-4d57-a032-405598369742"}},"repository":{"url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git","type":"git"},"_npmVersion":"11.11.0","description":"High-performance MCP server and library providing a cloud-native replacement for mcp-server-filesystem. Supports S3, Azure Blob, GCS, and SQLite with VFS cache coherence.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.0.0","jose":"^6.2.3","uuidv7":"^1.2.1","file-type":"^22.0.1","minimatch":"^9.0.0","@aws-sdk/client-s3":"^3.0.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/sdk":"^1.29.0","@aws-sdk/s3-request-presigner":"^3.1046.0","@modelcontextprotocol/ext-apps":"^1.7.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.12","express":"^5.2.1","ioredis":"^5.0.0","typedoc":"^0.28.19","nosecone":"^1.4.0","vitepress":"^2.0.0-alpha.17","@types/bun":"latest","typescript":"^5.0.0","@xterm/xterm":"^6.0.0","@biomejs/biome":"^2.4.13","@types/express":"^5.0.6","@xterm/addon-fit":"^0.11.0","vite-plugin-singlefile":"^2.3.3","typedoc-plugin-markdown":"^4.11.0","typedoc-vitepress-theme":"^1.1.2"},"peerDependencies":{"ioredis":"","nosecone":"","better-sqlite3":"","@azure/identity":""},"peerDependenciesMeta":{"ioredis":{"optional":true},"nosecone":{"optional":true},"better-sqlite3":{"optional":true},"@azure/identity":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-cloud-fs_0.6.0_1778807795861_0.39457443872639053","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@nogoo9/mcp-server-cloud-fs","mcpName":"io.github.nogoo9/mcp-server-cloud-fs","version":"0.7.0","description":"High-performance MCP server and library providing a cloud-native replacement for mcp-server-filesystem. Supports S3, Azure Blob, GCS, and SQLite with VFS cache coherence.","keywords":["mcp","mcp-server","model-context-protocol","cloud-storage","s3","aws-s3","azure-blob","gcs","google-cloud-storage","filesystem","vfs","virtual-filesystem","ai-agent","claude-code","gemini"],"author":{"name":"eterna2"},"contributors":[{"name":"eterna2"}],"type":"module","bin":{"cloud-fs-mcp":"dist/index.js","cloud-fs":"dist/cli-tui.js"},"main":"dist/lib.js","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"}},"scripts":{"build":"tsc -p tsconfig.build.json","prepublishOnly":"bun run build","typecheck":"tsc --noEmit","lint":"biome check src/","format":"biome check --write --unsafe src/","check":"biome check --write --unsafe src/","test":"bun test src/cache src/providers src/tools src/auth src/middleware src/path-utils.test.ts src/vfs.test.ts","test:coverage":"bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage","test:integration":"bun test src/providers/*.integration.test.ts","test:e2e":"bun test src/server.e2e.test.ts src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","test:e2e:http":"bun test src/transports/http.e2e.test.ts src/transports/ws.e2e.test.ts --timeout 30000","test:e2e:ws":"bun test src/transports/ws.e2e.test.ts --timeout 30000","test:e2e:infra":"bun test src/server.e2e.test.ts --timeout 30000","test:all":"bun test --timeout 30000","infra:up":"docker compose -f infra/docker-compose.yml up -d","infra:down":"docker compose -f infra/docker-compose.yml down","infra:setup":"docker compose -f infra/docker-compose.yml up -d","infra:logs":"docker compose -f infra/docker-compose.yml logs","build:app":"vite build -c src/app/vite.config.ts","inspect":"bun x @modelcontextprotocol/inspector -- bun src/index.ts","inspect:memory":"bun x @modelcontextprotocol/inspector -- bun src/index.ts memory mem://demo --enable-shell --seed-demo","docs:typedoc":"typedoc && typedoc --options typedoc.internals.json","docs:dev":"bun run docs:typedoc && vitepress dev docs","docs:build":"bun run docs:typedoc && vitepress build docs","docs:preview":"vitepress preview docs"},"license":"PolyForm-Shield-1.0.0","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git"},"homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"dependencies":{"@aws-sdk/client-s3":"^3.0.0","@aws-sdk/s3-request-presigner":"^3.1046.0","@azure/storage-blob":"^12.0.0","@google-cloud/storage":"^7.0.0","@modelcontextprotocol/ext-apps":"^1.7.1","@modelcontextprotocol/sdk":"^1.29.0","file-type":"^22.0.1","jose":"^6.2.3","minimatch":"^9.0.0","uuidv7":"^1.2.1","zod":"^3.0.0"},"peerDependencies":{"ioredis":"","better-sqlite3":"","nosecone":"","@azure/identity":""},"peerDependenciesMeta":{"ioredis":{"optional":true},"better-sqlite3":{"optional":true},"nosecone":{"optional":true},"@azure/identity":{"optional":true}},"devDependencies":{"@biomejs/biome":"^2.4.13","@types/bun":"latest","@types/express":"^5.0.6","@xterm/addon-fit":"^0.11.0","@xterm/xterm":"^6.0.0","express":"^5.2.1","ioredis":"^5.0.0","nosecone":"^1.4.0","typedoc":"^0.28.19","typedoc-plugin-markdown":"^4.11.0","typedoc-vitepress-theme":"^1.1.2","typescript":"^5.0.0","vite":"^8.0.12","vite-plugin-singlefile":"^2.3.3","vitepress":"^2.0.0-alpha.17"},"gitHead":"c3260f37ee9c64dd121f0a8da0fb4c9d398cb605","_id":"@nogoo9/mcp-server-cloud-fs@0.7.0","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-kqOifmRE1sR9wcF0b1PEBcOlOYP7z6L+UN/WKFqA0/2vhxMpqoR4h6knX0AKTfCtQ2iQQmA1B+jm558F1w8Qgw==","shasum":"faf8d8baaed29d39bf7aa195e5253b06d457288d","tarball":"https://registry.npmjs.org/@nogoo9/mcp-server-cloud-fs/-/mcp-server-cloud-fs-0.7.0.tgz","fileCount":376,"unpackedSize":1394082,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@nogoo9%2fmcp-server-cloud-fs@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFVSCsyt6aHKbpb/SFp1F2Vj7mXJNOjShBu967zb38bSAiA5jhJcP9HFFyen7VMdpm+gTvtpNaan3P2ZS9wr2MXIdw=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7164ac07-dd31-4d57-a032-405598369742"}},"directories":{},"maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-server-cloud-fs_0.7.0_1779122935040_0.05830110643961017"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-27T15:56:20.720Z","modified":"2026-05-18T16:48:55.566Z","0.1.0":"2026-04-27T15:56:21.016Z","0.2.0":"2026-05-11T17:37:06.576Z","0.3.0":"2026-05-11T18:58:08.159Z","0.4.0":"2026-05-12T17:04:25.999Z","0.5.0":"2026-05-13T19:08:20.911Z","0.6.0":"2026-05-15T01:16:36.094Z","0.7.0":"2026-05-18T16:48:55.244Z"},"bugs":{"url":"https://github.com/nogoo9/mcp-server-cloud-fs/issues"},"author":{"name":"eterna2"},"license":"PolyForm-Shield-1.0.0","homepage":"https://github.com/nogoo9/mcp-server-cloud-fs#readme","keywords":["mcp","mcp-server","model-context-protocol","cloud-storage","s3","aws-s3","azure-blob","gcs","google-cloud-storage","filesystem","vfs","virtual-filesystem","ai-agent","claude-code","gemini"],"repository":{"type":"git","url":"git+https://github.com/nogoo9/mcp-server-cloud-fs.git"},"description":"High-performance MCP server and library providing a cloud-native replacement for mcp-server-filesystem. Supports S3, Azure Blob, GCS, and SQLite with VFS cache coherence.","contributors":[{"name":"eterna2"}],"maintainers":[{"name":"eterna2","email":"eterna2@hotmail.com"}],"readme":"<p align=\"center\">\n  <img src=\"docs/public/images/logo.png\" alt=\"nogoo9\" width=\"128\" />\n</p>\n\n<h1 align=\"center\">@nogoo9/mcp-server-cloud-fs</h1>\n\n<p align=\"center\">\n  <a href=\"https://github.com/nogoo9/mcp-server-cloud-fs/actions/workflows/ci.yml\"><img src=\"https://github.com/nogoo9/mcp-server-cloud-fs/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"https://nogoo9.github.io/mcp-server-cloud-fs/\"><img src=\"https://img.shields.io/badge/docs-GitHub_Pages-blue?logo=github\" alt=\"Docs\"></a>\n  <a href=\"https://coveralls.io/github/nogoo9/mcp-server-cloud-fs?branch=main\"><img src=\"https://coveralls.io/repos/github/nogoo9/mcp-server-cloud-fs/badge.svg?branch=main\" alt=\"Coverage\"></a>\n  <a href=\"https://semgrep.dev\"><img src=\"https://img.shields.io/badge/SAST-Semgrep-4B11A8?logo=semgrep&logoColor=white\" alt=\"Semgrep\"></a>\n  <br/>\n  <a href=\"https://www.npmjs.com/package/@nogoo9/mcp-server-cloud-fs\"><img src=\"https://img.shields.io/npm/v/@nogoo9/mcp-server-cloud-fs\" alt=\"npm\"></a>\n  <img src=\"https://img.shields.io/npm/dm/%40nogoo9%2Fmcp-server-cloud-fs\" alt=\"NPM Downloads\">\n  <a href=\"https://skills.sh/nogoo9/mcp-server-cloud-fs\"><img src=\"https://skills.sh/b/nogoo9/mcp-server-cloud-fs\" alt=\"skills.sh\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-PolyForm--Shield--1.0.0-blue\" alt=\"License\"></a>\n</p>\n\n<p align=\"center\">\n  Cloud replacement for <code>mcp-server-filesystem</code> — 30 tools for S3, Azure Blob, and GCS.<br/>\n  Deploy locally via STDIO or remotely over HTTP/WebSocket with OAuth 2.1 auth.<br/>\n  Also available as an npm library and interactive TUI.\n</p>\n\n<p align=\"center\">\n  <strong>📖 <a href=\"https://nogoo9.github.io/mcp-server-cloud-fs/latest/\">Read the full documentation →</a></strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://buymeacoffee.com/eterna2\">\n    <img src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" height=\"48\">\n  </a>\n</p>\n\n![cloud-fs in Claude Code](docs/public/images/cloud-fs-claude-demo.svg)\n\n![cloud-fs interactive shell](docs/public/images/cloud-fs-cli-demo.svg)\n\n**Providers:** Amazon S3 · Azure Blob Storage · Google Cloud Storage · MinIO · RustFS · Cloudflare R2 · Backblaze B2 · Wasabi · LocalStack · SQLite · In-Memory\n\n---\n\n## Table of Contents\n\n- [What it does](#what-it-does)\n- [Quick start](#quick-start)\n- [Interactive Shell](#interactive-shell-cloud-fs)\n- [Transports](#transports)\n- [Authentication & Authorization](#authentication--authorization)\n- [Production Features](#production-features)\n- [CLI Reference](#cli-reference)\n- [Provider Setup](#provider-setup)\n- [MCP Client Config](#mcp-client-config)\n- [Tool Reference](#tool-reference)\n- [Architecture: VFS](#architecture-virtual-filesystem-vfs)\n- [Caching](#caching)\n- [Programmatic Usage](#programmatic-usage-npm-library)\n- [MCP Inspector](#mcp-inspector)\n- [Development & Testing](#development--testing)\n- [AI Agent Skill](#ai-agent-skill)\n- [Documentation](#documentation)\n- [License](#license)\n\n---\n\n## What it does\n\n`@nogoo9/mcp-server-cloud-fs` exposes all 14 tools defined by [`mcp-server-filesystem`](https://github.com/modelcontextprotocol/servers/tree/main/src/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.\n\nIt also includes **5 extended tools** inspired by [claude-code's filesystem tool surface](https://github.com/codeaashu/claude-code/tree/main/src/tools): 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).\n\nA **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**.\n\n### v0.7.0 Highlights\n\n- **Dynamic tool surface reduction**: scope-aware tool filtering — clients only see tools they're authorized to use\n- **DLP content sanitization**: regex-based middleware redacts PII, API keys, and credentials from tool responses (`--enable-dlp`)\n- **AI-native tools**: `get_file_schema` extracts CSV/JSON structure; `summarize_file` returns compact head/tail previews\n- **ETag concurrency control**: SHA-256 content-addressable ETags with `expected_etag` conflict detection on `edit_file` and `patch_file`\n- **`patch_file` macro tool**: atomic read-diff-write in a single tool call — supports unified diffs and line-range replacements\n\n### v0.6.0 Highlights\n\n- **Cloud-native tools**: presigned URLs, object metadata/tags, version history, version restore\n- **Byte-range reads**: `read_file_chunk` fetches specific byte ranges without downloading the full object\n- **Structured audit logging**: tool invocation audit trail with pluggable sinks (stderr, file)\n- **Multi-provider routing**: `MultiProvider` serves S3 + Azure + GCS from a single server instance\n- **Azure Managed Identity**: `DefaultAzureCredential` for OIDC and federated auth\n- **Connection health-check**: startup credential validation with diagnostic reporting\n- **MCP Resources**: browse cloud storage as native MCP Resources (no tool calls needed)\n- **Structured errors**: `CloudError` with typed codes and provider-specific error mappers\n\n### v0.5.0 Highlights\n\n- **Interactive TUI (`cloud-fs`)**: Terminal shell with `cd`, tab completion, and command history\n- **Multi-transport**: STDIO (default), Streamable HTTP, and WebSocket\n- **Dual runtime**: Bun-native and Node.js support (HTTP transport + SQLite provider)\n- **OAuth 2.1**: Built-in auth server or external IdP token validation\n- **ext-auth extensions**: Client Credentials (M2M) and Enterprise-Managed Authorization (SSO)\n- **Production hardening**: Rate limiting, CORS, security headers, health checks, structured logging\n- **AI agent skill**: Installable `skills/cloud-fs` for Claude Code, Gemini CLI, and other AI assistants\n\n---\n\n## Quick start\n\n### Local (STDIO — default)\n\n```bash\nnpx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket\n```\n\n### Remote (HTTP)\n\n```bash\n# Bun (zero Express dependency)\nbunx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket --transport http --port 3000\n\n# Node.js (requires express peer dep)\nnpx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket --transport http --port 3000\n```\n\n### Remote (WebSocket — Bun only)\n\n```bash\nbunx @nogoo9/mcp-server-cloud-fs s3 s3://my-bucket --transport ws --port 3000\n```\n\n### Demo (no cloud credentials needed)\n\n```bash\nbunx @nogoo9/mcp-server-cloud-fs memory mem://demo --enable-shell --seed-demo\n```\n\n---\n\n## Interactive Shell (`cloud-fs`)\n\n![cloud-fs interactive shell demo](docs/public/images/cloud-fs-cli-demo.svg)\n\nDrop into an interactive terminal for exploring and managing cloud storage — no MCP client needed:\n\n```bash\n# S3\nnpx -p @nogoo9/mcp-server-cloud-fs cloud-fs s3 s3://my-bucket\n\n# In-memory demo with sample files\nnpx -p @nogoo9/mcp-server-cloud-fs cloud-fs memory mem://demo --seed-demo\n\n# With a config file (cloud-fs.json in CWD)\nnpx -p @nogoo9/mcp-server-cloud-fs cloud-fs\n```\n\n### Features\n\n- **`cd` navigation** — `cd data`, `cd ..`, `cd /` with dynamic prompt showing current directory\n- **Tab completion** — context-aware path and command completion\n- **Command history** — persistent across sessions (`~/.cloud-fs_history`)\n- **Relative paths** — all commands resolve relative to `cwd`, just like a real shell\n- **19 built-in commands** — `ls`, `cat`, `head`, `tail`, `cp`, `mv`, `rm`, `mkdir`, `touch`, `stat`, `find`, `grep`, `wc`, `du`, `echo`, `tee`, `diff`, `jq`, `cd`\n- **Pipes & redirects** — `cat config.json | jq '.database'`, `echo hello > file.txt`\n\n### Local development\n\n```bash\nbun src/cli-tui.ts memory mem://demo --seed-demo\n```\n\n---\n\n## Transports\n\nThe server supports three MCP transports, selected via `--transport`:\n\n| Transport | Flag | Runtime | Use case |\n|---|---|---|---|\n| **STDIO** | `--transport stdio` (default) | Bun, Node | Local `npx`, Claude Desktop, Claude Code |\n| **Streamable HTTP** | `--transport http` | Bun ✅, Node ✅ | Remote deployment, multi-user, enterprise |\n| **WebSocket** | `--transport ws` | Bun only | Low-latency bidirectional, real-time apps |\n\n### Streamable HTTP\n\nImplements the [MCP Streamable HTTP specification](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) with a single `/mcp` endpoint for POST (requests), GET (SSE notifications), and DELETE (session termination).\n\n**Dual runtime support:**\n\n- **Bun**: Uses `WebStandardStreamableHTTPServerTransport` with `Bun.serve()` directly — zero Express dependency, maximum performance.\n- **Node.js**: Falls back to `StreamableHTTPServerTransport` with Express. Requires `express` as an optional peer dependency (`npm install express`).\n\nRuntime is auto-detected at startup.\n\n**Session management:**\n\nSessions 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.\n\n**Resumability:**\n\nWhen an EventStore is configured, clients can reconnect and resume receiving messages from where they left off via the `Last-Event-ID` SSE header.\n\n```bash\n# Basic HTTP server\ncloud-fs-mcp s3 s3://my-bucket --transport http --port 3000\n\n# With authentication\ncloud-fs-mcp s3 s3://my-bucket --transport http --port 3000 --auth builtin --auth-issuer https://my-server.example.com\n\n# Production deployment\ncloud-fs-mcp s3 s3://my-bucket \\\n  --transport http --port 3000 --host 0.0.0.0 \\\n  --auth external --auth-jwks-uri https://login.example.com/.well-known/jwks.json \\\n  --cors-origin https://app.example.com \\\n  --rate-limit 60 --rate-limit-burst 10 \\\n  --security-headers \\\n  --request-logging\n```\n\n### WebSocket\n\nBun-native WebSocket transport using `Bun.serve()` with WebSocket upgrade handling. Provides lower latency than HTTP for high-frequency tool invocations.\n\n- JSON-RPC message framing over WebSocket\n- UUID v7 session assigned on upgrade\n- WS ping/pong heartbeat for connection liveness\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket --transport ws --port 3000\n```\n\n---\n\n## Authentication & Authorization\n\nAuthentication is **disabled by default** and only applies to HTTP/WS transports. STDIO mode never requires auth.\n\n### Auth modes\n\n| Mode | Flag | Description |\n|---|---|---|\n| `none` | `--auth none` (default) | No authentication. Suitable for local/trusted networks. |\n| `builtin` | `--auth builtin` | Self-hosted OAuth 2.1 Authorization Server. The MCP server acts as both AS and RS. |\n| `external` | `--auth external` | Validate bearer tokens against an external IdP (Okta, Auth0, Keycloak, Azure AD). |\n\n### Built-in OAuth server (`--auth builtin`)\n\nThe server runs a full OAuth 2.1 Authorization Server using the MCP SDK's `mcpAuthRouter()`:\n\n- **Authorization Code + PKCE** (mandatory) — interactive user consent flow\n- **Dynamic Client Registration** — MCP clients auto-register on first connect\n- **Refresh token rotation** — single-use refresh tokens prevent replay\n- **Metadata discovery** — `/.well-known/oauth-authorization-server` (RFC 8414) and `/.well-known/oauth-protected-resource` (RFC 9728)\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket \\\n  --transport http --port 3000 \\\n  --auth builtin --auth-issuer https://my-server.example.com\n```\n\n### External IdP (`--auth external`)\n\nThe server only validates bearer tokens — it does not issue tokens. Use this when you have an existing identity provider.\n\n- **JWKS validation** — fetches and caches signing keys from your IdP\n- **JWT verification** — checks signature, issuer, audience, expiry\n- **Token introspection** — fallback for opaque tokens\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket \\\n  --transport http --port 3000 \\\n  --auth external \\\n  --auth-jwks-uri https://login.example.com/.well-known/jwks.json \\\n  --auth-audience https://cloud-fs.example.com\n```\n\n### ext-auth: Client Credentials (M2M)\n\nImplements the [MCP Client Credentials extension](https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/draft/oauth-client-credentials.mdx) for machine-to-machine authentication without user interaction. Designed for CI/CD pipelines, background services, and automated workflows.\n\n- **JWT assertion auth** (`private_key_jwt` per RFC 7523) — recommended\n- **Client secret auth** (`client_secret_basic`) — simpler but less secure\n- No user interaction required — tokens granted based on pre-registered client credentials\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket \\\n  --transport http --port 3000 \\\n  --auth builtin --auth-issuer https://my-server.example.com \\\n  --auth-client-credentials\n```\n\n### ext-auth: Enterprise-Managed Authorization (SSO)\n\nImplements the [MCP Enterprise-Managed Authorization extension](https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/draft/enterprise-managed-authorization.mdx) for seamless SSO via your organization's Identity Provider.\n\n**How it works:**\n\n1. User logs in to the MCP Client via the enterprise IdP (OpenID Connect or SAML)\n2. Client exchanges the ID Token for an Identity Assertion JWT Authorization Grant (ID-JAG) via Token Exchange (RFC 8693)\n3. Client presents the ID-JAG to this server's Authorization Server (RFC 7523)\n4. Server validates the ID-JAG and issues an access token\n\n**Benefits:**\n\n- Zero manual authorization per MCP Server — SSO handles everything\n- Enterprise admins control which users/groups can access which MCP servers\n- Granular scope enforcement via IdP policies\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket \\\n  --transport http --port 3000 \\\n  --auth builtin --auth-issuer https://my-server.example.com \\\n  --auth-enterprise-idp https://acme.okta.com\n```\n\n### OAuth Scopes\n\nWhen auth is enabled, tool access is controlled by granular scopes:\n\n| Scope | Tools |\n|---|---|\n| `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` |\n| `cloud-fs:write` | `write_file`, `edit_file`, `create_directory`, `set_object_tags`, `restore_version`, `patch_file` |\n| `cloud-fs:delete` | `delete_file` |\n| `cloud-fs:search` | `search_files`, `grep_file`, `grep_files`, `list_directory`, `list_directory_with_sizes`, `directory_tree`, `search_by_tag` |\n| `cloud-fs:shell` | `shell` |\n| `cloud-fs:admin` | All tools + `get_file_info`, `list_allowed_directories` |\n\nWhen `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.\n\nTokens with insufficient scopes receive a clear error response indicating which scope is required.\n\n---\n\n## Production Features\n\n### Health Checks\n\nHTTP/WS transports expose Kubernetes-convention health endpoints:\n\n| Endpoint | Purpose | Success | Failure |\n|---|---|---|---|\n| `/healthz` | Liveness — is the process alive? | `200 OK` always | Process is dead |\n| `/readyz` | Readiness — can it serve traffic? | `200 OK` after VFS hydration | `503` during startup |\n\nConfigure your orchestrator's liveness and readiness probes to use these endpoints.\n\n### Rate Limiting\n\nToken bucket rate limiting protects against abuse. **Disabled by default.**\n\n- **In-memory** — per-IP/per-client counters for single-process deployments\n- **Redis** — distributed rate limiting for multi-instance deployments (uses existing optional `ioredis` peer dep)\n- Returns `429 Too Many Requests` with `Retry-After` header when limits are exceeded\n\n```bash\n# 60 requests/minute with burst of 10\ncloud-fs-mcp s3 s3://my-bucket --transport http \\\n  --rate-limit 60 --rate-limit-burst 10\n```\n\n### CORS\n\nCross-Origin Resource Sharing for browser-based MCP clients:\n\n- Strict origin allowlist — no wildcards in production\n- Exposes `Mcp-Session-Id` and `Mcp-Protocol-Version` headers\n- Localhost auto-allows `*` when `--host 127.0.0.1` (dev convenience)\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket --transport http \\\n  --cors-origin https://app.example.com \\\n  --cors-origin https://staging.example.com\n```\n\n### Structured Request Logging\n\nJSON audit trail to stderr for compliance and debugging:\n\n```json\n{\"ts\":\"2026-05-12T12:00:00Z\",\"sessionId\":\"019...\",\"tool\":\"read_file\",\"user\":\"alice@example.com\",\"latencyMs\":42,\"status\":200}\n```\n\nEnable with `--request-logging`.\n\n### DNS Rebinding Protection\n\nAutomatically applied when binding to localhost addresses. Validates the `Host` header against allowed hostnames to prevent DNS rebinding attacks.\n\n### Security Headers\n\nOpt-in HTTP response hardening via [nosecone](https://github.com/arcjet/arcjet-js/tree/main/nosecone) — a framework-agnostic security headers library. Works with both Bun-native and Node/Express transports.\n\nWhen enabled, every HTTP response includes standard security headers:\n\n- `Content-Security-Policy`\n- `Strict-Transport-Security`\n- `X-Content-Type-Options: nosniff`\n- `X-Frame-Options`\n- `Cross-Origin-Opener-Policy`\n- `Cross-Origin-Resource-Policy`\n- `Referrer-Policy`\n- And more (see [nosecone defaults](https://docs.arcjet.com/nosecone/quick-start))\n\n```bash\n# Enable with defaults\ncloud-fs-mcp s3 s3://my-bucket --transport http --security-headers\n\n# Custom configuration via inline JSON\ncloud-fs-mcp s3 s3://my-bucket --transport http \\\n  --security-headers-config '{\"contentSecurityPolicy\":false}'\n\n# Custom configuration via file\ncloud-fs-mcp s3 s3://my-bucket --transport http \\\n  --security-headers-config-file ./nosecone.json\n```\n\n> **Note:** Requires the `nosecone` peer dependency: `npm install nosecone`\n\n---\n\n## CLI Reference\n\n```\ncloud-fs-mcp <provider> <root-uri> [root-uri...] [options]\n```\n\n### Providers\n\n| Provider | URI format | Description |\n|---|---|---|\n| `s3` | `s3://bucket[/prefix]` | AWS S3, and any S3-compatible endpoint (MinIO, RustFS, Cloudflare R2, Backblaze B2, Wasabi, LocalStack, …) |\n| `azure` | `az://container[/prefix]` | Azure Blob Storage |\n| `gcs` | `gs://bucket[/prefix]` | Google Cloud Storage |\n| `memory` | `mem://name` | In-memory (ephemeral, for demos) |\n| `sqlite` | `sqlite://name` | SQLite (persistent local) |\n\n### Options\n\n#### Transport & Network\n\n| Flag | Default | Description |\n|---|---|---|\n| `--transport <stdio\\|http\\|ws>` | `stdio` | Transport protocol |\n| `--port <number>` | `3000` | Listen port (http/ws only) |\n| `--host <address>` | `127.0.0.1` | Bind address (http/ws only) |\n\n#### Authentication\n\n| Flag | Default | Description |\n|---|---|---|\n| `--auth <none\\|builtin\\|external>` | `none` | Auth mode (http/ws only) |\n| `--auth-issuer <url>` | — | OAuth issuer URL (builtin mode) |\n| `--auth-jwks-uri <url>` | — | JWKS URI (external mode) |\n| `--auth-audience <string>` | — | Expected token audience (external mode) |\n| `--auth-client-credentials` | `false` | Enable Client Credentials ext-auth flow |\n| `--auth-enterprise-idp <url>` | — | Enable Enterprise-Managed Authorization |\n\n#### Production\n\n| Flag | Default | Description |\n|---|---|---|\n| `--cors-origin <origin>` | — | Allowed CORS origin (repeatable) |\n| `--rate-limit <req/min>` | `0` (off) | Rate limit per client |\n| `--rate-limit-burst <n>` | `10` | Burst allowance |\n| `--request-logging` | `false` | Enable structured JSON request logging |\n| `--audit-log` | `false` | Enable tool invocation audit logging to stderr |\n| `--audit-log-file <path>` | — | Write audit log to file (implies `--audit-log`) |\n| `--security-headers` | `false` | Enable security headers via nosecone |\n| `--security-headers-config <json>` | — | Inline JSON config for nosecone |\n| `--security-headers-config-file <path>` | — | Load nosecone config from a JSON file |\n\n#### Storage & Cache\n\n| Flag | Default | Description |\n|---|---|---|\n| `--region <region>` | — | Cloud region (S3, GCS) |\n| `--endpoint <url>` | — | Custom endpoint for S3-compatible backends |\n| `--cache-store <memory\\|fs\\|redis>` | `memory` | Cache backend |\n| `--cache-ttl <seconds>` | `60` | Cache TTL in seconds |\n| `--sync-debounce <ms>` | `2000` | Write flush delay in ms |\n| `--cache-dir <path>` | — | Directory for fs cache store |\n| `--no-cache` | — | Bypass cache entirely (pass-through mode) |\n| `--gcs-endpoint <url>` | — | Custom endpoint for GCS |\n| `--sqlite-db <path>` | — | SQLite database file path |\n| `--ca-file <path>` | — | PEM CA bundle for TLS (S3-compatible + Redis) |\n\n#### Tools\n\n| Flag | Default | Description |\n|---|---|---|\n| `--enable-delete` | `false` | Enable the `delete_file` tool |\n| `--enable-shell` | `false` | Enable the `shell` tool |\n| `--enable-dlp` | `false` | Enable DLP content sanitization (redacts PII/secrets from responses) |\n| `--grep-max-objects <n>` | `1000` | Max objects `grep_files` scans per call |\n| `--seed-demo` | `false` | Seed VFS with sample files for demo |\n\nCredentials are always sourced from SDK credential chains — never CLI flags.\n\n---\n\n## Provider Setup\n\n### AWS S3\n\nCredentials 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.\n\n```bash\ncloud-fs-mcp s3 s3://my-bucket --region us-east-1\n```\n\n### S3-compatible storage\n\nAny S3-compatible backend works via `--endpoint`. All use the standard AWS credential chain (`AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY`).\n\n| Provider | `--endpoint` value | Notes |\n|---|---|---|\n| **MinIO** | `http://minio:9000` | Self-hosted; use `--ca-file` for TLS with a private CA |\n| **RustFS** | `http://rustfs:9000` | Rust-native S3-compatible store |\n| **LocalStack** | `http://localhost:4566` | Full AWS emulator for local dev and CI |\n| **Cloudflare R2** | `https://<account-id>.r2.cloudflarestorage.com` | No egress fees; use an R2 API token as the secret key |\n| **Backblaze B2** | `https://s3.<region>.backblazeb2.com` | Use B2 application key ID / key |\n| **Wasabi** | `https://s3.<region>.wasabisys.com` | Compatible, no egress fees |\n| **DigitalOcean Spaces** | `https://<region>.digitaloceanspaces.com` | Use a Spaces access key |\n| **Scaleway** | `https://s3.<region>.scw.cloud` | Use a Scaleway access key |\n| **Ceph RGW** | `http://<rgw-host>:<port>` | Enterprise self-hosted; supports all S3 APIs |\n| **SeaweedFS** | `http://<master>:8333` | High-throughput distributed FS with S3 API |\n| **Garage** | `http://<node>:3900` | Lightweight distributed S3 for homelabs |\n\n```bash\n# MinIO\nexport AWS_ACCESS_KEY_ID=minioadmin\nexport AWS_SECRET_ACCESS_KEY=minioadmin\ncloud-fs-mcp s3 s3://my-bucket --endpoint http://minio:9000\n\n# Cloudflare R2\nexport AWS_ACCESS_KEY_ID=<r2-access-key-id>\nexport AWS_SECRET_ACCESS_KEY=<r2-secret-access-key>\ncloud-fs-mcp s3 s3://my-bucket --endpoint https://<account-id>.r2.cloudflarestorage.com --region auto\n\n# Backblaze B2\nexport AWS_ACCESS_KEY_ID=<b2-key-id>\nexport AWS_SECRET_ACCESS_KEY=<b2-application-key>\ncloud-fs-mcp s3 s3://my-bucket --endpoint https://s3.us-west-004.backblazeb2.com --region us-west-004\n\n# LocalStack\nexport AWS_ACCESS_KEY_ID=test\nexport AWS_SECRET_ACCESS_KEY=test\ncloud-fs-mcp s3 s3://my-bucket --endpoint http://localhost:4566 --region us-east-1\n```\n\n> **TLS with private CA:** For MinIO, RustFS, or Ceph with a self-signed certificate, add `--ca-file /path/to/ca.pem`.\n\n### Azure Blob Storage\n\nUses `DefaultAzureCredential` — works with `AZURE_TENANT_ID` / `AZURE_CLIENT_ID` / `AZURE_CLIENT_SECRET` env vars, managed identity, `az login`, and so on.\n\n```bash\ncloud-fs-mcp azure az://my-container\n```\n\n### Google Cloud Storage\n\nUses Application Default Credentials (ADC). Set `GOOGLE_APPLICATION_CREDENTIALS` or run `gcloud auth application-default login`.\n\n```bash\ncloud-fs-mcp gcs gs://my-bucket\n```\n\n### In-Memory (ephemeral)\n\nZero-config, zero-dependency provider. All data lives in a `Map` and is lost when the process exits.\n\n```bash\ncloud-fs-mcp memory mem://demo --enable-shell\n```\n\n### SQLite (persistent local)\n\nPersistent 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`).\n\n```bash\ncloud-fs-mcp sqlite sqlite://my-bucket --sqlite-db /tmp/cloud-fs.db --enable-shell\n```\n\n---\n\n## MCP Client Config\n\n### Claude Desktop\n\n`~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows):\n\n```json\n{\n  \"mcpServers\": {\n    \"cloud-fs\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@nogoo9/mcp-server-cloud-fs\", \"s3\", \"s3://my-bucket\"]\n    }\n  }\n}\n```\n\n### Claude Code\n\n`.mcp.json` in your project root:\n\n```json\n{\n  \"mcpServers\": {\n    \"cloud-fs\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@nogoo9/mcp-server-cloud-fs\", \"s3\", \"s3://my-bucket\"]\n    }\n  }\n}\n```\n\n### Remote HTTP client\n\n```json\n{\n  \"mcpServers\": {\n    \"cloud-fs\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://cloud-fs.example.com/mcp\"\n    }\n  }\n}\n```\n\n---\n\n## Tool Reference\n\nAll 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.\n\n### Read tools\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `read_file` | `path` | Read a file. Binary → base64; text → UTF-8. |\n| `read_text_file` | `path`, `head?`, `tail?` | Read text file with optional head/tail line limits. |\n| `read_media_file` | `path` | Read image/media as base64 MCP image content block. |\n| `read_multiple_files` | `paths` | Read several files in parallel. |\n| `read_file_range` ✨ | `path`, `offset`, `limit` | Read a 1-based line range with total line count header. |\n| `read_file_chunk` ✨ | `path`, `start_byte`, `end_byte?`, `encoding?` | Read a byte range without downloading the entire file. Max 10MB. |\n\n### Write tools\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `write_file` | `path`, `content` | Write/overwrite a file. Flushed after debounce window. |\n| `edit_file` | `path`, `edits[]`, `dryRun?`, `expected_etag?` | Apply `{ oldText, newText }` edits. Preview with `dryRun`. Optional ETag conflict detection. |\n\n### Directory tools\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `create_directory` | `path` | Create a directory placeholder and parent prefixes. |\n| `list_directory` | `path` | List immediate children (like `ls`). |\n| `list_directory_with_sizes` | `path`, `sortBy?`, `limit?` | List children with sizes. Sort by size or name. |\n| `directory_tree` | `path`, `excludePatterns?` | Recursive directory tree with glob exclusions. |\n\n### Move, Copy & Delete tools\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `move_file` | `source`, `destination` | Move file. Server-side copy + delete for same-bucket. |\n| `copy_file` ✨ | `source`, `destination` | Copy file. Server-side for same-bucket. |\n| `delete_file` ✨ | `path` | Delete file. **Requires `--enable-delete`.** |\n\n### Search tools\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `search_files` | `path`, `pattern`, `excludePatterns?` | Glob-based object key search. |\n| `grep_file` ✨ | `path`, `pattern`, `case_insensitive?` | Regex search in a single file with line numbers. |\n| `grep_files` ✨ | `path`, `pattern`, `glob?`, `case_insensitive?`, `output_mode?`, `max_objects?` | Regex search across all objects under a path. |\n\n### Info tools\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `get_file_info` | `path` | File metadata: size, last-modified, content type. |\n| `list_allowed_directories` | _(none)_ | List configured root URIs. |\n\n> ✨ = Extended tool\n\n### Cloud-native tools ☁️\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `get_presigned_url` ☁️ | `path`, `operation?`, `expires_in?` | Generate a temporary access URL (default: GET, 1 hour). |\n| `get_object_metadata` ☁️ | `path` | Size, content type, last modified, custom metadata, and tags. |\n| `set_object_tags` ☁️ | `path`, `tags` | Replace object tags with key-value pairs. |\n| `search_by_tag` ☁️ | `path`, `tags`, `recursive?` | Find objects matching tag filters (AND logic). |\n| `list_versions` ☁️ | `path`, `max_results?`, `page_token?` | Version history with timestamps, sizes, and markers. |\n| `restore_version` ☁️ | `path`, `version_id` | Restore a previous object version (copies over current). |\n\n> ☁️ = Cloud-native tool (requires provider support)\n\n### AI-native tools 🧠\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `get_file_schema` 🧠 | `path` | Extract structural schema: CSV column names/types/samples, JSON shape, or text line/byte counts. |\n| `summarize_file` 🧠 | `path`, `max_lines?` | Compact head/tail preview with file size, line count, and content type. |\n\n> 🧠 = AI-native tool (reduces LLM context token waste)\n\n### Macro tools 🩹\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `patch_file` 🩹 | `path`, `patch`, `format?`, `expected_etag?` | Apply unified diffs or line-range replacements atomically in a single tool call. |\n\n> 🩹 = Macro tool (combines read + transform + write)\n\n### Shell tool ⚡\n\n| Tool | Parameters | Description |\n|---|---|---|\n| `shell` ⚡ | `command` | Execute POSIX-like commands. Supports pipes, redirects. **Requires `--enable-shell`.** |\n\n**Built-in commands:** `ls`, `cat`, `head`, `tail`, `cp`, `mv`, `rm`, `mkdir`, `touch`, `stat`, `find`, `grep`, `wc`, `du`, `echo`, `tee`, `diff`, `jq`, `cd`\n\n#### Relative paths\n\nAll 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:\n\n```bash\n# With root s3://my-bucket/data, these are equivalent:\nshell \"cat config.json\"\nshell \"cat s3://my-bucket/data/config.json\"\n\n# Subdirectories work naturally:\nshell \"ls logs/\"\nshell \"cat logs/app.log | grep ERROR\"\n\n# ls with no args lists the root's contents:\nshell \"ls\"\n\n# find with no args searches from the root:\nshell \"find -name '*.json'\"\n```\n\nStandard `.` and `..` are normalized, with `..` traversal blocked at the root boundary for security.\n\n#### Examples\n\n```bash\n# List root contents\nshell \"ls -l\"\n\n# JSON query with jq\nshell \"cat config.json | jq '.database.port'\"\n\n# Search and count\nshell \"grep -i error server.log | wc -l\"\n\n# Write files\nshell \"echo hello world > greeting.txt\"\n\n# Copy and diff\nshell \"cp config.json config.backup.json\"\nshell \"diff config.json config.backup.json\"\n\n# Full URIs still work for cross-root access\nshell \"cat s3://other-bucket/file.txt\"\n```\n\n> ⚡ Requires `--enable-shell`. `rm` and `mv` additionally require `--enable-delete`.\n\n---\n\n## Architecture: Virtual Filesystem (VFS)\n\nAll tool operations are mediated through a **Virtual Filesystem (VFS)** layer inspired by [FUSE](https://en.wikipedia.org/wiki/Filesystem_in_Userspace).\n\n```\n┌─────────────────────────────────────────────────────────┐\n│  MCP Tool Handlers (read, write, list, stat, …)         │\n├─────────────────────────────────────────────────────────┤\n│  VirtualFS                                              │\n│  ┌───────────┐ ┌───────────┐ ┌───────────┐              │\n│  │  Inodes   │ │ DirIndex  │ │ Tombstones│              │\n│  │ (metadata)│ │ (parents) │ │ (deleted) │              │\n│  └─────┬─────┘ └─────┬─────┘ └─────┬─────┘              │\n│        └──────────────┴─────────────┘                   │\n│         ⇣ Overlay (in-memory, persisted to CacheStore)  │\n├─────────────────────────────────────────────────────────┤\n│  CacheStore (Memory / Filesystem / Redis)               │\n├─────────────────────────────────────────────────────────┤\n│  StorageProvider (S3 / Azure Blob / GCS / Memory / SQL) │\n└─────────────────────────────────────────────────────────┘\n```\n\n| Operation | Resolution |\n|---|---|\n| **`get()`** | Cache hit → return. Tombstoned → throw. Else → provider fallback. |\n| **`stat()`** | Inode overlay → cached content size → provider `headObject`. |\n| **`list()`** | Provider listing – tombstones + overlay dirIndex entries. |\n| **`put()`** | Cache set + markDirty + inode update + dirIndex. Immediate visibility. |\n| **`remove()`** | Provider deleteObject + cache evict + tombstone. Immediate invisibility. |\n\nVFS metadata is persisted to the CacheStore under `__vfs__/*` keys. On startup, `VirtualFS.hydrate()` restores state; corrupted data is silently discarded.\n\n---\n\n## Caching\n\n| Backend | Flag | Notes |\n|---|---|---|\n| **Memory** (default) | `--cache-store memory` | In-process, fast, not shared, not persistent. |\n| **Filesystem** | `--cache-store fs --cache-dir <path>` | Survives restarts. |\n| **Redis** | `--cache-store redis` | Shared, persistent. Requires `ioredis` peer dep. `REDIS_URL` env var. Use `rediss://` for TLS. |\n\n**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.\n\n> **⚠️ Redis TLS:** The server warns at startup when `REDIS_URL` uses unencrypted `redis://`. Use `rediss://` for TLS-encrypted connections in production.\n\n### Custom CA Certificates\n\nUse `--ca-file <path>` to supply a PEM CA bundle for S3-compatible endpoints (MinIO, RustFS) and Redis running with a private CA:\n\n```bash\n# S3-compatible with self-signed CA\ncloud-fs-mcp s3 s3://my-bucket \\\n  --endpoint https://minio.internal:9000 \\\n  --ca-file /etc/ssl/certs/my-ca.pem\n\n# Redis with private CA\nREDIS_URL=rediss://redis.internal:6380 \\\ncloud-fs-mcp s3 s3://my-bucket --cache-store redis \\\n  --ca-file /etc/ssl/certs/my-ca.pem\n```\n\nFor runtime-wide CA trust (all providers + Redis), use the standard `NODE_EXTRA_CA_CERTS` env var instead:\n\n```bash\nNODE_EXTRA_CA_CERTS=/etc/ssl/certs/my-ca.pem cloud-fs-mcp s3 s3://my-bucket\n```\n\n---\n\n## Programmatic Usage (npm library)\n\n```ts\nimport {\n  createMcpServer, VirtualFS, MemoryStore,\n  S3Provider, parseUri,\n} from \"@nogoo9/mcp-server-cloud-fs\";\n\nconst roots    = [parseUri(\"s3://my-bucket\")];\nconst provider = new S3Provider({ region: \"us-east-1\" });\nconst cache    = new MemoryStore(provider, { ttlMs: 60_000, syncDebounceMs: 2000 });\nconst vfs      = new VirtualFS(provider, cache);\nawait vfs.hydrate();\n\nconst server = createMcpServer({ vfs, roots });\n```\n\n### Exported API\n\n| Export | Description |\n|---|---|\n| `createMcpServer(ctx)` | Create a configured MCP server instance |\n| `executeShell(command, ctx)` | Run POSIX-like commands against the VFS |\n| `VirtualFS` | FUSE-inspired write-back overlay |\n| `MemoryStore`, `FilesystemStore`, `createRedisStore`, `PassThroughCache` | Cache backends |\n| `S3Provider`, `AzureProvider`, `GcsProvider`, `MemoryProvider`, `SqliteProvider`, `MultiProvider` | Storage providers |\n| `CloudError`, `CloudErrorCode` | Structured cloud-aware error handling |\n| `checkHealth`, `formatHealthReport` | Connection health-check utilities |\n| `AuditLogger`, `StderrAuditSink`, `FileAuditSink` | Tool invocation audit logging |\n| `parseUri`, `toCacheKey`, `resolveToolPath` | Path utilities |\n| `ShellContext`, `ShellCommandHandler` | Shell extension types |\n\n---\n\n## MCP Inspector\n\n```bash\n# Quick demo (no credentials needed)\nbun run inspect:memory\n\n# Custom configuration\nbun run inspect -- s3 s3://my-bucket --region us-east-1 --enable-shell\n```\n\n---\n\n## MCP App: Interactive Shell (xterm.js)\n\nBuild the app: `bun run build:app` → outputs `dist/app/shell-app.html`.\n\nCatppuccin Mocha theme, command history, auto-resize. Renders inside compatible MCP hosts (Claude Desktop) via the MCP Apps extension.\n\n---\n\n## Development & Testing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for full setup instructions.\n\n**AI agent skills** are installed separately after cloning via `bun x skills add semgrep/skills` — see [CONTRIBUTING.md](CONTRIBUTING.md#ai-agent-skills) for details.\n\n### Test tiers\n\n| Tier | Command | Infra? |\n|---|---|---|\n| **Unit** | `bun run test` | No |\n| **E2E (HTTP)** | `bun run test:e2e:http` | No |\n| **E2E (Infra)** | `bun run test:e2e:infra` | Docker |\n| **Integration** | `bun run test:integration` | Docker |\n| **All** | `bun run test:all` | Docker |\n\n### CI pipeline\n\nThe CI workflow runs on every push/PR:\n\n1. **ci** job: lint → typecheck → unit tests (with coverage) → HTTP E2E → build\n2. **e2e** job: full E2E with Docker Compose (MinIO, Redis)\n\nHTTP E2E tests use the in-memory provider and need zero infrastructure, making them fast and reliable for every CI run.\n\n---\n\n## AI Agent Skill\n\n![cloud-fs skill in action](docs/public/images/cloud-fs-claude-demo.svg)\n\nThe `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.\n\n### What it provides\n\n- **MCP mode auto-detection** — recognizes `mcp__cloud-fs__*` tools and maps user intents to the right tool calls\n- **Bootstrap flow** — walks the user through first-time setup when the MCP server isn't configured yet\n- **POSIX-to-MCP mapping** — translates shell commands (`ls`, `cat`, `grep`, `find`, `cp`, etc.) into the correct MCP tool calls\n- **Provider credential reference** — AWS, Azure, GCS, MinIO/RustFS, SQLite setup guidance\n- **`.mcp.json` persistence** — offers to save provider configuration so future sessions are pre-wired\n\n### Installation\n\n```bash\n# Claude Code\nclaude mcp add-skill nogoo9/mcp-server-cloud-fs\n\n# skills.sh\nnpx skills add nogoo9/mcp-server-cloud-fs\n\n# or with bun instead\nbun x skills add nogoo9/mcp-server-cloud-fs\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md#ai-agent-skills) for details on the skill system.\n\n---\n\n## Documentation\n\nFull documentation is available at **[nogoo9.github.io/mcp-server-cloud-fs](https://nogoo9.github.io/mcp-server-cloud-fs/)**.\n\n- 📖 Versioned docs for each release (v0.4.0+)\n- 🔄 PR preview docs for open pull requests\n- 🔍 Full-text search, dark mode, responsive design\n- Built with [VitePress](https://vitepress.dev/)\n\nTo run the documentation site locally:\n\n```bash\nbun run docs:dev      # start dev server at http://localhost:5173\nbun run docs:build    # build static site\nbun run docs:preview  # preview production build\n```\n\n---\n\n## License\n\n[PolyForm Shield 1.0.0](LICENSE). Free for any non-competitive use.\n\n---\n\nBuilt with [![Claude](https://img.shields.io/badge/Claude-d97706?logo=anthropic&logoColor=white)](https://claude.ai) [![Gemini](https://img.shields.io/badge/Gemini-8E75FF?logo=googlegemini&logoColor=white)](https://gemini.google.com) [![Antigravity](https://img.shields.io/badge/Antigravity-4285F4?logo=google&logoColor=white)](https://antigravity.google/)\n","readmeFilename":"README.md"}