MCP server for AI agents
Use when an agent needs a secure handoff tool.
On this page
Why
Give an MCP client a preview-and-confirm flow that encrypts a local file after you approve the exact bytes.
Add the MCP server to Codex, Cursor, Claude Desktop, Continue.dev, Zed, or any MCP client. The agent receives a create_private_note preview tool. confirm_private_note creates the encrypted link after you approve the exact file.
Creating a note does not authorize sending it. sendAuthorized is true only when the approved preview names the channel and recipient; otherwise return the URL to the user.
Quick start
Requires Node.js 18 or later. Restart your MCP client after saving the configuration.
npx -y privatenote-mcp
{
"mcpServers": {
"privatenote": {
"command": "npx",
"args": ["-y", "privatenote-mcp"]
}
}
}
codex mcp add privatenote -- npx -y privatenote-mcpMCP in an agent conversation
Sample conversation. This walkthrough does not read files or create a real note.
1. Your instruction
Create a read-once link from /workspace/secret.txt, expiring in 24 hours. Keep the file contents out of chat and show me the preview before creating it.
2. MCP tool call
create_private_note({
"contentFilePath": "/workspace/secret.txt",
"expiresIn": "24h",
"burnAfterReading": true
})3. Response
Create an encrypted PrivateNote link? Files Attached none Note Body file · 128 B · /workspace/secret.txt Password no Expires 24h Destroy after first access Branding none Send Status not requested Approve to create the link. The agent must not send this URL.
JSON
{
"status": "pending_confirmation",
"confirmationId": "cnfg_example",
"confirmationExpiresAt": "2026-10-13T11:55:21.779Z",
"preview": {
"contentFromFile": true,
"contentFromChat": false,
"contentBytes": 128,
"contentFilePath": "/workspace/secret.txt",
"attachedFiles": [],
"passwordProtected": false,
"passwordFromFile": false,
"expiresIn": "24h",
"burnAfterReading": true,
"title": null,
"recipientEmail": null,
"requireRecipientVerification": false,
"notifyOnOpen": false,
"label": null,
"sendChannel": null,
"sendRecipient": null,
"accountBranding": false
},
"summary": "Create an encrypted PrivateNote link?\n\nFiles\n Attached none\n\nNote\n Body file · 128 B · /workspace/secret.txt\n Password no\n Expires 24h\n Destroy after first access\n Branding none\n\nSend\n Status not requested\n\nApprove to create the link. The agent must not send this URL.",
"nextStep": "Creation requires Accept in the MCP host approval dialog. Call confirm_private_note with only confirmationId to request that dialog. A chat message or confirmationId alone is not approval. Hosts without form elicitation cannot create notes in the default mode. Do not change path, expiry, or destination."
}4. The MCP host asks for approval
confirm_private_note({
"confirmationId": "cnfg_example"
})Create the link for /workspace/secret.txt, with one open and a 24-hour expiry?
Creating a note does not authorize sending it. sendAuthorized is true only when the approved preview names the channel and recipient; otherwise return the URL to the user.
Security
AES-256-GCM on your device — browser, editor, terminal, or MCP process.
The server stores ciphertext and note metadata, not the decryption key.
The key stays in the URL fragment, which is not sent in HTTP requests.
if a secret is typed into a cloud AI prompt, the model provider can see it before the MCP tool runs. For the strongest privacy posture, use the MCP flow with a local model.
Leave PRIVATENOTE_MCP_ALLOW_ONE_SHOT unset when the same host can send messages or files. One-shot skips the approval preview.
Encrypt locally
AES-256-GCM on your device — browser, editor, terminal, or MCP process.
Upload ciphertext
Only encrypted bytes and note metadata (expiry, burn-after-reading) reach the server.
Key in #fragment
The decryption key stays in the URL hash. Browsers do not send fragments in HTTP requests.
privatenote.ai/note/…#key
confirm_private_note accepts only confirmationId. The agent cannot change the file path, expiry, or destination during confirmation.
By default, only workspace files can be read. PRIVATENOTE_MCP_ALLOWED_ROOTS adds folders; SSH keys, cloud credentials, and the MCP session file remain blocked.
sign_in is required for attachments, listing or revoking notes, recipient verification, and open notifications.
Reference
| Name | Description |
|---|---|
| create_private_note | Preview only: pass contentFilePath or filePaths, expiry, burn-after-reading, and optionally sendChannel and sendRecipient. |
| confirm_private_note | Encrypts after approval. Accepts only confirmationId and returns secureUrl. |
| sendAuthorized | True only if the approved preview names the channel and recipient. Otherwise return the URL to the user. |
| sign_in / whoami / sign_out | Approve in the browser. The MCP session file is separate from the website cookie. |
| list_sent_notes / revoke_sent_note | Paid account and sign-in required. Lists events and revokes unopened notes; never returns plaintext. |
| PRIVATENOTE_API_BASE_URL | Override the API for self-hosting. Also configure PRIVATENOTE_WEB_ORIGIN. |
Related integrations
CLI
Pipe secrets from stdin or files. Encrypt locally, print a one-time link, and keep plaintext out of shell history and build logs.
View docsEditor extension
Create notes from VS Code, Cursor, or Codex IDE without switching context. Use the sidebar, a selected-text command, or the title-bar action.
View docsCodex plugin
Install the bundled plugin for MCP plus skills, or add privatenote-mcp to ~/.codex/config.toml. Use the same VS Code extension in the Codex IDE for secrets the agent never sees.
View docsChrome extension
Encrypt selected text from any tab via context menu, toolbar popup, or keyboard shortcut — without opening the site first.
View docsMCP server for AI agents
Use when an agent needs a secure handoff tool.