Skip to content

Conversation

@r33drichards
Copy link
Owner

This commit extends the V8 JavaScript runtime with built-in resource functions that provide sandboxed file system access within JavaScript code.

Features:

  • resource.read(uri): Read file contents
  • resource.list(uri): List directory contents
  • resource.write(uri, content): Write to files
  • resource.delete(uri): Delete files or directories

Implementation details:

  • New ResourceStorage trait with FileResourceStorage implementation
  • V8 function callbacks bridge JavaScript to Rust async operations
  • Path traversal protection and directory sandboxing
  • Configurable resource directory via --resource-directory CLI flag
  • Default resource directory: /tmp/mcp-v8-resources

Changes:

  • server/src/mcp/resource_storage.rs: New module implementing resource storage
  • server/src/mcp.rs: Added V8 callbacks and integrated into execution context
  • server/src/main.rs: Added CLI argument and wired resource storage to services
  • README.md: Documented new resource functions and updated limitations

All resource operations are sandboxed to prevent unauthorized file access.

This commit extends the V8 JavaScript runtime with built-in resource functions
that provide sandboxed file system access within JavaScript code.

Features:
- resource.read(uri): Read file contents
- resource.list(uri): List directory contents
- resource.write(uri, content): Write to files
- resource.delete(uri): Delete files or directories

Implementation details:
- New ResourceStorage trait with FileResourceStorage implementation
- V8 function callbacks bridge JavaScript to Rust async operations
- Path traversal protection and directory sandboxing
- Configurable resource directory via --resource-directory CLI flag
- Default resource directory: /tmp/mcp-v8-resources

Changes:
- server/src/mcp/resource_storage.rs: New module implementing resource storage
- server/src/mcp.rs: Added V8 callbacks and integrated into execution context
- server/src/main.rs: Added CLI argument and wired resource storage to services
- README.md: Documented new resource functions and updated limitations

All resource operations are sandboxed to prevent unauthorized file access.
Tests cover:
- resource.write() and resource.read() basic operations
- resource.list() for directory listing
- resource.delete() for file deletion
- Nested directory creation and access
- Error handling for non-existent files/directories
- file:// URI scheme support
- Complex JSON operations with resource functions

Also adds:
- common.rs test utilities module
- StdioServer::start_with_resources() helper method
- Temporary directory creation for resource storage
- Use v8::Context::new() instead of non-existent new_from_template()
- Remove unused Path import from resource_storage.rs
- Remove unused FileResourceStorage import from mcp.rs
Use v8::ContextOptions struct with global_template field
instead of passing the template directly to v8::Context::new()
Fixes:
- Added resource test functions to correct location (server/tests/)
- Added start_with_resources() helper to StdioServer
- Added create_temp_resource_dir() and cleanup_resource_dir() to common module
- Removed incorrectly placed test files in wrong directory

Tests added (8 comprehensive test cases):
- test_stdio_resource_write_and_read: Basic read/write operations
- test_stdio_resource_list: Directory listing functionality
- test_stdio_resource_delete: File deletion
- test_stdio_resource_nested_directories: Nested directory handling
- test_stdio_resource_error_handling: Error cases validation
- test_stdio_resource_file_uri_scheme: URI scheme support
- test_stdio_resource_json_operations: Complex JSON workflows

All tests properly create isolated temp directories for resource storage.
Capture tokio runtime handle before entering spawn_blocking context
in both StatelessService and StatefulService. This prevents EOF errors
that occur when trying to access Handle::current() from within blocking
threads where the runtime context is not available.

The runtime handle is now passed as a parameter to execute_stateless()
and execute_stateful() functions, ensuring async resource operations
can be bridged correctly from V8 callbacks.
Changed ResourceStorage trait and implementation from async to sync using
std::fs instead of tokio::fs. This eliminates the need for block_on() calls
from V8 callbacks, which was causing deadlocks in stdio transport.

V8 callbacks are inherently synchronous, so using blocking I/O is appropriate
and avoids the complexity and pitfalls of bridging async/sync contexts within
the tokio runtime.

Changes:
- Removed async_trait and async/await from ResourceStorage trait
- Updated FileResourceStorage to use std::fs instead of tokio::fs
- Removed runtime_handle from IsolateData struct
- Updated V8 callbacks to call storage methods directly
- Simplified execute_stateless and execute_stateful function signatures
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants