A Go application that mounts multiple FUSE filesystems based on a configuration file. Each service (Notion, Gmail, etc.) is mounted under its own directory, allowing filesystem-based access to cloud services.
- Multi-service FUSE mounting: Mount multiple services simultaneously under different mount points
- Extensible architecture: Easy to add new services through a registry pattern
- Configuration-driven: Simple YAML configuration file
- Graceful shutdown: Clean unmounting on SIGINT/SIGTERM
- Notion: Access Notion workspaces and pages as files
- Gmail: Access Gmail labels and emails as files
- Website: Mount any website as a filesystem with routes as files and markdown versions
go build -o agentos ./cmd/agentos# Run directly with go run
go run ./cmd/agentos
# Run with a specific config file
go run ./cmd/agentos --config config.yaml
# List available services
go run ./cmd/agentos --list-services
# Force unmount stale mount points before mounting (useful after crashes)
go run ./cmd/agentos --force
# Or build and run the binary
go build -o agentos ./cmd/agentos
./agentosCreate a config.yaml file (see config.example.yaml for a template):
services:
- type: notion
mount_point: /tmp/agentos/notion
options:
# api_token: "your-notion-api-token"
- type: gmail
mount_point: /tmp/agentos/gmail
options:
# client_id: "your-client-id"
- type: website
mount_point: /tmp/agentos/website
options:
base_url: "https://example.com"# List available services
./agentos --list-services
# Mount services from config
./agentos --config config.yaml
# Use default config.yaml in current directory
./agentosPress Ctrl+C to unmount all services and exit.
If the application crashes or is forcefully terminated, FUSE mount points may remain active and prevent remounting. You'll see errors like:
failed to mount gmail at /tmp/agentos/gmail: failed to create mount point: mkdir /tmp/agentos/gmail: file exists
Or when trying to delete:
rm: cannot remove './agentos/gmail': Is a directory
Solution: Manually unmount the stuck mount point:
# Unmount a specific mount point
fusermount3 -u /tmp/agentos/gmail
# Or use sudo if needed
sudo umount /tmp/agentos/gmail
# Then clean up the directory
rm -rf /tmp/agentosTo check active FUSE mounts:
mount | grep fuseTo add a new service:
- Create a new package under
internal/services/<servicename>/ - Implement the
mount.Serviceinterface:
package myservice
import (
"github.com/hanwen/go-fuse/v2/fs"
"github.com/pdparchitect/agentos/internal/mount"
)
func init() {
mount.Register("myservice", func() mount.Service {
return &Service{}
})
}
type Service struct{}
func (s *Service) Name() string {
return "myservice"
}
func (s *Service) CreateRoot(options map[string]interface{}) (fs.InodeEmbedder, error) {
return &MyRootNode{}, nil
}- Import the service package in
cmd/agentos/main.go:
import (
_ "github.com/pdparchitect/agentos/internal/services/myservice"
)- Rebuild the application
.
├── cmd/agentos/ # Main application entry point
├── internal/
│ ├── config/ # Configuration loading and parsing
│ ├── mount/ # FUSE mounting infrastructure and service registry
│ └── services/ # Service implementations
│ ├── notion/ # Notion filesystem service
│ ├── gmail/ # Gmail filesystem service
│ └── website/ # Website filesystem service
├── config.example.yaml # Example configuration
└── README.md
- Go 1.21+
- FUSE (Linux) or macFUSE (macOS)
MIT