Developer

Project Filesystem API

Read, write, and manage files in the project's folder directory.

The Project Filesystem API gives your resource access to files in the project folder - the local directory associated with the project the resource belongs to. This is different from the Filesystem API which operates on the resource’s private data directory.

Capabilities:

  • fs:project - read-only access (readFile, readFileBase64, readDir, exists, stat)
  • fs:project:write - read + write access (all operations including writeFile, mkdir, delete, move, copy)

Frontend (iframe)

import { createResourceClient } from "@rightplace/sdk";

const rp = createResourceClient();
await rp.ready();

// Read a project file
const pkg = await rp.project.readFile("package.json");
const config = JSON.parse(pkg);

// List directory contents
const entries = await rp.project.readDir("src");
// → [{ name: "index.ts", type: "file", size: 1024 }, { name: "components", type: "dir", size: 0 }]

// Check if a file exists
const hasConfig = await rp.project.exists(".eslintrc.json");

// Get file metadata
const info = await rp.project.stat("README.md");
// → { size: 2048, type: "file", created: 1713250000, modified: 1713260000 }

// Write operations (requires fs:project:write)
await rp.project.writeFile("output/report.json", JSON.stringify(data, null, 2));
await rp.project.mkdir("output/exports");
await rp.project.copy("config.json", "config.backup.json");
await rp.project.move("old-name.txt", "new-name.txt");
await rp.project.delete("output/temp");

Backend (Node.js)

import { createResourceServer } from "@rightplace/sdk/server";

const server = createResourceServer({
  methods: {
    analyzeProject: async (_params, { rp }) => {
      // Read project files
      const entries = await rp.project.readDir("src");
      const tsFiles = entries.filter(e => e.name.endsWith(".ts"));

      // Read and analyze each file
      const results = [];
      for (const file of tsFiles) {
        const content = await rp.project.readFile(`src/${file.name}`);
        results.push({ file: file.name, lines: content.split("\n").length });
      }

      return results;
    },

    generateReport: async (params, { rp }) => {
      await rp.project.mkdir("reports");
      await rp.project.writeFile(
        `reports/${params.name}.json`,
        JSON.stringify(params.data, null, 2)
      );
      return { ok: true };
    },
  },
});

server.start();

MCP

The project folder isn’t exposed as a raw filesystem over MCP. Agents read project content through higher-level tools that are aware of its structure:

GoalMCP tool
List docs in the projectrightplace_docs_list
Read a docrightplace_docs_get
Write a docrightplace_docs_create / rightplace_docs_update
Walk git staterightplace_git_status, rightplace_git_file_content
Object storage in the projectrightplace_storage_list, rightplace_storage_get_object

RobinPath Bridge

Same story from a script - use the domain-specific calls, not a raw filesystem:

# List every doc in the active project
rightplace.docs_list into $docs
for $d in $docs
  log $d.path
endfor

# Read a doc
rightplace.docs_get {path: "rightplace/docs/README.md"} into $doc
log "content:" $doc.content

# Or list raw objects stored under a resource
rightplace.storage_list {resourceId: "res_abc", prefix: "exports/"} into $keys

If you really need filesystem primitives, use the built-in fs module with absolute paths - but honoring the manifest capability model is always preferred.

API Reference

rp.project.readFile(path)

Read a file as UTF-8 text.

ParameterTypeDescription
pathstringRelative path to the file
ReturnsPromise<string>File contents as text

rp.project.readFileBase64(path)

Read a file as base64-encoded binary.

ParameterTypeDescription
pathstringRelative path to the file
ReturnsPromise<string>File contents as base64

rp.project.writeFile(path, content)

Write text content to a file. Creates parent directories automatically. Requires fs:project:write.

ParameterTypeDescription
pathstringRelative path to the file
contentstringText content to write

rp.project.writeFileBase64(path, content)

Write binary content from a base64 string. Creates parent directories automatically. Requires fs:project:write.

ParameterTypeDescription
pathstringRelative path to the file
contentstringBase64-encoded content

rp.project.mkdir(path)

Create a directory (and any missing parent directories). Requires fs:project:write.

ParameterTypeDescription
pathstringRelative path to create

rp.project.readDir(path)

List the contents of a directory.

ParameterTypeDescription
pathstringRelative directory path
ReturnsPromise<FsDirEntry[]>Array of entries

Each entry: { name: string, type: "file" | "directory", size: number }

rp.project.delete(path)

Delete a file or directory (recursive for directories). Requires fs:project:write.

ParameterTypeDescription
pathstringRelative path to delete

rp.project.move(from, to)

Move or rename a file or directory. Requires fs:project:write.

ParameterTypeDescription
fromstringSource relative path
tostringDestination relative path

rp.project.copy(from, to)

Copy a file. Requires fs:project:write.

ParameterTypeDescription
fromstringSource relative path
tostringDestination relative path

rp.project.exists(path)

Check if a file or directory exists.

ParameterTypeDescription
pathstringRelative path to check
ReturnsPromise<boolean>

rp.project.stat(path)

Get file or directory metadata.

ParameterTypeDescription
pathstringRelative path
ReturnsPromise<FsStatResult>Metadata object

Returns: { size: number, type: "file" | "directory", created: number, modified: number }

Timestamps are seconds since Unix epoch.

Path Rules

  • All paths are relative to the project folder
  • No ../ - path traversal is rejected
  • No absolute paths - rejected with an error
  • Parent directories are created automatically for write operations
  • Paths use forward slashes (/) on all platforms

Manifest Configuration

{
  "capabilities": [
    "fs:project"
  ]
}

For write access:

{
  "capabilities": [
    "fs:project:write"
  ]
}

Note: fs:project:write implies read access - you do not need to list both.

Use Cases

  • Code analysis tools - read source files to generate reports, metrics, or documentation
  • Build tools - read project configuration and write build artifacts
  • Deployment resources - read deployment configs and push to hosting
  • Linters / formatters - read and rewrite source files with formatting changes
  • Project scaffolding - generate boilerplate files and directory structures