mountable.io

OpenAI Agents SDK file tools

Give OpenAI Agents SDK agents persistent notes on a capped mountable.io filesystem selected by your backend for each user.

The runnable Python example uses openai-agents 0.24.0 and mountable-sdk 0.3.0. It is maintained by mountable.io, independently of OpenAI.

Prerequisites

Use Python 3.11+, uv, an OpenAI API key and an existing mountable.io account with a saved payment method. Set OPENAI_API_KEY, MOUNTABLE_API_KEY and MOUNTABLE_ORG in your private environment or secret manager. Keep keys out of prompts, command arguments and source files.

mountable.io storage and operations are paid usage. OpenAI model usage is billed separately. A mountable.io filesystem cap does not limit OpenAI charges.

Provision once per user

Run this on your trusted backend after authenticating the user:

git clone https://github.com/writeitai/mountable.git
cd mountable/examples/openai-agents
uv sync --locked
uv run python workspace.py provision --name notes-demo --spending-cap-cents 100

Save the returned filesystem_id in your database against the authenticated user's ID. Look up that saved mapping on every later request. Serialize first-time provisioning for that user. After a timeout, list filesystems and reconcile the result before trying creation again.

The command sets a 100-cent monthly cap in the organisation's currency (USD or EUR), a 1 GiB storage quota, 10,000 entries and 30 mutations/minute. This is a spending ceiling, not free credit. Change the limit to suit your app's pricing and usage.

Run with the saved filesystem

Set FS_ID to the returned ID. Use the same ID on later runs:

export FS_ID="your-filesystem-id"
uv run python workspace.py run --filesystem "$FS_ID" --note /note.txt
uv run python workspace.py run --filesystem "$FS_ID" --note /note.txt

The agent has write_note(text) and read_note() tools. They use the same backend-selected filesystem and note path. The write is create-only, so a second run reads the existing note instead of replacing it. --text sets new note contents; --note is a trusted backend setting. The default model is gpt-4.1-mini; use --model for another model available to your account. The runner allows at most six turns and disables SDK tracing. The turn limit is not an OpenAI dollar budget.

Bind tools to the authenticated user

The example passes a Workspace(filesystem, note) object through Runner.run(..., context=workspace). Each request receives a new context created from the authenticated user's saved mapping. The model gets no filesystem-ID or path argument:

@function_tool(failure_error_function=None)
async def read_note(ctx: RunContextWrapper[Workspace]) -> str:
    note = await asyncio.to_thread(
        ctx.context.filesystem.read, ctx.context.note
    )
    if len(note.data) > 16_384:
        raise ValueError("Note exceeds 16 KiB")
    return note.data.decode("utf-8")

Imports and the paired write tool are in the runnable example. The write tool also checks the UTF-8 byte length and uses if_none_match=True. Do not let a model or an untrusted browser field supply the user-to-filesystem mapping. Keep API keys on the trusted backend and use filesystem-limited keys where practical. These tools do not isolate the host that holds the key.

Only read notes you intend to share with OpenAI. The SDK downloads the file before the 16 KiB check; the check limits text sent to the model. The script prints the model's summary. Treat notes as data, not instructions.

Stop at a user's cap

A 402 filesystem_spending_cap_reached propagates out of the tool and ends the agent run. The tools cannot raise the cap or create a replacement filesystem. Other users keep their own filesystems and limits. Stored files are kept; the cap already reserves their storage cost for the month. See cap behavior.

A 412 means the note already exists: read it. After an uncertain write, read back before retrying. The CLI prints storage error codes without private provider details.

Sources: OpenAI Agents SDK quickstart, OpenAI local context.