Memoshelf · quickstart
Simple start
Memoshelf gives your AI a notebook it keeps between chats. You set it up once. After that your AI reads its notes before it starts and leaves a short note when it's done. No technical skill needed.
1. Sign in
Click Sign in, type your email, open the email from Memoshelf and click the button.
2. Pick a name for your AI
Any name you like — the name you already call it is best. Example: my-assistant.
3. Let your AI set itself up
- Open the AI app you already chat with.
- Start a new chat.
- Find the box below labeled Setup message — it holds the message for your AI — and click its Copy setup message button. Your AI's name is already filled in.
- Click in the chat's message box, paste (Ctrl+V on Windows, Cmd+V on Mac), and press Send.
- Your AI will reply with a short list of steps for its app. Do them one at a time. If you get stuck, tell your AI what you see on your screen.
Your AI connects to Memoshelf in one of two ways. It picks the way — you just follow along.
- • Connect (easiest): In your AI app's settings you add Memoshelf, type your Memoshelf email, and click Allow. Nothing to copy.
- • Secure key (only if Connect isn't offered): A key is like a password for your notebook.
- Your AI shows you where its private settings box is.
- On your Memoshelf page, click Make a key and give it the same name as your AI.
- Click Copy next to the new key.
- Paste it into that private settings box — never into the chat.
If your AI says neither way works, that app can't use Memoshelf yet. Try a different AI app, or email support@memoshelf.com.
Where to add Memoshelf in your app
These menu paths are current as of this build and may move.
- ChatGPT (web): Click your avatar (bottom left) → Settings → Plugins → Developer mode → turn it on → back in Plugins click Browse plugins → the + button (top right) → Add custom MCP server → Create MCP App → Name Memoshelf, Connection: Server URL https://memoshelf.com/mcp, Authentication OAuth → tick the risk box → Create → Memoshelf's sign-in/consent page opens → sign in with your Memoshelf email, keep the AI name, click Allow. (No Connect option? The private box for a secure key is that same plugin's Authentication or API key field.) The first time ChatGPT saves a note it shows a card 'Allow ChatGPT to use Memoshelf?' — click Always allow. Not it: 'Plugin Creator', 'Create plugin' and 'Upload plugin' build other plugins; skip them. ChatGPT may show a 'not all tools connected' notice after Allow — harmless.
- Claude (claude.ai): Settings → Connectors → Add custom connector → name Memoshelf, URL https://memoshelf.com/mcp (the address must end in /mcp) → Add → Connect → Sign in now (if asked, Register automatically) → sign in → Allow. (Secure key instead? Open the connector's Advanced settings for the private key box.) The Claude phone app can add connectors too.
- grok.com: Settings → Connectors → add MCP server https://memoshelf.com/mcp → sign in → Allow.
- Cursor, other IDEs and other apps with a secrets box: Use the Secure key path: Make a key on your Memoshelf page, paste it into the app's secrets box as MEMOSHELF_API_KEY, never into a chat.
- Any app not listed: Paste the Setup message below and let your AI point you to its setting.
On a phone: when the Memoshelf sign-in opens, request the link, then type the code from the email into the same screen (do not tap the link).
NEVER PASTE YOUR KEY INTO A CHAT.
Not into your AI's chat, not into email, not to anyone. A key goes only into a secure settings box that your AI points you to. If a key ever lands in a chat by mistake, delete it on your Memoshelf page and make a new one — it takes one click.
Use exactly the same AI name everywhere — on the consent screen and in the message — lowercase, no spaces (example: chatgpt).
Setup message
I use Memoshelf (https://memoshelf.com), a notebook my AI assistants keep between chats. Please set it up for yourself. Your name on my notebook: YOUR-AI-NAME Important: never ask me to paste a key into this chat, and never show or repeat a key. 1. I will add Memoshelf to this app myself, in this app's own settings — you do not need to do it. Tell me, for THIS app: (a) where the connectors, integrations, MCP servers or apps setting is (menu path), and (b) what to enter: name Memoshelf, server URL https://memoshelf.com/mcp, authentication OAuth, then sign in with my Memoshelf email. If this app has no such setting but you can read a secret from a secure settings box, tell me exactly where that box is and I will create a key named YOUR-AI-NAME at https://memoshelf.com/app and paste it there under MEMOSHELF_API_KEY. If this app has neither, say so plainly. Do not say you cannot connect — I do the connecting; you only point me to the setting. 2. Once connected, read with lane=YOUR-AI-NAME (entries tagged lane:YOUR-AI-NAME in your shared workspace, what_happened_last). A new notebook is empty — that's fine. 3. Ask me in one question what I mainly use you for, then save a pinned page titled "How we work" (3–5 short lines) tagged lane:YOUR-AI-NAME. It comes back automatically with every check-in. 4. Read it back and confirm in one sentence that it worked. 5. Optional extra — saving an instruction in your AI is not required, because the How we work page comes back with every check-in. If I want one, give me the permanent instruction text in ONE block, clearly labeled PASTE THIS INTO YOUR CUSTOM INSTRUCTIONS, and tell me exactly where that setting is in THIS app (for ChatGPT: avatar → Settings → Personalization → Custom instructions). Do not put any other text in a copy box. If I already have a Memoshelf block there, I will replace it, not add a second one. Then I will open a brand-new chat and ask 'what were we working on?' without mentioning Memoshelf — setup is finished only when that chat reads the notebook on its own. From now on: read the notebook at the start of each task, and save one short note at the end (what we did, what's next), tagged lane:YOUR-AI-NAME. Never save passwords, account numbers, API keys, anyone's medical or health information, or other private details in the notebook. Technical reference for you: https://memoshelf.com/quickstart#developers and https://memoshelf.com/openapi.json
4. Open a new chat and ask your AI: what's in my notebook? If it tells you, you're done.
How you know it worked
Your AI tells you in one sentence, and your Memoshelf page shows your AI as Connected or its key as Last used: just now. In a new chat, ask 'what were we working on?' without mentioning Memoshelf. If your AI reads the notebook on its own, it is set up.
On your phone, desktop app and browser
- On every surface where the connector is added (phone, desktop app, browser), your AI reads the shelf at the start of every task and saves a note at the end.
- A connector added to your account shows up on every surface of that AI. You add it once.
- Run the day-two check once on each surface you use.
- Claude: the preferences box is Settings → Profile → preferences in the app.
Day two: is it working?
Ask your AI: what did we do last time? It should answer from Memoshelf.
If it can't, paste this to your AI:
Fix message
Add this to your permanent instructions (not just this chat) for YOUR-AI-NAME: Before any task, read my Memoshelf notebook (read with lane=YOUR-AI-NAME for entries tagged lane:YOUR-AI-NAME in your shared workspace). When you finish, save one short note tagged lane:YOUR-AI-NAME saying what you did and what's next. Then tell me exactly where you saved this instruction.
Setting up several AIs or standing rules? Read the playbooks.
Something not working? See Help.
For developers: the same setup by hand
From the landing page to the first note
One path from the landing page to the first note, written for a person who has never seen the product. A copy-paste sits beside each step for a programmer.
Find it
Open https://memoshelf.com. Click Quickstart on the landing page.
What you should see: You are reading this page.
Sign in by magic link
Open Sign in, enter your email, open the email, and click the link.
What you should see: The email contains a link. Click it. Do not copy a callback URL by hand.
Land in the app
The link takes you to memoshelf.com/app, signed in.
What you should see: The address bar is https://memoshelf.com/app and you are signed in. If you land on any other host, stop.
Make a key with the smallest scopes
Make one key with scope write — the smallest scope that can log a run and store a note. Label it lane:<name>.
What you should see: The app shows the secret once. Copy it now.
Where the key goes
Put the key in an environment variable or the caller's secret store. Never a prompt. Never a file in git.
What you should see: Later calls send the key as an Authorization header, never in the URL.
The first log_run
Write a run: a goal and an outcome for this lane.
POST /v1/runs
curl -sS -X POST https://memoshelf.com/v1/runs \
-H "Authorization: Bearer $MEMOSHELF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"goal":"first run","outcome":"signed up","tags":["lane:my-assistant"]}'
What you should see: You get 201 and a run id.
Expected response
{
"id": "run_onboarding_example",
"goal": "first run",
"outcome": "signed up",
"tools": [],
"operator": "my-assistant",
"created_at": "2026-09-28T17:00:00.000Z",
"status": "succeeded",
"started_at": "2026-09-28T17:00:00.000Z",
"tags": [
"lane:my-assistant"
]
}
The first store_note
Store a pinned standing-rules note tagged lane:<name>.
POST /v1/notes
curl -sS -X POST https://memoshelf.com/v1/notes \
-H "Authorization: Bearer $MEMOSHELF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"standing-rules","body":"Tag every write lane:<name>. Pin standing-rules pages.","tags":["lane:my-assistant"],"pinned":true}'
What you should see: You get 201 and a note id.
Expected response
{
"id": "note_onboarding_example",
"title": "standing-rules",
"body": "Tag every write lane:<name>. Pin standing-rules pages.",
"tags": [
"lane:my-assistant"
],
"operator": "my-assistant",
"created_at": "2026-09-28T17:00:00.000Z",
"pinned": true
}
The first what_happened_last
Read the shelf back. After logging a run and storing a note, the runs array includes that run and the notes array lists the pinned note first.
GET /v1/what_happened_last?tags=lane:<name>
curl -sS https://memoshelf.com/v1/what_happened_last?tags=lane:my-assistant -H "Authorization: Bearer $MEMOSHELF_API_KEY"
What you should see: The notes array lists the pinned note first.
Expected response
{
"markdown": "applied: {\"tags\":[\"lane:my-assistant\"]}\n\n## Runs\n- succeeded · first run — signed up\n\n## Notes\n- standing-rules: Tag every write lane:<name>. Pin standing-rules…",
"tokens": 22,
"n": 5,
"truncated": false,
"next_cursor": null,
"runs": [
{
"id": "run_onboarding_example",
"created_at": "2026-09-28T17:00:00.000Z",
"goal": "first run",
"outcome": "signed up",
"status": "succeeded"
}
],
"notes": [
{
"id": "note_onboarding_example",
"created_at": "2026-09-28T17:00:00.000Z",
"body": "Tag every write lane:<name>. Pin standing-rules pages.",
"title": "standing-rules",
"tags": [
"lane:my-assistant"
],
"pinned": true
}
],
"notes_omitted": 0,
"applied": {
"tags": [
"lane:my-assistant"
]
}
}
Bounded writes
A lane-bounded key can only write its own lane. POST /v1/lanes/<lane>/notes and POST /v1/lanes/<lane>/runs make that bound write visible in the URL (a bounded key may only call its own lane). lane:team is writable only by an unrestricted key.
Rule
lane:<name> on everything, rules on standing-rules pages, pinned.
Agent prompt
You'll see this
You have one Memoshelf key for this lane. Before you write, read with lane=YOUR-AI-NAME (GET /v1/what_happened_last?lane=<name> for entries tagged lane:NAME in your shared workspace); then POST /v1/notes tagged lane:<name> (pin standing-rules pages) and read it back — the pinned note comes first.
Glossary
- operator = the public prefix of the key you created
- md = one-line digest, full text in notes[].body under max_chars default 4,000 max 80,000
Connect
- In the chat client, add a custom connector / MCP server with URL https://memoshelf.com/mcp. There is no field for an API key — that is expected.
- The client fetches /.well-known/oauth-protected-resource, then /.well-known/oauth-authorization-server, and registers itself at /oauth/register.
- Sign in on the page that opens (same magic link as /app). Name the AI and click Allow. No API key is created or shown. The grant is bounded to that name.
- After Allow, the client stores a Bearer token. Data tools (what_happened_last, notes) now authorize. Header-key auth (x-api-key or Authorization: Bearer ms_…) keeps working.
- Revoke the grant on owner /app under Connected AIs. A 401 from /mcp carries WWW-Authenticate: Bearer resource_metadata=… so the client can rediscover.
What the warnings mean
A write always succeeds. warnings: ["no_read_before_write"] means this key had no what_happened_last, notes list, notes get, or MCP notes read in the last READ_WINDOW_MINUTES (default 30). Fix the prompt: read first, then write. warnings: ["process_claim_contradicted"] means the POST sent process: {"read_first": true} but the meter saw no read — drop the claim or actually read. Mode off on the key silences warnings. The record still stores read_before_write.
How your agent sets the alert destination
PATCH /v1/workspace with {"alert_webhook_url":"https://…","alert_email":"you@example.com"} (write key or signed-in session). MCP keys with settings_op: "alert" and the same fields. The webhook path delivers process.skipped_read and process.claim_contradicted with HMAC. Email alerts are not sent yet. Set alert_webhook_url to receive alerts today; alert_email is saved for when email alerts launch.
If something is off
401
Missing, revoked, or wrong key. You'll see this.
You'll see this
{
"error": "unauthorized",
"code": "unauthorized",
"fix": "Sign in or send a valid API key in Authorization or X-Api-Key.",
"help": "/help#help-401"
}
Empty read
A 200 with empty runs and notes is an empty shelf, not a failure. You'll see this.
You'll see this
{
"markdown": "applied: {\"tags\":[\"lane:my-assistant\"]}\n\nNo recent runs or notes.",
"tokens": 7,
"n": 5,
"truncated": false,
"next_cursor": null,
"runs": [],
"notes": [],
"notes_omitted": 0,
"applied": {
"tags": [
"lane:my-assistant"
]
}
}
4xx on POST
POST /v1/notes rejected the body. You'll see this.
You'll see this
{
"error": "body_required",
"code": "body_required",
"fix": "Include body and try once more.",
"help": "/help#help-400"
}