1. Introduction to AGFS
AGFS is a project that provides storage services through a RESTful API. It supports a variety of storage backends, including memory, files, databases, message queues, and more.
Because it does not need POSIX interface support, data can be stored through remote calls, which is very useful in AI Agents.
When an AI Agent runs certain workflows, it often produces intermediate results. These results need to be shared with other Agents or used for the next Agent execution, and AGFS meets this need well — especially in Sandbox environments, where AGFS is a very suitable choice.
Each backend service corresponds to a plugin (MemFS, QueueFS, KVFS, S3FS, SQLFS, etc.), mounted into a unified directory tree.
agfs-server (Go) provides the HTTP API + plugin management.
agfs-shell (Python) provides an interactive Shell.
agfs-fuse (Go) supports Linux FUSE mounting.
agfs-mcp provides MCP protocol access.
- Mapping to traditional approaches
| Traditional | AGFS |
|---|
redis.set("key", "value") | echo "value" > /kvfs/keys/mykey |
sqs.send_message(queue, msg) | echo "msg" > /queuefs/q/enqueue |
s3.put_object(bucket, key, d) | cp file /s3fs/bucket/key |
mysql.execute("SELECT ...") | echo "SELECT ..." > /sqlfs2/.../query |
2. Deploying AGFS
- Prepare the data directory
1
2
| mkdir -p agfs/data
chmod -R 777 agfs/data
|
- Prepare the configuration file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
| cat > agfs/config.yaml <<'EOF'
server:
address: ":8080"
log_level: info
plugins:
serverinfofs:
enabled: true
path: /serverinfo
config:
version: "1.0.0"
memfs:
enabled: true
path: /memfs
config:
init_dirs:
- /tmp
queuefs:
enabled: true
path: /queuefs
config: {}
kvfs:
enabled: true
path: /kvfs
config:
initial_data:
welcome: "Hello from AGFS!"
heartbeatfs:
enabled: true
path: /heartbeatfs
localfs:
enabled: true
path: /local
config:
local_dir: /data
sqlfs:
- name: local
enabled: true
path: /sqlfs
config:
backend: sqlite
db_path: /data/sqlfs.db
cache_enabled: true
cache_max_size: 1000
cache_ttl_seconds: 5
s3fs:
- name: s3
enabled: false
path: /s3fs
config:
region: cn-beijing
bucket: YOUR_BUCKET
access_key_id: "YOUR_ACCESS_KEY_ID"
secret_access_key: "YOUR_SECRET_ACCESS_KEY"
prefix: agfs/
endpoint: "YOUR_ENDPOINT"
disable_ssl: false
proxyfs:
- name: remote
enabled: false
path: /proxyfs/remote
config:
base_url: "http://other-agfs-host:8080/api/v1"
EOF
|
1
2
3
4
5
6
7
8
9
10
11
12
| nerdctl run -d \
--name agfs-server \
--restart always \
--security-opt apparmor=unconfined \
--security-opt seccomp=unconfined \
-p 8080:8080 \
--privileged \
--device /dev/fuse \
--cap-add SYS_ADMIN \
-v $(pwd)/agfs/data:/data \
-v $(pwd)/agfs/config.yaml:/config.yaml \
c4pt0r/agfs:latest
|
You can also use the SKIP_FUSE_MOUNT=true environment variable to skip the in-container FUSE mount, in which case privileged mode and the FUSE device mount are not required.
1
| nerdctl rm -f agfs-server
|
- Check the fuse mount point
1
2
3
| nerdctl exec -it agfs-server df -h | grep agfs
agfs 4.0T 2.0T 2.0T 50% /mnt/agfs
|
1
| curl http://127.0.0.1:8080/api/v1/health
|
1
| {"status":"healthy","version":"1.4.0","gitCommit":"unknown","buildTime":"unknown"}
|
3. Using AGFS Features
3.1 Key-Value Storage
Through the KVFS plugin, you can create and manage key-value pairs.
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/kvfs/keys/hello" \
-d "world"
|
1
| {"message":"Written 5 bytes"}
|
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/kvfs/keys/hello"
|
1
| curl "http://127.0.0.1:8080/api/v1/directories?path=/kvfs/keys/"
|
1
| {"files":[{"name":"hello","size":5,"mode":420,"modTime":"2026-03-25T08:23:51.098035422Z","isDir":false,"meta":{"Name":"kvfs","Type":"file","Content":null}}]}
|
1
| curl -X DELETE "http://127.0.0.1:8080/api/v1/files?path=/kvfs/keys/hello"
|
3.2 Message Queue
Through the QueueFS plugin, you can create and manage message queues.
1
| curl -X POST "http://127.0.0.1:8080/api/v1/directories?path=/queuefs/tasks"
|
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/queuefs/tasks/enqueue" \
-d "my-message"
|
1
| {"message":"Written 10 bytes"}
|
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/queuefs/tasks/size"
|
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/queuefs/tasks/dequeue"
|
1
| {"id":"019d2418-6424-7570-873a-311aad406c44","data":"my-message","timestamp":"2026-03-25T08:24:31.52435231Z"}
|
Peeking does not remove the head message from the queue.
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/queuefs/tasks/peek"
|
1
| {"id":"019d2419-7045-7d64-b9e7-8ccb24c9b0cb","data":"my-message","timestamp":"2026-03-25T08:25:40.165873217Z"}
|
3.3 In-Memory File System
Through the MemFS plugin, you can create and manage an in-memory file system.
1
| curl -X POST "http://127.0.0.1:8080/api/v1/directories?path=/memfs/my-memfs"
|
1
| {"message":"directory created"}
|
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/memfs/my-memfs/note.txt" \
-d "Hello AGFS"
|
1
| {"message":"Written 10 bytes"}
|
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/memfs/my-memfs/note.txt"
|
1
| curl "http://127.0.0.1:8080/api/v1/directories?path=/memfs/my-memfs"
|
1
| {"files":[{"name":"note.txt","size":10,"mode":420,"modTime":"2026-03-25T08:27:21.323579029Z","isDir":false,"meta":{"Name":"memfs","Type":"file","Content":null}}]}
|
1
| curl "http://127.0.0.1:8080/api/v1/stat?path=/memfs/my-memfs/note.txt"
|
1
| {"name":"note.txt","size":10,"mode":420,"modTime":"2026-03-25T08:27:21.323579029Z","isDir":false,"meta":{"Name":"memfs","Type":"file","Content":null}}
|
3.4 Agent Heartbeat Management
Through the HeartbeatFS plugin, you can create and manage Agent heartbeats.
1
| curl -X POST "http://127.0.0.1:8080/api/v1/directories?path=/heartbeatfs/agent-1"
|
1
| {"message":"directory created"}
|
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/heartbeatfs/agent-1/keepalive" \
-d "ping"
|
1
| {"message":"Written 4 bytes"}
|
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/heartbeatfs/agent-1/ctl"
|
1
2
3
4
| last_heartbeat_ts: 2026-03-25T08:32:37Z
expire_ts: 2026-03-25T08:37:37Z
timeout: 300
status: alive
|
3.5 Local File System
Through the localfs plugin, you can directly read and write a local directory mapped into the container.
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/local/kubectl" \
--data-binary @/usr/bin/kubectl
|
1
2
| curl -X GET "http://127.0.0.1:8080/api/v1/files?path=/local/kubectl" \
-o kubectl-local
|
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/local/test.txt" \
-d "persistent data"
|
1
| {"message":"Written 15 bytes"}
|
1
| curl "http://127.0.0.1:8080/api/v1/files?path=/local/test.txt"
|
Running cat $(pwd)/agfs/data/test.txt directly also shows the same content.
3.6 Using agfs-shell
1
| nerdctl exec -it agfs-server /bin/sh
|
You can also run commands directly, for example nerdctl exec -it agfs-server agfs ls /.
- Enter the Shell interactive mode
1
2
3
4
5
6
7
8
9
| agfs:/> ls /
dev/
heartbeatfs/
kvfs/
local/
memfs/
queuefs/
serverinfo/
sqlfs/
|
1
2
3
| agfs:/> echo "task-1" > /queuefs/tasks/enqueue
agfs:/> echo "value" > /kvfs/keys/mykey
agfs:/> cat /kvfs/keys/mykey
|
4. Plugin Management
AGFS supports mounting and unmounting plugins dynamically at runtime, with no need to restart the service.
1
| curl http://127.0.0.1:8080/api/v1/mounts
|
1
| {"mounts":[{"path":"/dev","pluginName":"devfs"},{"path":"/heartbeatfs","pluginName":"heartbeatfs"},{"path":"/kvfs","pluginName":"kvfs"},{"path":"/local","pluginName":"localfs"},{"path":"/memfs","pluginName":"memfs"},{"path":"/queuefs","pluginName":"queuefs"},{"path":"/serverinfo","pluginName":"serverinfofs"},{"path":"/sqlfs","pluginName":"sqlfs"}]}
|
- Dynamically mount a plugin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| curl -X POST http://127.0.0.1:8080/api/v1/mount \
-H "Content-Type: application/json" \
-d '{
"fstype": "s3fs",
"name": "s3",
"path": "/s3fs",
"config": {
"region": "cn-beijing",
"bucket": "YOUR_BUCKET",
"access_key_id": "YOUR_ACCESS_KEY_ID",
"secret_access_key": "YOUR_SECRET_ACCESS_KEY",
"prefix": "agfs/",
"endpoint": "YOUR_ENDPOINT",
"disable_ssl": false
}
}'
|
1
| {"message":"plugin mounted"}
|
1
2
| curl -X PUT "http://127.0.0.1:8080/api/v1/files?path=/s3fs/test.txt" \
-d "Hello AGFS"
|
1
| {"message":"Written 10 bytes"}
|
1
2
3
| curl -X POST http://127.0.0.1:8080/api/v1/unmount \
-H "Content-Type: application/json" \
-d '{"path": "/s3fs"}'
|
1
| {"message":"plugin unmounted"}
|
5. References