Expose Bucket Hierarchies as MCP Resources
Status: ✅ Implemented in v0.6.0 Issue: #11Commit:
9ba9a52—feat(resources): expose bucket hierarchies as MCP ResourcesBranch:feature/cloud-native-v1
Problem
Currently, all interactions with cloud storage go through MCP Tools (e.g., list_directory, read_file). This forces the LLM to explicitly call list_directory before it can "see" the file structure, consuming extra tokens and round-trips. The MCP specification includes a Resources primitive designed for exactly this — exposing data the LLM can browse in its context window without explicit tool calls.
Design
Resource URI Scheme
Map each configured root + its directory structure to MCP Resources:
cloud-fs://{scheme}://{bucket}/{prefix}Examples:
cloud-fs://s3://my-bucket/→ lists top-level objects/prefixescloud-fs://s3://my-bucket/data/→ lists objects underdata/cloud-fs://s3://my-bucket/config.json→ returns file content
Resource Templates
Register a parameterized resource template per configured root:
server.registerResourceTemplate(
"cloud-fs-browse",
{
uriTemplate: "cloud-fs://{rootUri}/{path*}",
name: "Cloud Storage Browser",
description: "Browse files and directories in configured cloud storage roots.",
mimeType: "text/plain",
},
async ({ rootUri, path }) => { /* resolve via VFS */ }
);Static Root Resources
On startup, register a static resource for each configured root URI:
for (const root of ctx.roots) {
server.registerResource(
`root:${root.uri}`,
`cloud-fs://${root.uri}/`,
{ name: `Root: ${root.uri}`, description: `Top-level listing of ${root.uri}` },
async () => { /* VFS list with delimiter "/" */ }
);
}Response Format
- Directory resources: Return a structured listing (JSON or formatted text) of objects and sub-prefixes.
- File resources: Return UTF-8 text content (or base64 for binary, with
mimeTypeset). - Metadata: Include
size,lastModified,contentTypein resource metadata when available.
Architecture Impact
src/server.ts → new registerResources(server, ctx) call
src/resources/ → [NEW] resource handler module
index.ts → registration logicNo changes to VFS, providers, or existing tools. Resources are a read-only view.
Implementation Plan
- Create
src/resources/index.tswithregisterResources(server, ctx). - Register static root resources for each
ctx.rootsentry. - Register a resource template that resolves
{path}to either a directory listing or file content viactx.vfs. - Add
registerResources()call increateMcpServer()insrc/server.ts. - Unit tests:
src/resources/index.test.ts— mock VFS, verify resource resolution. - E2E test: extend
http.e2e.test.tsto verify resource listing over transport.
Acceptance Criteria
- [x] MCP clients can discover root resources without calling any tool
- [x] Navigating a resource URI returns directory listing or file content
- [x] Resource template handles nested paths (
a/b/c/) - [x] Binary files return base64 with correct
mimeType - [x] Unit tests pass with mock provider
