Developer

Storage API

Key-value storage scoped to your custom applet.

The Storage API provides simple key-value storage scoped to your applet. Each applet has its own isolated namespace - you cannot read or write another applet’s storage.

Capability required: storage:kv

Frontend (iframe)

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

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

// Set a value
await rp.storage.set("api_endpoint", "https://api.example.com");

// Get a value
const endpoint = await rp.storage.get("api_endpoint");
// → "https://api.example.com"

// Get a non-existent key
const missing = await rp.storage.get("not_here");
// → null

// List keys by prefix
await rp.storage.set("cache:page1", "...");
await rp.storage.set("cache:page2", "...");
await rp.storage.set("setting:theme", "dark");

const cacheKeys = await rp.storage.list("cache:");
// → ["cache:page1", "cache:page2"]

// Delete a key
await rp.storage.delete("cache:page1");

Backend (Node.js)

The same API is available in backend methods via the rp host object:

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

const server = createResourceServer({
  methods: {
    saveSettings: async (params, { rp }) => {
      await rp.storage.set("settings", JSON.stringify(params));
      return { ok: true };
    },
    
    loadSettings: async (_params, { rp }) => {
      const raw = await rp.storage.get("settings");
      return raw ? JSON.parse(raw) : {};
    },
  },
});

server.start();

MCP

A different storage tier is exposed to agents: the project’s object storage (files/folders), not the applet’s private key-value store. Use these tools for blob-style data; they all scope by resourceId.

ToolPurposePermission
rightplace_storage_listList objects with an optional prefixstorage:read
rightplace_storage_get_objectRead one object (text or base64)storage:read
rightplace_storage_put_objectWrite/overwrite one objectstorage:write
rightplace_storage_delete_objectDelete one objectstorage:write
rightplace_storage_delete_prefixDelete everything under a prefixstorage:write
rightplace_storage_create_folderCreate an empty folder markerstorage:write
rightplace_storage_renameRename an object or prefixstorage:write

The per-applet KV store (rp.storage.get/set) is NOT in MCP - it’s sandboxed to the iframe.

RobinPath Bridge

From a script, use dynamic MCP names on the rightplace module:

# List
rightplace.storage_list {resourceId: "res_abc", prefix: "cache/"} into $objects
for $o in $objects
  log $o.key $o.size
endfor

# Write text
rightplace.storage_put_object {
  resourceId: "res_abc",
  key: "cache/report.txt",
  body: "generated at 2026-04-19"
}

# Read
rightplace.storage_get_object {resourceId: "res_abc", key: "cache/report.txt"} into $obj
log $obj.body

# Delete
rightplace.storage_delete_prefix {resourceId: "res_abc", prefix: "cache/"}

API Reference

rp.storage.get(key)

ParameterTypeDescription
keystringThe key to retrieve
ReturnsPromise<string | null>The value, or null if not found

rp.storage.set(key, value)

ParameterTypeDescription
keystringThe key to store
valuestringThe value to store
ReturnsPromise<void>

rp.storage.delete(key)

ParameterTypeDescription
keystringThe key to delete
ReturnsPromise<void>

rp.storage.list(prefix?)

ParameterTypeDescription
prefixstring (optional)Filter keys by prefix
ReturnsPromise<string[]>Array of matching key names

Manifest Configuration

{
  "capabilities": [
    "storage:kv"
  ]
}

Notes

  • Values are strings only. To store objects, use JSON.stringify() / JSON.parse().
  • Storage persists across app restarts and applet updates.
  • Storage is deleted when the applet is uninstalled.
  • There is no size limit per key, but keep values reasonable (under 1MB).