ContextFS Documentation

Back to Home

Overview

ContextFS gives LLM agents a persistent, structured filesystem they can read from, write to, and search — without giving them direct access to your machine.

It exposes a standard MCP (Model Context Protocol) surface over SSE or stdio, so any MCP-compatible LLM client (Claude Desktop, Cursor, custom agents) can use it out of the box.

Architecture

graph TD
    Agent[LLM Agent] -->|MCP SSE/Stdio| Server[ContextFS Server]
    Server -->|WebSocket| WS1[WS Client A]
    Server -->|WebSocket| WS2[WS Client B]
    WS1 -->|Sandboxed| FS1[Workspace A1]
    WS1 -->|Sandboxed| FS2[Workspace A2]

ContextFS follows a Hub-and-Spoke architecture:

Quick Start

Option A — Local mode (simplest, single machine)

npx contextfs server --local --mcp sse
# Create a virtual client
curl -s -X POST http://localhost:3010/api/virtual-clients \
  -H 'Content-Type: application/json' \
  -d '{"name":"my-agent"}' | jq .
# → copy "id" and "apiKey"

# Open dashboard
open http://localhost:3010

# Chat
CONTEXTFS_VC_ID= CONTEXTFS_VC_KEY= OPENROUTER_API_KEY=sk-or-... \
  npx contextfs chat --mcp-server http://localhost:3010

Option B — Remote WS client mode

# Terminal 1 — server
npx contextfs server --mcp sse

# Terminal 2 — create entities
curl -s -X POST http://localhost:3010/api/ws-clients \
  -H 'Content-Type: application/json' -d '{"name":"worker-1"}' | jq .
# → copy wsc id + apiKey

curl -s -X POST http://localhost:3010/api/virtual-clients \
  -H 'Content-Type: application/json' -d '{"name":"agent-1"}' | jq .
# → copy vc id + apiKey

# Terminal 3 — WS client (can be on a different machine)
CONTEXTFS_API_KEY= \
  npx contextfs client \
    --url ws://localhost:3010 \
    --ws-client-id  \
    --api-key 

# Terminal 4 — chat
CONTEXTFS_VC_ID= CONTEXTFS_VC_KEY= OPENROUTER_API_KEY=sk-or-... \
  npx contextfs chat --mcp-server http://localhost:3010

CLI Reference

`contextfs server`

contextfs server [options]

Options:
  --port        HTTP + WS port (default: 3010, env: PORT)
  --local             Local mode: tools run in-process, no WS clients (env: CONTEXTFS_LOCAL=1)
  --mcp [sse]         Enable MCP server
                        (default: stdio — requires --vc-id + --vc-key)
                        (sse — VC creds per-connection: ?vcId=&vcKey= or headers)
  --vc-id         Virtual client ID for stdio MCP (env: CONTEXTFS_VC_ID)
  --vc-key       Virtual client API key for stdio MCP (env: CONTEXTFS_VC_KEY)
  --insecure          Enable contextfs.bash_script_once tool
  --verbose           Verbose logging

`contextfs client`

contextfs client [options]

Options:
  --url          Server WebSocket URL (required, env: CONTEXTFS_SERVER_URL)
  --ws-client-id    WS client ID (required, env: CONTEXTFS_WS_CLIENT_ID)
  --api-key        WS client API key (required, env: CONTEXTFS_API_KEY)
  --cwd           Workspace root (default: ~/.contextfs/workspaces/)
  --insecure            Enable contextfs.bash_script_once
  --verbose             Verbose logging

`contextfs chat`

contextfs chat [options]

