diff --git a/apps/docs/smfs/providers/cloudflare.mdx b/apps/docs/smfs/providers/cloudflare.mdx
index bc027d86..93ee0d4b 100644
--- a/apps/docs/smfs/providers/cloudflare.mdx
+++ b/apps/docs/smfs/providers/cloudflare.mdx
@@ -1,205 +1,122 @@
---
title: "Cloudflare"
-sidebarTitle: "Cloudflare"
-description: "Add persistent memory to Cloudflare Workers agents with SMFS."
-icon: "cloud"
+description: "Give your AI agent persistent memory inside a Cloudflare Container using SMFS"
---
-[Cloudflare Workers](https://workers.cloudflare.com) run at the edge in V8 isolates — no filesystem, no shell. That's exactly what `@supermemory/bash` is built for. It gives your Worker a virtual bash environment backed by Supermemory, so your agent can `ls`, `cat`, `grep`, and write to a persistent memory container without needing a real filesystem.
+Mount a Supermemory container inside a
+[Cloudflare Container](https://developers.cloudflare.com/containers/) so your
+agent can read and write memory with plain bash commands.
-## Architecture
+## How it works
-Cloudflare Workers can't mount SMFS (no FUSE, no disk). Instead, use `@supermemory/bash` as a tool for your agent. The bash tool runs entirely in-process — no child processes, no disk I/O, no native dependencies.
-
-```
-Request → Worker → LLM → calls bash tool → @supermemory/bash → Supermemory API
-```
-
-
- If you're using [Cloudflare Containers](https://developers.cloudflare.com/containers/) (full Linux containers at the edge), you can install the `smfs` binary directly. See [Alternative: Cloudflare Containers](#alternative-cloudflare-containers) below.
-
+1. Build a container image with SMFS pre-installed
+2. Deploy it as a Cloudflare Container
+3. On startup, mount a Supermemory container inside the container
+4. Run a Claude agent with bash access — it reads/writes the SMFS mount naturally
## Prerequisites
-- A [Supermemory](https://console.supermemory.ai) account and API key
-- A [Cloudflare](https://dash.cloudflare.com) account
-- Node.js 18+ and Wrangler CLI
+- A [Supermemory API key](https://supermemory.ai)
+- An [Anthropic API key](https://console.anthropic.com)
+- A [Cloudflare account](https://dash.cloudflare.com) with Containers enabled
+- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/)
-## 1. Set up a Worker
+## Container setup
-```bash
-npm create cloudflare@latest -- my-memory-agent
-cd my-memory-agent
-npm install @supermemory/bash
-```
-
-Add your Supermemory API key as a secret:
-
-```bash
-npx wrangler secret put SUPERMEMORY_API_KEY
-```
-
-## 2. Build an agent with memory
-
-```typescript src/index.ts
-import { createBash } from "@supermemory/bash";
-
-export default {
- async fetch(request: Request, env: Env): Promise {
- const { bash, toolDescription } = await createBash({
- apiKey: env.SUPERMEMORY_API_KEY,
- containerTag: "user_42",
- });
-
- // Read the user's profile
- const profile = await bash.exec("cat /profile.md");
-
- // Search memory semantically
- const results = await bash.exec("sgrep 'project deadlines'");
-
- // Write new memory
- await bash.exec('echo "Met with client on April 27" >> /notes.md');
-
- return new Response(JSON.stringify({
- profile: profile.stdout,
- search: results.stdout,
- }));
- },
-};
-```
-
-## 3. Full agent with tool calling
-
-Wire `@supermemory/bash` as a tool for an LLM. This example uses the OpenAI API, but any provider works:
-
-```typescript src/index.ts
-import { createBash } from "@supermemory/bash";
-
-interface Env {
- SUPERMEMORY_API_KEY: string;
- OPENAI_API_KEY: string;
-}
-
-export default {
- async fetch(request: Request, env: Env): Promise {
- const { messages, userId } = await request.json() as {
- messages: any[];
- userId: string;
- };
-
- const { bash, toolDescription } = await createBash({
- apiKey: env.SUPERMEMORY_API_KEY,
- containerTag: `user_${userId}`,
- });
-
- // Call the LLM with the bash tool
- const response = await fetch("https://api.openai.com/v1/chat/completions", {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${env.OPENAI_API_KEY}`,
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- model: "gpt-4o",
- messages: [
- {
- role: "system",
- content: `You have persistent memory via a bash tool.
-Use it to remember things about the user.
-Start by reading /profile.md for context.`,
- },
- ...messages,
- ],
- tools: [{
- type: "function",
- function: {
- name: "bash",
- description: toolDescription,
- parameters: {
- type: "object",
- properties: { cmd: { type: "string" } },
- required: ["cmd"],
- },
- },
- }],
- }),
- });
-
- const data = await response.json() as any;
-
- // Handle tool calls
- if (data.choices[0].message.tool_calls) {
- const toolCall = data.choices[0].message.tool_calls[0];
- const cmd = JSON.parse(toolCall.function.arguments).cmd;
- const result = await bash.exec(cmd);
-
- // Send the result back to the LLM
- const followUp = await fetch("https://api.openai.com/v1/chat/completions", {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${env.OPENAI_API_KEY}`,
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- model: "gpt-4o",
- messages: [
- ...messages,
- data.choices[0].message,
- {
- role: "tool",
- tool_call_id: toolCall.id,
- content: JSON.stringify(result),
- },
- ],
- }),
- });
-
- const followUpData = await followUp.json() as any;
- return new Response(followUpData.choices[0].message.content);
- }
-
- return new Response(data.choices[0].message.content);
- },
-};
-```
-
-## Alternative: Cloudflare Containers
-
-[Cloudflare Containers](https://developers.cloudflare.com/containers/) give you full Linux environments at the edge. Unlike Workers, containers have a real filesystem and shell — so you can install and mount SMFS directly.
+### Dockerfile
```dockerfile Dockerfile
FROM node:20-slim
+# Install FUSE and bash
+RUN apt-get update && apt-get install -y fuse3 curl bash && rm -rf /var/lib/apt/lists/*
+RUN echo 'user_allow_other' >> /etc/fuse.conf
+
# Install SMFS
RUN curl -fsSL https://smfs.ai/install | bash
-# Your agent code
-COPY . /app
-WORKDIR /app
-RUN npm install
+# Install the Claude Agent SDK
+RUN npm install -g @anthropic-ai/claude-agent-sdk
-CMD ["node", "agent.js"]
+COPY entrypoint.sh /entrypoint.sh
+RUN chmod +x /entrypoint.sh
+
+ENTRYPOINT ["/entrypoint.sh"]
```
-Inside the container, mount SMFS as you would on any Linux machine:
+### Entrypoint
-```bash
-smfs login --key $SUPERMEMORY_API_KEY
-smfs mount agent_memory --ephemeral --path /memory
+```bash entrypoint.sh
+#!/bin/bash
+set -e
+
+# Log in and mount
+smfs login --key "$SUPERMEMORY_API_KEY"
+smfs mount my_agent --ephemeral --path /memory --foreground &
+sleep 5
+
+# Run the agent
+node agent.js
```
-Your agent can then use standard Unix commands to interact with memory.
+### Agent
+
+```typescript agent.ts
+import { query } from "@anthropic-ai/claude-agent-sdk";
+
+async function main() {
+ for await (const message of query({
+ prompt: `You have access to a persistent memory filesystem mounted at /memory.
+Use bash commands to explore it (ls, cat) and write notes to it (echo "..." > file).
+
+Read /memory/profile.md to learn about the user.
+Then create /memory/session_notes.md with a summary of what you found.`,
+ options: {
+ allowedTools: ["Bash", "Read", "Write"],
+ },
+ })) {
+ if (message.type === "text") console.log(message.text);
+ }
+}
+
+main();
+```
+
+## Worker + Container pattern
+
+Use a Cloudflare Worker as the HTTP frontend that triggers the container:
+
+```typescript worker.ts
+export default {
+ async fetch(request: Request, env: any) {
+ // Start the container (it runs the agent with SMFS mounted)
+ const container = await env.MY_CONTAINER.start();
+
+ // The container runs the agent and writes results to SMFS
+ // Read the result back
+ const response = await container.fetch("/result");
+ return response;
+ },
+};
+```
+
+```toml wrangler.toml
+name = "memory-agent"
+main = "worker.ts"
+
+[[containers]]
+class_name = "MY_CONTAINER"
+image = "./Dockerfile"
+max_instances = 5
+```
## Tips
-- **Workers have a 30-second CPU time limit.** Keep tool call chains short. If your agent needs many steps, consider using Durable Objects for longer-running workflows.
-- **One container tag per user.** Use the user's ID as the container tag for isolated memory per user.
-- **`sgrep` for semantic search.** Inside the bash tool, `sgrep "query"` searches by meaning. Regular `grep` does literal matching.
-- **Cache-friendly.** `@supermemory/bash` warms its path index on `createBash`. For Workers that handle many requests, consider caching the instance in a Durable Object.
-
-## Resources
-
-- [Cloudflare Workers docs](https://developers.cloudflare.com/workers/)
-- [Cloudflare Containers docs](https://developers.cloudflare.com/containers/)
-- [SMFS Bash Tool reference](/smfs/bash-tool)
-- [Supermemory quickstart](/quickstart)
+- Use `--ephemeral` when mounting inside containers — it keeps the cache in memory
+ only, but writes still push to Supermemory
+- Use `smfs grep 'query'` for semantic search across all files in the container
+- Set `SUPERMEMORY_API_KEY` and `ANTHROPIC_API_KEY` as Cloudflare secrets:
+ ```bash
+ wrangler secret put SUPERMEMORY_API_KEY
+ wrangler secret put ANTHROPIC_API_KEY
+ ```
diff --git a/apps/docs/smfs/providers/daytona.mdx b/apps/docs/smfs/providers/daytona.mdx
index 97ad1bd4..decdfce1 100644
--- a/apps/docs/smfs/providers/daytona.mdx
+++ b/apps/docs/smfs/providers/daytona.mdx
@@ -1,121 +1,71 @@
---
title: "Daytona"
-sidebarTitle: "Daytona"
-description: "Give your Daytona sandboxes persistent memory with SMFS."
-icon: "server"
+description: "Give your AI agent persistent memory inside a Daytona sandbox using SMFS"
---
-[Daytona](https://www.daytona.io) gives AI agents isolated Linux sandboxes that boot in milliseconds. Pair it with SMFS and your agent gets both safe code execution **and** persistent memory it can `ls`, `cat`, and `grep`.
+Mount a Supermemory container inside a [Daytona](https://daytona.io) sandbox so
+your agent can read and write memory with plain bash commands.
-## Architecture
+## How it works
-Daytona sandboxes run full Linux with shell access, filesystem, and network. There are two ways to wire SMFS in:
-
-
-
- Use `@supermemory/bash` in the code that **orchestrates** the sandbox. The agent reads memory via the bash tool, then sends code to Daytona for execution. Works everywhere.
-
-
- Install the `smfs` binary inside the sandbox and mount a container directly. Requires unrestricted outbound HTTPS from the sandbox.
-
-
-
-
- Some Daytona sandbox configurations may restrict outbound TLS to certain hosts. If `smfs mount` or `smfs login` fails with connection errors, use the Bash Tool pattern instead — it runs in your orchestrating code, not inside the sandbox.
-
+1. Create a Daytona sandbox
+2. Install SMFS and mount a Supermemory container inside it
+3. Run a Claude agent inside the sandbox — it uses `cat`, `ls`, `echo`, etc. on the mount
+4. Everything the agent writes is persisted to Supermemory automatically
## Prerequisites
-- A [Supermemory](https://console.supermemory.ai) account and API key
-- A [Daytona](https://app.daytona.io) account and API key
-- Node.js 18+ or Python 3.10+
+- A [Supermemory API key](https://supermemory.ai)
+- A [Daytona API key](https://app.daytona.io) — go to **API Keys** in the sidebar
+- An [Anthropic API key](https://console.anthropic.com)
-## 1. Get your API keys
-
-### Supermemory
-
-1. Go to [console.supermemory.ai](https://console.supermemory.ai)
-2. Navigate to **Settings → API Keys**
-3. Create a new key and copy it
-
-### Daytona
-
-1. Go to [app.daytona.io](https://app.daytona.io)
-2. Sign up and verify your email
-3. Set your default region (US or EU)
-4. Navigate to **API Keys** in the sidebar
-5. Click **Create Key**, give it a name, and copy the key
-
-
- You can only view a Daytona API key once. Store it somewhere safe immediately after creation.
-
-
-## 2. Install the SDKs
+## Quick start
```bash
- npm install @supermemory/bash @daytonaio/sdk
+ npm install @anthropic-ai/claude-agent-sdk @daytonaio/sdk
```
-
-
- ```bash
- pip install daytona-sdk
- ```
-
-
-
-## 3. Build an agent with memory + code execution
-
-
-
- The recommended TypeScript pattern: use `@supermemory/bash` for memory in your orchestrating code and the Daytona SDK for code execution. The LLM gets both as tools.
```typescript agent.ts
- import { createBash } from "@supermemory/bash";
import { Daytona } from "@daytonaio/sdk";
- import { generateText, tool } from "ai";
- import { openai } from "@ai-sdk/openai";
- import { z } from "zod";
+ import { query } from "@anthropic-ai/claude-agent-sdk";
async function main() {
- // 1. Set up memory (SMFS bash tool)
- const { bash, toolDescription } = await createBash({
- apiKey: process.env.SUPERMEMORY_API_KEY!,
- containerTag: "agent_memory",
- });
-
- // 2. Set up code execution (Daytona sandbox)
+ // 1. Create a Daytona sandbox
const daytona = new Daytona({
apiKey: process.env.DAYTONA_API_KEY!,
apiUrl: "https://app.daytona.io/api",
});
const sandbox = await daytona.create();
- // 3. Give the LLM both tools
- const result = await generateText({
- model: openai("gpt-4o"),
- tools: {
- memory: tool({
- description: toolDescription,
- parameters: z.object({ cmd: z.string() }),
- execute: async ({ cmd }) => bash.exec(cmd),
- }),
- execute_code: tool({
- description: "Run code in an isolated sandbox",
- parameters: z.object({ code: z.string() }),
- execute: async ({ code }) => {
- const res = await sandbox.process.exec(code);
- return res.result;
- },
- }),
- },
- prompt: "Check my memory for the user's preferred language, then write and run a hello world in that language.",
- });
+ // 2. Install SMFS, log in, and mount
+ await sandbox.process.exec("curl -fsSL https://smfs.ai/install | bash");
+ await sandbox.process.exec(
+ `~/.local/bin/smfs login --key ${process.env.SUPERMEMORY_API_KEY}`
+ );
+ await sandbox.process.exec(
+ "~/.local/bin/smfs mount my_agent --ephemeral --path /home/daytona/memory"
+ );
- console.log(result.text);
+ // 3. Run a Claude agent inside the sandbox with bash access
+ for await (const message of query({
+ prompt: `You have access to a persistent memory filesystem mounted at /home/daytona/memory.
+ Use bash commands to explore it (ls, cat) and write notes to it (echo "..." > file).
+
+ First, read /home/daytona/memory/profile.md to learn about the user.
+ Then create /home/daytona/memory/session_notes.md with a summary of what you found.`,
+ options: {
+ allowedTools: ["Bash", "Read", "Write"],
+ },
+ })) {
+ if (message.type === "text") console.log(message.text);
+ }
// 4. Clean up
+ await sandbox.process.exec(
+ "~/.local/bin/smfs unmount my_agent 2>/dev/null"
+ );
await daytona.delete(sandbox);
}
@@ -123,64 +73,66 @@ Daytona sandboxes run full Linux with shell access, filesystem, and network. The
```
- In Python, install and mount SMFS inside the Daytona sandbox. The agent reads and writes memory via standard shell commands.
-
-
- This requires unrestricted outbound HTTPS from the sandbox. If `smfs login` fails with a connection error, see the note at the top of this page.
-
+ ```bash
+ pip install claude-agent-sdk daytona-sdk
+ ```
```python agent.py
+ import asyncio
import os
+ from claude_agent_sdk import query, ClaudeAgentOptions
from daytona_sdk import Daytona, DaytonaConfig
- # 1. Set up code execution (Daytona sandbox)
- config = DaytonaConfig(
- api_key=os.environ["DAYTONA_API_KEY"],
- api_url="https://app.daytona.io/api",
- )
- daytona = Daytona(config)
- sandbox = daytona.create()
+ async def main():
+ # 1. Create a Daytona sandbox
+ config = DaytonaConfig(
+ api_key=os.environ["DAYTONA_API_KEY"],
+ api_url="https://app.daytona.io/api",
+ )
+ daytona = Daytona(config)
+ sandbox = daytona.create()
- # 2. Install SMFS inside the sandbox
- sandbox.process.exec(
- "curl -fsSL https://smfs.ai/install | bash"
- )
+ # 2. Install SMFS, log in, and mount
+ sandbox.process.exec("curl -fsSL https://smfs.ai/install | bash")
+ sandbox.process.exec(
+ f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
+ )
+ sandbox.process.exec(
+ "~/.local/bin/smfs mount my_agent --ephemeral --path /home/daytona/memory"
+ )
- # 3. Log in and mount
- sandbox.process.exec(
- f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
- )
- sandbox.process.exec(
- "~/.local/bin/smfs mount agent_memory --ephemeral"
- )
+ # 3. Run a Claude agent inside the sandbox with bash access
+ async for message in query(
+ prompt="""You have access to a persistent memory filesystem mounted at /home/daytona/memory.
+ Use bash commands to explore it (ls, cat) and write notes to it.
- # 4. Read the auto-generated profile
- response = sandbox.process.exec("cat agent_memory/profile.md")
- print(response.result)
+ First, read /home/daytona/memory/profile.md to learn about the user.
+ Then create /home/daytona/memory/session_notes.md with a summary of what you found.""",
+ options=ClaudeAgentOptions(
+ allowed_tools=["Bash", "Read", "Write"],
+ ),
+ ):
+ print(message)
- # 5. Semantic search
- response = sandbox.process.exec(
- "~/.local/bin/smfs grep 'preferred language'"
- )
- print(response.result)
+ # 4. Clean up
+ sandbox.process.exec("~/.local/bin/smfs unmount my_agent 2>/dev/null")
+ daytona.delete(sandbox)
- # 6. Clean up
- sandbox.process.exec("~/.local/bin/smfs unmount agent_memory")
- daytona.delete(sandbox)
+ asyncio.run(main())
```
+
+ Some Daytona datacenter IPs may be blocked by upstream firewalls. If
+ `smfs login` or `smfs mount` fails with a TLS connection error, check
+ that outbound HTTPS to `api.supermemory.ai` is not restricted.
+
+
## Tips
-- **Use `--ephemeral` for sandboxes.** Sandbox filesystems are temporary. Ephemeral mode avoids writing a local SQLite cache that will be thrown away.
-- **One container, many sandboxes.** Mount the same container tag from multiple sandboxes. Bidirectional sync keeps them in step.
-- **Give each agent a subdirectory.** If multiple agents share a container, scope them to `/agent_a/`, `/agent_b/`, etc. They can still read across the whole mount.
-- **Clean up sandboxes.** Call `daytona.delete(sandbox)` when done to avoid burning through free credits.
-
-## Resources
-
-- [Daytona docs](https://www.daytona.io/docs)
-- [Daytona SDK reference](https://www.daytona.io/docs/en/tools/api/)
-- [SMFS Mount reference](/smfs/mount)
-- [SMFS Bash Tool reference](/smfs/bash-tool)
+- Use `--ephemeral` when mounting inside sandboxes — it keeps the cache in memory
+ only, but writes still push to Supermemory
+- Use `smfs grep 'query'` for semantic search across all files in the container
+- The agent can write structured data (JSON, markdown) to the mount and it
+ persists across sandbox sessions via Supermemory
diff --git a/apps/docs/smfs/providers/e2b.mdx b/apps/docs/smfs/providers/e2b.mdx
index 9d5c9034..fbd363b1 100644
--- a/apps/docs/smfs/providers/e2b.mdx
+++ b/apps/docs/smfs/providers/e2b.mdx
@@ -1,108 +1,71 @@
---
title: "E2B"
-sidebarTitle: "E2B"
-description: "Give your E2B sandboxes persistent memory with SMFS."
-icon: "cube"
+description: "Give your AI agent persistent memory inside an E2B sandbox using SMFS"
---
-[E2B](https://e2b.dev) runs AI-generated code in secure Firecracker microVMs. Pair it with SMFS and your agent gets both safe code execution **and** persistent memory it can `ls`, `cat`, and `grep`.
+Mount a Supermemory container inside an [E2B](https://e2b.dev) sandbox so your
+agent can read and write memory with plain bash commands.
-## Architecture
+## How it works
-E2B sandboxes are ephemeral Linux microVMs with full shell access and unrestricted network. Two ways to wire SMFS in:
-
-
-
- Install the `smfs` binary inside the sandbox and mount a container. The agent uses standard Unix commands to read and write memory.
-
-
- Use `@supermemory/bash` in the code that **orchestrates** the sandbox. Memory lives in your agent code; code execution lives in E2B.
-
-
+1. Create an E2B sandbox
+2. Install SMFS and mount a Supermemory container inside it
+3. Run a Claude agent inside the sandbox — it uses `cat`, `ls`, `echo`, etc. on the mount
+4. Everything the agent writes is persisted to Supermemory automatically
## Prerequisites
-- A [Supermemory](https://console.supermemory.ai) account and API key
-- An [E2B](https://e2b.dev) account and API key
-- Node.js 18+ or Python 3.10+
+- A [Supermemory API key](https://supermemory.ai)
+- An [E2B API key](https://e2b.dev)
+- An [Anthropic API key](https://console.anthropic.com)
-## 1. Get your API keys
-
-### Supermemory
-
-1. Go to [console.supermemory.ai](https://console.supermemory.ai)
-2. Navigate to **Settings → API Keys**
-3. Create a new key and copy it
-
-### E2B
-
-1. Go to [e2b.dev](https://e2b.dev) and sign up
-2. Open the [Dashboard](https://e2b.dev/dashboard)
-3. Navigate to **API Keys**
-4. Copy your API key
-
-## 2. Install the SDKs
+## Quick start
```bash
- npm install @supermemory/bash @e2b/code-interpreter
+ npm install @anthropic-ai/claude-agent-sdk @e2b/code-interpreter
```
-
-
- ```bash
- pip install e2b-code-interpreter
- ```
-
-
-
-## 3. Build an agent with memory + code execution
-
-
-
- The recommended TypeScript pattern: use `@supermemory/bash` for memory in your orchestrating code and the E2B SDK for code execution. The LLM gets both as tools.
```typescript agent.ts
- import { createBash } from "@supermemory/bash";
import { Sandbox } from "@e2b/code-interpreter";
- import { generateText, tool } from "ai";
- import { openai } from "@ai-sdk/openai";
- import { z } from "zod";
+ import { query, ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
async function main() {
- // 1. Set up memory (SMFS bash tool)
- const { bash, toolDescription } = await createBash({
- apiKey: process.env.SUPERMEMORY_API_KEY!,
- containerTag: "agent_memory",
- });
+ // 1. Create an E2B sandbox
+ const sandbox = await Sandbox.create({ timeoutMs: 300_000 });
- // 2. Set up code execution (E2B sandbox)
- const sandbox = await Sandbox.create();
+ // 2. Fix FUSE permissions (required in E2B)
+ await sandbox.commands.run("sudo chmod 666 /dev/fuse");
+ await sandbox.commands.run(
+ "echo 'user_allow_other' | sudo tee -a /etc/fuse.conf > /dev/null"
+ );
- // 3. Give the LLM both tools
- const result = await generateText({
- model: openai("gpt-4o"),
- tools: {
- memory: tool({
- description: toolDescription,
- parameters: z.object({ cmd: z.string() }),
- execute: async ({ cmd }) => bash.exec(cmd),
- }),
- execute_code: tool({
- description: "Run Python code in an isolated sandbox",
- parameters: z.object({ code: z.string() }),
- execute: async ({ code }) => {
- const execution = await sandbox.runCode(code);
- return execution.text;
- },
- }),
+ // 3. Install SMFS, log in, and mount
+ await sandbox.commands.run("curl -fsSL https://smfs.ai/install | bash");
+ await sandbox.commands.run(
+ `~/.local/bin/smfs login --key ${process.env.SUPERMEMORY_API_KEY}`
+ );
+ await sandbox.commands.run(
+ "bash -c '~/.local/bin/smfs mount my_agent --ephemeral --path /home/user/memory --foreground > /tmp/smfs.log 2>&1 & sleep 5'"
+ );
+
+ // 4. Run a Claude agent inside the sandbox with bash access
+ for await (const message of query({
+ prompt: `You have access to a persistent memory filesystem mounted at /home/user/memory.
+ Use bash commands to explore it (ls, cat) and write notes to it (echo "..." > file).
+
+ First, read /home/user/memory/profile.md to learn about the user.
+ Then create /home/user/memory/session_notes.md with a summary of what you found.`,
+ options: {
+ allowedTools: ["Bash", "Read", "Write"],
},
- prompt: "Check my memory for the user's preferences, then write a script that uses them.",
- });
+ })) {
+ if (message.type === "text") console.log(message.text);
+ }
- console.log(result.text);
-
- // 4. Clean up
+ // 5. Clean up
+ await sandbox.commands.run("~/.local/bin/smfs unmount my_agent 2>/dev/null");
await sandbox.kill();
}
@@ -110,122 +73,80 @@ E2B sandboxes are ephemeral Linux microVMs with full shell access and unrestrict
```
- In Python, mount SMFS inside the E2B sandbox. The agent reads and writes memory via standard shell commands.
+ ```bash
+ pip install claude-agent-sdk e2b-code-interpreter
+ ```
```python agent.py
+ import asyncio
import os
+ from claude_agent_sdk import query, ClaudeAgentOptions
from e2b_code_interpreter import Sandbox
- # 1. Create an E2B sandbox
- sandbox = Sandbox.create(timeout=300)
+ async def main():
+ # 1. Create an E2B sandbox
+ sandbox = Sandbox.create(timeout=300)
- # 2. Fix FUSE permissions (required in E2B sandboxes)
- sandbox.commands.run("sudo chmod 666 /dev/fuse")
- sandbox.commands.run(
- "echo 'user_allow_other' | sudo tee -a /etc/fuse.conf > /dev/null"
- )
+ # 2. Fix FUSE permissions (required in E2B)
+ sandbox.commands.run("sudo chmod 666 /dev/fuse")
+ sandbox.commands.run(
+ "echo 'user_allow_other' | sudo tee -a /etc/fuse.conf > /dev/null"
+ )
- # 3. Install SMFS and log in
- sandbox.commands.run("curl -fsSL https://smfs.ai/install | bash")
- sandbox.commands.run(
- f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
- )
+ # 3. Install SMFS, log in, and mount
+ sandbox.commands.run("curl -fsSL https://smfs.ai/install | bash")
+ sandbox.commands.run(
+ f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
+ )
+ sandbox.commands.run(
+ "bash -c '~/.local/bin/smfs mount my_agent --ephemeral"
+ " --path /home/user/memory --foreground > /tmp/smfs.log 2>&1"
+ " & sleep 5'",
+ timeout=15,
+ )
- # 4. Mount memory
- sandbox.commands.run(
- "bash -c '~/.local/bin/smfs mount agent_memory --ephemeral"
- " --path /home/user/memory --foreground > /tmp/smfs.log 2>&1"
- " & sleep 5 && echo MOUNTED'",
- timeout=15,
- )
+ # 4. Run a Claude agent inside the sandbox with bash access
+ async for message in query(
+ prompt="""You have access to a persistent memory filesystem mounted at /home/user/memory.
+ Use bash commands to explore it (ls, cat) and write notes to it.
- # 5. Read the auto-generated profile
- result = sandbox.commands.run("cat /home/user/memory/profile.md")
- print(result.stdout)
+ First, read /home/user/memory/profile.md to learn about the user.
+ Then create /home/user/memory/session_notes.md with a summary of what you found.""",
+ options=ClaudeAgentOptions(
+ allowed_tools=["Bash", "Read", "Write"],
+ ),
+ ):
+ print(message)
- # 6. Semantic search
- result = sandbox.commands.run(
- "~/.local/bin/smfs grep 'preferred language'"
- )
- print(result.stdout)
+ # 5. Clean up
+ sandbox.commands.run(
+ "~/.local/bin/smfs unmount my_agent 2>/dev/null", timeout=10
+ )
+ sandbox.kill()
- # 7. Clean up
- sandbox.commands.run(
- "~/.local/bin/smfs unmount agent_memory 2>/dev/null",
- timeout=10,
- )
- sandbox.kill()
+ asyncio.run(main())
```
-## Mount SMFS inside the sandbox
-
-E2B sandboxes have full network access and FUSE support, so you can install and mount SMFS directly. Two setup steps are needed first:
-
- E2B sandboxes require FUSE permission fixes before mounting. Run these commands once after creating the sandbox:
+ E2B sandboxes require two FUSE permission fixes before mounting:
+ 1. `sudo chmod 666 /dev/fuse` — the device exists but is root-only by default
+ 2. `echo 'user_allow_other' | sudo tee -a /etc/fuse.conf` — needed for the `allow_other` mount option
- ```bash
- sudo chmod 666 /dev/fuse
- echo 'user_allow_other' | sudo tee -a /etc/fuse.conf > /dev/null
- ```
+ Without these, `smfs mount` will fail with a permission error.
-```python
-from e2b_code_interpreter import Sandbox
-import os
-
-sandbox = Sandbox.create(timeout=300)
-
-# One-time FUSE setup
-sandbox.commands.run("sudo chmod 666 /dev/fuse")
-sandbox.commands.run(
- "echo 'user_allow_other' | sudo tee -a /etc/fuse.conf > /dev/null"
-)
-
-# Install SMFS
-sandbox.commands.run("curl -fsSL https://smfs.ai/install | bash")
-
-# Log in
-sandbox.commands.run(
- f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
-)
-
-# Mount with ephemeral mode (recommended for sandboxes)
-# Run in background since mount is a long-running daemon
-sandbox.commands.run(
- "bash -c '~/.local/bin/smfs mount agent_memory --ephemeral"
- " --path /home/user/memory --foreground > /tmp/smfs.log 2>&1"
- " & sleep 5 && echo MOUNTED'",
- timeout=15,
-)
-
-# Read the auto-generated profile
-result = sandbox.commands.run("cat /home/user/memory/profile.md")
-print(result.stdout)
-
-# Write to memory (use sudo — FUSE mount is owned by root)
-sandbox.commands.run(
- "sudo bash -c 'echo \"User prefers Python\" > /home/user/memory/notes.md'"
-)
-
-# Semantic grep works inside the mount
-result = sandbox.commands.run("~/.local/bin/smfs grep 'deadlines'")
-print(result.stdout)
-
-# Clean up
-sandbox.commands.run("~/.local/bin/smfs unmount agent_memory 2>/dev/null", timeout=10)
-sandbox.kill()
-```
-
- The FUSE mount is owned by root. Writing files requires `sudo` (e.g., `sudo bash -c 'echo "..." > /path/file'`). Reads work without sudo.
+ The FUSE mount is owned by root. Writing files requires `sudo`
+ (e.g., `sudo bash -c 'echo "..." > /path/file'`). Reads work without sudo.
+ The Claude agent handles this automatically when using the Bash tool.
-## Custom E2B template with SMFS pre-installed
+## Custom E2B template
-For faster startup, bake SMFS and the FUSE fixes into a custom E2B template:
+For production, bake SMFS into a custom E2B template so every sandbox starts
+with it pre-installed:
```dockerfile e2b.Dockerfile
FROM e2b/code-interpreter:latest
@@ -233,7 +154,8 @@ FROM e2b/code-interpreter:latest
# Pre-install SMFS
RUN curl -fsSL https://smfs.ai/install | bash
-# Fix FUSE permissions for SMFS mount
+# Fix FUSE permissions
+RUN chmod 666 /dev/fuse
RUN echo 'user_allow_other' >> /etc/fuse.conf
```
@@ -241,38 +163,12 @@ RUN echo 'user_allow_other' >> /etc/fuse.conf
e2b template build -d e2b.Dockerfile
```
-Then use your custom template — no setup needed at runtime:
-
-```python
-sandbox = Sandbox.create(template="your-custom-template")
-
-# FUSE device still needs chmod at runtime (device nodes reset on boot)
-sandbox.commands.run("sudo chmod 666 /dev/fuse")
-
-# Mount directly
-sandbox.commands.run(
- f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
-)
-sandbox.commands.run(
- "bash -c '~/.local/bin/smfs mount agent_memory --ephemeral"
- " --path /home/user/memory --foreground > /tmp/smfs.log 2>&1"
- " & sleep 5'",
- timeout=15,
-)
-```
+Then your agent code only needs to log in and mount — no install step.
## Tips
-- **Use `--ephemeral` for sandboxes.** E2B sandboxes are short-lived. Ephemeral mode avoids writing a local cache that will be thrown away.
-- **Always fix FUSE permissions.** E2B sandboxes need `sudo chmod 666 /dev/fuse` and `user_allow_other` in `/etc/fuse.conf` before mounting.
-- **Mount in background.** The SMFS daemon is long-running. Use `bash -c '... --foreground &'` with a sleep to let it initialize.
-- **Custom templates save time.** Pre-install SMFS in a template to skip the install step on every sandbox boot.
-- **E2B sandboxes have a timeout.** Default is 5 minutes. Pass `timeout=300` (or more) when creating the sandbox if your agent needs longer.
-- **One container, many sandboxes.** Mount the same container tag from multiple E2B sandboxes. Bidirectional sync keeps them in step.
-
-## Resources
-
-- [E2B docs](https://e2b.dev/docs)
-- [E2B SDK reference](https://e2b.dev/docs/sdk-reference)
-- [SMFS Mount reference](/smfs/mount)
-- [SMFS Bash Tool reference](/smfs/bash-tool)
+- Use `--ephemeral` when mounting inside sandboxes — it keeps the cache in memory
+ only, but writes still push to Supermemory
+- Use `smfs grep 'query'` for semantic search across all files in the container
+- The agent can write structured data (JSON, markdown) to the mount and it
+ persists across sandbox sessions via Supermemory
diff --git a/apps/docs/smfs/providers/vercel.mdx b/apps/docs/smfs/providers/vercel.mdx
index 615ac953..5295021c 100644
--- a/apps/docs/smfs/providers/vercel.mdx
+++ b/apps/docs/smfs/providers/vercel.mdx
@@ -1,63 +1,73 @@
---
title: "Vercel AI SDK"
-sidebarTitle: "Vercel AI SDK"
-description: "Add persistent memory to agents built with the Vercel AI SDK."
-icon: "triangle"
+description: "Give your AI agent persistent memory using SMFS with the Vercel AI SDK"
---
-The [Vercel AI SDK](https://sdk.vercel.ai) is the most popular framework for building AI agents in TypeScript. SMFS plugs in as a tool — give your agent a `bash` tool backed by `@supermemory/bash` and it can `ls`, `cat`, `grep`, and write to a Supermemory container without any filesystem to manage.
+Mount a Supermemory container on your server and give your Vercel AI SDK agent
+access to it through a bash tool.
-## Architecture
+## How it works
-The Vercel AI SDK uses a tool-calling pattern: you define tools, the model decides when to call them. `@supermemory/bash` fits this perfectly — it's a single tool that exposes a virtual filesystem backed by Supermemory.
+1. Install SMFS on your server and mount a Supermemory container
+2. Define a bash tool that runs commands against the mount
+3. The Vercel AI SDK agent uses the tool to read/write memory with standard commands
-```
-User → AI SDK → LLM → calls bash tool → @supermemory/bash → Supermemory API
-```
-
-No sandbox needed. The bash tool runs in your server process and handles all the memory operations.
+
+ The Vercel AI SDK runs in your server process (not in a sandbox). SMFS mounts
+ directly on the host where your server runs.
+
## Prerequisites
-- A [Supermemory](https://console.supermemory.ai) account and API key
-- Node.js 18+
-- An LLM provider (OpenAI, Anthropic, Google, etc.)
+- A [Supermemory API key](https://supermemory.ai)
+- An [OpenAI](https://platform.openai.com) or [Anthropic](https://console.anthropic.com) API key
+- SMFS installed on your server: `curl -fsSL https://smfs.ai/install | bash`
-## 1. Install
+## Quick start
```bash
-npm install @supermemory/bash ai @ai-sdk/openai zod
+npm install ai @ai-sdk/anthropic zod
```
-## 2. Create an agent with memory
-
```typescript agent.ts
-import { createBash } from "@supermemory/bash";
import { generateText, tool } from "ai";
-import { openai } from "@ai-sdk/openai";
+import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";
+import { execSync } from "child_process";
+
+// Mount SMFS before starting the server:
+// smfs login --key $SUPERMEMORY_API_KEY
+// smfs mount my_agent --path ./memory
+
+const MEMORY_PATH = "./memory";
async function main() {
- // Set up the SMFS bash tool
- const { bash, toolDescription } = await createBash({
- apiKey: process.env.SUPERMEMORY_API_KEY!,
- containerTag: "user_42",
- });
-
const result = await generateText({
- model: openai("gpt-4o"),
+ model: anthropic("claude-sonnet-4-20250514"),
tools: {
bash: tool({
- description: toolDescription,
- parameters: z.object({ cmd: z.string() }),
- execute: async ({ cmd }) => bash.exec(cmd),
+ description:
+ "Run a bash command. The persistent memory filesystem is at " +
+ MEMORY_PATH,
+ parameters: z.object({ command: z.string() }),
+ execute: async ({ command }) => {
+ try {
+ return execSync(command, {
+ cwd: MEMORY_PATH,
+ encoding: "utf-8",
+ timeout: 10_000,
+ });
+ } catch (e: any) {
+ return e.stderr || e.message;
+ }
+ },
}),
},
maxSteps: 10,
- system: `You have access to a persistent memory filesystem via the bash tool.
-Use it to remember things about the user across conversations.
-Start by reading /profile.md to see what you already know.`,
- prompt: "What do you remember about me?",
+ prompt: `You have access to a persistent memory filesystem at ${MEMORY_PATH}.
+Use the bash tool to explore it (ls, cat) and write notes (echo "..." > file).
+
+Read profile.md to learn about the user, then create session_notes.md with a summary.`,
});
console.log(result.text);
@@ -66,103 +76,47 @@ Start by reading /profile.md to see what you already know.`,
main();
```
-That's it. The model will call `bash({ cmd: "cat /profile.md" })` to read the user's profile, `bash({ cmd: "ls /" })` to browse memory, and `bash({ cmd: "grep 'preferences'" })` to search semantically.
+## Streaming
-## 3. Multi-step agent with memory
-
-A more complete example with conversation history and memory persistence:
-
-```typescript chat.ts
-import { createBash } from "@supermemory/bash";
-import { generateText, tool, CoreMessage } from "ai";
-import { openai } from "@ai-sdk/openai";
-import { z } from "zod";
-
-// Create one bash instance per user (reuse across requests)
-const userBashInstances = new Map();
-
-async function getBash(userId: string) {
- if (!userBashInstances.has(userId)) {
- const instance = await createBash({
- apiKey: process.env.SUPERMEMORY_API_KEY!,
- containerTag: `user_${userId}`,
- });
- userBashInstances.set(userId, instance);
- }
- return userBashInstances.get(userId);
-}
-
-export async function chat(userId: string, messages: CoreMessage[]) {
- const { bash, toolDescription } = await getBash(userId);
-
- return generateText({
- model: openai("gpt-4o"),
- tools: {
- bash: tool({
- description: toolDescription,
- parameters: z.object({ cmd: z.string() }),
- execute: async ({ cmd }) => bash.exec(cmd),
- }),
- },
- maxSteps: 10,
- system: `You are a helpful assistant with persistent memory.
-
-Use the bash tool to:
-- Read /profile.md at the start of each conversation for context
-- Save important facts to /memory.md
-- Search with grep when looking for specific information
-- Organize notes in subdirectories as needed`,
- messages,
- });
-}
-```
-
-## With Vercel AI SDK Streams
-
-For streaming responses in a Next.js app:
-
-```typescript app/api/chat/route.ts
-import { createBash } from "@supermemory/bash";
+```typescript
import { streamText, tool } from "ai";
-import { openai } from "@ai-sdk/openai";
+import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";
+import { execSync } from "child_process";
-export async function POST(req: Request) {
- const { messages, userId } = await req.json();
+const MEMORY_PATH = "./memory";
- const { bash, toolDescription } = await createBash({
- apiKey: process.env.SUPERMEMORY_API_KEY!,
- containerTag: `user_${userId}`,
- });
+const result = streamText({
+ model: anthropic("claude-sonnet-4-20250514"),
+ tools: {
+ bash: tool({
+ description:
+ "Run a bash command against the memory filesystem at " + MEMORY_PATH,
+ parameters: z.object({ command: z.string() }),
+ execute: async ({ command }) => {
+ try {
+ return execSync(command, {
+ cwd: MEMORY_PATH,
+ encoding: "utf-8",
+ timeout: 10_000,
+ });
+ } catch (e: any) {
+ return e.stderr || e.message;
+ }
+ },
+ }),
+ },
+ maxSteps: 10,
+ prompt: "Read my memory and summarize what you know about me.",
+});
- const result = streamText({
- model: openai("gpt-4o"),
- tools: {
- bash: tool({
- description: toolDescription,
- parameters: z.object({ cmd: z.string() }),
- execute: async ({ cmd }) => bash.exec(cmd),
- }),
- },
- maxSteps: 10,
- system: "You have persistent memory via the bash tool. Read /profile.md for context.",
- messages,
- });
-
- return result.toDataStreamResponse();
+for await (const chunk of result.textStream) {
+ process.stdout.write(chunk);
}
```
## Tips
-- **One `createBash` per user.** Use the user's ID as the container tag. Each user gets their own isolated memory.
-- **Read `profile.md` first.** Tell the model to `cat /profile.md` at the start of each conversation. It's a live digest of everything in the container.
-- **`sgrep` for semantic search.** Inside the bash tool, `sgrep "query"` searches by meaning, not just text. Regular `grep` does literal matching.
-- **Cache the bash instance.** `createBash` warms the path index on startup. Reuse the instance across requests for the same user.
-- **Works with any LLM provider.** Swap `openai("gpt-4o")` for `anthropic("claude-sonnet-4-20250514")`, `google("gemini-2.0-flash")`, or any AI SDK-compatible provider.
-
-## Resources
-
-- [Vercel AI SDK docs](https://sdk.vercel.ai/docs)
-- [SMFS Bash Tool reference](/smfs/bash-tool)
-- [Supermemory quickstart](/quickstart)
+- Mount SMFS once when your server starts, not per-request
+- Use `smfs grep 'query'` for semantic search across all files in the container
+- Use `--ephemeral` if you don't need a local cache on the server