Secure Local Memory MCP Server avatar

Secure Local Memory MCP Server

Pricing

Pay per usage

Go to Apify Store
Secure Local Memory MCP Server

Secure Local Memory MCP Server

Model Context Protocol (MCP) server for encrypted local storage and memory vaults.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

CQ

CQ

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

a day ago

Last modified

Share

A Model Context Protocol (MCP) server that stores key/value secrets encrypted at rest and lets an AI agent (or a batch job) store and retrieve them by key. Encryption is real AES-256-GCM with a key derived from your passphrase via scrypt — the persistent vault on disk never contains the plaintext, and the wrong passphrase fails authentication.

It runs three ways:

  1. Hosted MCP server (Standby HTTP) — the way MCP clients connect on Apify: when Apify starts the Actor in Standby mode it serves the MCP protocol as stateless JSON-RPC 2.0 over HTTP (initialize, tools/list, tools/call) and stays up to be reused.
  2. Platform / batch mode: you pass a list of commands (or a single query) in the Actor input. Each command is executed, the encrypted vault is persisted, and one result row per command is pushed to the dataset.
  3. Local stdio MCP mode: when the Actor is run locally with no commands and a process pipes JSON-RPC into stdin, it speaks MCP (JSON-RPC 2.0) over stdin/stdout so it can be wired into an MCP client as a local server.

What it does

  • Encrypts each stored value with AES-256-GCM (16-byte random salt + 12-byte random IV per value; key derived with scrypt). The stored blob is base64(salt | iv | tag | ciphertext).
  • Persists the encrypted vault in a named Apify key-value store (secure-local-memory-vault), which is not purged between runs, so the vault persists across runs (when a real passphrase is used — see Limitations for the demo/ephemeral case).
  • Decrypts on retrieval only with the correct passphrase. A wrong passphrase is rejected by the GCM authentication tag (you get an error, never a wrong/garbage value).

Output — the MCP tools this server exposes

The primary output of this Actor is its MCP tools. An MCP client calls them via tools/call; each returns a JSON result object.

ToolParametersReturns / purpose
store_secretkey (string, required), value (string, required)Encrypts value with AES-256-GCM and stores it under key. Returns { status, message }.
retrieve_secretkey (string, required)Decrypts and returns the value stored under key (value: "NOT_FOUND" and an error status if the key is missing; an error if the passphrase is wrong).
list_keys(none)Returns the list of keys currently in the vault as a JSON array. Values stay encrypted.

A tool result object has this shape:

FieldTypeDescription
toolstringThe tool that ran.
keystringThe affected key (when applicable).
valuestringThe decrypted value (successful retrieve_secret), the JSON key list (list_keys), or NOT_FOUND. Absent for store_secret.
statusstringsuccess or error.
messagestringHuman-readable status / error description.

Batch-mode dataset output

When you run the Actor in batch mode (with commands/query) or as a demo run (no input), the same result objects are also pushed to the run's default dataset — one row per command, plus an info/config status row on demo runs. The dataset row shape is exactly the tool-result shape above (tool, key, value, status, message), described in .actor/dataset_schema.json. A combined { "results": [...] } object is also written to the default key-value store under the key OUTPUT.

Example dataset row (retrieve):

{
"tool": "retrieve_secret",
"key": "api_token",
"value": "sk-live-abc123",
"status": "success",
"message": "Decrypted secret for key: api_token"
}

The encrypted vault itself is stored in the named key-value store secure-local-memory-vault under the record ENCRYPTED_VAULT (a map of key → base64 ciphertext). Plaintext values are never written there.


Input

All fields are optional. In batch mode you provide commands or query; a passphrase (or the SLM_PASSPHRASE env var) is what makes stored secrets secure and persistent — without it the Actor runs in an insecure demo mode (see Limitations).

