mcp-virtual-fs
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-virtual-fssave a new file named todo.md with my daily tasks"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-virtual-fs
An MCP server that provides AI agents with a persistent, PostgreSQL-backed virtual filesystem. Supports session-isolated file operations, cross-session shared stores, glob/grep search, and Row Level Security — all exposed as standard Model Context Protocol tools.
Works with any MCP client: Claude Desktop, Claude Code, Cursor, Windsurf, Cline, and others.
Features
Persistent file storage — files are stored in PostgreSQL and survive process restarts, container recycling, and redeployments
Session isolation — each agent session gets its own namespace automatically, no configuration needed
Cross-session stores — named persistent stores for sharing data between agents or for long-term agent memory
11 POSIX-style tools —
read,write,append,stat,ls,mkdir,rm,mv,glob,grep,storesGlob and grep search — find files by pattern (
**/*.ts) or search content by regex, powered by PostgreSQL trigram indexesRow Level Security — optional database-enforced isolation between sessions for multi-tenant deployments
Zero config — auto-creates tables on first run with
VFS_AUTO_INIT=true
Related MCP server: better-mcp
Use Cases
Agent scratchpad — give LLM agents a persistent workspace to read/write files across tool calls
Long-term agent memory — store notes, context, and knowledge across sessions using named stores
Multi-agent collaboration — multiple agents share files through cross-session stores
Sandboxed file operations — agents interact with a virtual filesystem instead of the host OS
CI/CD artifact storage — persist build outputs, logs, and reports in a queryable filesystem
Why
Agents work well with filesystems for context management, but coupling storage to the agent runtime means data is lost when pods restart or containers are recycled. This MCP server decouples storage from runtime by moving file operations to PostgreSQL — giving agents persistent, isolated, and searchable file storage without touching the host filesystem.
Prerequisites
Node.js 20 or later
PostgreSQL 14 or later (with
pg_trgmextension — included in most distributions)
Quick Start
1. Set up PostgreSQL
# Using Docker
docker run -d --name vfs-postgres \
-e POSTGRES_DB=vfs \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16-alpine2. Configure your MCP client
Add to your MCP client config (e.g., Claude Desktop claude_desktop_config.json or Claude Code .mcp.json):
{
"mcpServers": {
"virtual-fs": {
"command": "npx",
"args": ["-y", "mcp-virtual-fs"],
"env": {
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/vfs",
"VFS_AUTO_INIT": "true"
}
}
}
}That's it. VFS_AUTO_INIT=true creates the tables on first run.
3. Use the tools
Tool names are short POSIX-style names:
write({ path: "/notes/todo.md", content: "# My Tasks\n- Ship feature" })
read({ path: "/notes/todo.md" })
ls({ path: "/notes" })
glob({ pattern: "**/*.md" })
grep({ pattern: "TODO" })All tools return structured JSON responses.
Tools
Tool | Parameters | Returns | Description |
|
|
| Read file contents |
|
|
| Write file (creates parents automatically) |
|
|
| Append to file (creates if missing) |
|
|
| Check existence and get metadata |
|
|
| List directory (dirs first, then alphabetical) |
|
|
| Create directory and parents (mkdir -p) |
|
|
| Remove file or directory recursively |
|
|
| Move/rename file or directory |
|
|
| Find files by glob (e.g., |
|
|
| Search file contents by regex |
| (none) |
| List all persistent store names |
All tools (except stores) accept an optional store parameter for cross-session persistent storage.
Session Management
Sessions are handled automatically — no session ID in tool parameters.
How it works:
Transport | Session identity | Behavior |
stdio | Auto-generated UUID per process | Each MCP connection = unique session |
HTTP/SSE | Transport-provided | MCP protocol handles it |
Any |
| Deterministic/resumable sessions |
Priority: transport sessionId > VFS_SESSION_ID env var > auto-generated UUID.
Resumable sessions
To resume a previous session across process restarts, set a deterministic session ID:
{
"env": {
"DATABASE_URL": "postgresql://...",
"VFS_SESSION_ID": "my-agent-session-1"
}
}Cross-Session Stores
Named stores persist across sessions. Any session can read/write to a store by passing the store parameter:
// Session A writes to a store
write({ path: "/context.md", content: "project notes", store: "agent-memory" })
// Session B (days later) reads from the same store
read({ path: "/context.md", store: "agent-memory" })
// Without `store`, operations target the session's own namespace
write({ path: "/scratch.txt", content: "session-only data" })
// List all available stores
stores()Stores are auto-created on first use.
Environment Variables
Variable | Required | Default | Description |
| Yes | — | PostgreSQL connection string |
| No |
| Auto-create tables on startup |
| No | random UUID | Deterministic session ID |
| No |
| Enable Row Level Security |
| No |
| Storage backend type |
Manual Database Setup
If you prefer to manage the schema yourself instead of using VFS_AUTO_INIT:
psql $DATABASE_URL -f sql/schema.sqlRow Level Security (optional)
RLS provides database-enforced session isolation. Even if application code has a bug that omits a WHERE session_id = clause, PostgreSQL itself prevents cross-session access.
# Run after schema.sql
psql $DATABASE_URL -f sql/rls.sql
# Update the vfs_app password
psql $DATABASE_URL -c "ALTER ROLE vfs_app PASSWORD 'your-secure-password'"Then configure the MCP server to connect as vfs_app:
{
"env": {
"DATABASE_URL": "postgresql://vfs_app:your-secure-password@localhost:5432/vfs",
"VFS_ENABLE_RLS": "true"
}
}Development
Requirements
Node.js 20+
Docker (for integration tests — runs PostgreSQL via testcontainers)
git clone https://github.com/lu-zhengda/mcp-virtual-fs.git
cd mcp-virtual-fs
npm install
npm run buildCommands
Command | Description |
| Compile TypeScript |
| Run all tests (requires Docker) |
| Run unit tests only |
| Run integration tests only |
| Run ESLint |
| Auto-fix lint issues |
| Run with tsx (no build step) |
Testing
Tests use testcontainers to spin up real PostgreSQL instances in Docker. No mocks — the integration tests exercise actual SQL queries, trigram indexes, and RLS policies.
# Requires Docker running
npm testSession Cleanup
Ephemeral sessions can be cleaned up periodically:
DELETE FROM vfs_sessions
WHERE is_persistent = false
AND created_at < now() - interval '7 days';The ON DELETE CASCADE on vfs_nodes handles file cleanup automatically. Persistent stores (created via the store parameter) are never affected.
License
MIT
Available Tools
11 toolsappendA
Append content to the end of a file. Creates the file if it doesn't exist. Parent directories are created automatically. Useful for logs or incrementally building files. The 10 MB limit is per call — total file size is not capped. Errors: EISDIR if the path is an existing directory, EINVAL if appending to root.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the file to append to | |
| content | Yes | Content to append (max 10 MB per call) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Discloses file creation, parent directory auto-creation, 10MB per-call limit, and specific errors (EISDIR, EINVAL).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five sentences, each adds value. Front-loaded with primary action, no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers key behaviors and errors, but lacks return value description. Since no output schema, mentioning typical success response would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds valuable context beyond schema: explains store parameter's persistence model (cross-session vs ephemeral) and error conditions for path.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action ('Append content to the end of a file') and resource, distinguishes from siblings like 'write' by specifying incremental building.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides use cases ('logs or incrementally building files') and error conditions but lacks explicit when-not-to-use or alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
globARead-only
Find files matching a glob pattern. Supports wildcards (.ts), recursive matching (**/.md), and brace expansion ({py,json}). Returns an array of matching file paths. Only matches files, not directories.
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Glob pattern (e.g. **/*.ts, /src/**/*.{js,ts}) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds detailed behavioral context beyond annotations: supported patterns, return format, and that it only matches files. The store parameter explanation about persistence is also provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each concise and informative: purpose, pattern support, return type and constraint. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a glob matching tool with two simple parameters and no output schema, the description fully covers purpose, behavior, and constraints. Sibling tools are diverse, and the description is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions are present for both parameters. Description adds value with pattern examples and cross-session storage behavior, exceeding what the schema alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Find files matching a glob pattern' with examples of wildcards, recursive matching, and brace expansion. Distinguishes from siblings by specifying it returns files only and not directories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Does not explicitly state when to use this tool versus alternatives like ls or grep. The description implies its domain but lacks direct guidance on context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grepARead-only
Search file contents using a regular expression. Returns matching lines with file path and line number. Optimized for fast content search across all files. Optionally filter which files to search with a path glob.
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Regular expression pattern to search for (e.g. TODO|FIXME) | |
| path_filter | No | Glob pattern to limit which files are searched (e.g. /src/**) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, which is consistent. Description adds behavioral details: returns specific format (lines with path and line number), optimization hint, and optional path filtering. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences. Front-loaded with main action and result, followed by optimization and optional filtering. No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description covers the return format adequately. Combined with schema param descriptions and readOnly annotation, it provides sufficient context for the agent. Could mention limits on pattern length, but schema already does.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds value by explaining the return format (matching lines with path and line number) and the nature of the path_filter (glob pattern).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it searches file contents using a regular expression and returns matching lines with file path and line number. Distinguishes from sibling tools like glob (file listing) and read (file content).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Indicates it is optimized for fast content searches and optionally allows filtering by path glob. Does not explicitly state when not to use, but the context implies it is for content search, not for file listing or full reads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lsARead-only
List the contents of a directory. Returns an array of entries, each with a name and type (file or directory). Entries are sorted with directories first, then alphabetically. Errors: ENOENT if the directory does not exist, ENOTDIR if the path is a file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the directory to list (e.g. / or /src) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true, and the description reinforces a read-only operation. Adds details about sorting (directories first, then alphabetically) and error types, which are not in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action, followed by return type and errors. Efficient and focused.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list operation, the description covers return values, sorting, error cases, and the optional 'store' parameter context. No output schema needed as return is described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed parameter descriptions. The tool description does not add extra meaning beyond the schema, so baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it lists directory contents with specific output details (array of entries with name and type). Sibling tools like 'glob', 'stat', 'read' serve different purposes, so it stands out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Describes when to use (list directory) and documents error conditions (ENOENT, ENOTDIR). Does not explicitly state when not to use or alternatives, but sibling names provide context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mkdirAIdempotent
Create a directory and any missing parent directories (mkdir -p behavior). Idempotent — succeeds even if the directory already exists. Returns whether the directory already existed. Errors: EEXIST if a file (not directory) already exists at the path.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path of the directory to create (e.g. /src/utils) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide idempotentHint true. Description adds parent directory creation, idempotency details, return value (whether existed), and error condition (EEXIST for file). No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with main action, no redundancy or wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Tool is simple with no output schema. Description covers creation behavior, idempotency, return value, and errors completely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions. Description adds context: path is absolute, store is named persistent store cross-session, sessions ephemeral. Adds value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Create a directory and any missing parent directories' (verbose+resource) and distinguishes from sibling tools like rm, ls, write. Idempotent behavior and return value are specified.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Describes mkdir -p behavior, idempotency, and when it errors (file conflict). Does not explicitly mention when not to use or alternatives, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mvA
Move or rename a file or directory. Moves all descendants when moving a directory. Parent directories at the destination are created automatically. Errors: ENOENT if source doesn't exist, EEXIST if destination already exists, EINVAL if moving root or moving a directory into itself.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Absolute path of the file or directory to move | |
| destination | Yes | Absolute path of the new location | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses important behaviors: moving descendants, auto-creating parent directories, and specific error conditions (ENOENT, EEXIST, EINVAL). It does not mention permissions or side effects, but covers mutation and edge cases well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences efficiently convey purpose, key behaviors, and error conditions. Front-loaded with the core action, no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description covers usage, behavior, and errors thoroughly. It lacks explicit mention of return value, but that is typical for file operations. Overall, it provides sufficient context for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover all 3 parameters (100% coverage), so baseline is 3. The tool description adds value by linking parameters to behaviors (auto-create for destination, error conditions for source and destination) and clarifying store semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Move or rename a file or directory' using a specific verb and resource. It adds key behavior like moving all descendants and auto-creating parent directories, which distinguishes it from siblings like rm, mkdir, and write.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when moving or renaming files/directories, but does not explicitly state when to choose this tool over alternatives or mention exclusions. Sibling tools have different purposes, so the context is adequate but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
readARead-only
Read the contents of a file. Returns the file content and size in bytes. Errors: ENOENT if the file does not exist, EISDIR if the path is a directory.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the file (e.g. /src/index.ts) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, and the description adds return values (file content and size) and specific error conditions (ENOENT, EISDIR), providing useful behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences: first states purpose and return, second lists errors. No wasted words, front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool, the description covers purpose, return values, and errors. No output schema exists, but the description adequately explains what the tool returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters are fully described in the input schema (100% coverage), so the description adds no additional parameter details. Baseline score 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Read the contents of a file' with a specific verb and resource, and mentions return values and errors. It does not explicitly distinguish from sibling tools like grep or stat, but the purpose is obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives (e.g., grep, stat). The description implies reading files but does not mention when not to use or suggest other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rmADestructive
Remove a file or directory. Directories are removed recursively including all descendants. This operation is non-recoverable — there is no undo or trash. Returns the total number of nodes deleted. Errors: ENOENT if the path does not exist, EINVAL if attempting to remove root.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to remove | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant context beyond the destructiveHint annotation: it explains recursive removal for directories, non-recoverability, return value (total nodes deleted), and specific error codes (ENOENT, EINVAL). This fully informs the agent of the tool's behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: purpose, behavior, and return/errors. Every sentence adds value, and the purpose is front-loaded. It is concise with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core functionality, recursive behavior, recovery warning, return value, and errors. It does not elaborate on the 'store' parameter, but the schema provides that. For a deletion tool with no output schema, this is nearly complete missing only a small detail about store usage in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters described. The description does not add extra meaning beyond the schema, so it meets the baseline of 3. It could have elaborated on the 'store' parameter but the schema already handles it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Remove a file or directory' which clearly states the tool's action and resource. It distinguishes itself from sibling tools like 'mv' (move) and 'mkdir' (create) by specifying removal and recursive behavior for directories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'This operation is non-recoverable — there is no undo or trash,' which guides when to use (when permanent deletion is intended) and when not to (if recovery is needed). It also lists errors that help the agent handle failures, but does not explicitly mention alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statARead-only
Check whether a path exists and get metadata about it. Returns exists (boolean), and if it exists: type (file or directory), size (bytes, for files), or children count (for directories). Never errors — returns {exists: false} for missing paths.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to check | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. Description adds that it never errors and returns specific fields (exists, type, size, children count), providing full transparency beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. Front-loaded with the action and followed by return details. Ideal structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description fully explains the return shape (exists, type, size for files, children count for directories), making it complete for agent usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for both parameters. Description adds context that store is for cross-session persistence and that sessions are ephemeral, which is useful beyond the schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Check' and resource 'path', clearly distinguishing from sibling tools like 'ls' (list directory) and 'read' (read file content). It states the tool checks existence and returns metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states it never errors and returns {exists: false} for missing paths, guiding safe usage. No explicit when-not-to-use, but the purpose is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
storesARead-only
List all named persistent stores. Stores are cross-session namespaces for long-term data that persists indefinitely. Returns an array of store names.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds behavioral context: stores are cross-session and persist indefinitely, and the return type is an array of store names. This enriches understanding without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise—only two sentences—with no redundant information. Every sentence adds value: the first states the action, the second clarifies the nature of stores and output.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, no output schema), the description fully covers what the tool does and what it returns. It is complete for an AI agent to understand and invoke.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0 parameters, the baseline is 4. The description adds no parameter details because none exist, but it compensates by explaining the concept of stores.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists all named persistent stores, defines stores as cross-session namespaces for long-term data, and specifies the output format. It effectively distinguishes from sibling file operation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While the purpose is clear, the description does not provide explicit guidance on when to use this tool versus alternatives or any context about when not to use it. Usage is implied but not elaborated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
writeAIdempotent
Write content to a file, creating it if it doesn't exist. Parent directories are created automatically (mkdir -p). Overwrites existing file content entirely. Errors: EISDIR if the path is an existing directory, EINVAL if writing to root.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the file (e.g. /notes/todo.md) | |
| content | Yes | Full content to write (max 10 MB per call) | |
| store | No | Named persistent store for cross-session access. Sessions are ephemeral (one per MCP connection); named stores persist indefinitely. Omit to use the session's own namespace. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only idempotentHint. Description adds critical details: automatic parent directory creation, full content overwrite, specific errors (EISDIR, EINVAL). This goes well beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is brief (three sentences), front-loads the action, and efficiently adds necessary details without filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 params and no output schema, the description covers behavior (create, overwrite, auto-mkdir), error cases, and storage semantics. Complete enough for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers all parameters with descriptions (100% coverage). Description adds marginal value by specifying path is absolute and store is for cross-session, but these are already in schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Write content to a file, creating it if it doesn't exist.' It uses a specific verb ('Write') and resource ('file'), and distinguishes from sibling 'append' by implying overwrite behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides behavioral context (creates parent dirs, overwrites completely) and error conditions. It doesn't explicitly state when to use this vs sibling tools like 'append', but the overwrite behavior is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.2.2- First observed
append - First observed
glob - First observed
grep - First observed
ls - First observed
mkdir - First observed
mv - First observed
read - First observed
rm - First observed
stat - First observed
stores - First observed
write
TDQS
Scored across 11 tools
Each tool has a distinct file system operation (read, write, list, delete, search, etc.) with no functional overlap. An agent can easily distinguish between them.
Tool names are all lowercased single words, mostly verbs (append, glob, grep, ls, mkdir, mv, read, rm, stat, write) with one noun (stores). This follows a consistent command-like pattern.
With 11 tools, the server provides a comprehensive but not overwhelming set of file system operations. The count is well-scoped for the domain.
The tool set covers most file system operations including create, read, update, delete, search, and metadata. However, a copy operation is missing, which is a notable gap for a file system server.
Maintenance
Related MCP Connectors
Persistent file storage for AI agents via MCP and curl. Upload, download, and version files.
Cloud-hosted MCP server for durable AI memory
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseAqualityDmaintenanceMulti-user, file-backed MCP memory server enabling isolated namespaces and persistent memory across sessions and AI clients.910 npmMIT
- FlicenseAqualityDmaintenanceA universal MCP server that provides AI agents with structured tools for filesystem, database, shell, and git operations, enabling seamless interaction with projects.19-
- AlicenseNot gradedqualityCmaintenanceA self-hostable MCP server that provides permanent memory for AI agents using Postgres + pgvector for semantic search and Markdown file sync.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server providing AI agents with persistent shells, filesystem access, and multi-machine management backed by Docker containers or remote SSH hosts.1AGPL 3.0