Options:
  --mcp-server     MCP server base URL (default: http://localhost:3010)
  --vc-id           Virtual client ID (env: CONTEXTFS_VC_ID)
  --vc-key         Virtual client API key (env: CONTEXTFS_VC_KEY)
  --model        LLM model via OpenRouter (env: CONTEXTFS_MODEL)
  --message       Non-interactive: send single message, exit 0 (alias: -m)
  --stdin               Read message from stdin
  --output json         Output { message, toolCalls, durationMs } JSON
  --no-tools            Disable tool calls (pure LLM)
  --verbose             Verbose logging

Interactive commands: `/exit`, `/clear`, `/tools`, `/history`

MCP Integration

SSE (recommended for web/agent use)

GET http://localhost:3010/mcp/sse?vcId=&vcKey=
POST http://localhost:3010/mcp/message?sessionId=

Or via headers:

GET http://localhost:3010/mcp/sse
X-VC-ID: 
Authorization: Bearer 

stdio (for Claude Desktop, Cursor, etc.)

{
  "mcpServers": {
    "contextfs": {
      "command": "npx",
      "args": ["contextfs", "server", "--local", "--mcp", "--vc-id", "", "--vc-key", ""]
    }
  }
}

Tools Reference

All tools are sandboxed within the virtual client's active workspace root.

Tool Description
`contextfs.list` List files/directories. Supports recursive, depth, glob filter.
`contextfs.read` Read file content. Supports line ranges and byte limits.
`contextfs.write` Write or append to a file.
`contextfs.list_workspaces` List available workspaces for the current virtual client.
`contextfs.use_workspace` Switch the active workspace for the current session.
`contextfs.save_skill` Save a reusable skill as Markdown under `/skills/`.
`contextfs.list_skills` List skills, optionally filtered by tag.
`contextfs.save_memory` Persist a memory entry under `/memory/YYYY/MM/`.
`contextfs.search_memory` Full-text keyword search across all memory files.
`contextfs.bash_script_once` Execute a one-shot bash script (requires `--insecure`).

REST API reference

Base URL: `http://localhost:3010/api`

WS Clients

GET    /api/ws-clients                        List all WS clients
POST   /api/ws-clients                        Create WS client → returns apiKey (once)
DELETE /api/ws-clients/:id                    Delete WS client
POST   /api/ws-clients/:id/regen-key          Regenerate API key → returns new apiKey

Virtual Clients

GET    /api/virtual-clients                   List all virtual clients
POST   /api/virtual-clients                   Create virtual client → returns apiKey (once)
DELETE /api/virtual-clients/:id               Delete virtual client + owned workspaces
POST   /api/virtual-clients/:id/regen-key     Regenerate API key

Workspaces

GET    /api/virtual-clients/:vcId/workspaces              List workspaces
POST   /api/virtual-clients/:vcId/workspaces              Create workspace
DELETE /api/virtual-clients/:vcId/workspaces/:wsId        Delete workspace

Dispatch

POST /api/dispatch
Body: { virtualClientId, virtualClientApiKey, tool, params, timeoutMs? }

Dispatches a tool call to the assigned WS client and waits for the response.

Status + MCP

GET /api/status          Summary counts
GET /mcp/sessions        Active MCP SSE sessions

Security model

Data directory

All state is persisted to `~/.contextfs/`:

~/.contextfs/
├── ws-clients.json         WS client registry
├── virtual-clients.json    Virtual client registry
├── workspaces.json         Workspace registry
├── chat-config.json        Chat TUI config (API key, model)
├── .machine-id             Persistent client identity
└── workspaces/
    └── /
        └── /
            ├── skills/     Saved skills (.md files)
            ├── memory/     Memory entries (YYYY/MM/*.md)
            └── ...         Your files

Environment variables

Variable Description Default
`PORT` Server HTTP port `3010`
`CONTEXTFS_LOCAL` Enable local mode (`1`)
`CONTEXTFS_INSECURE` Enable bash_script_once (`1`)
`CONTEXTFS_SERVER_URL` WS server URL for client
`CONTEXTFS_WS_CLIENT_ID` WS client ID
`CONTEXTFS_API_KEY` WS client API key
`CONTEXTFS_VC_ID` Virtual client ID for chat/MCP
`CONTEXTFS_VC_KEY` Virtual client API key for chat/MCP
`CONTEXTFS_MCP_SERVER` MCP server base URL for chat `http://localhost:3010`
`CONTEXTFS_MODEL` LLM model for chat `google/gemini-2.5-flash-preview`
`OPENROUTER_API_KEY` OpenRouter API key for chat
`VERBOSE` Enable verbose logging (`1`)

Requirements

License

ISC © Javier Leandro Arancibia