FieldTypeRequiredDescription
passphrasestring (secret)OptionalMaster passphrase used to derive the AES key via scrypt. The same passphrase is needed to decrypt previously stored secrets. Falls back to the SLM_PASSPHRASE environment variable if omitted. If neither is set, the run uses an insecure demo passphrase and an ephemeral vault.
commandsarray of objectsNoBatch of tool calls. Each item is { "tool": "store_secret", "key": "...", "value": "..." }, { "tool": "retrieve_secret", "key": "..." }, or { "tool": "list_keys" }. JSON-RPC-style items ({ "method": "tools/call", "params": { "name", "arguments" } }) are also accepted. Defaults to [].
querystringNoA single command as a JSON string — either a simple object like {"tool":"store_secret","key":"k","value":"v"} or a raw JSON-RPC line. Use commands for batches. Defaults to "".

Example input

{
"passphrase": "correct horse battery staple",
"commands": [
{ "tool": "store_secret", "key": "api_token", "value": "sk-live-abc123" },
{ "tool": "store_secret", "key": "db_pw", "value": "p@ssw0rd" },
{ "tool": "list_keys" },
{ "tool": "retrieve_secret", "key": "api_token" }
]
}

Connecting as a hosted MCP server (Standby HTTP)

On Apify, MCP clients connect to the Actor's Standby URL and speak stateless JSON-RPC 2.0 over HTTP. A GET returns server info and the tool names; a POST carries the JSON-RPC request:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": { "name": "store_secret", "arguments": { "key": "k", "value": "v" } } }

In Standby mode the passphrase is taken from the SLM_PASSPHRASE environment variable (it cannot be passed per request); if it is unset the server uses the insecure demo passphrase.

Running as a local MCP server (stdio mode)

Run locally with no commands/query and pipe JSON-RPC requests on stdin:

$SLM_PASSPHRASE="correct horse battery staple" node src/main.js

Then send newline-delimited JSON-RPC, e.g.:

{"jsonrpc":"2.0","id":1,"method":"tools/list"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"store_secret","arguments":{"key":"k","value":"v"}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"retrieve_secret","arguments":{"key":"k"}}}

Each request gets a JSON-RPC response on stdout.


Setup / auth

  • No third-party API keys. The only credential is your passphrase (or SLM_PASSPHRASE), which never leaves the Actor.
  • Encryption uses Node's built-in crypto module — no extra dependencies beyond the Apify SDK.

Pricing

This Actor runs on the Apify platform and is billed by the platform-usage (compute/storage) it consumes while running — there are no third-party API costs. See the Actor's pricing tab on Apify for current details.


Limitations

  • At-rest encryption covers the persistent vault, not the per-run outputs. A successful retrieve_secret returns the decrypted value; in batch/demo mode that plaintext is written to the run's dataset and to the OUTPUT key-value record. Treat run storage accordingly.
  • Demo / ephemeral mode. If no passphrase (and no SLM_PASSPHRASE) is set, the Actor runs with an insecure hard-coded demo passphrase and — in batch mode — a temporary, non-persistent vault. Set a real passphrase to store secrets securely and persistently.
  • The Standby HTTP endpoint has no authentication. It responds with Access-Control-Allow-Origin: * and does not check any auth header, so anyone who can reach the URL can call the tools. Protect the Standby URL at the platform level and do not treat it as an authenticated API.
  • Vault scope. The vault lives in the named key-value store secure-local-memory-vault on the account that runs the Actor. If you run it under a different account/store, or that store is deleted, the data is gone. There is no external/shared database backend.
  • If you lose the passphrase, the data is unrecoverable — by design. There is no recovery mechanism or backdoor.
  • Requires an MCP client for the MCP transports (Standby HTTP and local stdio). Batch mode does not need an MCP client.
  • Single-vault, single-passphrase design. It is not a multi-tenant secrets manager and does not do key rotation, sharing, or access control beyond the passphrase.
  • All values are strings. Binary blobs must be base64/encoded by the caller.

License

Provided as-is. See repository for details.